Ubuntu 18.04で30日OS自作入門をやりたい[3日目-1]
Ubuntu 18.04で「30日でできる!OS自作入門」をやりたい[2日目] - まりものメモ帳の続きです。
定期試験と文化祭とかいろいろ重なっていつの間にかこんな時期です。終わるのかこれ。まずいでしょ。
前回と間が空き過ぎてて「あっ…(察し)」と思った方もいるかと思いますが大丈夫です。俺は生きてる。
というわけで3日目やっていきます。
アセンブリタイム
やることは特に変わらず、nasmくんが読んでくれるように頑張りながらアセンブリを写経します。
IPL作り
ipl.asm
;haribote-ipl ;TAB=4 CYLS EQU 10 ;CYLS = 10と定義する ORG 0x7c00 JMP entry DB 0x90 DB "HARIBOTE" DW 512 DB 1 DW 1 DB 2 DW 224 DW 2880 DB 0xf0 DW 9 DW 18 DW 2 DD 0 DD 2880 DB 0, 0, 0x29 DD 0xffffffff DB "HARIBOTEOS " ;11byte DB "FAT12 " ;8byte TIMES 18 DB 0 entry: MOV AX, 0 MOV SS, AX MOV SP, 0x7c00 ;0x7c00にブートセクタを読み込む MOV DS, AX ;Read Disk MOV AX, 0x0820 MOV ES, AX MOV CH, 0 ;シリンダ番号0 <--① MOV DH, 0 ;ヘッド番号0 <--① MOV CL, 2 ;セクタ番号2 <--① readloop: MOV SI, 0 ;失敗回数のリセット retry: MOV AH, 0x02 ;INT命令用 MOV AL, 1 MOV BX, 0 MOV DL, 0x00 ;ドライブ番号0 <--① INT 0x13 ;disk BIOSコール(AH=0x02) <--②-1 JNC next ;エラーがなければnextへ ADD SI, 1 ;SIレジスタ(失敗回数) + 1 CMP SI, 5 ;SIと5を比較 JAE error ;SI >= 5のときerrorへ MOV AH, 0x00 ;INT命令用 MOV DL, 0x00 ;ドライブ番号0 INT 0x13 ;disk BIOSコール(AH=0x00) <--②-2 JMP retry next: MOV AX, ES ;アドレスを0x200(=512=1セクタ)進める ADD AX, 0x20 MOV ES, AX ;ADD ES, 0x20という命令が無い ADD CL, 1 ;CL(セクタ番号)を1増やす CMP CL, 18 ;CLと18を比較 JBE readloop ;CL <= 18の時readloopへ MOV CL, 1 ;CL=1 ADD DH, 1 ;DH(ヘッダ番号)を1増やす CMP DH, 2 ;DHと2を比較 JB readloop ;DH < 2の時readloopへ MOV DH, 0 ;DH=0 ADD CH, 1 ;CH(シリンダ番号)を1増やす CMP CH, CYLS ;CHとCYLS(=10)を比較 JB readloop ;CH < CYLSの時readloopへ fin: HLT JMP fin error: MOV SI, msg ;SIにmsgのメモリ番地を代入 putloop: MOV AL, [SI] ;ALにSI番地の中身を渡す ADD SI, 1 ;SIを1増やす CMP AL, 0 ;ALと0を比較 JE fin ;AL=0のときfinへ MOV AH, 0x0e MOV BX, 15 INT 0x10 ;video BIOSのコール(AH=0x0e, BX=15) JMP putloop msg: DB 0x0a, 0x0a DB "load error" ;エラーメッセージ DB 0x0a DB 0 TIMES 0x7dfe-0x7c00-($-$$) DB 0 DB 0x55, 0xaa ;有効なブートセクタであることを示す
コメントアウトの作業が一番疲れた…
いきなり
- エラーになったらやり直す
- 18セクタ読む
- 10シリンダ読む
所までやっちゃいました。
本との変更点を以下に記します。
- RESB命令をTIMES DB命令に
- 0x7dfe-$を0x7dfe-0x7c00-($-$$)に
調べたこととか
そもそもIPLってなんだ
IPL(Initial Program Loader)というのはまあ名前の通りで、コンピュータの電源をONにしたときに最初に実行されるプログラムのことです。今回はこれを作ってます。
実行
default: make img ipl.bin: ipl.asm Makefile nasm ipl.asm -o ipl.bin -l ipl.lst helloos.img: ipl.bin Makefile cat ipl.bin > helloos.img asm: make -r ipl.bin img: make -r helloos.img run: make img qemu-system-i386 -fda helloos.img #<- (1)
(1)でqemuに-fdaオプションをつけてますが、これはフロッピーディスクからの起動であることを明示してます。ないと動かないみたい。
何はともあれ実行してみましょう、当たって砕けろ。
$ make run make img make[1]: ディレクトリ '/home/admarimoin/project/os/day3' に入ります make -r helloos.img make[2]: ディレクトリ '/home/admarimoin/project/os/day3' に入ります nasm ipl.asm -o ipl.bin -l ipl.lst cat ipl.bin > helloos.img make[2]: ディレクトリ '/home/admarimoin/project/os/day3' から出ます make[1]: ディレクトリ '/home/admarimoin/project/os/day3' から出ます qemu-system-i386 -fda helloos.img WARNING: Image format was not specified for 'helloos.img' and probing guessed raw. Automatically detecting the format is dangerous for raw images, write operations on block 0 will be restricted. Specify the 'raw' format explicitly to remove the restrictions.
で、結果はこんな感じ。
Boot failedとか言われてますけどエラーメッセージ出てないんで大丈夫っぽいです。よかったよかった。(エラーだったらload failedと表示される)
メッチャ疲れました。でもこれまだ3日目前半なんですよね……