裸のS3C2440 - 再配置(1組み込ま移転を、なぜ再配置)

1.再配置の導入(なぜ再配置)

私たちは、あなたが起動したときも、0でもアドレスに対応するから、CPUのS3C2440は、アドレスを実行するために0からの命令フェッチを開始知っている、またメモリは同じように読むことができますが、同じ缶は、メモリのように記述していません。私たちは、命令フェッチからも実行することができます。

例1:スタートNAND、私たちの前の4KにおけるNANDを自動的に命令のSRAM、外出先にロードされた状態になる、と、アドレスの対応0 SRAMへ。

だから、私たちのプログラムは、NAND開始から、4Kよりも大きい場合、SRAMは唯一の最初の4Kは、この問題を解決するためにどのようにして、コードのNANDにコピー?
再配置可能なコードは、大容量のSDRAM、SDRAMに行く必要があり、直接CPUにアクセスすることができます。

例2:私たちは、プログラムが含まれていることを知っています:

代码段(.text)
数据段(.data):存放初始值不为0的全局变量/静态变量
rodata段(.rodata):const修饰的全局变量或静态变量
bss段(.bss):存放初始值为0或者未初始化的全局变量/静态变量
commen段(.commen):注释

binファイルに次のコードを考えてみましょう。

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

int g_Char = 'A'; //.data
int g_CharB = 'B'; //.data
int g_CharC = 'C'; //.data
int g_CharD = 'D'; //.data


const int g_roval = 'C'; //.rodata
int g_A = 0; //bss
int g_B; //bss

int main(void)
{
    uart0_init();
    while (1)
    {
        putchar(g_Char);
        g_Char++;         /* nor启动时, 此代码无效,由于nor启动,nor上不可写 */
        delay(1000000);
    }
    return 0;
}

私たちは、NANDにそれを入れても違いが何であるかを見るために燃えていますか?

1.書き込みにも:私たちは、プログラムが出力「AAAAAAA」を持っていることがわかりました。

2.は、NANDにバーン:私たちは、プログラムが出力を持っていないことがわかりました。

我々が見つかりました。でも、なぜ、g_Char ++無効の開始、NAND任意の出力せずにプログラムを起動しますか?
私たちは、プログラムの抗コンパイルを見てみましょう:

私たちは、その後、0 CPUの命令実行、フェッチからアドレスをデコードし、プログラムのの.textセクションは、0番地から開始することです発見しました。
出発しても、0がアドレスに対応する場合も、SRAMアドレスに対応するNAND、0から始まる場合、それはCPUから実行されてもフェッチNANDからの両方を開始することができます。

しかし、私たちの次の.dataセクションの観点から、.dataセクションの開始アドレスは、(0x8474にすなわちアドレスg_Char変数)0x8474です見つけます。
その後:

1)デバイスが同じメモリので、領域も一定期間においても、データセクションにプログラムされても私は読むことができ、場合
「g_Char」は無効な修飾にはなく、書き込み直接と同じメモリへ。

2)当把程序烧录进nand, .data段在nand的某一区域,nand启动时硬件会自动把nand上的前4K数据copy到SRAM,然后cpu从sram取指令执行。但是.data段的起始地址0x8474>0x1000,超过了4K,cpu没法把.data段也copy到SRAM,所以当访问'g_Char'时,发生了异常(abt数据访问终止,这个异常后面我会在“异常与中断”里面专门讲解)。

那我们再仔细看看反汇编,发现.rodata段和.text段是连续的,但是.rodata段和.data段中间有一段"空洞"。用图形表示更形象,bin文件的内容分布如下所示:

那么我们怎么去掉空洞,让.data段了紧接着.rodata段呢?

用链接脚本(这个下节会讲),但现在直接在编译的时候用 "-Tdata 0x800",这样指定.data段基地址为0x800,这样nand启动时.data就能自动copy到SRAM了。再看下反汇编的.data段:

这时我们烧录程序到nand,从nand启动,发现能输出‘ABCDEFG’...

通过上面2个例子,现在总结下为什么要代码重定位:
1.nand启动,前4K代码被自动copy到sram,当程序大于4K的时候需要重定位代码到sdram。
2.nor启动, 全局变量在nor上,不能像内存一样直接写该全局变量,那么也需要重定位到sdram。

おすすめ

転載: www.cnblogs.com/fuzidage/p/12038514.html