当前位置:   article > 正文

第13课 重定位笔记_qspbss

qspbss

1、 段的概念_重定位的引入

  • J2440 有4k的SRAM
  • NAND 启动时,前4k会被复制到SRAM(由硬件做的)
  • CPU从(SDRAM)0地址开始运行

1、1 重定位的引出

要是程序大于4k的时候怎么办?
  • 1

前4k代码需要把整个程序读出,放到SDRAM(重定位)

1、2 NOR Flash 启动有什么不同

片内基地址
NAND启动0
NOR启动0x4000,00000(可以像内存一样读,不能像内存一样写)
	MOV R0, #0
	LDR R1,[R0]
	STR R1,[R0] # 对nor flash 内存无效
  • 1
  • 2
  • 3

程序中函数需要写的全局/静态变量,他们在bin中,卸载NOR上,直接修改变量无效
当我们需要直接修改全局/静态变量的值的时候,我们需要把全局/静态变量重定位到SDRAM上

	
#include "s3c2440_soc.h"
#include "uart.h"




void delay(volatile int d)
{
	while(d--);
}
char g_Char = 'A'; 
const g_Char2 = 'B';
int g_A = 0;
int  g_B;

int main(void)
{
	unsigned char c;
	int i;
	

	uart_init();

	
	while(1)
	{
		putchar(g_Char);
		g_Char ++;  	/* nor 启动是此代码无效*/
		delay(100000);
		
	}
	return 0;
}


  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36

代码所对应汇编


main.elf:     file format elf32-littlearm

Disassembly of section .text:

