FPGA開発日記

FPGAというより、コンピュータアーキテクチャかもね! カテゴリ別記事インデックス https://sites.google.com/site/fpgadevelopindex/

U-bootをMIPSアーキテクチャ向けにビルドする

OSの勉強の一環として、u-bootがどのようにして動作するのかを見てみることにした。

WebHome < U-Boot < DENX

U-bootはOSのブートローダとして、特にマイコンや、マイコンボードなどで利用されているようだ。xv6の勉強をしていると、BIOSからの動作ばかりを見てしまうが、ブートローダについて理解するために、 U-bootの中身を見ておいても損は無いと思う。

Das U-Boot - Wikipedia

まずは、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でしかきちんとビルドできないことが分かった。

community.imgtec.com

"MTI GNU Linux Toolchain" からダウンロードする。

make CROSS_COMPILE=mips-mti-linux-gnu- ARCH=mips

上記ならコンパイルできるが、以下のコンパイルは失敗した。

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