首页 > 代码库 > s5pv210重定位

s5pv210重定位

1:上一节解释了什么是位置无关码、位置有关码。当程序的加载地址与链接地址不一致的时候,如果使用位置有关码则需要重定位。

2:重定位的操作实质就是把链接脚本中的想要重定位的代码段如:.text、 .data段的内容复制到链接地址处。

3:具体分析一下位置有关码,位置无关码:位置无关码和位置有关码实质的区别是操作使用的是绝对地址,还是PC + offset 的相对地址,主要集中在取址、和跳转两个操作上:

b、BL、都是用的相对地址,所以是位置无关码, ldr pc =main 因为main标志在编译的时候会受到链接脚本的链接位置的影响,所以main是链接后的绝对地址,所以是位置有关码

ldr r0, 0xe0002700 这个操作的作用是取0xe0002700内存地址中的值赋值给r0,因为这个内存地址不会受到链接脚本中链接位置的影响,所以是位置无关码

#define WTCON         0xE2700000
#define PS_HOLD_CONTROL   0xE010E81C
#define SVC_STACK       0xD0037D80

ldr r0, =WTCON

ldr r0, =PS_HOLD_CONTROL

同样这几句代码不会受到链接脚本中链接位置的影响,所以也位置无关码

ldr r0, =bss_start

这句代码的作用是把bss_start的地址放入r0中,因为会受到链接脚本中链接位置的影响,所以是位置有关码

看一下反汇编之后的汇编代码

led.elf:     file format elf32-littlearm


Disassembly of section .text:

