打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
关于uboot重定位方面的总结和问题
在老的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
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
uboot 2011.3分析start.S(转)
S3C2440移植uboot之启动过程概述
了解动态链接(六)
u-boot总结
s3c6410 uboot代码分析《一》
u-boot之start.S小结
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服