FPGA開発日記

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

ブートセクションをずらしてISSでブートできるようにする

※ この記事はまだ勉強中のため、いろいろ間違いがあるかもしれません。

xv6のブートセクションはx86のものに従っているため、ディスクの先頭のセクションに配置されている。

hexdump xv6.img | less -o xv6.img.dmp
0000000 31fa 8ec0 8ed8 8ec0 e4d0 a864 7502 b0fa
0000010 e6d1 e464 a864 7502 b0fa e6df 0f60 1601
0000020 7c78 200f 66c0 c883 0f01 c022 31ea 087c
0000030 6600 10b8 8e00 8ed8 8ec0 66d0 00b8 8e00
0000040 8ee0 bce8 7c00 0000 dfe8 0000 6600 00b8
0000050 668a c289 ef66 b866 8ae0 ef66 feeb 9066
0000060 0000 0000 0000 0000 ffff 0000 9a00 00cf
0000070 ffff 0000 9200 00cf 0017 7c60 0000 8955
0000080 bae5 01f7 0000 83ec c0e0 403c f875 c35d
0000090 8955 57e5 8b53 0c5d e1e8 ffff baff 01f2
00000a0 0000 01b8 0000 ee00 f3b2 d889 89ee c1d8
00000b0 08e8 f4b2 89ee c1d8 10e8 f5b2 89ee c1d8
00000c0 18e8 c883 b2e0 eef6 f7b2 20b8 0000 ee00
00000d0 a9e8 ffff 8bff 087d 80b9 0000 ba00 01f0
00000e0 0000 f3fc 5b6d 5d5f 55c3 e589 5657 8b53
00000f0 085d 758b 8910 03df 0c7d f089 ff25 0001
0000100 2900 c1c3 09ee c683 3901 76df 5617 e853
0000110 ff7c ffff c381 0200 0000 c683 8301 08c4
0000120 df39 e977 658d 5bf4 5f5e c35d 8955 57e5
0000130 5356 ec83 6a0c 6800 1000 0000 0068 0100
0000140 e800 ffa3 ffff c483 810c 003d 0100 7f00
0000150 4c45 7546 a150 001c 0001 988d 0000 0001
0000160 b70f 2c35 0100 c100 05e6 de01 f339 2f73
0000170 7b8b ff0c 0473 73ff 5710 6ae8 ffff 8bff
0000180 144b 438b 8310 0cc4 c139 0c76 c701 c129
0000190 00b8 0000 fc00 aaf3 c383 3920 77de ffd1
00001a0 1815 0100 8d00 f465 5e5b 5d5f 00c3 0000
00001b0 0000 0000 0000 0000 0000 0000 0000 0000
*
00001f0 0000 0000 0000 0000 0000 0000 0000 aa55
...

ところが、MIPSの場合はリセット後にロードされるのはbfc0_0000から始まるため、ディスクの先頭では意味が無い。 0xA000_0000から0xC000_0000までは、カーネルマップkseg0としてアーキテクチャで定義されている。

ファイル:MIPS32 MemoryMap.png - Wikipedia

そこで、ddでディスクイメージを作成するときにオフセットを移動させて、ブートローダをbfc0_0000に移動させるようにした。

xv6.img: bootblock kernel fs.img Makefile
        dd if=/dev/zero of=xv6.img count=10000
        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

seek=6283264 はちょっと難しいが、0xbfc00000 / 512byte の計算結果を10進数で記述している。これで、ブートコードがbfc0_0000に配置される。 これをISSにロードすれば、ISSを無理に変更することなくロードできる。

less xv6.img.dmp
...

