※ この記事はまだ勉強中のため、いろいろ間違いがあるかもしれません。
xv6のbootmain.cをコンパイルしてブートローダを作ってみたが、何とMIPSのコンパイラではオブジェクトのサイズが1セクタ(512バイト)に入り切らなかった! そこで、今回はアーキテクチャも違う、ということで、割り切って、1セクタにブートローダを入れる制約を無くし、自由にロードできるようにする。
ISSにおいて、imgファイルをロードするのは、以下のような機能を追加した。IDEのセクションにアクセスすると、自動的にディスクを読み込んで、次の位置までポインタを進める。
Word_t ModuleIde::ReadImgFile (void) { Word_t word = 0; for (int i = 0; i < 4; i++) { Byte_t byte_data; if ((byte_data = fgetc (m_img_fp)) == EOF) { return 0; } word = ((word >> 8) & 0x00FFFFFFULL) | (byte_data << 24); } m_env->DebugPrint ("<ReadImgFile(Index=%d)=>%08x>\n", m_read_count, word); if ((++m_read_count) == 512 / 4) { CloseImgFile (); m_read_count = 0; } return word; }
さて、これをロードするために、readsect()内に入っているstosb()を変更する。
static inline void stosb(void *addr, int data, int cnt) { int i; for (i = 0; i < cnt; i++) { *(((volatile char *) addr) + i) = (char) data; } }
また、実行している最中に気が付いたのだが、img_env.cpp内でread()関数に1024バイト分のイメージをロードしている。
{ const int read_size = 1024; uint8_t buf[read_size]; Addr_t start_addr = 0xbfc00000; // open binary int fs_img = open (filename.c_str(), O_RDONLY, S_IREAD); if (fs_img < 0) { perror (filename.c_str()); exit (EXIT_FAILURE); } // Seek Kernel Load position if (lseek (fs_img, start_addr, 0) == -1) { perror ("lseek"); } // Read head 1024byte of image file if (read (fs_img, buf, 1024) != 1024){ perror ("read"); exit (EXIT_FAILURE); }
このとき、ブートローダはディスクイメージの最後の方にいて、実は1024バイト分イメージが存在していない。 これにより、
if (read (fs_img, buf, 1024) != 1024){
が成立せずに落ちてしまうことが分かった。 これを防ぐために、xv6.imgを拡張して、最初からbfc0_0000から2セクタ分余分にディスク領域を確保しておく。
xv6.img: bootblock kernel fs.img Makefile dd if=/dev/zero of=xv6.img count=6283266 dd if=bootblock of=xv6.img seek=6283264 conv=notrunc dd if=kernel of=xv6.img seek=1 conv=notrunc hexdump xv6.img > xv6.img.dmp
イメージとしては3GBにもなってしまうが、まあ、実験用だし、いっか。
-rw-rw-r-- 1 vagrant vagrant 3.0G Sep 16 15:37 xv6.img
これで、ブートローダがディスクからイメージをロードして、main()まで行く道筋が出来上がった! 実行してみよう。
swimmer_mips --imgfile xv6.img --out debug.log --debug_func --debug_gvar --max 10000000 --img_dump --binfile bootblock.o --only_info_load --debug bfc00000 : 00 60 08 40 01 00 09 24 25 40 29 01 26 40 09 01 bfc00010 : 00 ff 08 35 00 10 09 3c 25 40 09 01 00 60 88 40 bfc00020 : c0 bf 1d 3c 00 00 bd 27 c0 bf 18 3c 4c 01 18 27 bfc00030 : 09 f8 00 03 00 00 00 00 20 00 00 42 00 b4 05 3c bfc00040 : c0 ff 04 24 40 00 03 24 f7 01 a2 90 ff 00 42 30 bfc00050 : 24 10 44 00 fc ff 43 14 00 00 00 00 08 00 e0 03 bfc00060 : 00 00 00 00 e0 ff bd 27 1c 00 bf af 18 00 b1 af bfc00070 : 14 00 b0 af 21 88 80 00 0f 00 f0 0f 21 80 a0 00 bfc00080 : 00 b4 02 3c 01 00 03 24 f2 01 43 a0 02 1a 10 00 bfc00090 : f3 01 50 a0 f4 01 43 a0 e0 ff 05 24 02 1c 10 00 bfc000a0 : 02 86 10 00 f5 01 43 a0 25 80 05 02 20 00 03 24 bfc000b0 : f6 01 50 a0 0f 00 f0 0f f7 01 43 a0 21 20 20 02 bfc000c0 : 00 02 22 26 00 b4 05 3c f0 01 a3 8c 04 00 84 24 bfc000d0 : fd ff 82 14 fc ff 83 ac 1c 00 bf 8f 18 00 b1 8f bfc000e0 : 14 00 b0 8f 08 00 e0 03 20 00 bd 27 e0 ff bd 27 bfc000f0 : 14 00 b1 af ff 01 d1 30 42 32 06 00 18 00 b2 af bfc00100 : 10 00 b0 af 1c 00 bf af 21 90 85 00 23 88 91 00 bfc00110 : 01 00 d0 24 2b 10 32 02 06 00 40 10 21 20 20 02 bfc00120 : 19 00 f0 0f 21 28 00 02 00 02 31 26 45 00 f0 0b bfc00130 : 01 00 10 26 1c 00 bf 8f 18 00 b2 8f 14 00 b1 8f bfc00140 : 10 00 b0 8f 08 00 e0 03 20 00 bd 27 e0 ff bd 27 bfc00150 : 10 80 04 3c 00 10 05 24 21 30 00 00 1c 00 bf af bfc00160 : 18 00 b2 af 14 00 b1 af 3b 00 f0 0f 10 00 b0 af bfc00170 : 10 80 02 3c 00 00 44 8c 4c 46 03 3c 7f 45 63 24 bfc00180 : 25 00 83 14 1c 00 bf 8f 1c 00 50 8c 2c 00 51 94 bfc00190 : 21 80 50 00 40 89 11 00 21 88 11 02 2b 10 11 02 bfc001a0 : 16 00 40 10 10 80 02 3c 0c 00 12 8e 10 00 05 8e bfc001b0 : 04 00 06 8e 3b 00 f0 0f 21 20 40 02 14 00 03 8e bfc001c0 : 10 00 02 8e 2b 20 43 00 f4 ff 80 50 20 00 10 26 bfc001d0 : 23 18 62 00 21 28 00 00 21 10 52 00 2a 20 a3 00 bfc001e0 : 04 00 80 10 21 20 45 00 00 00 80 a0 77 00 f0 0b bfc001f0 : 01 00 a5 24 67 00 f0 0b 20 00 10 26 1c 00 bf 8f bfc00200 : 18 00 b2 8f 14 00 b1 8f 10 00 b0 8f 18 00 59 8c bfc00210 : 08 00 20 03 20 00 bd 27 18 00 b2 8f 14 00 b1 8f bfc00220 : 10 00 b0 8f 08 00 e0 03 20 00 bd 27 00 00 00 00 bfc00230 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 bfc00240 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 bfc00250 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 bfc00260 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 bfc00270 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 bfc00280 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 bfc00290 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 bfc002a0 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 bfc002b0 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 bfc002c0 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 bfc002d0 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 bfc002e0 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 bfc002f0 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 bfc00300 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 bfc00310 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 bfc00320 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 bfc00330 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 bfc00340 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 bfc00350 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 bfc00360 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 bfc00370 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 bfc00380 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 bfc00390 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 bfc003a0 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 bfc003b0 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 bfc003c0 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 bfc003d0 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 bfc003e0 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 bfc003f0 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 $ less debug.log ... 4962745 : [bfc001fc] 8fbf001c : lw r31,0x001c(r29) r29=>bfbfffe0 (bfbffffc)=>bfc00038 r31<=bfc00038 4962746 : [bfc00200] 8fb20018 : lw r18,0x0018(r29) r29=>bfbfffe0 (bfbffff8)=>00000000 r18<=00000000 4962747 : [bfc00204] 8fb10014 : lw r17,0x0014(r29) r29=>bfbfffe0 (bfbffff4)=>00000000 r17<=00000000 4962748 : [bfc00208] 8fb00010 : lw r16,0x0010(r29) r29=>bfbfffe0 (bfbffff0)=>00000000 r16<=00000000 4962749 : [bfc0020c] 8c590018 : lw r25,0x0018(r02) r02=>80100000 (80100018)=>80100000 r25<=80100000 4962750 : [bfc00210] 03200008 : jr r25 r25=>80100000 pc<=bfc00214 pc<=80100000 4962751 : [bfc00214] 27bd0020 : addiu r29,r29,0x0020 r29=>bfbfffe0 r29<=bfc00000 <Error: instruction is not decoded. [80100000]=464c457f
途中で命令デコードエラーが発生して落ちた。これを次回は解析しよう。