#はじめに
こちらの本
30日でできる! OS自作入門
を最初はそのままWindows上で進めていましたが、naskのような著者の独自ツールが使われており情報が少ないのと、普段Ubuntuを使っているのでその上で実行できるといいなと思ったので、
できるだけLinuxで標準的なツールを使って進めていきます。
これも既にやっている方がたくさんいますが、何番煎じでも気にせずやってきます。
#環境
$ uname -a
Linux furble 5.3.0-42-generic #34~18.04.1-Ubuntu SMP Fri Feb 28 13:42:26 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
$ nasm -v
NASM version 2.13.02
$ qemu-system-i386 --version
QEMU emulator version 2.11.1(Debian 1:2.11+dfsg-1ubuntu7.23)
Copyright (c) 2003-2017 Fabrice Bellard and the QEMU Project developers
#必要なツールのインストール
##QEMU
$ sudo apt install qemu-kvm qemu
qemu-kvmは別にいらなかったかもしれない。
##NASM
$ sudo apt install nasm
#helloos0をQEMU上で実行
$ qemu-system-i386 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.
でウィンドウが出現し、「hello, world」と表示されたので、うまくいったようです。
このままでも問題無いですが、警告が気になるので、
$ qemu-system-i386 -drive file=helloos.img,format=raw,if=floppy
とすることで消すことができました。以降はこちらを使っていきます。
#helloos1を実行
$ nasm helloos.nas -o helloos.img
helloos.nas:9: warning: uninitialized space declared in .text section: zeroing
helloos.nas:17: warning: uninitialized space declared in .text section: zeroing
helloos.nas:20: warning: uninitialized space declared in .text section: zeroing
helloos.nas:22: warning: uninitialized space declared in .text section: zeroing
$ qemu-system-i386 -drive file=helloos.img,format=raw,if=flopp
nasmが警告を出していますが、問題なく実行できました。
調べると、RESB命令で警告が出ており、代わりにTIMES命令を使うことで消せます。
helloos.nas(nask用)をhelloos.asm(nasm用)に書き換えます。
$ diff -u projects/01_day/helloos1/helloos.nas tolset/helloos1/helloos.asm
--- projects/01_day/helloos1/helloos.nas 2020-03-25 17:15:30.927931338 +0900
+++ tolset/helloos1/helloos.asm 2020-03-28 12:33:54.545613281 +0900
@@ -6,7 +6,7 @@
DB 0xff, 0xff, 0xff, 0x48, 0x45, 0x4c, 0x4c, 0x4f
DB 0x2d, 0x4f, 0x53, 0x20, 0x20, 0x20, 0x46, 0x41
DB 0x54, 0x31, 0x32, 0x20, 0x20, 0x20, 0x00, 0x00
- RESB 16
+ TIMES 16 DB 0x00
DB 0xb8, 0x00, 0x00, 0x8e, 0xd0, 0xbc, 0x00, 0x7c
DB 0x8e, 0xd8, 0x8e, 0xc0, 0xbe, 0x74, 0x7c, 0x8a
DB 0x04, 0x83, 0xc6, 0x01, 0x3c, 0x00, 0x74, 0x09
@@ -14,9 +14,9 @@
DB 0xee, 0xf4, 0xeb, 0xfd, 0x0a, 0x0a, 0x68, 0x65
DB 0x6c, 0x6c, 0x6f, 0x2c, 0x20, 0x77, 0x6f, 0x72
DB 0x6c, 0x64, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00
- RESB 368
+ TIMES 368 DB 0x00
DB 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0xaa
DB 0xf0, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00
- RESB 4600
+ TIMES 4600 DB 0x00
DB 0xf0, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00
- RESB 1469432
+ TIMES 1469432 DB 0x00
RESB xxx は TIMES xxx DB 0 と同じです。
#helloos2を実行
RESBをTIMES命令に書き換えます。
$ nasm helloos.asm -o helloos.img
helloos.asm:41: error: non-constant argument supplied to TIMES
TIMES 0x1fe-$ DB 0
の行でエラーが出ています。
nasmマニュアル(英語) section 3.5より
$ evaluates to the assembly position at the beginning of the line containing the expression; so you can code an infinite loop using JMP $.
$$ evaluates to the beginning of the current section; so you can tell how far into the section you are by using ($−$$).
$はその行の最初の式(この場合TIMES)のアドレス、$$は現在のセクションの最初のアドレスを表す、とあります。セクションとは後で出てくる.textや.dataなどのことです(多分)。
今回はセクション分けはされてないので、$$はファイルの先頭アドレスを指すものと考えられます。よって、($-$$)はセクションの先頭(今回はファイルの先頭)から($-$$)の記述のある行の先頭までのバイト数となり、naskにおける$と同じ意味になるということです(多分)。
$ diff -u projects/01_day/helloos2/helloos.nas tolset/helloos2/helloos.asm | nkf -Sw
--- projects/01_day/helloos2/helloos.nas 2020-03-25 17:15:30.927931338 +0900
+++ tolset/helloos2/helloos.asm 2020-03-29 11:37:16.045372158 +0900
@@ -21,7 +21,7 @@
DD 0xffffffff ; たぶんボリュームシリアル番号
DB "HELLO-OS " ; ディスクの名前(11バイト)
DB "FAT12 " ; フォーマットの名前(8バイト)
- RESB 18 ; とりあえず18バイトあけておく
+ TIMES 18 DB 0 ; とりあえず18バイトあけておく
; プログラム本体
@@ -38,13 +38,13 @@
DB 0x0a ; 改行
DB 0
- RESB 0x1fe-$ ; 0x001feまでを0x00で埋める命令
+ TIMES 0x1fe-($-$$) DB 0 ; 0x001feまでを0x00で埋める命令
DB 0x55, 0xaa
; 以下はブートセクタ以外の部分の記述
DB 0xf0, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00
- RESB 4600
+ TIMES 4600 DB 0
DB 0xf0, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00
- RESB 1469432
+ TIMES 1469432 DB 0
$ nasm helloos.asm -o helloos.img -l helloos.lst
$ qemu-system-i386 -drive file=helloos.img,format=raw,if=floppy
これで成功です。