0432960 0000 0000 0000 0000 0000 0000 0000 0000
*
bfc00000 6000 4008 0001 2409 4025 0129 4026 0109
bfc00010 ff00 3508 1000 3c09 4025 0109 6000 4088
bfc00020 bfc0 3c1d 0000 27bd bfc0 3c18 0120 2718
bfc00030 f809 0300 0000 0000 0020 4200 b400 3c05
bfc00040 ffc0 2404 0040 2403 01f7 90a2 00ff 3042
bfc00050 1024 0044 fffc 1443 0000 0000 0008 03e0
bfc00060 0000 0000 ffe8 27bd 0014 afbf 0010 afb0
bfc00070 000f 0ff0 8021 00a0 b400 3c02 0001 2403
bfc00080 01f2 a043 1a02 0010 01f3 a050 01f4 a043
bfc00090 ffe0 2405 1c02 0010 8602 0010 01f5 a043
bfc000a0 8025 0205 0020 2403 01f6 a050 01f7 a043
bfc000b0 0014 8fbf 0010 8fb0 000f 0bf0 0018 27bd
bfc000c0 ffe0 27bd 0014 afb1 01ff 30d1 3242 0006
bfc000d0 0018 afb2 0010 afb0 001c afbf 9021 0085
bfc000e0 8823 0091 0001 24d0 102b 0232 0006 1040
bfc000f0 2021 0220 0019 0ff0 2821 0200 0200 2631
bfc00100 003a 0bf0 0001 2610 001c 8fbf 0018 8fb2
bfc00110 0014 8fb1 0010 8fb0 0008 03e0 0020 27bd
bfc00120 ffe0 27bd 0001 3c04 1000 2405 3021 0000
bfc00130 001c afbf 0018 afb2 0014 afb1 0030 0ff0
bfc00140 0010 afb0 0001 3c02 0000 8c44 464c 3c03
bfc00150 457f 2463 0025 1483 001c 8fbf 001c 8c50
bfc00160 002c 9451 8021 0050 8940 0011 8821 0211
bfc00170 102b 0211 0016 1040 0001 3c02 000c 8e12
bfc00180 0010 8e05 0004 8e06 0030 0ff0 2021 0240
bfc00190 0014 8e03 0010 8e02 202b 0043 fff4 5080
bfc001a0 0020 2610 1823 0062 2821 0000 1021 0052
bfc001b0 202a 00a3 0004 1080 2021 0045 0000 a080
bfc001c0 006c 0bf0 0001 24a5 005c 0bf0 0020 2610
bfc001d0 001c 8fbf 0018 8fb2 0014 8fb1 0010 8fb0
bfc001e0 0018 8c59 0008 0320 0020 27bd 0018 8fb2
bfc001f0 0014 8fb1 0010 8fb0 0008 03e0 0020 27bd
bfc00200

これで、この領域をimgfileとしてロードするようにする。

swimmer_mips --debug --imgfile xv6.img --out debug.log --debug_func --debug_gvar --max 1000000

--imgfile のオプションでは、とりあえず0xbfc0_0000の領域しかロードしないようにしている。この部分は後で直す。

github.com

uint32_t EnvBase::LoadImage (std::string filename)
{
    uint8_t buf[512];

    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 512byte of image file
    if (read (fs_img, buf, 512) != 512){
        perror ("read");
        exit (EXIT_FAILURE);
    }

    fprintf (g_debug_fp, "<Load Image %s>\n", filename.c_str());
    for (int byte = 0; byte < 512; byte++) {
        StoreMemoryDebug (start_addr + byte, buf[byte], Size_Byte);
        if (g_img_dump == true) {
            if ((byte % 16) == 0) {
                fprintf (stdout, "%08x : ", byte + start_addr);
            }
            fprintf (stdout, "%02x ", buf[byte]);
            if ((byte % 16) == 15) {
                fprintf (stdout, "\n");
            }
        }
    }

    return 0;
}

これで、とりあえずブートコードが動きはじめた!次は、IDEのコントローラを何とかする。

<IDE: SectorCount(0xb40001f2) Store>
        55 : [bfc00080] a04301f2 : sb      r03,0x01f2(r03)         r02=>b4000000 r03=>00000001
        56 : [bfc00084] 00101a02 : srl     r03,r16,0x08            r16=>00000001 r03<=00000000
<IDE: SecNum:LBAlo(0xb40001f3) Store>
        57 : [bfc00088] a05001f3 : sb      r16,0x01f3(r16)         r02=>b4000000 r16=>00000001
<IDE: SecNum:LBAmid(0xb40001f4) Store>
        58 : [bfc0008c] a04301f4 : sb      r03,0x01f4(r03)         r02=>b4000000 r03=>00000000
        59 : [bfc00090] 2405ffe0 : addiu   r05,r00,0xffe0          r00=>00000000 r05<=ffffffe0
        60 : [bfc00094] 00101c02 : srl     r03,r16,0x10            r16=>00000001 r03<=00000000
        61 : [bfc00098] 00108602 : srl     r16,r16,0x18            r16=>00000001 r16<=00000000
<IDE: SecNum:LBAhi(0xb40001f5) Store>
        62 : [bfc0009c] a04301f5 : sb      r03,0x01f5(r03)         r02=>b4000000 r03=>00000000
        63 : [bfc000a0] 02058025 : or      r16,r16,r05             r16=>00000000 r05=>ffffffe0 r16<=ffffffe0
        64 : [bfc000a4] 24030020 : addiu   r03,r00,0x0020          r00=>00000000 r03<=00000020
