プロテクトモードモニタを作る
一時、「MyOS」ブームだったようです。
最近少なくなった、「直制御」の世界に興味を持つ人が増えたことは、
OSASKの河合さんを始め、多くの人の功績でしょう。
一方、私は個人的に、生産装置分野で、「プロテクトモード・モニタ」などを作っています。
OSと呼べるものではないと思っているので、「モニタ」と呼んでいます。
その開発成果物のうち、公開しても差し支えないものを、公開していきたいと思います。
始める前に
なんとも軟弱な話ですが、開発はWindows上で行っています。
言い訳をすれば、生産装置分野で現地調整ともなると、ノーパ持って、日本中(いや世界中・・)移動になります。
そして、Windowsでしか動かないユーティリティもあるので、BSD上に開発環境を持っていてしまうと、
パソを2台か、それこそエミュ上のBSDでなんてことになってしまいます。
〜使っているもの〜
秀丸エディタ
nasm
mingw
qemu
bochs
intel社のマニュアルpdf
あと、書籍が数冊といったところでしょうか。
もちろん、インターネットエクスプローラも使っています。
基本的にC言語で開発していますので、mingwのgcc、でもアセンブラは表記が気に入らないので、
nasmを使っています。後は、気に入ったエディタとエミュがあれば、OKです。
エミュはBochsとQEMUの両方を用意したいところです。
昔、モニタ開発当初は、エミュもなく、出来上がったバイナリをFDに書き込んで、
リセットして実際に起動させておりました。
ブートセクタを作る
もし、マイOSを作りたいと考えている人がいらっしゃったら、
ブートセクタを最初に作ることはお勧めしません。
マイクロソフトの管理された世界から、自由の海を求めて旅たてば、
そこは、INTELの管理社会だったなんてことになってます。
ちょっとプロテクトモードを実験するにも、GDT,IDT、ページング(これは任意かな)
TSS(仮想86や特権いじるなら必須)割り込み、フォルト、アセンブラの知識 etc,etcと必要になり、
これに、ハード仕様の調べモノなどが加わって、かなり大変です。
この分野でネットを巡回していると、「リンク切れ率」が非常に高い気がします。
それは、OSの構築が、布教活動あるいは価値観の押し付け、議論になりやすいといった問題もあるでしょうし、
一人で取り組むには、あまりに範囲の広い総合技術だからという点もあるでしょう。
GUIなんかの実験をするのであれば、別にWindows上で、DIBに描画して、
(但し、Windows依存コードを局所化しておいて)ある程度デバック終わってから独自ブートにするとか、
ファイルシステムなんかでも、イメージファイルを作って、一晩、ファイル読み書きを続けて、
システム破綻しないか、windows上やUnix上で実験するなど、OS技術の大半は、
アプリケーションとして、他のOS上で検証できるものだと思います。
前にH8上にFAT16載せる仕事していたときも、FAT16のデバックはwindows上で行いました。
一晩、ランダムにファイルを読み書きして、そのイメージファイルをFreeBSD上で、SDカードに書き出し、
それをwindowsで検証するという方法で。(あ、でも、この後、リトルエンディアンの問題で、
H8上でバグるという失敗を犯してますが)
さて、前置きが長くなりました。ブートセクタを作るのですが、
BSDやLINUXにあるものと同じものを作っても仕方ないと思います。
ここでは、「プロテクトされていない何でもアリの32ビット環境」を最終形として狙っています。
また、実験を行うのには、コンパクトなほうが良いだろうとか、
16ビットコードは、少ないほうがよいだろうというのも頭の隅にいれています。
で、作ったのがこんな感じです。さすがに最初のブート部分は全部アセンブラです。
; ; boot1 一番最初のブート ; >nasm -f bin boot1.bin boot1.asm ; boot2を0x8000に読み込んで(最大32K) ; プロテクトモードに(必要最小限度設定で)移行 ; 0x00008000 番地にJUMP 割り込みは止まったまま。 ; ページングは動作していない。 ; copyright(c)2000-2007 by faicha ; org 0x7c00 cli jmp entry2 ; ; メッセージの表示 ; msgout: mov ah,0x0e .loop mov al,[bx] cmp al,0x00 jnz .next ret .next int 10h ; テレタイプ式書き込み inc bx jmp .loop ; ; PANIC ; panic: jmp panic ; 永久ループへ ; ; エントリー2 ; entry2: mov ax,cs mov ds,ax mov es,ax mov ax,0x6000 mov sp,ax ; ; 拡張INT13H の検査 ; chk_e13: mov bx,0x55aa ; 拡張検査用数値 mov ah,0x41 ; 拡張検査コマンド int 0x13 ; DISK BIOS cmp bx,0xaa55 ; 拡張機能有効 jz .next ; 有効であればOK mov bx,err1 ; エラーメッセージアドレス call msgout ; エラー表示 jmp panic ; 永久ループ .next ; ; boot2を読み込む ; read2: mov bx,drv mov dl,[bx] ; ドライブを指定 mov si,dap ; DISK Address Packetを設定 mov ah,0x42 ; 拡張read int 0x13 jnc .next mov bx,err2 ; エラーメッセージアドレス call msgout ; エラー表示 jmp panic ; 永久ループ .next ; ; プロテクトモードの準備 ; setup: mov bx,gdtdat lgdt [bx] ; GDTのセット ; ; プロテクトモードへの移行 ; go32bit: cli mov eax,cr0 or eax,1 ; PEビットをセットしてプロテクトモードへ mov cr0,eax jmp .next ; パイプラインクリアのため .next: ;********* bits 32 ;********* db 0xea ; セレクタ付JUMPの命令 dw .next2 ; dw 0x08 ; セレクタ 0x08 .next2: mov ax,0x10 ; セレクタ0x10をds,esに mov ds,ax mov es,ax mov ax,0x18 ; セレクタ0x18をssに mov ss,ax mov eax,0x00007800 ; スタックの新しい値 mov esp,eax ; ; 32ビット起動コードへJUMP ; jmp 0x00008000 ; boot2コードの先頭へ ; ; 文字列 ; msg0: db "Faicha IPL version 2.20",0x0d,0x0a,0x00 err1: db "ERR INT13 EXT.",0x00 err2: db "ERR READ BOOT2",0x00 ; ; Disk Address Packet ; dap: db 0x10 ; パケットサイズ(=16) db 0x00 ; 予約 db 63 ; Blocks = 31.5Kbyte db 0 ; 予約 dw 0x0000 ; 読み込みオフセット位置 dw 0x0800 ; 読み込みセグメント位置 dd 1 ; 読み込み先頭セクタ番号 dd 0 ; 読み込み先頭セクタ番号上位32ビット drv: db 0x80 ; ブートドライブ ; ; GDT用データ ; gdt: db 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00 ; セレクタ 0x00 なし db 0xff,0xff,0x00,0x00, 0x00,0x9a,0xcf,0x00 ; セレクタ 0x08 code/code386/bigseg db 0xff,0xff,0x00,0x00, 0x00,0x92,0xcf,0x00 ; セレクタ 0x10 data db 0x00,0x00,0x00,0x00, 0x00,0x96,0xc0,0x00 ; セレクタ 0x18 stack gdtdat: dw 0x0fff ; Limit = 4k (###) dw gdt ; offset 0-15 dw 0x0000 ; offset 16-31 ; ; Boot Sign ; times 510-($-$$) DB 0 dw 0xaa55 ; ブートサイン
パーティションはどうしたとか、色々問題のあるコードですが、 ひとまず、ハードディスクの先頭1セクタに書き込めば、次のセクタから64セクタほどを、 0x8000番地に読み込み、32ビット・プロテクトモードにして先頭を呼び出します。 但し、ページングは動いていませんし、GDTは暫定、IDT、TSSは未設定という、 本当に「ヨタヨタ」でプロテクトモードに入ります。あ、A20もONにしていません。
ただ、こんなひどい形ででもプロテクトモードに入ってしまったほうが、 (BIOSが使いにくいという一点を除いて)プログラムは書きやすいですし、 単なる実験であれば、32Kバイト内でコードを書けば、出来てしまうということで、 結構、使っています。
世の中の(特にフリーなUNIXは)古いハードを大切にするようですが、 このコードは、もともと組み込みPC用なので、あまり古いハードサポートを考えていません。 このBOOT1も、拡張int 13hをサポートしてないBIOSだと、 ERR INT13 EXT. というひどいエラーを出して止まります。ほとんど見たことありませんが。
無作為研究所トップページに戻る