《朱老师物联网大讲堂》学习笔记
学习地址:www.zhulaoshi.org
重定位实战
在SRAM中将0xD0020010重定位到0xD0024000,(重定位成功后,我们无法从结果看到什么现象)
思路
1.将链接地址设定为0xD0024000,
2.dnw下载地址设为0xD0020010,
3.代码执行时通过代码前段少量位置无关代码将整个代码搬移到0xD0024000,
4.使用一个长跳转ldr pc, =led_blink跳转到0xD0024000,完成重定位。
下面就是这节课涉及的汇编源文件,反汇编文件和链接脚本文件。
为了便于理解,先把一些关键点拿出来解释一下。
adr r0, _start // adr加载时就叫短加载
这句伪指令,用于加载_start当前运行地址,下面是反汇编得到的结果,
d002401c: e24f0024 sub r0, pc, #36 ; 0x24
ldr r1, =_start // ldr加载时如果目标寄存器是pc就叫长跳转,如果目标寄存器是r1等就叫长加载
这句伪指令,用于加载_start的链接地址:0xd0024000,下面是反汇编得到的结果
d0024020: e59f1048 ldr r1, [pc, #72] ; d0024070 <run_on_dram+0x10>
长跳转:跳转到的地址和当前地址差异比较大,跳转的范围比较远。
ldr pc, =led_blink // ldr指令实现长跳转
bl led_blink // bl指令实现短跳转
ldr和adr都是伪指令,区别是ldr是长加载、adr是短加载。
重点:adr指令加载符号地址,加载的是运行时地址;ldr指令在加载符号地址时,加载的是链接地址。
#define WTCON 0xE2700000 #define SVC_STACK 0xD0037D80 .global _start _start: ldr r0, =0x0 ldr r1, =WTCON str r0, [r1] ldr sp, =SVC_STACK mrc p15,0,r0,c1,c0,0 bic r0,r0,#(1<<12) // orr r0,r0,#(1<<12) mcr p15,0,r0,c1,c0,0 上面属于重定位代码部分,属于我们这里要分析讲解的内容 adr r0, _start 这里加载的是当前运行地址,也就是dnw下载时设定的0xd0020010 ldr r1, =_start 这里加载的是链接地址,也就是链接脚本开始处设定的0xd0024000 ldr r2, = bss_start cmp r0, r1 beq clean_bss copy_loop: ldr r3, [r0], #4 str r3, [r1], #4 这里的两句有个相似的方面, 这个相似的点就类似于C语言里面的这个特性,i++; 以前呢,只是知道++i和i++的区别,但是没有体会到用法上的妙处, 这里这样的用法,正好配合上后面的cmp比较语句, 其次也加深了对i++这里后加的特性, 开始只是知道++操作是在当前语句最后执行, 这里由于分解成了汇编,所以看的更清楚了。 cmp r1, r2 bne copy_loop clean_bss: ldr r0, =bss_start ldr r1, =bss_end 这里的标号bss_start和bss_end能更好的帮助我理解link.lds链接脚本 cmp r0, r1 beq run_on_dram mov r2, #0 clear_loop: str r2, [r0], #4 cmp r0, r1 bne clear_loop run_on_dram: ldr pc, =led_blink bl led_blink b .
SECTIONS { . = 0xd0024000; 这里的地址就是我们希望链接的地址 说一句无关上下,也有关上下的话, 这里也可以理解为内存,从上往下,地址是在增加的, 虽然我们并不知道增加的数值,不过我们也无需关系,这是编译器在负责。 .text : { start.o * (.text) } 这里要强调的是,start.o被安排在前面,后面用*代替的顺序不重要。 .data : { * (.data) } 这里要和下面的bss段联系下来讲, 这里如果存储的有数据的话,就是非0的, 知道了这一点,应该就能明白重定位代码中复制的功能,在什么情况下复制已经完成。 bss_start = .; .bss : { * (.bss) } bss_end = .; 这里的两个标号开始觉得长得有点怪,看了重定位代码后,想法改变了。 }
Makefile文件中改变了这一句
arm-linux-ld -Tlink.lds -o led.elf $^
下面是反汇编文件,反正是全部粘贴出来了,还有些讲不清楚,就把某些地方红色标记吧,下次看的方便些。
好像是因为地址无关指令占用了一些地址空间,所以在分析下面地址变化以及指令的时候,没很明白。
如果还是想懂得话,就看这节课的讲解。
led.elf: file format elf32-littlearm Disassembly of section .text: d0024000 <_start>: d0024000: e59f0060 ldr r0, [pc, #96] ; d0024068 <run_on_dram+0x8> d0024004: e3a01000 mov r1, #0 d0024008: e5801000 str r1, [r0] d002400c: e59fd058 ldr sp, [pc, #88] ; d002406c <run_on_dram+0xc> d0024010: ee110f10 mrc 15, 0, r0, cr1, cr0, {0} d0024014: e3800a01 orr r0, r0, #4096 ; 0x1000 d0024018: ee010f10 mcr 15, 0, r0, cr1, cr0, {0} d002401c: e24f0024 sub r0, pc, #36 ; 0x24 d0024020: e59f1048 ldr r1, [pc, #72] ; d0024070 <run_on_dram+0x10> d0024024: e59f2048 ldr r2, [pc, #72] ; d0024074 <run_on_dram+0x14> d0024028: e1500001 cmp r0, r1 d002402c: 0a000003 beq d0024040 <clean_bss> <span style="background-color: rgb(255, 0, 0);">d0024030 <copy_loop>:</span> d0024030: e4903004 ldr r3, [r0], #4 d0024034: e4813004 str r3, [r1], #4 d0024038: e1510002 cmp r1, r2 d002403c: 1afffffb bne d0024030 <copy_loop> <span style="background-color: rgb(255, 0, 0);">d0024040 <clean_bss>:</span> d0024040: e59f002c ldr r0, [pc, #44] ; d0024074 <run_on_dram+0x14> d0024044: e59f102c ldr r1, [pc, #44] ; d0024078 <run_on_dram+0x18> d0024048: e1500001 cmp r0, r1 d002404c: 0a000003 beq d0024060 <run_on_dram> d0024050: e3a02000 mov r2, #0 <span style="background-color: rgb(255, 0, 0);">d0024054 <clear_loop>:</span> d0024054: e4802004 str r2, [r0], #4 d0024058: e1500001 cmp r0, r1 d002405c: 1afffffc bne d0024054 <clear_loop> d0024060 <run_on_dram>: d0024060: e59ff014 ldr pc, [pc, #20] ; d002407c <run_on_dram+0x1c> d0024064: eafffffe b d0024064 <run_on_dram+0x4> d0024068: e2700000 rsbs r0, r0, #0 d002406c: d0037d80 andle r7, r3, r0, lsl #27 d0024070: d0024000 andle r4, r2, r0 d0024074: d0024128 andle r4, r2, r8, lsr #2 d0024078: d0024128 andle r4, r2, r8, lsr #2 d002407c: d002409c mulle r2, ip, r0 d0024080: 00001a41 andeq r1, r0, r1, asr #20 d0024084: 61656100 cmnvs r5, r0, lsl #2 d0024088: 01006962 tsteq r0, r2, ror #18 d002408c: 00000010 andeq r0, r0, r0, lsl r0 d0024090: 45543505 ldrbmi r3, [r4, #-1285] ; 0x505 d0024094: 08040600 stmdaeq r4, {r9, sl} d0024098: 00010901 andeq r0, r1, r1, lsl #18 d002409c <led_blink>: d002409c: e92d4800 push {fp, lr} d00240a0: e28db004 add fp, sp, #4 d00240a4: e59f3028 ldr r3, [pc, #40] ; d00240d4 <led_blink+0x38> d00240a8: e59f2028 ldr r2, [pc, #40] ; d00240d8 <led_blink+0x3c> d00240ac: e5832000 str r2, [r3] d00240b0: e59f3024 ldr r3, [pc, #36] ; d00240dc <led_blink+0x40> d00240b4: e3a02000 mov r2, #0 d00240b8: e5832000 str r2, [r3] d00240bc: eb000007 bl d00240e0 <delay> d00240c0: e59f3014 ldr r3, [pc, #20] ; d00240dc <led_blink+0x40> d00240c4: e3a02038 mov r2, #56 ; 0x38 d00240c8: e5832000 str r2, [r3] d00240cc: eb000003 bl d00240e0 <delay> d00240d0: eafffff6 b d00240b0 <led_blink+0x14> d00240d4: e0200240 eor r0, r0, r0, asr #4 d00240d8: 11111111 tstne r1, r1, lsl r1 d00240dc: e0200244 eor r0, r0, r4, asr #4 d00240e0 <delay>: d00240e0: e52db004 push {fp} ; (str fp, [sp, #-4]!) d00240e4: e28db000 add fp, sp, #0 d00240e8: e24dd00c sub sp, sp, #12 d00240ec: e59f3030 ldr r3, [pc, #48] ; d0024124 <delay+0x44> d00240f0: e50b3008 str r3, [fp, #-8] d00240f4: e51b3008 ldr r3, [fp, #-8] d00240f8: e3530000 cmp r3, #0 d00240fc: 03a02000 moveq r2, #0 d0024100: 13a02001 movne r2, #1 d0024104: e20220ff and r2, r2, #255 ; 0xff d0024108: e2433001 sub r3, r3, #1 d002410c: e50b3008 str r3, [fp, #-8] d0024110: e3520000 cmp r2, #0 d0024114: 1afffff6 bne d00240f4 <delay+0x14> d0024118: e28bd000 add sp, fp, #0 d002411c: e8bd0800 pop {fp} d0024120: e12fff1e bx lr d0024124: 000dbba0 andeq fp, sp, r0, lsr #23 Disassembly of section .comment: 00000000 <.comment>: 0: 43434700 movtmi r4, #14080 ; 0x3700 4: 5328203a teqpl r8, #58 ; 0x3a 8: 6372756f cmnvs r2, #465567744 ; 0x1bc00000 c: 20797265 rsbscs r7, r9, r5, ror #4 10: 202b2b47 eorcs r2, fp, r7, asr #22 14: 6574694c ldrbvs r6, [r4, #-2380]! ; 0x94c 18: 30303220 eorscc r3, r0, r0, lsr #4 1c: 2d337139 ldfcss f7, [r3, #-228]! ; 0xffffff1c 20: 20293736 eorcs r3, r9, r6, lsr r7 24: 2e342e34 mrccs 14, 1, r2, cr4, cr4, {1} 28: Address 0x00000028 is out of bounds. Disassembly of section .ARM.attributes: 00000000 <.ARM.attributes>: 0: 00002641 andeq r2, r0, r1, asr #12 4: 61656100 cmnvs r5, r0, lsl #2 8: 01006962 tsteq r0, r2, ror #18 c: 0000001c andeq r0, r0, ip, lsl r0 10: 45543505 ldrbmi r3, [r4, #-1285] ; 0x505 14: 08040600 stmdaeq r4, {r9, sl} 18: 12010901 andne r0, r1, #16384 ; 0x4000 1c: 15011404 strne r1, [r1, #-1028] ; 0x404 20: 18031701 stmdane r3, {r0, r8, r9, sl, ip} 24: Address 0x00000024 is out of bounds.