30日でできる! OS自作入門 3日目

この記事は2年以上前に書いたものです。
そのため情報が古い可能性があります。ご了承ください。m(_ _)m

OS自作入門がなかなか進まないのは、本が重いからだな。もしくは、重い本を置く場所が膝の上くらいしか無いから。我が家では。
広い机が欲しい。

三日目

ちゃんとしたIPL(*1)の作成、OS本体を書き始める、32ビットモード突入、C言語。

*1: ブートセクタ以外も読み込むIPLだとか


; ipl.nas
; haribote-ipl
; TAB=4

CYLS	EQU		10				; どこまで読み込むか

		ORG		0x7c00			; このプログラムがどこに読み込まれるのか

; 以下は標準的なFAT12フォーマットフロッピーディスクのための記述

		JMP		entry
		DB		0x90
		DB		"HARIBOTE"		; ブートセクタの名前を自由に書いてよい(8バイト)
		DW		512				; 1セクタの大きさ(512にしなければいけない)
		DB		1				; クラスタの大きさ(1セクタにしなければいけない)
		DW		1				; FATがどこから始まるか(普通は1セクタ目からにする)
		DB		2				; FATの個数(2にしなければいけない)
		DW		224				; ルートディレクトリ領域の大きさ(普通は224エントリにする)
		DW		2880			; このドライブの大きさ(2880セクタにしなければいけない)
		DB		0xf0			; メディアのタイプ(0xf0にしなければいけない)
		DW		9				; FAT領域の長さ(9セクタにしなければいけない)
		DW		18				; 1トラックにいくつのセクタがあるか(18にしなければいけない)
		DW		2				; ヘッドの数(2にしなければいけない)
		DD		0				; パーティションを使ってないのでここは必ず0
		DD		2880			; このドライブ大きさをもう一度書く
		DB		0,0,0x29		; よくわからないけどこの値にしておくといいらしい
		DD		0xffffffff		; たぶんボリュームシリアル番号
		DB		"HARIBOTEOS "	; ディスクの名前(11バイト)
		DB		"FAT12   "		; フォーマットの名前(8バイト)
		RESB	18				; とりあえず18バイトあけておく

; プログラム本体

entry:
		MOV		AX,0			; レジスタ初期化
		MOV		SS,AX
		MOV		SP,0x7c00
		MOV		DS,AX

; ディスクを読む

		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			; AH=0x02 : ディスク読み込み
		MOV		AL,1			; 1セクタ
		MOV		BX,0
		MOV		DL,0x00			; Aドライブ
		INT		0x13			; ディスクBIOS呼び出し
		JNC		next			; エラーがおきなければnextへ
		ADD		SI,1			; SIに1を足す
		CMP		SI,5			; SIと5を比較
		JAE		error			; SI >= 5 だったらerrorへ
		MOV		AH,0x00
		MOV		DL,0x00			; Aドライブ
		INT		0x13			; ドライブのリセット
		JMP		retry
next:
		MOV		AX,ES			; アドレスを0x200進める
		ADD		AX,0x0020
		MOV		ES,AX			; ADD ES,0x020 という命令がないのでこうしている
		ADD		CL,1			; CLに1を足す
		CMP		CL,18			; CLと18を比較
		JBE		readloop		; CL <= 18 だったらreadloopへ
		MOV		CL,1
		ADD		DH,1
		CMP		DH,2
		JB		readloop		; DH < 2 だったらreadloopへ
		MOV		DH,0
		ADD		CH,1
		CMP		CH,CYLS
		JB		readloop		; CH < CYLS だったらreadloopへ

; 読み終わったのでharibote.sysを実行だ!

		JMP		0xc200

error:
		MOV		AX,0
		MOV		ES,AX
		MOV		SI,msg
putloop:
		MOV		AL,[SI]
		ADD		SI,1			; SIに1を足す
		CMP		AL,0
		JE		fin
		MOV		AH,0x0e			; 一文字表示ファンクション
		MOV		BX,15			; カラーコード
		INT		0x10			; ビデオBIOS呼び出し
		JMP		putloop
fin:
		HLT						; 何かあるまでCPUを停止させる
		JMP		fin				; 無限ループ
msg:
		DB		0x0a, 0x0a		; 改行を2つ
		DB		"load error"
		DB		0x0a			; 改行
		DB		0

		RESB	0x7dfe-$		; 0x7dfeまでを0x00で埋める命令

		DB		0x55, 0xaa

↑のコードでは、読み込んだデータ(第2セクタ以降のデータ)を、0x08200~に入れていっている。


; ディスクを読む

		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			; AH=0x02 : ディスク読み込み
		MOV		AL,1			; 1セクタ
		MOV		BX,0
		MOV		DL,0x00			; Aドライブ
		INT		0x13			; ディスクBIOS呼び出し
・・・

0x08000~0x081ffには、後でブートセクタを入れるらしいので、
0x08000~ディスクを読み込んだデータが入る事になると。
FAT12の場合は(?)、ディスクイメージにファイルを保存すると、0x004200に保存されるらしく、
0x008000 + 0x004200 = 0xc200
だから、↓で0xc200にJMP。


; 読み終わったのでharibote.sysを実行だ!

		JMP		0xc200

そうすると、↓が実行される。


; haribote.nas
; haribote-os
; TAB=4

		ORG		0xc200			; このプログラムがどこに読み込まれるのか
fin:
		HLT
		JMP		fin

そんな感じのイメージの作成は、↓の部分らしい。


# Makefile
・・・
haribote.img : ipl.bin haribote.sys Makefile
$(EDIMG) imgin:../z_tools/fdimg0at.tek \
wbinimg src:ipl.bin len:512 from:0 to:0 \
copy from:haribote.sys to:@: \
imgout:haribote.img
・・・

tools/edimg – hrb-wikiによると、
copy from:xxx.xxx to:@:
は、ファイル(xxx.xxx)をディスクイメージにコピーする。

edimg.exeでコピーすると、
・ファイル名は、0x002600以降
・ファイルの中身は、0x004200以降
に入るとのこと。

The FAT File System
19~32セクタ(0x2600~0x41ff)が、Root Directory
33~2879セクタ(0x4200~0x167fff)が、File storage space
だとか。

32bitモードへ入るアセンブラの説明は後ほどとのこと。

OS自作入門でのC言語でのプログラミングは、
・cc1.exeでコンパイルし、gas(Gnu ASsembler)なファイルを作成する。
・gas2nask.exeを使って、gasなファイルをnaskなファイルに変換する。
・nask.exeを使って、naskなファイルをアセンブルする。
・obj2bim.exe(リンカ)を使って、リンクする。(bimは、Binary IMageの略だとか)
・bim2hrb.exeを使って、ハリボテOS用の形式にする。
という一連の流れが必要らしい。

Makefileでやってるので、叩くコマンドは変わらず。

カテゴリー: ソフトウェア タグ: , パーマリンク

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です