前回 initが読み込めないで停止する状態でしたが、まだ進捗がでていません。
printkで入出力パラメタやerrnoなどを表示して追っていますが、おかしいパラメタやerrnoもみつからずやや手詰まりになっています。
そこで、bootからinitの起動までソースをざっと追ってみることにします。
リセット直後のCPUの初期化ルーチン
リセットすると、$00000000にフラッシュメモリが配置されます。フラッシュメモリの$00000000から4バイトはスタックポインタの初期値、$00000004から4バイトはプログラム開始アドレスが書き込まれています。CPUはこれらの値を読み込み動き始めます。
リセット後に動作するプログラムは、arch/m68knommu/platform/68EZ328/ucsimm/crt0_rom.Sの_startから動きます。まずはステータスレジスタを設定しています。
.text _start: _stext: movew #0x2700,%sr
このあと、UARTの設定、PLLの設定を行い、PLLが安定するまで少しループで待ちます。
movew #0x0800, 0xfffff906 /* Ignore CTS */ movew #0x010b, 0xfffff902 /* BAUD to 9600 */ movew #0xe100, 0xfffff900 /* enable */ movew #0x2400, 0xfffff200 /* PLLCR */ movew #0x0123, 0xfffff202 /* PLLFSR */ moveq #0, %d0 movew #16384, %d0 /* PLL settle wait loop */ _pll_settle: subw #1, %d0 bne _pll_settle
続いて、フラッシュメモリを$10000000に配置、DRAMは$00000000に配置するなどのCPUの設定を行います。
moveb #0x00, 0xfffffb0b /* Watchdog off */ moveb #0x10, 0xfffff000 /* SCR */ moveb #0x00, 0xfffff40b /* enable chip select */ moveb #0x00, 0xfffff423 /* enable /DWE */ moveb #0x08, 0xfffffd0d /* disable hardmap */ moveb #0x07, 0xfffffd0f /* level 7 interrupt clear */ movew #0x8000, 0xfffff100 /* FLASH at 0x10000000 */ movew #0x01ed, 0xfffff110 /* 8Meg, 16bit, enable, 0ws */ movew #0x8f00, 0xfffffc00 /* DRAM configuration */ movew #0x8667, 0xfffffc02 /* DRAM control */ movew #0x0000, 0xfffff106 /* DRAM at 0x00000000 */ movew #0x068d, 0xfffff116 /* 8Meg, 16bit, enable, 0ws */ moveb #0x40, 0xfffff300 /* IVR */ movel #0x007FFFFF, %d0 /* IMR */ movel %d0, 0xfffff304 moveb 0xfffff42b, %d0 andb #0xe0, %d0 moveb %d0, 0xfffff42b movew #0x8000, 0xFFFFF102 /* CSB */ movew #0x0190, 0xFFFFF112 /* disable eth + DPRAM - KH */
変数領域の初期化
次はフラッシュメモリにあるデータセグメント(data)のデータをRAMにコピーします。これは初期値を持つ変数の値の内容になります。
/* Copy data segment from ROM to RAM */ moveal #__data_rom_start, %a0 moveal #_sdata, %a1 moveal #_edata, %a2 /* Copy %a0 to %a1 until %a1 == %a2 */ 1: movel %a0@+, %a1@+ cmpal %a1, %a2 bhi 1b
続いて初期値を持たない変数のエリア(bss)を0で埋めます。
moveal #_sbss, %a0 moveal #_ebss, %a1 /* Copy 0 to %a0 until %a0 == %a1 */ 1: clrl %a0@+ cmpal %a0, %a1 bhi 1b
グローバル変数の値を設定し、スタックポインタを設定します。
movel #_sdata, %d0 movel %d0, _rambase movel #_ebss, %d0 movel %d0, _ramstart movel #__ramend-CONFIG_MEMORY_RESERVE*0x100000, %d0 movel %d0, _ramend movel #__ramvec, %d0 movel %d0, _ramvec /* * load the current task pointer and stack */ lea init_task_union,%a0 movel %a0, _current_task lea 0x2000(%a0),%sp
カーネルの起動
最後にカーネルを動かします。戻ってきたら再度動かすように無限ループになっています。
1: jsr start_kernel bra 1b
ここから先はLinux kernelに入ります。以降はC言語で書かれているのでやや読みやすくなります。(続く)