x86 real modeでプログラミングをするための環境構築!!!!
real modeとはなに?
intel プロセッサを搭載しているパソコンを起動した時に一番最初にある”モード”です。
パソコン起動の流れ
パソコンスイッチオン ー> リセットベクタ ー> BIOS ー> bootloader ー> OS
この時、BIOSとBootloaderはreal modeにあります。bootloaderか、OSがreal modeからprotected modeに入りそこからreal modeに戻ることはありませんし、一度は行ってしまうとreal modeに戻ることなんてできません (厳密にいうと、プロセッサのレジスタを変更すれば、protected modeを解除できるみたいなのですが、そうするとOSにどう影響あるの?とかで、それだけの深い知識がないとできないと思います)。
real modeでプログラミングをする大きな利点
なんといってもOSの縛りがなく、x86の機能をふんだんに使える所だと思います。
-
OSの縛り ー アプリのアドレス空間
-
他のアプリに直接アクセスできない(inter-process communicationとかOSが提供しているアプリ同士のやり取りの方法ではなく直接にアクセスするという意味で)
通常アプリはここのアドレス空間を持っていて、他のアプリのアドレスにはアクセスできません。
-
アプリのアドレスは仮想アドレス
アプリのアドレスは仮想アドレスで物理的なアドレスではないです。例えば、あるデバイスのアドレスが0xfff3434にあったとしても、これはたいていの場合、物理的なアドレスでこのアドレスにアクセスするためには仮想アドレスから物理アドレスへ変換しなければいけません。
-
OSの作り方を学べる
-
x86を作りながら学べる
real modeに入り方
ほとんどこちらの資料を参考にしました。
ここでは僕が試したことを書きます。
プログラミング環境
まず以下のassembly プログラムを作成します。ファイル名はboot.sとします。
.code16
.global init
init:
mov $0x0e43, %ax
int $0x10
hlt
.fill 510-(.-init), 1, 0
.word 0xaa55
簡単な説明
.code16は16bitという指定。real modeでは16ビットです。
int $0x10はbiosのinterrupt routineを呼び出しています。
.fill 510-(.-init), 1, 0は510バイトまで0で埋め尽くすという意味だそうです。これはbiosは511と512バイト目に0xaa55をみつけて初めてboot可能なものと認識するためです。
このプログラムは何するの?
このプログラムを実行すると”c”の文字を画面に繰り返し書き込んでいきます。
このプログラムをassemblerでコンパイルします。
as -o boot.o boot.s
次にリンクをします。
ld -o boot.bin --oformat binary -e init boot.o
これでreal modeで動作可能なbinary ファイルができました!
auスマートパス会員なら送料無料【au PAY マーケット】
実際に動かす
ここで通常はemulatorを使われているのが多いのですが僕の場合はちゃんと物理的なコンピュータで試したかったのでusbにコピーして動かしました。
注意!!!
物理的なコンピュータで試すとmaster boot recordを書きかえたりするのでこれを試して普通に起動させようとしたとき起動できなくなる可能性が十分あります!
僕の場合はsuper grub2というのをUSBメモリにいれてそれで通常に起動できるようにしています。
この注意を理解した上でUSBメモリにバイナリファイルをコピーし方は以下になります。
USBメモリをさしてそのUSBメモリのファイルを/devで探します。この例では/dev/sdb1がUSBメモリのファイルでした。
以下のコマンドを実行します。
sudo dd if=boot.bin of=/dev/sdb1 bs=512
これでBIOSの起動の順番をusbメモリを上にして起動すれば先ほど書いたプログラムが実行されます。
実際に実行した様子です。
ただひたすら画面にcを書き込んでいます(笑)
でもこれでreal modeでプログラミングできる環境ができました!これからOSの作り方やx86をきちんと学べるのですごく楽しみです!