Windows system >> Windowsの知識 >  >> Linuxシステムチュートリアル >> LinuxシステムFAQ >> U-Boot第1フェーズのキーコードの理解

U-Boot第1フェーズのキーコードの理解

  

1. u-bootプログラムのエントリアドレス

プログラムのエントリアドレスを理解するには、当然接続ファイルを考えて、まず接続ファイル" /boardを見てください。 /smdk2410/u-boot.lds"

エントリ(_start)

セクション

{

。= 0x00000000;

= ALIGN(4);

.text:

{

cpu /arm920t /start.o(.text)

*(。text)

}

。= ALIGN(4);

.rodata:{*(。rodata)}

。= ALIGN(4); < Br>

.data:{*(。data)}

。= ALIGN(4);

.got:{*(。got)}

__u_boot_cmd_start =。;

.u_boot_cmd:{*(。u_boot_cmd)}

__u_boot_cmd_end =。;

。= ALIGN(4);

__bss_start =。;

.bss:{*(。bss)}

_end =。;

}

(1)ENTRYから(_start) u-bootの入り口機能が見えます_start

(2)。= 0x00000000から、_startのアドレスが0x00000000であることがわかりますが、0x00000000は無効であり、接続時にTETX_BASEに置き換えられます。 u-bootのルートディレクトリにあるconfig.mkを参照してください。

(3)インターネット上の多くのステートメントは_start = TEXT_BASEですが、これも正しいと思いますが、実際にはこのコードは0x0にマッピングされていません。場所、実際にはコンパイルするコンパイラは、リンクファイルに従っています。つまり、すべてのアドレスはコンパイル時にTEXT_BASEを基準にしてコンパイルされます。そして、このアドレスは接続ファイルで指定されています0x338f0000、あなたはリンクファイルを見ることができます、あなたは逆アセンブルでアドレスを見ることができます、すべて0x33f8XXXXアドレス。

1.1 cpu /arm920t /start.S説明のためのコードの一部

(1)

[html]プレーンコピーの表示_TEXT_BASE:

.word TEXT_BASE

ここでアセンブリ言語タグ_TEXT_BASEが定義されており、その値はコードが配置されているコードのリンクアドレス値です; TEXT_BASEはボード内で定義されています\\ smdk2410 \\ config.mkファイル

(つまり0x33F80000)。 TEXT_BASEの値は、後で_TEXT_BASEを参照して取得できます。

(2)

[html]プレーンコピーの表示.globl _armboot_start

_armboot_start:

.word _start

外部参照の定義変数_armboot_startは、コード「.word _start」が配置されているリンクアドレスの値である。

図1 u-boot.map

コンパイルが完了すると、図1に示すようにu-boot.mapファイルが生成されます。図1は、_armboot_startが指すアドレス値が0x33f80044であることを示しています。 UltraEditでu-boot.binを開き、オフセット0x44を見つけます(0x44は_armboot_startによってアドレス0x33f80044-TEXT_BASEで得られます)。図2に示すように、この値は_startが指すリンクアドレスの値です33 F8 00 00 (リトルエンディアンモード)

図2 u-boot.bin

(3)

[html]プレーンコピーの表示.globl _bss_start

_bss_start:

.word __bss_start

__bss_startの値は、board /smdk2410 /u-boot.ldsファイルに定義されています。

[html] view plaincopy。= ALIGN(4);

__bss_start =。;

.bss:{*(。bss)}

_end =。;

__bss_start =。;は、__ bss_start値が現在位置の値であることを示します。現在の位置はどうですか?次の文章から.bss:{*(。ss)}知っています。ポジションの直後に、bssセグメントデータが配置されます。したがって、__ bss_startは、もちろんbssセグメントの開始アドレスです。 _endは、bssセグメントの終了アドレスです。

