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

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

二日目

アセンブラの勉強と、レジスタの説明、BIOSの説明、Makefileの作成。

naskのマニュアルが見つからなかった。tools/nask – hrb-wikiによると,naskとNASMにほとんど差は無いらしい。
NASMのマニュアル(一部日本語化)は、NASM Manualに。(ver2.03)

アセンブラ(NASM)の勉強としては、Assembly Programming Linuxが分かりやすそう。標準入出力や、アセンブラからコマンドライン引数とか環境変数の扱い方とかも書かれている。Assembly Programming on x86-64 Linuxに、64bitについても。
OS自作入門では知らなくて良い情報かもしれないけど。

レジスタは、OS Project Wikiレジスタらへんに詳しく書いてある。

BIOSの割り込み機能(INTerrupt)の説明。(AT)BIOS – OS-Wiki に詳しく書いていると。
BIOS割り込みルーチン – Wikipediaにも。

メモリマップに注意してねとも書いてあった。決まった部分に書かないと動かないよと。
(AT)memorymap – OS-Wiki

二日目は、CD-ROM内のファイルの解説で終了。

ipl.nas


; hello-os
; TAB=4

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

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

		JMP		entry
		DB		0x90
		DB		"HELLOIPL"		; ブートセクタの名前を自由に書いてよい(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		"HELLO-OS   "	; ディスクの名前(11バイト)
		DB		"FAT12   "		; フォーマットの名前(8バイト)
		RESB	18				; とりあえず18バイトあけておく

; プログラム本体

entry:
		MOV		AX,0			; レジスタ初期化
		MOV		SS,AX
		MOV		SP,0x7c00
		MOV		DS,AX
		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		"hello, world"
		DB		0x0a			; 改行
		DB		0

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

		DB		0x55, 0xaa

「ORG 0x7c00」は、メモリのどこに読み込まれるかをnaskに教える命令だとか。AT互換機だと(?)ブートセクタは、0x00007c00~0x00007dffに読み込まれるらしいので、ORGで0x7c00を指定する・・・と。
× 0x7c00に、読み込んでくれ
○ 0x7c00に、読み込まれます
って感じかな。

他に使われている命令のメモ。
JMP: JuMP。指定したラベルとかアドレスに飛ぶ
MOV: MOVe。代入。
ADD: ADD。足し算
CMP: CoMPare。比較
JE : Jump Equal。等しければJUMP
INT: INTerrupt。BIOSの割り込み機能呼び出し
HLT: HaLT。停止

↑のソースをアセンブルした結果を視覚的に表したもの(?)が、↓。

ipl.lst


     1 00000000                                 ; hello-os
     2 00000000                                 ; TAB=4
     3 00000000                                 
     4                                          		ORG		0x7c00			; このプログラムがどこに読み込まれるのか
     5 00007C00                                 
     6 00007C00                                 ; 以下は標準的なFAT12フォーマットフロッピーディスクのための記述
     7 00007C00                                 
     8 00007C00 EB 4E                           		JMP		entry
     9 00007C02 90                              		DB		0x90
    10 00007C03 48 45 4C 4C 4F 49 50 4C         		DB		"HELLOIPL"		; ブートセクタの名前を自由に書いてよい(8バイト)
    11 00007C0B 0200                            		DW		512				; 1セクタの大きさ(512にしなければいけない)
    12 00007C0D 01                              		DB		1				; クラスタの大きさ(1セクタにしなければいけない)
    13 00007C0E 0001                            		DW		1				; FATがどこから始まるか(普通は1セクタ目からにする)
    14 00007C10 02                              		DB		2				; FATの個数(2にしなければいけない)
    15 00007C11 00E0                            		DW		224				; ルートディレクトリ領域の大きさ(普通は224エントリにする)
    16 00007C13 0B40                            		DW		2880			; このドライブの大きさ(2880セクタにしなければいけない)
    17 00007C15 F0                              		DB		0xf0			; メディアのタイプ(0xf0にしなければいけない)
    18 00007C16 0009                            		DW		9				; FAT領域の長さ(9セクタにしなければいけない)
    19 00007C18 0012                            		DW		18				; 1トラックにいくつのセクタがあるか(18にしなければいけない)
    20 00007C1A 0002                            		DW		2				; ヘッドの数(2にしなければいけない)
    21 00007C1C 00000000                        		DD		0				; パーティションを使ってないのでここは必ず0
    22 00007C20 00000B40                        		DD		2880			; このドライブ大きさをもう一度書く
    23 00007C24 00 00 29                        		DB		0,0,0x29		; よくわからないけどこの値にしておくといいらしい
    24 00007C27 FFFFFFFF                        		DD		0xffffffff		; たぶんボリュームシリアル番号
    25 00007C2B 48 45 4C 4C 4F 2D 4F 53 20 20   		DB		"HELLO-OS   "	; ディスクの名前(11バイト)
       00007C35 20 
    26 00007C36 46 41 54 31 32 20 20 20         		DB		"FAT12   "		; フォーマットの名前(8バイト)
    27 00007C3E 00 00 00 00 00 00 00 00 00 00   		RESB	18				; とりあえず18バイトあけておく
       00007C48 00 00 00 00 00 00 00 00 
    28 00007C50                                 
    29 00007C50                                 ; プログラム本体
    30 00007C50                                 
    31 00007C50                                 entry:
    32 00007C50 B8 0000                         		MOV		AX,0			; レジスタ初期化
    33 00007C53 8E D0                           		MOV		SS,AX
    34 00007C55 BC 7C00                         		MOV		SP,0x7c00
    35 00007C58 8E D8                           		MOV		DS,AX
    36 00007C5A 8E C0                           		MOV		ES,AX
    37 00007C5C                                 
    38 00007C5C BE 7C74                         		MOV		SI,msg
    39 00007C5F                                 putloop:
    40 00007C5F 8A 04                           		MOV		AL,[SI]
    41 00007C61 83 C6 01                        		ADD		SI,1			; SIに1を足す
    42 00007C64 3C 00                           		CMP		AL,0
    43 00007C66 74 09                           		JE		fin
    44 00007C68 B4 0E                           		MOV		AH,0x0e			; 一文字表示ファンクション
    45 00007C6A BB 000F                         		MOV		BX,15			; カラーコード
    46 00007C6D CD 10                           		INT		0x10			; ビデオBIOS呼び出し
    47 00007C6F EB EE                           		JMP		putloop
    48 00007C71                                 fin:
    49 00007C71 F4                              		HLT						; 何かあるまでCPUを停止させる
    50 00007C72 EB FD                           		JMP		fin				; 無限ループ
    51 00007C74                                 
    52 00007C74                                 msg:
    53 00007C74 0A 0A                           		DB		0x0a, 0x0a		; 改行を2つ
    54 00007C76 68 65 6C 6C 6F 2C 20 77 6F 72   		DB		"hello, world"
       00007C80 6C 64 
    55 00007C82 0A                              		DB		0x0a			; 改行
    56 00007C83 00                              		DB		0
    57 00007C84                                 
    58 00007C84 00 00 00 00 00 00 00 00 00 00   		RESB	0x7dfe-$		; 0x7dfeまでを0x00で埋める命令
       00007C8E 00 00 00 00 00 00 00 00 00 00 
       00007C98 00 00 00 00 00 00 00 00 00 00 
       00007CA2 00 00 00 00 00 00 00 00 00 00 
       00007CAC 00 00 00 00 00 00 00 00 00 00 
       00007CB6 00 00 00 00 00 00 00 00 00 00 
       00007CC0 00 00 00 00 00 00 00 00 00 00 
       00007CCA 00 00 00 00 00 00 00 00 00 00 
       00007CD4 00 00 00 00 00 00 00 00 00 00 
       00007CDE 00 00 00 00 00 00 00 00 00 00 
       00007CE8 00 00 00 00 00 00 00 00 00 00 
       00007CF2 00 00 00 00 00 00 00 00 00 00 
       00007CFC 00 00 00 00 00 00 00 00 00 00 
       00007D06 00 00 00 00 00 00 00 00 00 00 
       00007D10 00 00 00 00 00 00 00 00 00 00 
       00007D1A 00 00 00 00 00 00 00 00 00 00 
       00007D24 00 00 00 00 00 00 00 00 00 00 
       00007D2E 00 00 00 00 00 00 00 00 00 00 
       00007D38 00 00 00 00 00 00 00 00 00 00 
       00007D42 00 00 00 00 00 00 00 00 00 00 
       00007D4C 00 00 00 00 00 00 00 00 00 00 
       00007D56 00 00 00 00 00 00 00 00 00 00 
       00007D60 00 00 00 00 00 00 00 00 00 00 
       00007D6A 00 00 00 00 00 00 00 00 00 00 
       00007D74 00 00 00 00 00 00 00 00 00 00 
       00007D7E 00 00 00 00 00 00 00 00 00 00 
       00007D88 00 00 00 00 00 00 00 00 00 00 
       00007D92 00 00 00 00 00 00 00 00 00 00 
       00007D9C 00 00 00 00 00 00 00 00 00 00 
       00007DA6 00 00 00 00 00 00 00 00 00 00 
       00007DB0 00 00 00 00 00 00 00 00 00 00 
       00007DBA 00 00 00 00 00 00 00 00 00 00 
       00007DC4 00 00 00 00 00 00 00 00 00 00 
       00007DCE 00 00 00 00 00 00 00 00 00 00 
       00007DD8 00 00 00 00 00 00 00 00 00 00 
       00007DE2 00 00 00 00 00 00 00 00 00 00 
       00007DEC 00 00 00 00 00 00 00 00 00 00 
       00007DF6 00 00 00 00 00 00 00 00 
    59 00007DFE                                 
    60 00007DFE 55 AA                           		DB		0x55, 0xaa

今まで書いていた、↓の部分は、


; 以下はブートセクタ以外の部分の記述

		DB		0xf0, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00
		RESB	4600
		DB		0xf0, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00
		RESB	1469432

↓のコマンドで作る模様。

..\z_tools\edimg.exe imgin:../z_tools/fdimg0at.tek wbinimg src:ipl.bin len:512 from:0 to:0 imgout:helloos.img

edimg.exeの解説は、tools/edimg – hrb-wikiにあるけど、
fdimg0at.tekの内容については書かれていない。(空っぽの内容のディスクイメージらしいけど)

tek – OS-Wikiを見ると圧縮されたファイルの模様。
展開すると空の1.44MB相当のデータになるんだろうか。

結局は、ipl.nasをアセンブルして、ipl.binを作り、
edimg.exe で、fdimg0at.tek と ipl.bin を合体させて、helloos.img を作る。
ってことか。

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

コメントを残す

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