xv6のRISC-Vへのインポートの続き。
そういえばISSのRISC-V用ビルドには、IDEモジュールとUARTモジュールを追加していなかった。 x86では、IDEやUARTはinbやoutb命令で操作できるが(つまりポートマップドI/O)、MIPSやRISC-Vではそうはいかない。メモリマップに、これらのモジュールを定義しておかなければならない。
ポートマップドI/Oでは、入出力用の特別なCPU命令を使用する。例えば、インテルのx86には入出力専用の IN 命令と OUT 命令があり、入出力機器の1つのバイトの読み書きを行う。
RISC-Vの実装で、外部アクセス系を具体的にどこにマップすればよいのか資料を見つけることはできなかったが、とりあえず適当にマップを作成する。このマップは後で変更するつもりだけれども。
start | end | |
---|---|---|
IDEモジュール | 0xffff_0000 | 0xffff_7fff |
UARTモジュール | 0xffff_8000 | 0xffff_ffff |
基本的にメモリマップI/Oなので、ロードストア処理の部分に分岐を突っ込んでやっておけば外部I/Oモジュールにアクセスできるようになる。
この実装はずいぶんと付け焼刃な感じがして、拡張性に乏しいが、後でちゃんとテーブルとか作って書き直そう。
MemResult RiscvEnv::LoadFromBus (Addr_t addr, Size_t size, DWord_t *data) { Byte_t byte[8]; MemResult result; if (addr >= ide_start && addr <= ide_end) { Addr_t ide_addr = addr - ide_start; Word_t w_data; result = m_ide->LoadData (ide_addr, size, &w_data); *data = static_cast<Word_t>(w_data); } else if (addr >= uart_start && addr <= uart_end) { Addr_t uart_addr = addr - uart_start; Word_t w_data; result = m_uart->LoadData (uart_addr, size, &w_data); *data = static_cast<Word_t>(w_data); } else { result = LoadFromBus (addr, size, byte); memcpy (data, byte, 8); } return result; }
IDEモジュールについて
今回実装しているIDEモジュールは、MIPS用シミュレータを作ったときに実装したものだけれど、基本的にそれを流用すればよいと思っている。
ATA/ATAPI/I/O Port, Register - OS Project Wiki
UARTモジュールについて
こっちは、Intel 8250というモジュールを利用している。これも、MIPS用シミュレータを作ったときに実装したものだ。
実装した結果、まずはRISC-VのIPLが動作してOSをローディングするようになった。つまりIPL(Initial Program Loader)が動作し始めた。
103:M:MBar:[000002a0] ffff06b7 : lui r13,0xffff0 r13<=ffff0000 104:M:MBar:[000002a4] 04000713 : addi r14,r00,0x040 r00=>00000000 r14<=00000040 <IDE: CommandPort:RegularStatus(0x000001f7) Load> 105:M:MBar:[000002a8] 1f76c783 : lbu r15,r13,0x1f7 r13=>ffff0000 r15<=00000040 106:M:MBar:[000002ac] 0c07f793 : andi r15,r15,0x0c0 r15=>00000040 r15<=00000040 107:M:MBar:[000002b0] fee79ce3 : bne r15,r14,0x7f r15=>00000040 r14=>00000040 108:M:MBar:[000002b4] 00c12403 : lw r08,r02,0x00c r02=>bfffff98 (bfffffa4)=>000000ff r08<=ffffffff 109:M:MBar:[000002b8] 01010113 : addi r02,r02,0x010 r02=>bfffff98 r02<=bfffffa8 110:M:MBar:[000002bc] 00008067 : jalr r00,r01,0x067 r01=>00000328 pc<=00000328 111:M:MBar:[00000328] 20048693 : addi r13,r09,0x200 r09=>00010000 r13<=00010200 112:M:MBar:[0000032c] ffff0737 : lui r14,0xffff0 r14<=ffff0000 <IDE: DataPort(0x000001f0) Load> <ReadImgFile(Index=0)=>000000b3> 113:M:MBar:[00000330] 1f072783 : lw r15,r14,0x1f0 r14=>ffff0000 r15<=00000000 114:M:MBar:[00000334] 00f4a023 : sw r09,r15,0x00|r00 r09=>00010000 r15=>00000000 (00010000)<=00000000 115:M:MBar:[00000338] 00448493 : addi r09,r09,0x004 r09=>00010000 r09<=00010004 116:M:MBar:[0000033c] fe969ae3 : bne r13,r09,0x7f r13=>00010200 r09=>00010004 pc<=00000330 <IDE: DataPort(0x000001f0) Load> <ReadImgFile(Index=1)=>00000133> 117:M:MBar:[00000330] 1f072783 : lw r15,r14,0x1f0 r14=>ffff0000 r15<=00000000 118:M:MBar:[00000334] 00f4a023 : sw r09,r15,0x00|r00 r09=>00010004 r15=>00000000 (00010004)<=00000000 119:M:MBar:[00000338] 00448493 : addi r09,r09,0x004 r09=>00010004 r09<=00010008 120:M:MBar:[0000033c] fe969ae3 : bne r13,r09,0x7f r13=>00010200 r09=>00010008 pc<=00000330 <IDE: DataPort(0x000001f0) Load> <ReadImgFile(Index=2)=>000001b3> 121:M:MBar:[00000330] 1f072783 : lw r15,r14,0x1f0 r14=>ffff0000 r15<=00000000 122:M:MBar:[00000334] 00f4a023 : sw r09,r15,0x00|r00 r09=>00010008 r15=>00000000 (00010008)<=00000000 123:M:MBar:[00000338] 00448493 : addi r09,r09,0x004 r09=>00010008 r09<=0001000c 124:M:MBar:[0000033c] fe969ae3 : bne r13,r09,0x7f r13=>00010200 r09=>0001000c pc<=00000330 <IDE: DataPort(0x000001f0) Load> <ReadImgFile(Index=3)=>00000233> 125:M:MBar:[00000330] 1f072783 : lw r15,r14,0x1f0 r14=>ffff0000 r15<=00000000 126:M:MBar:[00000334] 00f4a023 : sw r09,r15,0x00|r00 r09=>0001000c r15=>00000000 (0001000c)<=00000000 127:M:MBar:[00000338] 00448493 : addi r09,r09,0x004 r09=>0001000c r09<=00010010
Initial Program Loader とは
IPLとは、CPUがブートしたときに最初に動作するプログラムで、ROMなどの不揮発性の媒体に格納されている。
CPUが起動すると、まずこのIPLを実行する。IPLはディスクの特定の場所からOSのイメージをロードし、メインメモリに転送する。 OS起動用のプログラムがメインメモリに格納されると、OSプログラムのブートアドレスにジャンプし、OSの起動が開始するという訳だ。
とりあえず、ここまではうまくいったようだ。RISC-V版で、xv6が起動するまで、頑張ろう。