S3c2440代码重定位详解3---链接脚本的解析

发布者:Huanle最新更新时间:2021-09-09 来源: eefocus关键字:S3c2440  代码重定位  链接脚本 手机看文章 扫描二维码
随时随地手机看文章

在这里插入图片描述

链接脚本的语法


SECTIONS {

...

secname start BLOCK(align) (NOLOAD) : AT ( ldadr )

  { contents } >region :phdr =fill

...

}


解释:


 secname  :段名

 start  :起始地址:运行时的地址(runtime addr);重定位地址(relocate addr)

 AT ( ldadr ) :可有可无(load addr:加载地址) 不写时LoadAddr = runtime addr

 { contents } 的内容: 

 start.o //内容为start.o文件

 *(.text)所有的代码段文件

 start.o *(.text)文件


elf文件格式


1 链接得到elf文件,含有地址信息(load addr)


2 使用加载器


:: 2.1 对于裸板是JTAG调试工具


:: 2.2 对于APP,加载器也是APP 把elf文件解析读入内存的加载地址


3 运行程序


4 如果loadaddr != runtimeaddr程序本身要重定位


核心程序运行时应该位于 runtimeaddr(reloate addr)或者链接地址


bin文件


1 elf生成bin文件 


2 硬件机制启动


3 如果bin文件所在位置 不等于runtimeaddr ,程序本身实现重定位

在这里插入图片描述

bin文件/elf文件都不保存bss段 这些都是初始值为0 或者没有初始化的全局变量


程序运行时把bss段对应的空间清零


做个实验,把全局变量g_A以16进制打印出来


/* 0xABCDEF12 */

void printHex(unsigned int val)

{

    int i;

    unsigned char arr[8];


    /* 先取出每一位的值 */

    for (i = 0; i < 8; i++)

    {

        arr[i] = val & 0xf;

        val >>= 4;   /* arr[0] = 2, arr[1] = 1, arr[2] = 0xF */

    }


    /* 打印 */

    puts("0x");

    for (i = 7; i >=0; i--)

    {

        if (arr[i] >= 0 && arr[i] <= 9)

            putchar(arr[i] + '0');

        else if(arr[i] >= 0xA && arr[i] <= 0xF)

            putchar(arr[i] - 0xA + 'A');

    }

}


//打印初始值为0的变量

int g_A = 0;

int g_B;


int main(void)

