总结:代码重定位

发布者:MysticJourney最新更新时间:2025-02-06 来源: cnblogs关键字:代码  重定位  S5PV210 手机看文章 扫描二维码
随时随地手机看文章

什么是重定位?为什么要代码重定位?

要弄清楚上面的这两个问题,首先要理解下面这几个概念

一、编码

(1)位置无关编码:PIC,可执行程序运行时与代码在内存中的地址无关,代码中没有使用绝对地址,而是使用的相对地址。(例如:B、BL、MOV等指令)

(2)位置有关编码:可执行程序运行时与代码在内存中的地址有关系。(例如:LDR PC, =MAIN等指令)

 

二、地址

(1)链接地址:程序编译链接时指定的地址(使用makefile或者链接脚本可以指定链接地址)

(2)运行地址:程序在内存中实际运行的地址。

参考资料:http://blog.csdn.net/linux_103/article/details/8888427

 

三、S5PV210的启动

       在uboot中的启动方式,将整个uboot分为2个部分(BL1和BL2),是分别加载到内存中去运行的。在这个过程中,程序的链接地址和运行地址就很可能不是相同的了,但是在代码中又有一些位置有关码,为了使得程序可以正常的运行,就必须使用重定位来解决。(关于S5PV210的启动在另一篇文章里有介绍)

 

四、如何重定位?

1、链接脚本指定链接地址

2、判断运行地址和链接地址是否相同

3、复制代码到指定的链接地址处,使用长转移指令进行跳转

具体的实现如下:

【链接脚本代码】

 1 SECTIONS

 2 {

 3     . = 0xd0024000;

 4     

 5     .text : {

 6         start.o

 7         * (.text)

 8     }

 9 

10     .data : {

11         *(.data)

12     }

13     

14     bss_start = .;

15     .bss : {

16         * (.bss)

17     }

18     

19     bss_end = .;

20 }


【重定位代码】


adr r0, _start         // 短加载,获取_start的运行地址

ldr r1, =_start        // 长加载,获取_start的链接地址

ldr r2, =bss_start   // 获取bss链接地址,重定位代码的结束地址

cmp r0, r1             // 比较_start的运行地址和链接地址是否相等

beq clean_bss        // 相等:不需要重定位;跳转到clean_bss

                        // 不相等:需要重定位;继续往下执行

                           

// 汇编实现while完成代码赋值到重定位地址                           

copy_loop:

    ldr r3, [r0], #4       // 源

    str r3, [r1], #4       // 目的 先把r3中的内容放入r1的指向的地址;

    cmp r1, r2              // 然后r1 =r1 + 4

    bne copy_loop


关键字:代码  重定位  S5PV210 引用地址:总结:代码重定位

上一篇:gec210 NAND BOOT与SD BOOT启动原理
下一篇:uboot总结:uboot配置和启动过程3(config.mk分析)

推荐阅读最新更新时间:2026-03-14 10:31