<IDE: Drive/HeadPort(0xb40001f6) Store>
        65 : [bfc000a8] a05001f6 : sb      r16,0x01f6(r16)         r02=>b4000000 r16=>ffffffe0
<IDE: CommandPort:RegularStatus(0xb40001f7) Store>
        66 : [bfc000ac] a04301f7 : sb      r03,0x01f7(r03)         r02=>b4000000 r03=>00000020
        67 : [bfc000b0] 8fbf0014 : lw      r31,0x0014(r29)         r29=>bfbfffa8 (bfbfffbc)=>bfc000fc r31<=bfc000fc
        68 : [bfc000b4] 8fb00010 : lw      r16,0x0010(r29)         r29=>bfbfffa8 (bfbfffb8)=>00000001 r16<=00000001
        69 : [bfc000b8] 0bf0000f : j       0x3f0000f               pc<=bfc000bc pc<=bfc0003c
        70 : [bfc000bc] 27bd0018 : addiu   r29,r29,0x0018          r29=>bfbfffa8 r29<=bfbfffc0
        71 : [bfc0003c] 3c05b400 : lui     r05,0xb400              r05<=b4000000
        72 : [bfc00040] 2404ffc0 : addiu   r04,r00,0xffc0          r00=>00000000 r04<=ffffffc0
        73 : [bfc00044] 24030040 : addiu   r03,r00,0x0040          r00=>00000000 r03<=00000040
<IDE: CommandPort:RegularStatus(0xb40001f7) Load>
        74 : [bfc00048] 90a201f7 : lbu     r02,0x01f7(r05)         r05=>b4000000 r02<=00000020
        75 : [bfc0004c] 304200ff : andi    r02,r02,0x00ff          r02=>00000020 r02<=00000020
        76 : [bfc00050] 00441024 : and     r02,r02,r04             r02=>00000020 r04=>ffffffc0 r02<=00000000
        77 : [bfc00054] 1443fffc : bne     r02,r03,0xfffc          r02=>00000000 r03=>00000040 pc<=bfc00058 pc<=bfc00048
        78 : [bfc00058] 00000000 : sll     r00,r00,0x00            r00=>00000000
<IDE: CommandPort:RegularStatus(0xb40001f7) Load>
        79 : [bfc00048] 90a201f7 : lbu     r02,0x01f7(r05)         r05=>b4000000 r02<=00000020
        80 : [bfc0004c] 304200ff : andi    r02,r02,0x00ff          r02=>00000020 r02<=00000020
        81 : [bfc00050] 00441024 : and     r02,r02,r04             r02=>00000020 r04=>ffffffc0 r02<=00000000
        82 : [bfc00054] 1443fffc : bne     r02,r03,0xfffc          r02=>00000000 r03=>00000040 pc<=bfc00058 pc<=bfc00048
        83 : [bfc00058] 00000000 : sll     r00,r00,0x00            r00=>00000000
<IDE: CommandPort:RegularStatus(0xb40001f7) Load>
        84 : [bfc00048] 90a201f7 : lbu     r02,0x01f7(r05)         r05=>b4000000 r02<=00000020
        85 : [bfc0004c] 304200ff : andi    r02,r02,0x00ff          r02=>00000020 r02<=00000020
        86 : [bfc00050] 00441024 : and     r02,r02,r04             r02=>00000020 r04=>ffffffc0 r02<=00000000
        87 : [bfc00054] 1443fffc : bne     r02,r03,0xfffc          r02=>00000000 r03=>00000040 pc<=bfc00058 pc<=bfc00048
        88 : [bfc00058] 00000000 : sll     r00,r00,0x00            r00=>00000000
<IDE: CommandPort:RegularStatus(0xb40001f7) Load>
        89 : [bfc00048] 90a201f7 : lbu     r02,0x01f7(r05)         r05=>b4000000 r02<=00000020
        90 : [bfc0004c] 304200ff : andi    r02,r02,0x00ff          r02=>00000020 r02<=00000020
        91 : [bfc00050] 00441024 : and     r02,r02,r04             r02=>00000020 r04=>ffffffc0 r02<=00000000
        92 : [bfc00054] 1443fffc : bne     r02,r03,0xfffc          r02=>00000000 r03=>00000040 pc<=bfc00058 pc<=bfc00048
        93 : [bfc00058] 00000000 : sll     r00,r00,0x00            r00=>00000000
<IDE: CommandPort:RegularStatus(0xb40001f7) Load>