bssは、このリンクスクリプトの最後の段落です。 start.Sは、このセグメントの開始アドレスによって移動されるu-bootコードのサイズを計算することです。つまり、このセグメントの前にあるすべてのデータはTEXT_BASEに移動され、次にC言語のエントリコードであるstart_armbootにジャンプします。 。 __bss_startの値は何ですか?私のコンパイルした値は0x33f979d4です。図3に示すように、u-boot.mapファイルにあります。bssセグメントは0x33f979d4から割り当てられています。

図3 u-boot.map

図1からわかるように、_bss_startが指すリンクアドレスは0x33f80048で、これにはbssセグメントの開始アドレスが格納されています。図2に示すようにu-boot.binを開き、オフセット0x48(0x48は_bss_startアドレス0x33f80048-TEXT_BASEで取得されます)を探します。この値は実際には33 F9 79 D4です(スモールエンドモード)。

2.SDRAMの初期化、lowleverl_init.S

_TEXT_BASE:

.word TEXT_BASE

.globl lowlevel_init

lowlevel_init:

/*メモリ制御設定* /

/* r0を現在位置に設定することで、メモリではなくフラッシュからSMRDATAを読み取ることができます。* /< Br>

ldr r0、= SMRDATA

ldr r1、_TEXT_BASE

sub r0、r0、r1

ldr r1、= BWSCON /*バス幅ステータスコントローラ* /

add r2、r0、#13 * 4

SMRDATAと_TEXT_BASEを引いた値がわかりません。減算する必要があるのはなぜですか?

このプログラムのアドレスはロードアドレスと呼ばれ、もちろんアドレス0x0から始まり、プログラムで使用されるラベルは次のコードに基づいてコンパイルされます。 _TEXT_BASEアドレス。これをリンクまたは実行アドレスと呼びます。現時点では、ロードアドレスとランアドレスは同じではないため、TEXT_BASE(0x33f80000)の位置に移動する前に、これらのラベルを使用する必要があります。ラベルが直接呼び出されると、プログラムは飛行し、ラベルはSDRAM内で実行されている場合にのみ呼び出すことができます。これは0x33f80000がSDRAM内にあるためです。したがって、実際のSMRDATA定義データを取得するには、0x0を基準としたオフセットアドレスを1つだけ見つけることができます。つまり、コードのこの部分はアドレスに依存せず、PCオフセットに基づいています。コードを分析しましょう:

ldr r0、= SMRDATAはラベルSMRDATAの絶対アドレス(_TEXT_BASEよりも大きい)を取ります; ldr r1、_TEXT_BASEはベースアドレス(0x33f80000)を取ります。 Sub r0、r0、r1を減算して、_TEXT_BASEに対するSMRDATAオフセットを取得します。

3.UBOOT起動コードの再配置

#ifndef CONFIG_SKIP_RELOCATE_UBOOT

再配置:/* U-BootをRAMに再配置* /

adr r0、_start /* r0< - コードの現在位置* /

ldr r1、_TEXT_BASE /*フラッシュまたはRAMから実行する場合はテスト* /

r1が等しいときは常にr0を混同します。待ってはいけないのであれば、adrとldrの疑似ディレクタの違いを見てください。

adrは狭い範囲のアドレス読み込みディレクティブで、命令はPC相対オフセットアドレス値に基づいてレジスタに読み込まれます; ldrは大きいです範囲読み出しアドレス指令は、32を即値に、またはアドレスを指定されたレジスタにロードするために使用されます。

_startのリンクアドレスは、リンク時に決定され、命令間のオフセットアドレスは、位置に関係なく、_startは常にコードセグメントの開始アドレスであるため、負の値になります。 PCが示す命令のリンクアドレスと_startとのオフセットがxで、値が負であるとすると、adr r0、_startを実行すると、ldr r0、= PC + x(x< 0)と等価になります。 r0の値はコードセグメントの開始アドレスです。 PC内のアドレスは現在のコードのロードアドレスであり、参照する命令のリンクアドレスは_startのオフセット(コードのリンク開始アドレス)に基づいて追加されるので、コードに格納されている開始アドレス、つまりロードです。開始アドレス

Copyright © Windowsの知識 All Rights Reserved