私たちのブートローダーは、次の機能を実現する必要があります。
- ハードウェアの初期化:ウォッチドッグをオフにし、クロックを設定し、SDRAMを設定し、nandfalshを初期化します。
- ブートローダーが大きい場合は、SDRAMに再配置します。
- nandflashからSDRAMへのカーネルの読み取り
- 「カーネルに渡すパラメータ」を設定する
- カーネルにジャンプ
最初の段階では、初期化と再配置を実装し、nandread関数をカプセル化しました。次に、次の3つの関数を実装します。新しいboot.cを作成し、これら3つの関数を内部のmain関数に実装します。
1nandflashからカーネルをメモリに読み込みます
では、どのアドレスから読み取りを開始し、どこから読み取り、どのくらいの大きさで読み取りますか?開発ボードのubootコマンドラインでmtdコマンドを使用して、表示および取得してみましょう。
カーネルに0x0060000が存在することがわかります。別の問題は、プログラムしたカーネルがuImage、uImage=64バイトのヘッダー+zImageであるということです。ここでuImageは0x0060000に存在し、次にzImageはここで0x0060000+64に存在します。
それで、どこでそれを読みましたか、ubootのbootコマンドでそれを始めましょう、そして
カーネルがメモリの30008000に配置されていることがわかります。したがって、次のコードを使用して、カーネルをnandflashからSDRAMに読み取ります。
nand_read(0x60000+64, (unsigned char *)0x30008000, 0x200000);
2パラメータを設定します
ubootは、カーネルにメモリの量を通知し、開始するコマンドラインパラメータをカーネルに通知する必要があります。これらのパラメータはタグを介して渡されます。つまり、これらのパラメータは特定のメモリに保存され、次にカーネルに直接保存されます。このメモリからパラメータを読み取ります。合計4つのタグが必要です。
/* 2. 设置参数 */
puts("Set boot params\n\r");
setup_start_tag();
setup_memory_tags();
setup_commandline_tag("noinitrd root=/dev/mtdblock3 init=/linuxrc console=ttySAC0");
setup_end_tag();
- setup_start_tag()は、セットアップパラメータが開始する場所を示します。
- setup_memory_tags()高速カーネルのメモリの大きさ。
- setup_commandline_tag( "noinitrd root = / dev / mtdblock3 init = / linuxrc console = ttySAC0");コマンドラインパラメータータグ
- setup_end_tag();パラメータが終了する場所を示します。
2.1 setup_start_tag()
まず、ubootのstart_tagがどのように記述されているかを見てみましょう。
パラメータparamがあります。paramの定義を見てみましょう。
次に、ブートローダーでそのような構造を定義します。タグはそのような構造です。
タグ構造はubootのsetup.hで宣言されています。setup.hを直接コピーして使用すると、setup.hのu32 u16 u8が定義されていないので、内部で定義しましょう。
次に、setup_start_tagの記述を開始し、upbootのsetup_start_tag関数を直接コピーします。
void setup_start_tag(void)
{
params = (struct tag *)0x30000100;
params->hdr.tag = ATAG_CORE;
params->hdr.size = tag_size (tag_core);
params->u.core.flags = 0;
params->u.core.pagesize = 0;
params->u.core.rootdev = 0;
params = tag_next (params);
}
setup_start_tagを取得した後
params = tag_next(params);は次のタグを指すことを意味しますが、このマクロ定義は、次のタグを指す現在のタグ+サイズです。。
2.2 setup_memory_tag
また、ubootでの書き込みを模倣します。まず、ubootでの書き込みを見てみましょう。
メモリの開始アドレスは0x30000000で、サイズは64Mなので、次のようになります。
void setup_memory_tags(void)
{
params->hdr.tag = ATAG_MEM;
params->hdr.size = tag_size (tag_mem32);
params->u.mem.start = 0x30000000;
params->u.mem.size = 64*1024*1024;
params = tag_next (params);
}
2.3 setup_commandline_tag
ビデオの長さは24分です。
3ジャンプ
ubootのコードを参照します。ubootstartupは主にbootmコマンドを実行します
それでは、ubootコードに移動して、bootmコマンド、cmd_bootm.cファイルのdo_bootm関数、および関数ポインターを定義するdo_bootm関数のdo_bootm_linux関数を検索してみましょう。
また、関数ポインタの定義に従います。
void (*theKernel)(int zero, int arch, unsigned int params);