{

    uart0_init();


    puts("nrg_A = ");

    printHex(g_A);

    puts("nr");


上述代码,没有清理bss段 g_A等于莫名奇妙的值 并不等于0 所以需要清理bss段


修改lds链接文件


SECTIONS {

   .text   0  : { *(.text) }

   .rodata  : { *(.rodata) }

   .data 0x30000000 : AT(0x700) 

   { 

      data_load_addr = LOADADDR(.data);

      data_start = . ;

      *(.data) 

      data_end = . ;

   }


   bss_start = .; //bss开始地址是当前位置

   .bss  : { *(.bss) *(.COMMON) }

   bss_end = .; //bss结束地址也是当前位置

}


修改start.s,清除bss段


/* 清除BSS段 */

ldr r1, =bss_start

ldr r2, =bss_end

mov r3, #0

clean:

    strb r3, [r1]

    add r1, r1, #1

    cmp r1, r2

    bne clean


    bl main

halt:


现在的代码全局变量就是为0,通过几行代码,就可以少几十个甚至上千个全局变量的存储空间。

关键字:S3c2440  代码重定位  链接脚本 引用地址:S3c2440代码重定位详解3---链接脚本的解析

上一篇:S3c2440代码重定位详解2---链接脚本的引入与简单测试
下一篇:S3c2440代码重定位详解4---拷贝代码和链接脚本的改进

推荐阅读最新更新时间:2024-11-04 10:46

嵌入式Linux学习笔记之——代码定位002_链接脚本的引入
① NOR启动: ② nand 启动: 上次讲到的g_char不能按照程序正确输出的原因是nor启动的时候g_char在nor flash中,其不可写的特性决定了输出结果。 现在能否修改Makefile让nor启动时讲代码拷贝到SDRAM中,这样就可以实现全局变量的可读可写了。 现在想在nor flash启动的时候将其中的代码段拷贝至SDRAM中0地址起始的空间,将全局变量g_char拷贝至0x30000000起始的空间。 编译之后发现.bin文件变成了800M,805306369-- 0x30000001,符合程序中的g_char所占1字节的设置。 但是nor flash一共才2M,不可实现。 解决方
[单片机]
嵌入式Linux学习笔记之——<font color='red'>代码</font><font color='red'>重</font><font color='red'>定位</font>002_<font color='red'>链接</font><font color='red'>脚本</font>的引入
基于S3C2440的Linux内核移植和yaffs2文件系统制作--启动系统
第三章 启动系统 将前面两章生成的内核映像文件和根文件系统映像文件下载到mini2440开发板,查看启动信息。我成功移植启动信息如下: VIVI version 0.1.4 ( root@capcross ) (gcc version 2.95.3 20010315 (release)) #0.1.4 Mon Oct 27 10:18:15 CST 2008 MMU table base address = 0x33DFC000 Succeed memory mapping. DIVN_UPLL0 MPLLVal CLKDIVN:5h +------------------------------------------
[单片机]
s3c2440 mmu.c的分析
/************************************************ NAME : MMU.C DESC : Revision : 1.0 ************************************************/ #include def.h #include option.h #include 2440addr.h #include 2440lib.h #include 2440slib.h #include mmu.h // 1) Only the section table is used. // 2) The cachable/non-cach
[单片机]
对<font color='red'>s3c2440</font> mmu.c的分析
s3c2440如何设置fclk
  1设置LockTIme变频锁定时间   2设置FCLK与晶振输入频率(Fin)的倍数   3设置FCLK,HCLK,PCLK三者之间的比例   LockTIme 变频锁定时间由LOCKTIME寄存器(见下表)来设置,由于变频后开发板所有依赖时钟工作的硬件都需要一小段调整时间,该时间计数通过设置 LOCKTIME寄存器[31:16]来设置UPLL(USB时钟锁相环)调整时间,通过设置LOCKTIME寄存器 [15:0]设置MPLL调整时间,这两个调整时间数值一般用其默认值即可。   表2-8变频锁定时间寄存器(LOCKTIME)      FCLK与Fin的倍数通过MPLLCON寄存器设置,三者之前有以下关系:   M
[单片机]
<font color='red'>s3c2440</font>如何设置fclk
OpenCV2.0.0移植到ARM9(五)(JZ2440----S3c2440)
Linux系统:Ubuntu9.10 交叉编译器:arm-linux-gcc-4.3.2(已安装) Qt:qt-x11-opensource-src-4.5.3.tar.gz qt-embedded-linux-opensource-src-4.5.3.tar.gz 1、安装Qt Qt下载地址:https://www.qt.io/download-open-source/ 这里下载的安装包为:qt-embedded-linux-opensource-src-4.5.3.tar.gz(大小123MB) 2、安装Qt-x11 将qt-x11-opensource-src-4.5.3.tar.gz包放到U
[单片机]
OpenCV2.0.0移植到ARM9(五)(JZ2440----S3c2440)
冲孔打桩机的自动控制系统设计
0 引言 冲孔打桩机主要由桩锤、支架、卷扬机以及其他辅助设备组成,其工作原理是利用冲孔打桩机的卷扬机构,将电动机输出动力的回转运动转变为往复运动,通过钢丝绳来带动桩锤的提升,并在一定高度时使桩锤自由下落,利用桩锤的冲击作用冲挤土层或破碎岩石,同时钻渣随泥浆(或用取渣桶)排出,最后在地基土中形成桩孔。施工人员在桩孔内放置钢筋笼,灌注混凝土而制成桩。 目前,冲孔打桩机的打桩作业均由人工手动机械式操纵来完成。操作人员在工作过程中需要频繁对离合装置、刹车装置等控制部件进行操纵,劳动强度很大。随着微电子技术和自动控制理论的发展,将自动控制技术应用于冲孔打桩机,实现打桩的全自动化或半自动化,使操作人员从繁琐重复的体力劳动中解放出来成为
[单片机]
冲孔打桩机的自动控制系统设计
S3C2440——使用URAT0查询方式发送和接收字符串
UART初始化函数 void Uart_Init(int pclk,int baud) { int i; rGPHCON|=0xa0; //GPH2,GPH3 as TXD0,RXD0 rGPHUP = 0x0; //GPH2,GPH3内部上拉 if(pclk == 0) pclk = PCLK; rUFCON0 = 0x0; //禁止3个通道的FIFO控制寄存器 rUFCON1 = 0x0; rUFCON2 = 0x0; rUMCON0 = 0x0; rUMCON1 = 0x0; rUMCON2 = 0x0; //初始化3个通道的MODEM控制寄存器,禁止AFC //Lin
[单片机]
u-boot-2011.06在基于s3c2440开发板的移植之支持YAFFS2
YAFFS和YAFFS2是由AlephOne公司开发的NAND Flash文件系统。YAFFS和YAFFS2主要差异在于PAGE读写size的大小,YAFFS2可支持到2Kper page,远高于YAFFS的512 Bytes,因此YAFFS2对于大容量NANDflash来说更具优势。 就u-boot来说,主要是能够使它支持下载YAFFS文件,以供操作系统使用,因此只要能够实现YAFFS的写入功能即可,无需实现读取功能。 u-boot-2011.06是支持写入YAFFS文件的,但默认情况下,该功能没有开启。要想开启该功能,就必须在include/configs/zhaocj2440.h文件内定义CONFIG_CMD_N
[单片机]
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved