×
单片机 > 单片机程序设计 > 详情

【s3c2440】第三课:代码重定位

发布时间:2024-05-20 发布时间:
|

什么是重定位

简单来说就是把程序从内存的一个位置复制到另一个位置。


重定位的重要性

若s3c2440使用Nand Flash启动,则CPU会将Nand Flash的前4k拷贝到s3c2440 soc内部的SRAM。如果程序没有重定位代码,则只能运行Nand flash前4k的程序。


若s3c2440使用Nor Flash启动,则CPU无法修改Nor Flash内存中的数据。如果程序没有重定位代码,则会因为无法修改全局变量、静态变量的值导致程序运行出错。


链接脚本

链接脚本的格式如下:


SECTIONS

{

sectname start BLICK(align) (NOLOAD) : AT( ldadr )

{ contents } >region :phdr =fill

...

}

主要会用到的格式如下:


SECTIONS

{

.sectname : AT( ldadr )

{ contents }

...

}

具体的代码如下:


SECTIONS

{

. = 0x30000000; #表示relocate addr从0x3000000(sdram的基地址)开始


__code_start = .; #声明一个变量用于重定位,其值等于0x30000000(该变量的地址就是他的值)


. = ALIGN(4); #4字节对齐

.text : #一个标号

{

*(.text) #表示.text里的内容是所有的text段

}


. = ALIGN(4);

.rodata : { *(.rodata) } #只读数据段


. = ALIGN(4);

.data : { *(.data) } #初值不为0的全局变量段


. = ALIGN(4);

__bss_start = .; #声明一个变量用于之后清除bss和comment段,也用于重定位

.bss : { *(.bss) *(.COMMON) } #bss段和comment段

_end = .; #用于清除bss和comment段的变量

}


重定位函数:


void relocate_to_sdram(void)

{

/* 要从lds文件中获得 __code_start, __bss_start

* 然后从0地址把数据复制到__code_start

*/


extern int __code_start, __bss_start; //在lds文件里的变量需要extern声明


volatile unsigned int *dest = (volatile unsigned int *)&__code_start;//变量的地址就是变量的值

volatile unsigned int *end = (volatile unsigned int *)&__bss_start;

volatile unsigned int *src = (volatile unsigned int *)0;


while (dest < end)

{

*dest++ = *src++;//循环复制代码

}

}



void clean_bss(void)

{

/* 要从lds文件中获得 __bss_start, _end

*/

extern int _end, __bss_start;


volatile unsigned int *start = (volatile unsigned int *)&__bss_start;

volatile unsigned int *end = (volatile unsigned int *)&_end;



while (start <= end)

{

*start++ = 0;//循环删除bss段和comment段

}

}


『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
单片机制作超级流水灯