免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 3839 | 回复: 2
打印 上一主题 下一主题

[BootLoader] 关于uboot重定位方面的总结和问题 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2013-12-01 18:04 |只看该作者 |倒序浏览
在老的uboot中,如果我们想要uboot启动后把自己拷贝到内存中的某个地方,只要把要拷贝的地址写给TEXT_BASE即可,然后boot启动后就会把自己拷贝到TEXT_BASE内的地址处运行,在拷贝之前的代码都是相对的,不能出现绝对的跳转,否则会跑飞。
在最新的uboot里(2013.07),TEXT_BASE的含义改变了。他表示用户要把这个代码下载到哪里,通常是通过串口等工具。然后搬移的时候由uboot自己计算一个地址来进行搬移。在init_f函数中计算出了要搬移到的地方,然后relocate.S来进行搬移。问题是我们在编译的时候明明指定的TEXT_BASE和这个地址不一致,那么在搬移到新的地址后,代码运行不会跑飞吗?在代码阅读的过程中发现,新版的uboot采用了动态链接技术,在lds文件中有__rel_dyn_start和__rel_dyn_end,这两个符号之间的区域存放着动态链接符号,只要给这里面的符号加上一定的偏移,拷贝到内存中代码的后面相应的位置处,就可以在绝对跳转中找到正确的函数。
我的开发环境是2440,现在还留有两个问题:
1.在新版的uboot中如果我定义TEXT_BASE是0x32000000,但是下载代码到0x30000000启动会不会能正确运行?
初步分析:不能
因为在拷贝之前执行了init_f函数,这个函数中程序跑飞了,具体原因可能是有绝对的跳转,但是没有足够证据。
2.在relocate.S中有以下代码:
copy_loop:这段主要是进行代码段拷贝
46         ldmia   r1!, {r10-r11}          /* copy from source address [r1]    */
47         stmia   r0!, {r10-r11}          /* copy to   target address [r0]    */
48         cmp     r1, r2                  /* until source end address [r2]    */
49         blo     copy_loop
50
51         /*
52          * fix .rel.dyn relocations
53          */
54         ldr     r2, =__rel_dyn_start    /* r2 <- SRC &__rel_dyn_start */
55         ldr     r3, =__rel_dyn_end      /* r3 <- SRC &__rel_dyn_end */
56 fixloop:/这段进行了根据动态链接区域修改函数跳转表的动作,加了偏移的地址
57         ldmia   r2!, {r0-r1}            /* (r0,r1) <- (SRC location,fixup) */
58         and     r1, r1, #0xff
59         cmp     r1, #23                 /* relative fixup? */
60         bne     fixnext
61         
62         /* relative fix: increase location by offset */
63         add     r0, r0, r9/r9为偏移数值,基本原理就是取出之前函数对应的位置,加上偏移,写到新地址的对应位置处(应该是跳转表什么的)。
64         ldr     r1, [r0]
65         add     r1, r1, r9
66         str     r1, [r0]
67 fixnext:
68         cmp     r2, r3
69         blo     fixloop
这里有个疑问,这里判断r1 和#23的关系,通过察看二进制文件可以发现确实有这样的一个排布:
7545 001d780: 1700 0000 3800 0032 1700 0000 8407 0032  ....8..2.......2
7546 001d790: 1700 0000 8807 0032 1700 0000 8c07 0032  .......2.......2
7547 001d7a0: 1700 0000 e407 0032 1700 0000 e807 0032  .......2.......2
7548 001d7b0: 1700 0000 ec07 0032 1700 0000 f007 0032  .......2.......2
7549 001d7c0: 1700 0000 4808 0032 1700 0000 4c08 0032  ....H..2....L..2
7550 001d7d0: 1700 0000 7808 0032 1700 0000 4009 0032  ....x..2....@..2
7551 001d7e0: 1700 0000 4409 0032 1700 0000 4809 0032  ....D..2....H..2
7552 001d7f0: 1700 0000 4c09 0032 1700 0000 5009 0032  ....L..2....P..2
7553 001d800: 1700 0000 5409 0032 1700 0000 5809 0032  ....T..2....X..2
7554 001d810: 1700 0000 5c09 0032 1700 0000 6009 0032  ....\..2....`..2
7555 001d820: 1700 0000 6409 0032 1700 0000 a00a 0032  ....d..2.......2
7556 001d830: 1700 0000 a40a 0032 1700 0000 a80a 0032  .......2.......2
这里为什么要用0x17(23)呢?他的来历是什么?每一个地址后面都跟了一个0x17.比如:
0x32000038 0x00000017

论坛徽章:
0
2 [报告]
发表于 2013-12-02 23:27 |只看该作者
今天貌似又有点进展:
之前看老的版本的uboot,比如1.1.6.它是用了got表,具体用到没有分析,但是教新的版本(2013.07)采用了动态链接段。先贴段代码:
{
30   *(.__image_copy_end)
31  }
32  .rel_dyn_start :
33  {
34   *(.__rel_dyn_start)
35  }
36  .rel.dyn : {
37   *(.rel*)
38  }
39  .rel_dyn_end :
40  {
41   *(.__rel_dyn_end)
42  }
这是u-boot.lds文件中的一段:有个rel.dyn段,这个段里面存放的是动态链接的信息。这个是我们在写lds文件的时候事先设置好的。那么怎么让ld能根据我们的设定来进行操作呢?在arch/arm目录下有一个config.mk文件,里面有LDFLASG_u-boot += pie,这个选项表示的意思我们可以在 doc/README.arm-relocation 文件中找到说明,也可以man elf找到。他就是告诉ld要动态链接,ld看到有这个选项就会去找rel区域。
在GCC的文档中找到:
fpie
-fPIE
These options are similar to ‘-fpic’ and ‘-fPIC’, but generated position inde-
pendent code can be only linked into executables. Usually these options are
used when ‘-pie’ GCC option will be used during linking.
‘-fpie’ and ‘-fPIE’ both define the macros __pie__ and __PIE__. The macros
have the value 1 for ‘-fpie’ and 2 for ‘-fPIE’.

就是说我们在编译的时候需要指定fpie这个选项,这样在编译的时候就给ld提供了需要rel段数据,这个数据应该是保存在每个.o文件中的。然后ld根据这些rel数据在最后的elf类型文件中合成一个大的rel段。这个区域必须以.rel开头,后面可以是.dyn也可以不是,ld只认.rel开头的区域。
不知道这样理解对不对,先写到这里,后期要把gcc的编译选项了解一下,ld的选项,和elf文件的格式也要学习。

论坛徽章:
0
3 [报告]
发表于 2013-12-06 08:41 |只看该作者
一般下载地址与执行地址关系不大。
至少以前的代码中,下载地址与链接地址不一样是可以执行的。

这个也与程序有关系的,当然你可以搞成原地执行。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP