自分でブートローダーを作成する------第2段階を作成する

私たちのブートローダーは、次の機能を実現する必要があります。

  • ハードウェアの初期化:ウォッチドッグをオフにし、クロックを設定し、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);

おすすめ

転載: blog.csdn.net/u013171226/article/details/123607387