韦东山嵌入式Linux学习笔记之——代码重定位001_段的概念_重定位的引入
2018年07月12日 21:39:06
Iron_man73 阅读数:78
在2440中,cpu的命令可以通过内存控制器直接到达SRAM、SDRAM、NOR flash中,因此可以将代码直接放在上述三种内存单元中直接运行,相应地就可以设置为SRAM、SDRAM或者NOR flash 启动机制。但是在实际应用中我们也可以设置nand flash启动,这是为什么呢?
原因是这里用到了代码重定位的机制。
(1)nand flash 启动:

随之而来的有一个问题,就是如果程序>4K怎么办呢?
在前4K的代码中,需要完成将后续程序拷贝至SDRAM的工作。

(2)nor flash启动:
使用nor启动时,cpu看到的0地址时nor flash中的0地址。此时片内内存SRAM的基地址为:0x40000000
而在采用nand flash启动时,片内内存SRAM的基地址为:0

nor flash的特点:

nor flash就像电脑的硬盘,里面通常保存了一些程序代码等比较重要的内容,因此不能够通过常用指令对其进行写操作。
如果要写nor flash, 则需要一些特殊的指令。

这里的例子是全局/静态变量。它们在bin文件中,写在nor flash上,如果程序中直接对其进行修改,则无效。
因此需要将其重定位,放到SDRAM中,然后进行修改操作,最后重新写入nor flash中。
现在根据之前的SDRAM的程序验证刚刚的理论:
在原函数中定义全局变量g_char,之后在主程序中对其进行加值操作,最后将程序分别下载值开发板的nor flash和nand flash中观察程序运行的现象来验证nor和nand flash的特性。
#include "s3c2440_soc.h"
#include "uart.h"
#include "init.h"
char g_char = 'A'
int main(void)
{
uart0_init();
while(1)
{
putchar(g_char);
g_char++; /* nor启动时,此代码无效 */
delay(100000);
}
return 0;
}
编译整个程序后发现生成的.bin文件有30+K,显然不合理,打开汇编文件后查看到程序的数据段存放在0x00008474(33.9K)的内存空间中,这显然是不合理的。

下面需要修改Makefile:

重新make编译后结果为:

可以看到这时候.bin文件的大小变为了2049字节。
之后将.bin文件分别烧写进开发板的nor 和nand flash中运行:
前面全是A的是用了nor启动的效果,后面的字母递增的是采用了nand启动的效果

打开反汇编分析:

这里的strb是存储器写入指令,其中[r2]的地址在nor flash上,nor的特性就是只读不写,因此这里的存储指令没法执行,故一直显示A。
给代码加入一些变量:
char g_char = 'A';
const char g_char2 = 'B';
int g_A = 0;
int g_B;
重新编译后查看反汇编内容。

值得注意的是,这里的comment段存放的是一些表示系统信息的字符串,
如这里的00474343表示:

总结:一个程序所包含的内容: