《朱老师物联网大讲堂》学习笔记
学习地址: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>
d0024070处的值是d0024000,即链接地址,
ps:这里的ARM是3级流水线,所以pc的值是当前地址的值往后数2个,
这里还有更细的讲解,开始有点脑袋不够用了,
长跳转:跳转到的地址和当前地址差异比较大,跳转的范围比较远。
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 .
copy代码的长度,有一次看错了,实际上没错,下次看的时候注意这里的提醒!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.