1期第84讲——代码重定位与位置无关码 总结

本节课程讲要点是将程序从Flash拷贝到SDRAM运行所遇到的问题。

 

以下为链接文件代码:

//./Sdram.lds
SECTIONS
{
	. = 0x30000000;

	. = ALIGN(4);
	.text : { *(.text) }

	. = ALIGN(4);
	.rodata :{ *(.rodata) }

	. = ALIGN(4);
	.data :{ *(.data) }

	. = ALIGN(4);
	__bss_start = .;
	.bss :{ *(.bss) *(.COMMON) }
	_end = .;
}

以下是start.S重定位部分的代码:

//./start.S(部分)
        mov r1, #0
	ldr r0, [r1]
	str r1, [r1]
	ldr r2, [r1]
	cmp r1, r2
	ldr sp, = 0x40000000+4096
	moveq sp, #4096
	streq r0, [r1]

	bl sdram_init

	//重定位data段
	mov r1, #0
	ldr r2, =_start     		//第1条指令运行时的地址
	ldr r3, =__bss_start		//BSS段的起始地址
cpy:
	ldr r4, [r1]
	str r4, [r2]
	add r1, r1, #4
	add r2, r2, #4
	cmp r2, r3
	ble cpy

	//清除BSS段
	ldr r1, =__bss_start
	ldr r2, =_end
	mov r3, #0

clean:
	str r3, [r1]
	add r1, r1, #4
	cmp r1, r2
	ble clean

	//bl main //使用BL命令相对跳转,程序仍然在NOR/sram执行
	ldr pc, =main //绝对跳转,调到sdram

start.S中的_start就是0地址

如果使用bl命令,将会使用相对地址跳转,bl main的话,程序将仍然在Flash中运行。如果要跳转到重定位后的SDRAM,需要使用绝对地址跳转,使用ldr pc, =main实现。

 

怎么写位置无关的程序:
使用位置无关码!不使用绝对地址!最根本的办法是看反汇编
1、使用相对跳转命令,B/BL
2、重定位之前,不可使用绝对地址:
不可访问全局变量/静态变量
不可访问有初始值的数组(因为初始值放在rodata里,使用绝对地址来访问)
3、重定位之后,使用ldr pc =xxx跳转到runtime addr。如果用bl命令的话,还是在flash上运行。

 

 

你可能感兴趣的:(Linux笔记)