00000000 <_start>:
   0:	e3a00453 	mov	r0, #1392508928	; 0x53000000
   4:	e3a01000 	mov	r1, #0	; 0x0
   8:	e5801000 	str	r1, [r0]
   c:	e3a00313 	mov	r0, #1275068416	; 0x4c000000
  10:	e3e01000 	mvn	r1, #0	; 0x0
  14:	e5801000 	str	r1, [r0]
  18:	e59f0044 	ldr	r0, [pc, #68]	; 64 <.text+0x64>
  1c:	e3a01005 	mov	r1, #5	; 0x5
  20:	e5801000 	str	r1, [r0]
  24:	ee110f10 	mrc	15, 0, r0, cr1, cr0, {0}
  28:	e3800103 	orr	r0, r0, #-1073741824	; 0xc0000000
  2c:	ee010f10 	mcr	15, 0, r0, cr1, cr0, {0}
  30:	e59f0030 	ldr	r0, [pc, #48]	; 68 <.text+0x68>
  34:	e59f1030 	ldr	r1, [pc, #48]	; 6c <.text+0x6c>
  38:	e5801000 	str	r1, [r0]
  3c:	e3a01000 	mov	r1, #0	; 0x0
  40:	e5910000 	ldr	r0, [r1]
  44:	e5811000 	str	r1, [r1]
  48:	e5912000 	ldr	r2, [r1]
  4c:	e1510002 	cmp	r1, r2
  50:	e59fd018 	ldr	sp, [pc, #24]	; 70 <.text+0x70>
  54:	03a0da01 	moveq	sp, #4096	; 0x1000
  58:	05810000 	streq	r0, [r1]
  5c:	eb000011 	bl	a8 <main>

00000060 <halt>:
  60:	eafffffe 	b	60 <halt>
  64:	4c000014 	stcmi	0, cr0, [r0], {20}
  68:	4c000004 	stcmi	0, cr0, [r0], {4}
  6c:	0005c011 	andeq	ip, r5, r1, lsl r0
  70:	40001000 	andmi	r1, r0, r0

00000074 <delay>:
  74:	e1a0c00d 	mov	ip, sp
  78:	e92dd800 	stmdb	sp!, {fp, ip, lr, pc}
  7c:	e24cb004 	sub	fp, ip, #4	; 0x4
  80:	e24dd004 	sub	sp, sp, #4	; 0x4
  84:	e50b0010 	str	r0, [fp, #-16]
  88:	e51b3010 	ldr	r3, [fp, #-16]
  8c:	e2433001 	sub	r3, r3, #1	; 0x1
  90:	e50b3010 	str	r3, [fp, #-16]
  94:	e51b3010 	ldr	r3, [fp, #-16]
  98:	e3730001 	cmn	r3, #1	; 0x1
  9c:	0a000000 	beq	a4 <delay+0x30>
  a0:	eafffff8 	b	88 <delay+0x14>
  a4:	e89da808 	ldmia	sp, {r3, fp, sp, pc}

000000a8 <main>:
  a8:	e1a0c00d 	mov	ip, sp
  ac:	e92dd800 	stmdb	sp!, {fp, ip, lr, pc}
  b0:	e24cb004 	sub	fp, ip, #4	; 0x4
  b4:	e24dd008 	sub	sp, sp, #8	; 0x8
  b8:	eb00000d 	bl	f4 <uart_init>
  bc:	e59f302c 	ldr	r3, [pc, #44]	; f0 <.text+0xf0>
  c0:	e5d33000 	ldrb	r3, [r3]
  c4:	e1a00003 	mov	r0, r3
  c8:	eb000035 	bl	1a4 <putchar>
  cc:	e59f201c 	ldr	r2, [pc, #28]	; f0 <.text+0xf0>
  d0:	e59f3018 	ldr	r3, [pc, #24]	; f0 <.text+0xf0>
  d4:	e5d33000 	ldrb	r3, [r3]
  d8:	e2833001 	add	r3, r3, #1	; 0x1
  dc:	e5c23000 	strb	r3, [r2]
  e0:	e3a00b61 	mov	r0, #99328	; 0x18400
  e4:	e2800e2a 	add	r0, r0, #672	; 0x2a0
  e8:	ebffffe1 	bl	74 <delay>
  ec:	eafffff2 	b	bc <main+0x14>
  f0:	0000827c 	andeq	r8, r0, ip, ror r2

000000f4 <uart_init>:
  f4:	e1a0c00d 	mov	ip, sp
  f8:	e92dd800 	stmdb	sp!, {fp, ip, lr, pc}
  fc:	e24cb004 	sub	fp, ip, #4	; 0x4
 100:	e3a02456 	mov	r2, #1442840576	; 0x56000000
 104:	e2822070 	add	r2, r2, #112	; 0x70
 108:	e3a03456 	mov	r3, #1442840576	; 0x56000000
 10c:	e2833070 	add	r3, r3, #112	; 0x70
 110:	e5933000 	ldr	r3, [r3]
 114:	e20330f0 	and	r3, r3, #240	; 0xf0
 118:	e5823000 	str	r3, [r2]
 11c:	e3a02456 	mov	r2, #1442840576	; 0x56000000
 120:	e2822070 	add	r2, r2, #112	; 0x70
 124:	e3a03456 	mov	r3, #1442840576	; 0x56000000
 128:	e2833070 	add	r3, r3, #112	; 0x70
 12c:	e5933000 	ldr	r3, [r3]
 130:	e38330a0 	orr	r3, r3, #160	; 0xa0
 134:	e5823000 	str	r3, [r2]
 138:	e3a02456 	mov	r2, #1442840576	; 0x56000000
 13c:	e2822078 	add	r2, r2, #120	; 0x78
 140:	e3a03456 	mov	r3, #1442840576	; 0x56000000
 144:	e2833078 	add	r3, r3, #120	; 0x78
 148:	e5933000 	ldr	r3, [r3]
 14c:	e3c3300c 	bic	r3, r3, #12	; 0xc
 150:	e5823000 	str	r3, [r2]
 154:	e3a02245 	mov	r2, #1342177284	; 0x50000004
 158:	e3a03245 	mov	r3, #1342177284	; 0x50000004
 15c:	e5933000 	ldr	r3, [r3]
 160:	e3833b02 	orr	r3, r3, #2048	; 0x800
 164:	e5823000 	str	r3, [r2]
 168:	e3a02245 	mov	r2, #1342177284	; 0x50000004
 16c:	e3a03245 	mov	r3, #1342177284	; 0x50000004
 170:	e5933000 	ldr	r3, [r3]
 174:	e3833005 	orr	r3, r3, #5	; 0x5
 178:	e5823000 	str	r3, [r2]
 17c:	e3a03205 	mov	r3, #1342177280	; 0x50000000
 180:	e2833028 	add	r3, r3, #40	; 0x28
 184:	e3a0201a 	mov	r2, #26	; 0x1a
 188:	e5832000 	str	r2, [r3]
 18c:	e3a02205 	mov	r2, #1342177280	; 0x50000000
 190:	e3a03205 	mov	r3, #1342177280	; 0x50000000
 194:	e5933000 	ldr	r3, [r3]
 198:	e3833003 	orr	r3, r3, #3	; 0x3
 19c:	e5823000 	str	r3, [r2]
 1a0:	e89da800 	ldmia	sp, {fp, sp, pc}

000001a4 <putchar>:
 1a4:	e1a0c00d 	mov	ip, sp
 1a8:	e92dd800 	stmdb	sp!, {fp, ip, lr, pc}
 1ac:	e24cb004 	sub	fp, ip, #4	; 0x4
 1b0:	e24dd004 	sub	sp, sp, #4	; 0x4
 1b4:	e50b0010 	str	r0, [fp, #-16]
 1b8:	e3a03205 	mov	r3, #1342177280	; 0x50000000
 1bc:	e2833010 	add	r3, r3, #16	; 0x10
 1c0:	e5933000 	ldr	r3, [r3]
 1c4:	e2033004 	and	r3, r3, #4	; 0x4
 1c8:	e3530000 	cmp	r3, #0	; 0x0
 1cc:	1a000000 	bne	1d4 <putchar+0x30>
 1d0:	eafffff8 	b	1b8 <putchar+0x14>
 1d4:	e3a03205 	mov	r3, #1342177280	; 0x50000000
 1d8:	e2833020 	add	r3, r3, #32	; 0x20
 1dc:	e51b2010 	ldr	r2, [fp, #-16]
 1e0:	e5c32000 	strb	r2, [r3]
 1e4:	e1a00003 	mov	r0, r3
 1e8:	e89da808 	ldmia	sp, {r3, fp, sp, pc}

000001ec <getchar>:
 1ec:	e1a0c00d 	mov	ip, sp
 1f0:	e92dd800 	stmdb	sp!, {fp, ip, lr, pc}
 1f4:	e24cb004 	sub	fp, ip, #4	; 0x4
 1f8:	e3a03205 	mov	r3, #1342177280	; 0x50000000
 1fc:	e2833010 	add	r3, r3, #16	; 0x10
 200:	e5933000 	ldr	r3, [r3]
 204:	e2033001 	and	r3, r3, #1	; 0x1
 208:	e3530000 	cmp	r3, #0	; 0x0
 20c:	1a000000 	bne	214 <getchar+0x28>
 210:	eafffff8 	b	1f8 <getchar+0xc>
 214:	e3a03205 	mov	r3, #1342177280	; 0x50000000
 218:	e2833024 	add	r3, r3, #36	; 0x24
 21c:	e5d33000 	ldrb	r3, [r3]
 220:	e20330ff 	and	r3, r3, #255	; 0xff
 224:	e1a00003 	mov	r0, r3
 228:	e89da800 	ldmia	sp, {fp, sp, pc}

0000022c <puts>:
 22c:	e1a0c00d 	mov	ip, sp
 230:	e92dd800 	stmdb	sp!, {fp, ip, lr, pc}
 234:	e24cb004 	sub	fp, ip, #4	; 0x4
 238:	e24dd004 	sub	sp, sp, #4	; 0x4
 23c:	e50b0010 	str	r0, [fp, #-16]
 240:	e51b3010 	ldr	r3, [fp, #-16]
 244:	e5d33000 	ldrb	r3, [r3]
 248:	e3530000 	cmp	r3, #0	; 0x0
 24c:	0a000007 	beq	270 <puts+0x44>
 250:	e51b3010 	ldr	r3, [fp, #-16]
 254:	e5d33000 	ldrb	r3, [r3]
 258:	e1a00003 	mov	r0, r3
 25c:	ebffffd0 	bl	1a4 <putchar>
 260:	e51b3010 	ldr	r3, [fp, #-16]
 264:	e2833001 	add	r3, r3, #1	; 0x1
 268:	e50b3010 	str	r3, [fp, #-16]
 26c:	eafffff3 	b	240 <puts+0x14>
 270:	e1a00003 	mov	r0, r3
 274:	e89da808 	ldmia	sp, {r3, fp, sp, pc}
Disassembly of section .rodata:

00000278 <g_Char2>:
 278:	00000042 	andeq	r0, r0, r2, asr #32
Disassembly of section .data:

0000827c <__data_start>:
    827c:	Address 0x827c is out of bounds.

Disassembly of section .bss:

00008280 <g_A>:
    8280:	00000000 	andeq	r0, r0, r0

00008284 <g_B>:
    8284:	00000000 	andeq	r0, r0, r0
Disassembly of section .comment:

00000000 <.comment>:
   0:	43434700 	cmpmi	r3, #0	; 0x0
   4:	4728203a 	undefined
   8:	2029554e 	eorcs	r5, r9, lr, asr #10
   c:	2e342e33 	mrccs	14, 1, r2, cr4, cr3, {1}
  10:	47000035 	smladxmi	r0, r5, r0, r0
  14:	203a4343 	eorcss	r4, sl, r3, asr #6
  18:	554e4728 	strplb	r4, [lr, #-1832]
  1c:	2e332029 	cdpcs	0, 3, cr2, cr3, cr9, {1}
  20:	00352e34 	eoreqs	r2, r5, r4, lsr lr

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207

注: bss 和 commen段不保存在bin文件中

.text代码段
.data数据段(全局变量)
.rodataconst 全局变量
.bss初始值为0,无初始值的全局变量
commen注释

2、链接脚本的引入与简单测试

3、链接脚本

SECTIONS {

secname start BLOCK(align) (NOLOAD) : AT ( ldadr )
{ contents } >region :phdr =fill

}

名称作用
sename段名
start起始地址,运行时地址(runtime addr ),重定位地址(relocate addr)
AT ( ldadr )加载地址(默认为 runtime addr)
contentsstart.o / *(.text) / start.0 *(.text)

程序运行时应该位于runtime addr(relocate data, 也可以成为链接地址)

  • 链接得到elf 文件 ,含有地址信息(loadaddr)

  • 使用加载器(对于裸板时JTAG调试工具)(对于app 加载器也是app 把elf文件读入内存 读到loadaddr)

  • 运行

  • 如果loaddr 不等于 runtime addr 程序本身要重地位

  • elf —> bin

  • 如果没有加载器,硬件机制启动

  • 如果bin所在位置 不等于runtime addr 程序本身需要重定位

例:


SECTIONS {
    .text 0 :{ *(.text) } # loadaddr = runtime addr = 0
    .rodata :{ *(.rodata) }
    .data 0x30000000 : AT(0x800)   # loadaddr = 0x8000 runtimeaddr = 0x300000000
    { 
        data_load_addr = LOADADDR(.data);
        data_start = .; # 当前位置 地址
        *(.data)
        data_end = .;
     }
  	.bss :{ *(.bss) *(.COMMON) }# runtime = 0x3xxxxxxx 
}
bin文件 /elf 文件都不存 bss
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

	bl sdram_init /*初始化 sdram */

	/*重定位*/
	ldr r1,= data_load_addr /*data段在bin文件中的地址,加载地址*/
	ldr r2, = data_start		/*data段在重定位地址,运行时地址*/
	ldr r3, = data_end		/*data段在重定位地址,运行时地址*/
cpy:
	ldrb r4,[r1] 	/*从r1读取1byte数据到r4*/
	strb r4,[r2] 	/*把r4的值存放到r2的位置*/
	add r1,r1,#1	/*r1 = r1+1*/
	add r2,r2,#1	/* r2 = r2 +1*/
	cmp r2,r3		/*比较r2和r3是否相同*/
	bne cpy			/*不相同 继续cpy*/


makefile
all:
	arm-linux-gcc -c -o main.o  main.c
	arm-linux-gcc -c -o uart.o  uart.c
	arm-linux-gcc -c -o init.o  init.c
	arm-linux-gcc -c -o start.o start.S
	# arm-linux-ld -Ttext 0 start.o main.o uart.o -o main.elf
	arm-linux-ld -T sdram.lds start.o main.o uart.o init.o -o main.elf
	arm-linux-objcopy -O binary -S main.elf main.bin
	arm-linux-objdump -D main.elf > main.dis
clean:
	rm *.bin *.o *.elf *.dis
	
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29

程序运行时把bss 段清 0

SECTIONS {

    .text 0 :{ *(.text) }
    .rodata :{ *(.rodata) }
    .data 0x30000000 : AT(0x800)   
    { 
        data_load_addr = LOADADDR(.data);
        data_start = .;
        *(.data)
        data_end = .;
     }
     bss_start = .;
    .bss :{ *(.bss) *(.COMMON) }
     bss_end = .;
   
}
	ldr r1, = bss_start
	ldr r2, = bss_end
	mov r3, #0   # r3 = 0
clean:
	strb r3,[r1]   
	add r1,r1,#1
	cmp r1,r2
	bne clean
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

拷贝代码链接代码的改进

现存:
  • 1

因为NOR 为 16 位 的SDRAM 为 32位的 如果每次读取一位效率会非常第
ldrb 从nor 得到数据 :需要执行16次,访问NOR 16次
strb 写SDRAM :需要执行16次,访问SDRAM 16次

因为 SDRAM 是32位的所以一次操作最小的单位为;32位
如果读一个字节,内存控制器会去SDRAM 读出4个字节然后挑出CPU感兴趣的字节,

CPU把地址和数据发给内存控制器,内存控制把32位的数据发给SDRAM,同时还会发出数据屏蔽信号(DQM)屏蔽其他3字节数据

改进
  • 1

使用ldr 和 str 每次4字节操作

指令str:无论存入地址为多少都是以4个字节为单位存入,也就是说无论存入地址是0x40000000或0x40000001或0x400000002或0x40000003,存入都是以0x40000000开始;
这里我们需要 链接命令
ALIGN(exp)

  • ALIGN doesn’t change the value of the location counter–it just does arithmetic on it. As an example, to align the output .data section to the next 0x2000 byte boundary after the preceding section and to set a variable within the section to the next 0x8000 boundary after the input sections:
  • (. + exp - 1) & ~(exp - 1)-也就是 0,exp,2exp,3exp 只能是这样的地址
sdram.lds

SECTIONS {
    .text 0 :{ *(.text) }
    .rodata :{ *(.rodata) }
    .data 0x30000000 : AT(0x800)   
    { 
        data_load_addr = LOADADDR(.data);
        . = ALIGN(4);
        data_start = .;
        *(.data)
        data_end = .;
     }
     . = ALIGN(4); # . = 0x30000002 所以 这里 . = 0x30000004 为了 对于str
     bss_start = .;
    .bss :{ *(.bss) *(.COMMON) }
     bss_end = .;  
}
start.S
	/*重定位*/
	
	ldr r1,= data_load_addr /*data段在bin文件中的地址,加载地址*/
	ldr r2, = data_start		/*data段在重定位地址,运行时地址*/
	ldr r3, = data_end		/*data段在重定位地址,运行时地址*/
cpy:
	ldr r4,[r1] 	/*从r1读取1byte数据到r4*/
	str r4,[r2] 	/*把r4的值存放到r2的位置*/
	add r1,r1,#4	/*r1 = r1+1*/
	add r2,r2,#4	/* r2 = r2 +1*/
	cmp r2,r3		/*比较r2和r3/
	ble cpy			/*如果r2<r则 继续 cpy*/

	ldr r1, = bss_start
	ldr r2, = bss_end
	mov r3, #0
clean:
	str r3,[r1]
	add r1,r1,#4
	cmp r1,r2
	ble clean
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/很楠不爱3/article/detail/647051
推荐阅读
相关标签
  

闽ICP备14008679号