Mini210S 開発キット詳細URL
第VII章 IRAM+0x4000 にコードをリロケーション
第一節 リロケーション
プログラムについて、まず二つの概念を理解しておく必要があります、一つプログラムの現在のアドレス、すなわち実行時にそのプログラムのアドレス;二是程序的链接地址、即程序运行时应该位于的运行地址。プログラムのコンパイル時に、プログラムのリンクアドレスは指定することができます。
S5PV210にとっては、起動時はNAND Flash/sdブートデバイスから最初の16KコードをIRAMへコピーするだけで、もしプログラムが16Kを超えた場合はどうなりましょう?プログラム全体のコードを DRAM などの広いスペースへ全てコピーして、そして DRAM にジャンプし、コードを実行します、この転移の過程はリロケーションと呼びます。この章では、主にリロケーション方法を説明します。DRAM単にIRAMの 0xD0020010 から0xD0024000までにコードをコピーして、0xD0024000でコードを実行するプロセスです。
第二節 プログラム説明
完全なコードは、ディレクトリ5.link_0x4000、ご参照ください。前章と比べったら、start.S 中にリンカスクリプトlink.ldsを追加致します。
1. link.lds
リンカスクリプトとはリンクスクリプトは、その主な機能は、どのように入力ファイル内のセグメント(SECTION)を出力ファイルへのマッピング、および出力ファイル•のストレージ•レイアウト・ドキュメントを制御することです。リンカスクリプトの基本コマンドはSECTIONSで、一つのSECTIONSには一つや多数のSECTIONを含み、セクション(SECTION)はリンカスクリプトの基本単位で、これは入力ファイルのセグメントの配置方を示します。
リンクスクリプトの標準形式は次のとおりです:
SECTIONS
{
sections-command
sections-command
}
次は link.lds と合わせって詳しい説明致します:
SECTIONS
{
. = 0xD0024000;
.text : {
start.o
* (.text)
}
.data : {
* (.data)
}
bss_start = .;
.bss : {
* (.bss)
}
bss_end = .;
}
1) リンカスクリプト中、独自の(.)は現在アドレスを示して、.= 0xD0024000はプログラムのリンクアドレスを示します;
2) link.lds中、.text 、 .data 、 .bss は各自textセクション、dataセクション、bssセクションのSECTION名を示します(セクションの名は固定するではありません、状況によって任意名を与えます。)。.textセクションの内容は start.o と残りのコードのtextセクションを含めます;.dataセクションはコード中すべてのdataセクション;.bss 段はコード中すべてのbssセクションを含めます;
3) bss_start と bss_end はbssクションの開始アドレスと終了アドレス、start.Sでは使用されます。
次は data、text、bssセクションを説明します:
1) dataセクション:データセグメント(datasegment)通常、プログラム中初期化されたグローバル変数を保存するメモリー領域です。データセグメントは、静的メモリ割り当てであります。
2) textセクション:コードセグメント通常のプログラムの実行コードを保存するメモリー領域です。。プログラムが実行される前に、スペースの容量は決めされます、読み取り専用メモリ領域に属しており、部分アーキテクチャはコード•セグメントを書き込みは可能、すなわちプログラムを変更できます。コード•セグメントは、読み取り専用の定数変数を含める場合もあります、例えば文字列定数など:
3) bssセクション:プログラム内で初期化されていないグローバル変数を保存するメモリ領域のことBSS(BlockStarted by Symbol)です。プログラムにグローバル変数がある場合、それはBSSセグメントに保存されます、そして、グローバル変数のデフォルトの初期値は0であるため、手動でbssセグメントをクリアする必要があります。
2. start.S
start.S 中、タイマーを初期化後、また三つの手順を追加します:
ステップ1 リロケーション、コードは次のとおりです:
// _start 現在のアドレス
adr r0、 _start
// _start のリンクアドレス
ldr r1、 =_start
ldr r2、 =bss_start
cmp r0、 r1
beq clean_bss
copy_loop:
ldr r3、 [r0]、 #4
str r3、 [r1]、 #4
cmp r1、 r2
bne copy_loop
ADR命令はコードの現在アドレス値を取得するに、ldr命令はのコードのリンクアドレス値のがをフェッチするとことです;コードでは、まず_startラベルは現在のアドレス(つまり0xD0020010)、そして続きリンクアドレス(0xD0024000)があります、binファイルにbssセグメントを保存する必要がないため、符号長はbss_startまたは-_startの実行アドレスをcopy_loopでコピーします。
ステップ2 bssをクリア、コードは次のとおりです:
ldr r0、 =bss_start
ldr r1、 =bss_end
cmp r0、 r1
beq run_on_dram
mov r2、 #0
clear_loop:
str r2、 [r0]、 #4
cmp r0、 r1
bne clear_loop
まずbssセグメントの開始アドレス(bss_start)、bssセグメント終了アドレス(bss_end)を取得します;最後にclear_loopコマンドで bssセグメントのメモリをクリアし、bss_startとbss_end位置をlink.ldsにロケーションします。
ステップ3 ジャンプ、コードは次のとおりです:
run_on_dram:
ldr pc、 =main
LDR命令はリンクmain関数のアドレスを取得する機能で、ldr pc、 =main を実行すると、プログラムは0xD002200 +main関数のoffsetアドレスにジャンプします。
---続く