d0020010 <_start>: 
d0020010:    e59f00dc     ldr    r0, [pc, #220]    ; d00200f4 <delay_loop+0x10>    //pc + 220 = 18 + DC = F4, d00200F4中的值是 0xe2700000 位置无关码
d0020014:    e3a01000     mov    r1, #0
d0020018:    e5801000     str    r1, [r0]                            //位置无关
d002001c:    e59f00d4     ldr    r0, [pc, #212]    ; d00200f8 <delay_loop+0x14>    //pc + 212 = 24 + D4 = F8,  d00200F8中的值是0xe010e81c 位置无关
d0020020:    e5901000     ldr    r1, [r0]F
d0020024:    e59f20d0     ldr    r2, [pc, #208]    ; d00200fc <delay_loop+0x18>
d0020028:    e1811002     orr    r1, r1, r2
d002002c:    e5801000     str    r1, [r0]
d0020030:    e59fd0c8     ldr    sp, [pc, #200]    ; d0020100 <delay_loop+0x1c>

d0020034 <bss_clean>:
d0020034:    e59f00c8     ldr    r0, [pc, #200]    ; d0020104 <delay_loop+0x20>    //这是原汇编代码是:ldr r0, =bss_start,可以看到 bss_start的值为d002013f明显位                                                     // 置有关
d0020038:    e59f10c8     ldr    r1, [pc, #200]    ; d0020108 <delay_loop+0x24>
d002003c:    e3a02000     mov    r2, #0
d0020040:    e1500001     cmp    r0, r1
d0020044:    0a000002     beq    d0020054 <led_blink>

d0020048 <bss_clean_loop>:
d0020048:    e4802004     str    r2, [r0], #4
d002004c:    e1500001     cmp    r0, r1
d0020050:    1afffffc     bne    d0020048 <bss_clean_loop>

d0020054 <led_blink>:
d0020054:    e59f00b0     ldr    r0, [pc, #176]    ; d002010c <delay_loop+0x28>
d0020058:    e59f10b0     ldr    r1, [pc, #176]    ; d0020110 <delay_loop+0x2c>
d002005c:    e5801000     str    r1, [r0]
d0020060:    e59f00ac     ldr    r0, [pc, #172]    ; d0020114 <delay_loop+0x30>
d0020064:    e5901000     ldr    r1, [r0]
d0020068:    e3c110f0     bic    r1, r1, #240    ; 0xf0
d002006c:    e3811010     orr    r1, r1, #16
d0020070:    e5801000     str    r1, [r0]

d0020074 <led_flash>:
d0020074:    e59f009c     ldr    r0, [pc, #156]    ; d0020118 <delay_loop+0x34>
d0020078:    e5901000     ldr    r1, [r0]
d002007c:    e3811002     orr    r1, r1, #2
d0020080:    e5801000     str    r1, [r0]
d0020084:    e59f0090     ldr    r0, [pc, #144]    ; d002011c <delay_loop+0x38>
d0020088:    e3a01030     mov    r1, #48    ; 0x30
d002008c:    e5801000     str    r1, [r0]
d0020090:    eb000011     bl    d00200dc <delay>
d0020094:    e59f0080     ldr    r0, [pc, #128]    ; d002011c <delay_loop+0x38>
d0020098:    e3a01028     mov    r1, #40    ; 0x28
d002009c:    e5801000     str    r1, [r0]
d00200a0:    eb00000d     bl    d00200dc <delay>
d00200a4:    e59f0070     ldr    r0, [pc, #112]    ; d002011c <delay_loop+0x38>
d00200a8:    e3a01018     mov    r1, #24
d00200ac:    e5801000     str    r1, [r0]
d00200b0:    eb000009     bl    d00200dc <delay>
d00200b4:    e59f0060     ldr    r0, [pc, #96]    ; d002011c <delay_loop+0x38>
d00200b8:    e3a01038     mov    r1, #56    ; 0x38
d00200bc:    e5801000     str    r1, [r0]
d00200c0:    e59f0050     ldr    r0, [pc, #80]    ; d0020118 <delay_loop+0x34>
d00200c4:    e5901000     ldr    r1, [r0]
d00200c8:    e3c11002     bic    r1, r1, #2
d00200cc:    e5801000     str    r1, [r0]
d00200d0:    eb000001     bl    d00200dc <delay>
d00200d4:    eaffffe6     b    d0020074 <led_flash>
d00200d8:    eafffffe     b    d00200d8 <led_flash+0x64>

d00200dc <delay>:
d00200dc:    e59f003c     ldr    r0, [pc, #60]    ; d0020120 <delay_loop+0x3c>
d00200e0:    e3a01000     mov    r1, #0

d00200e4 <delay_loop>:
d00200e4:    12400001     subne    r0, r0, #1
d00200e8:    e1500001     cmp    r0, r1
d00200ec:    1afffffc     bne    d00200e4 <delay_loop>
d00200f0:    e1a0f00e     mov    pc, lr
d00200f4:    e2700000     rsbs    r0, r0, #0
d00200f8:    e010e81c     ands    lr, r0, ip, lsl r8
d00200fc:    00000301     andeq    r0, r0, r1, lsl #6
d0020100:    d0037d80     andle    r7, r3, r0, lsl #27
d0020104:    d002013f     andle    r0, r2, pc, lsr r1
d0020108:    d002013f     andle    r0, r2, pc, lsr r1
d002010c:    e0200240     eor    r0, r0, r0, asr #4
d0020110:    11111111     tstne    r1, r1, lsl r1
d0020114:    e02000a0     eor    r0, r0, r0, lsr #1
d0020118:    e02000a4     eor    r0, r0, r4, lsr #1
d002011c:    e0200244     eor    r0, r0, r4, asr #4
d0020120:    00989680     addseq    r9, r8, r0, lsl #13
d0020124:    00001a41     andeq    r1, r0, r1, asr #20
d0020128:    61656100     cmnvs    r5, r0, lsl #2
d002012c:    01006962     tsteq    r0, r2, ror #18
d0020130:    00000010     andeq    r0, r0, r0, lsl r0
d0020134:    45543505     ldrbmi    r3, [r4, #-1285]    ; 0x505
d0020138:    08040600     stmdaeq    r4, {r9, sl}
d002013c:    Address 0xd002013c is out of bounds.

 

 

 

如:链接脚本为以下链接脚本,而我们程序执行的起始位置为0xd0020010,,我们只需要把从_start 到data_end的代码复制到链接链接的地址0xd0024000处即可;接着道0xd0024000中执行程序即可,注意重定位之前的汇编代码

一定要使用位置无关码。

SECTIONS
{
    . = 0xd0024000;
    .text : {
        start.o        
        *(.text)        
    }
    .data : {
        *(.data)
    }
    data_end = .;
    bss_start = .;
    .bss : {
        *(.bss)
    }
    bss_end = .;
}

3:代码实战:

 注:加载地址0xd0020010,连接地址:0xd0026000

 

/*
 *        s5pv210裸机实验
 *        
 *        重定位
 *
 */
 
#define WTCON                0xE2700000
#define PS_HOLD_CONTROL        0xE010E81C
#define SVC_STACK            0xD0037D80

//LED相关寄存器
#define _GPJ0CON            0xE0200240
#define _GPJ0DAT            0xE0200244
#define _GPD0CON            0xE02000A0
#define _GPD0DAT            0xE02000A4
#define _GPJ0CON_EN            0x11111111    
#define LED_1_ON            ((0<<3) | (1<<4) | (1<<5))
#define LED_2_ON            ((1<<3) | (0<<4) | (1<<5))
#define LED_3_ON            ((1<<3) | (1<<4) | (0<<5))
#define LED_OFF                ((1<<3) | (1<<4) | (1<<5))

#define DELAY_TIME            10000000
 
    .global _start
_start:
    
    //第一步关看门狗
    ldr r0, =WTCON
    ldr r1, =0x0
    str r1, [r0]
    
    //第二步电源开关置锁,PS_HOLD_CONTROL寄存器中的0、8、9三位置1
    ldr r0, =PS_HOLD_CONTROL
    ldr r1, [r0]
    ldr r2, =0x301
    orr r1, r1, r2
    str r1, [r0]
 
    //设置svc模式下的栈
    ldr sp, =SVC_STACK
    
    //重定位
    adr r0, _start
    ldr r1, =_start    
    ldr r3, =bss_end
    cmp r0, r1
    beq bss_clean
relocate_loop:
    ldr r2, [r0], #4
    str r2, [r1], #4
    cmp r1, r3
    bne relocate_loop
    ldreq pc, =bss_clean
    
    
    
    //清bss  因为清bss中的代码为位置有关码,所以要先重定位,
bss_clean:
    ldr r0, =bss_start            //把bss的起始地址读到r0中
    ldr r1, =bss_end            //把bss的结束地址读到r1中
    mov r2, #0x0                //把r2寄存器写入
    cmp r0, r1                    //对比r0 和r1 如果相等则跳转到led_blink
    ldr pc, =led_blink
bss_clean_loop:
    str r2, [r0], #4            //不等则把r0地址写入0,r0 + 4
    cmp r0, r1                    //判断r0 r1是否相等 不相等跳转到bss_clean_loop循环
    bne bss_clean_loop
    
    //bl led_blink
long_jump:
    ldr pc, =led_blink
    

    
    
    
    //设置死循环放置跑飞
    b .
    

 

led.elf:     file format elf32-littlearm


Disassembly of section .text:

d0026000 <_start>:
d0026000:    e59f006c     ldr    r0, [pc, #108]    ; d0026074 <long_jump+0x8>
d0026004:    e3a01000     mov    r1, #0
d0026008:    e5801000     str    r1, [r0]
d002600c:    e59f0064     ldr    r0, [pc, #100]    ; d0026078 <long_jump+0xc>
d0026010:    e5901000     ldr    r1, [r0]
d0026014:    e59f2060     ldr    r2, [pc, #96]    ; d002607c <long_jump+0x10>
d0026018:    e1811002     orr    r1, r1, r2
d002601c:    e5801000     str    r1, [r0]
d0026020:    e59fd058     ldr    sp, [pc, #88]    ; d0026080 <long_jump+0x14>
d0026024:    e24f002c     sub    r0, pc, #44    ; 0x2c
d0026028:    e59f1054     ldr    r1, [pc, #84]    ; d0026084 <long_jump+0x18>
d002602c:    e59f3054     ldr    r3, [pc, #84]    ; d0026088 <long_jump+0x1c>
d0026030:    e1500001     cmp    r0, r1
d0026034:    0a000004     beq    d002604c <bss_clean>

d0026038 <relocate_loop>:
d0026038:    e4902004     ldr    r2, [r0], #4
d002603c:    e4812004     str    r2, [r1], #4
d0026040:    e1510003     cmp    r1, r3
d0026044:    1afffffb     bne    d0026038 <relocate_loop>
d0026048:    059ff03c     ldreq    pc, [pc, #60]    ; d002608c <long_jump+0x20>

d002604c <bss_clean>:
d002604c:    e59f003c     ldr    r0, [pc, #60]    ; d0026090 <long_jump+0x24>
d0026050:    e59f1030     ldr    r1, [pc, #48]    ; d0026088 <long_jump+0x1c>
d0026054:    e3a02000     mov    r2, #0
d0026058:    e1500001     cmp    r0, r1
d002605c:    e59ff030     ldr    pc, [pc, #48]    ; d0026094 <long_jump+0x28>

d0026060 <bss_clean_loop>:
d0026060:    e4802004     str    r2, [r0], #4
d0026064:    e1500001     cmp    r0, r1
d0026068:    1afffffc     bne    d0026060 <bss_clean_loop>

d002606c <long_jump>:
d002606c:    e59ff020     ldr    pc, [pc, #32]    ; d0026094 <long_jump+0x28>
d0026070:    eafffffe     b    d0026070 <long_jump+0x4>
d0026074:    e2700000     rsbs    r0, r0, #0
d0026078:    e010e81c     ands    lr, r0, ip, lsl r8
d002607c:    00000301     andeq    r0, r0, r1, lsl #6
d0026080:    d0037d80     andle    r7, r3, r0, lsl #27
d0026084:    d0026000     andle    r6, r2, r0
d0026088:    d0026168     andle    r6, r2, r8, ror #2
d002608c:    d002604c     andle    r6, r2, ip, asr #32
d0026090:    d0026168     andle    r6, r2, r8, ror #2
d0026094:    d00260b4     strhle    r6, [r2], -r4
d0026098:    00001a41     andeq    r1, r0, r1, asr #20
d002609c:    61656100     cmnvs    r5, r0, lsl #2
d00260a0:    01006962     tsteq    r0, r2, ror #18
d00260a4:    00000010     andeq    r0, r0, r0, lsl r0
d00260a8:    45543505     ldrbmi    r3, [r4, #-1285]    ; 0x505
d00260ac:    08040600     stmdaeq    r4, {r9, sl}
d00260b0:    00010901     andeq    r0, r1, r1, lsl #18

d00260b4 <led_blink>:
d00260b4:    e59f3068     ldr    r3, [pc, #104]    ; d0026124 <led_blink+0x70>
d00260b8:    e92d41f0     push    {r4, r5, r6, r7, r8, lr}
d00260bc:    e59350a0     ldr    r5, [r3, #160]    ; 0xa0
d00260c0:    e59f1060     ldr    r1, [pc, #96]    ; d0026128 <led_blink+0x74>
d00260c4:    e3c500f0     bic    r0, r5, #240    ; 0xf0
d00260c8:    e3802010     orr    r2, r0, #16
d00260cc:    e1a04003     mov    r4, r3
d00260d0:    e3a08030     mov    r8, #48    ; 0x30
d00260d4:    e3a07028     mov    r7, #40    ; 0x28
d00260d8:    e3a06018     mov    r6, #24
d00260dc:    e3a05038     mov    r5, #56    ; 0x38
d00260e0:    e5831240     str    r1, [r3, #576]    ; 0x240
d00260e4:    e58320a0     str    r2, [r3, #160]    ; 0xa0
d00260e8:    e59430a4     ldr    r3, [r4, #164]    ; 0xa4
d00260ec:    e5848244     str    r8, [r4, #580]    ; 0x244
d00260f0:    e383e002     orr    lr, r3, #2
d00260f4:    e584e0a4     str    lr, [r4, #164]    ; 0xa4
d00260f8:    eb00000b     bl    d002612c <delay>
d00260fc:    e5847244     str    r7, [r4, #580]    ; 0x244
d0026100:    eb000009     bl    d002612c <delay>
d0026104:    e5846244     str    r6, [r4, #580]    ; 0x244
d0026108:    eb000007     bl    d002612c <delay>
d002610c:    e59420a4     ldr    r2, [r4, #164]    ; 0xa4
d0026110:    e5845244     str    r5, [r4, #580]    ; 0x244
d0026114:    e3c2c002     bic    ip, r2, #2
d0026118:    e584c0a4     str    ip, [r4, #164]    ; 0xa4
d002611c:    eb000002     bl    d002612c <delay>
d0026120:    eafffff0     b    d00260e8 <led_blink+0x34>
d0026124:    e0200000     eor    r0, r0, r0
d0026128:    11111111     tstne    r1, r1, lsl r1

d002612c <delay>:
d002612c:    e24dd008     sub    sp, sp, #8
d0026130:    e59f002c     ldr    r0, [pc, #44]    ; d0026164 <delay+0x38>
d0026134:    e58d0004     str    r0, [sp, #4]
d0026138:    e59d3004     ldr    r3, [sp, #4]
d002613c:    e3530000     cmp    r3, #0
d0026140:    0a000005     beq    d002615c <delay+0x30>
d0026144:    e59dc004     ldr    ip, [sp, #4]
d0026148:    e24c2001     sub    r2, ip, #1
d002614c:    e58d2004     str    r2, [sp, #4]
d0026150:    e59d1004     ldr    r1, [sp, #4]
d0026154:    e3510000     cmp    r1, #0
d0026158:    1afffff9     bne    d0026144 <delay+0x18>
d002615c:    e28dd008     add    sp, sp, #8
d0026160:    e12fff1e     bx    lr
d0026164:    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:    47000031     smladxmi    r0, r1, r0, r0
  2c:    203a4343     eorscs    r4, sl, r3, asr #6
  30:    756f5328     strbvc    r5, [pc, #-808]!    ; fffffd10 <bss_end+0x2ffd9ba8>
  34:    72656372     rsbvc    r6, r5, #-939524095    ; 0xc8000001
  38:    2b472079     blcs    11c8224 <_start-0xcee5dddc>
  3c:    694c202b     stmdbvs    ip, {r0, r1, r3, r5, sp}^
  40:    32206574     eorcc    r6, r0, #486539264    ; 0x1d000000
  44:    71393030     teqvc    r9, r0, lsr r0
  48:    37362d33     undefined instruction 0x37362d33
  4c:    2e342029     cdpcs    0, 3, cr2, cr4, cr9, {1}
  50:    00312e34     eorseq    r2, r1, r4, lsr lr

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.

 

采用长跳转的话,直接跳转到d00260b4中去执行led_blink,如果不重定位则不会亮,重定位则亮

技术分享

 

s5pv210重定位