0から作るソフトウェア開発

日々勉強中。。。

0から作るOS開発

環境準備

環境設定

ブートローダ

カーネルローダ

GRUB

カーネル

ドライバーその他

ブートローダその3 はじめてのブートローダとアセンブルと書き込み

前回までの内容

これまでで、 ということがわかりました。それでは最初のセクタとして読み込まれる

512バイトのブートローダを作ってみましょう

最初のブートローダを作ってみる

テキストエディタを開いて次のアセンブラプログラムを作ってみます

ここではファイル名を”boot.asm”としました

(テキストエディタはメモ帳でもなんでもいいです。 サクラエディタ とかはどうでしょうか)

;/********************************************************************************
; File:boot.asm
; Description:Bootloader
;
;********************************************************************************/
[BITS 16]

ORG	0x7C00

;/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
;
; BOOT
;
;/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
BOOT:
	CLI
	HLT
	
TIMES 510 - ($ - $$) DB 0

DW 0xAA55

ここでソースコードの説明をしたいと思います


[BITS 16]

最初のこの記述はプログラムが16ビットで始まることを意味しています

パソコンのCPUは起動後は16ビットのモードで動きます

なにやら古いOSとかのための互換性を保つためのようです

(もしかしたらDOSも最新のCPUで動くかもしれません)

ですので16ビットの命令をアセンブルする必要があります

この16ビットのモードはリアルモードと呼ばれています

(何がリアルなのかさっぱりわかりませんが。。。)

後" ; "を書くとそれ以降はコメントになります。好きなようにコメントをつけていきましょう


ORG	0x7C00

でてきました。見たことのある数字です

この記述はこのプログラムは0x7C00で始まることを宣言しています

なぜならBIOSが0x7C00にこのプログラムを置いてくれるからですね(復習、復習)

このプログラムがある変数などにアクセスするときにアドレスを指定した場合

アセンブルすると0x7C00をベースとしてアドレスを決めてくれます


BOOT:

:がつくとラベル付けができます。ここではBOOTというラベル名をつけています

ラベルをつけておくとアドレスを直に指定する代わりにBOOTというラベルを使うことができます


CLI

これが初めてのアセンブラ言語の命令となります

この命令は割り込みをすべて受け付けないように(割り込みフラグをクリア)します

とりあえず念のためこの命令を入れただけであまり意味はありません


HLT

次の命令は実行を止めてCPUを停止状態にする命令です

このプログラムはここでこれ以上何もしなくなります


TIMES 510 - ($ - $$) DB 0

これは命令ではなくプリプロセッサで処理される擬似命令となります

少し複雑ですが、TIMES 510 - ($ -$$)の擬似命令とDB 0と分けて見てみます

DBのDは定義(Define)を、Bはバイトを意味しています。DBですので1バイトと言う意味で

0を宣言しているので、値が0の1バイトをこの場所に置くことになります

その前のTIMES以降についてはまず$、$$について説明します

$$は最初の命令(最初の行でここではCLI命令)の場所を意味しています

逆に$は現在の場所を意味しています

ですので($ - $$)は先頭から現在の行まで何バイト使っているかを表しています

(ここでは($ - $$) = (2 - 0)となります。16ビットの命令(CLIが1バイト、HLTが1バイト)が2つなので2バイト引く最初の0

厳密には(0x7C02 - 0x7C00)となります)

510については、1セクタのバイト数が512バイト−最後のデータは0xAA55の2バイトなので

プログラムのサイズとしては510バイトとなります

そしてこのプログラムで使用している命令のバイト数は($ - $$)=2でしたので

命令以外の空きサイズは510-($ - $$) = 508バイトとなります

そしてTIMESはデータ(または命令)をその数だけ繰り返す擬似命令です

この2つを組み合わせると”値が0である1バイトを508バイト配置する”を意味します


DW 0xAA55

最後は簡単です。DWはワードサイズ(16ビットのワードは2バイト)のデータを配置します

ここでは0xAA55というデータを置きます

もちろんこのデータは511バイト目に置かれることに注意してください

これでようやく何もしない最初のブートローダのソースができました

ではアセンブルしていきます

アセンブル

アセンブルするためにまずCygwinを起動して作ったソースがあるフォルダまで

cdコマンドで移動してください。そして


nasm -o boot.img boot.asm

と入力してEnterを押すとアセンブルします

ここでオプションとして-oを指定しました。-oは出力ファイル名を指定します

ここではboot.imgを指定しました(好きなファイル名でOKです)

boot.imgというファイルができたと思います。

試しにバイナリエディタ(例えば Stirling など)で開いてどのような

バイナリができているのか眺めて見ることをおすすめいたします

フロッピーディスクの最初のセクタに書き込む

まず、ImDisk Virtual Disk Driverを起動して適当にフロッピーの

イメージファイルをマウントしてAドライブができているか確認をしておきましょう

できていることが確認できたら


dd if=boot.img bs=512 count=1 of=/proc/sys/Device/ImDisk0



とCygwinに入力します。ここでddはファイルをコピーするコマンドです

ifオプションは入力ファイルを指定します。アセンブルしたboot.imgを指定しています

bsはコピーするバイト数で当然512バイトです。countはあまり気にしなくいいですが、

一応コピーするブロック数で1ブロックのみコピーを指定しています(よくわかってないです。。。)

ofは出力ファイルを指定しています。/proc/sys/Device/ImDisk0は

ImDiskがマウントしているはAドライブを意味しています

これでImDiskで例えばfd.imgをAドライブとしてマウントしておくとfd.imgのブートセクタにあたる部分が

boot.imgに書き換わります。試しにImDiskで開いているフロッピーディスクイメージを

バイナリエディタで確認してみてください

ようやく起動してみる

それではVirtual Boxを起動して環境設定でやったようにデバイスとしてAドライブを

指定して仮想マシンを起動してみてください

上手くいけば何も表示されません。起動するとこんな画面になります

boot.imgを起動。何も表示されません

inserted by FC2 system