OSの勉強の一環として、u-bootがどのようにして動作するのかを見てみることにした。
U-bootはOSのブートローダとして、特にマイコンや、マイコンボードなどで利用されているようだ。xv6の勉強をしていると、BIOSからの動作ばかりを見てしまうが、ブートローダについて理解するために、 U-bootの中身を見ておいても損は無いと思う。
まずは、U-bootをダウンロードする。ドキュメントを見てみると、mips用のリポジトリがあるらしい。まずはそれをダウンロードした
git clone git://git.denx.de/u-boot-mips.git u-boot-mips
次に、make menuconfigでビルドオプションを選択する。
アーキテクチャはMIPS、エンディアンはLittle Endianだ (これは僕のISSがLittle Endianしか対応していないため)
設定が完了すると、makeでビルドを開始する。このときに必要なのがMIPSのクロスコンパイル用GCCだが、いろいろ試した結果、MIPS Technologiesの公式GCCでしかきちんとビルドできないことが分かった。
"MTI GNU Linux Toolchain" からダウンロードする。
make CROSS_COMPILE=mips-mti-linux-gnu- ARCH=mips
- GNUの場合
make CROSS_COMPILE=mipsel-linux-elf- ARCH=mips ... HOSTCC tools/fdtgrep.o HOSTLD tools/fdtgrep CC arch/mips/cpu/time.o CC arch/mips/cpu/interrupts.o CC arch/mips/cpu/cpu.o LD arch/mips/cpu/built-in.o mipsel-linux-elf-ld.bfd: unrecognised emulation mode: elf32ltsmip Supported emulations: elf32elmip scripts/Makefile.build:356: recipe for target 'arch/mips/cpu/built-in.o' failed make[1]: *** [arch/mips/cpu/built-in.o] Error 1 Makefile:1206: recipe for target 'arch/mips/cpu' failed make: *** [arch/mips/cpu] Error 2
- IMG GCCの場合
make CROSS_COMPILE=mips-img-linux-gnu- ARCH=mips ... CC common/env_callback.o CC common/env_flags.o CC common/env_flash.o CC common/cmd_source.o CC common/cmd_bdinfo.o CC common/cmd_console.o CC common/cmd_echo.o scripts/Makefile.build:277: recipe for target 'common/cmd_echo.o' failed make[1]: *** [common/cmd_echo.o] Interrupt Makefile:1206: recipe for target 'common' failed make: *** [common] Interrupt
どうやらTargetの仕様が違うようだ。
とりあえず、ビルドできたu-bootのバイナリを、ISSで回してみた。
swimmer_mips --binfile u-boot --debug --out debug.log --debug_gvar --debug_func
トレースしてみると、何となく動作しているようだ。 じゃあこのログを見ながら、U-bootの勉強をしていこう。
<BSF_Global: 0xbfc38668 _u_boot_list_2_cmd_2_itest <BSF_Global: 0xbfc38710 _u_boot_list_2_cmd_2_md <BSF_Global: 0xbfc383e4 _u_boot_list_2_cmd_2_cp <BSF_Global: 0xbfc38828 _u_boot_list_2_cmd_2_saveenv <Finish loading global variable table> 0 : [bfc00000] 10000123 : beq r00,r00,0x0123 r00=>00000000 r00=>00000000 pc<=bfc00004 pc<=bfc00490 1 : [bfc00004] 00000000 : sll r00,r00,0x00 r00=>00000000 2 : [bfc00490] 40809000 : mtc0 r18,0x12,0x0 3 : [bfc00494] 40809800 : mtc0 r19,0x13,0x0 4 : [bfc00498] 40806800 : mtc0 r13,0x0d,0x0 5 : [bfc0049c] 40086000 : mfc0 r12,0x0c,0x0 6 : [bfc004a0] 3c011000 : lui r01,0x1000 r01<=10000000 7 : [bfc004a4] 3421001f : ori r01,r01,0x001f r01=>10000000 r01<=1000001f 8 : [bfc004a8] 01014025 : or r08,r08,r01 r08=>00000000 r01=>1000001f r08<=1000001f 9 : [bfc004ac] 3908001f : xori r08,r08,0x001f r08=>1000001f r08<=10000000 10 : [bfc004b0] 40886000 : mtc0 r12,0x0c,0x0 11 : [bfc004b4] 000000c0 : sll r00,r00,0x03 r00=>00000000 12 : [bfc004b8] 40804800 : mtc0 r09,0x09,0x0 13 : [bfc004bc] 40805800 : mtc0 r11,0x0b,0x0 14 : [bfc004c0] 24080002 : addiu r08,r00,0x0002 r00=>00000000 r08<=00000002 15 : [bfc004c4] 40888000 : mtc0 r16,0x10,0x0 16 : [bfc004c8] 04110002 : bgezal r00,0x0002 r00=>00000000 r31<=bfc004d0 pc<=bfc004cc pc<=bfc004d4