代码定位
1 说明 实验平台: JZ2440 CPU: S3C2440 2 S3C2440的启动过程 图1 S3C2440A Memory Map after Reset S3C2440支持从多种存储设备启动:NOR/NAND Flash, EEPROM, 等等。芯片内部有4K SRAM用于启动设备使用。至于,设备最终以哪一种方式启动,通过配置芯片的OM引脚,由芯片内部实现。 摘自《S3C2440A_UserManual_Rev13》: 图2 BANK0 BUS WIDTH 举个例子,当选择以NOR Flash的方式启动时,芯片的0地址(4K地址空间)会直接映射到Nor Flash上,
[单片机]
<font color='red'>代码</font><font color='red'>重</font><font color='red'>定位</font>
S3c2440代码定位详解4---拷贝代码和链接脚本的改进
本节进行拷贝代码的改进和链接脚本的改进。 前面重定位时,需要ldrb命令从的Nor Flash读取1字节数据,再用strb命令将1字节数据写到SDRAM里面 cpy: ldrb r4, /*首先从flash读出一个字节*/ strb r4, /*让后把数据写到SDRAM*/ add r1, r1, #1 add r2, r2, #1 cmp r2, r3 bne cpy JZ2440上的Nor Flash是16位,SDRAM是32位。 假设现在需要复制16byte数据, 采用ldrb命令每次只能加载1byte,因此CPU需要发出16次命令,内存控制器每次收到命令后,访问硬件Nor Flash,
[单片机]
S3c2440<font color='red'>代码</font><font color='red'>重</font><font color='red'>定位</font>详解4---拷贝<font color='red'>代码</font>和链接脚本的改进
S3c2440代码定位详解3---链接脚本的解析
链接脚本的语法 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)所有的代码段文件 sta
[单片机]
S3c2440<font color='red'>代码</font><font color='red'>重</font><font color='red'>定位</font>详解3---链接脚本的解析
S3c2440代码定位详解2---链接脚本的引入与简单测试
前面程序运行,发现从Nand Flash启动和从Nor Flash启动表现是不一样的。 设置成Nand Flash启动没有问题 显示ABCDE… 设置成NOor Flash启动则显示AAA… 这是什么原因呢? Nor启动 Nor Flash就被认为是0地址,g_Char被放在0x700后面。CPU上电后从0地址开始执行,它能读取Nor Flash上的代码,打印出A,当进行g_Char++的时候,写操作操作无效,下次读取的数据仍然是A。 NAND启动 上电后,Nand Flash前4K代码就被自动的复制到SRAM里面,SRAM是CPU认为的0地址。CPU上电后从0地址开始执行,它读取SRAM上的代码,并g
[单片机]
S3c2440<font color='red'>代码</font><font color='red'>重</font><font color='red'>定位</font>详解2---链接脚本的引入与简单测试
S3C2440 代码定位实验(三)
代码重定位 我们现在来解决代码重定位实验(一)所引入的代码重定位问题。 对于S3C2440来说: BIN文件小于4KB时: 若是Nand方式启动,则不存在任何问题 若是Nor方式启动,则我们可以只重定位.data段即可 当BIN文件大于4KB时: 若是Nand方式启动,则需要重定位整个程序,包括代码段和数据段 若是以Nor方式启动,则依然只重定位.data段即可 只重定位.data段和清零.bss段 对于重定位.data段的代码,正常情况下应该是使用汇编来编写的,我为了简便起见,使用了C语言来编写。由于此时尚未重定位数据段和清零BSS段,是不应该调用C函数的。但是我保证了这两个函数不访问全局变量,所以只要正确设置了栈指针,调用
[单片机]
S3C2440 <font color='red'>代码</font><font color='red'>重</font><font color='red'>定位</font>实验(三)
s3c2440学习之路-011代码定位
1 基本原理 承接上1篇博客 s3c2440学习之路-010 sdram, sdram已经初始化完毕,现在可以正式的发挥SDRAM的价值了。(SDRAM 是可以随意读写的,后续的代码都会放到上面来运行) 1.1 程序段的划分 一个程序编译后,会有代码段、数据段、只读数据段、bss段和注释段 这里主要讲一下bss段为什么可以减小bin文件的大小。bbs主要记录未初始化和初始化为0的全局(static 修饰的局部)变量的位置,而不会记录其具体数据,因为这部分的数值会默认设置为0。 这里看2个小程序 test1.c #include stdio.h char a ; int main(int argc, ch
[单片机]
s3c2440学习之路-011<font color='red'>代码</font><font color='red'>重</font><font color='red'>定位</font>
【s3c2440】第三课:代码定位
什么是重定位 简单来说就是把程序从内存的一个位置复制到另一个位置。 重定位的重要性 若s3c2440使用Nand Flash启动,则CPU会将Nand Flash的前4k拷贝到s3c2440 soc内部的SRAM。如果程序没有重定位代码,则只能运行Nand flash前4k的程序。 若s3c2440使用Nor Flash启动,则CPU无法修改Nor Flash内存中的数据。如果程序没有重定位代码,则会因为无法修改全局变量、静态变量的值导致程序运行出错。 链接脚本 链接脚本的格式如下: SECTIONS { sectname start BLICK(align) (NOLOAD) : AT( ldadr ) {
[单片机]
【s3c2440】第三课:<font color='red'>代码</font><font color='red'>重</font><font color='red'>定位</font>
tiny4412裸机程序——代码定位
在前面介绍exynos4412芯片启动过程时,我们知道:一上电,exynos4412首先执行固化在iROM中的代码,iROM首先设置程序运行环境(比如关看门狗、关中断、关MMU、设置栈、设置栈、启动PLL等),然后根据OM引脚确定启动设备(NAND Flash/SD卡/其他),把BL1从里面读出存入iRAM的0x02021400地址处,然后开始启动BL1;BL1从SD卡适当的位置读入14K字节的数据,存在iRAM地址0x02023400处,所以BL2不能大于(14K–4) 字节,这里引出了为什么写这一节的原因:如果我们的程序很大,大于14K怎么办? 运行地址和链接地址: 运行地址是程序当前所处的地址,即程序在运行时,所处的
[单片机]
小广播
最新单片机文章
何立民专栏 单片机及嵌入式宝典

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

厂商技术中心

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

 
机器人开发圈

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