OS自作入門 on Ubuntu 16.04 (1日目)

「30日でできる!OS自作入門」(川合秀実著)で OS の勉強を始めたのですが,Ubuntu 16.04 LTS 環境で試したいと思います.


1日目は
  1. バイナリエディタで直接 OS イメージを作成する
  2. 18万行のアセンブラコードを書いて OS イメージを作成する
  3. 22行のアセンブラコードを書いて OS イメージを作成する
  4. 50行の「かなりそれっぽいソースプログラム」(アセンブラ)を書いて OS イメージを作成する
の4つがありますが,4.だけ試します.

ツールのインストール

GNU assembler と QEMU をインストールします.

$ sudo apt install binutils qemu

インストールされた GNU assembler のバージョンは 2.26,QEMU のバージョンは 2.5.0 です.

NASKとGASとの違い

構文が違うようです.
NASK は NASM をベースとしたアセンブラで,「インテル構文」と呼ばれる書き方です.
一方,GAS は「AT&T構文」と呼ばれる書き方です.
書き方は異なりますが,大きく違うわけでは無いようで,意味的にはさほど変わりません.

helloos2.s の書き換え

DB命令の意味は,「ファイルの内容を1バイトだけ直接書く」ですが,GAS のAT&T構文では,DBの代わりに .byte と書きます.
つまり,

DB 1

となっているところを GAS では

.byte 1

とします.
見た目は若干違いますが,意味は同じです.

ところが,DB命令の次が文字列の場合は .byte ではなく,.ascii を使います.
つまり,

DB "HELLOIPL"



.ascii "HELLOIPL"

と書きます.ややこしいですね.

DW命令とDD命令は .word と .long に置き換えるだけです.

RESB命令は少しややこしいです.
.org を使えばいいのですが,単純な置き換えではありません.

RESB 18



.org .+18

と書きます.
RESB命令を .org に書き換えて,次の数字の前に .+ を加えています.
現在の場所から相対的に18バイト空けておく(0を書き込んでおく)という意味で,  .+ を使っているようです.

ところが,helloos2.s には

RESB 0x1fe-$

という部分があります.
これは (絶対的な場所)0x1fe まで0で埋めるという意味で, .+ を使わずに,

.org 0x1fe

と書けばオッケーです.

このルールに則って,helloos2.s をインテル構文からAT&T構文に書き換えると次のようになります.

.byte 0xeb, 0x4e, 0x90
.ascii "HELLOIPL"
.word 512
.byte 1
.word 1
.byte 2
.word 224
.word 2880
.byte 0xf0
.word 9
.word 18
.word 2
.long 0
.long 2880
.byte 0,0,0x29
.long 0xffffffff
.ascii "HELLO-OS   "
.ascii "FAT12   "
.org .+18

# プログラム本体
.byte 0xb8, 0x00, 0x00, 0x8e, 0xd0, 0xbc, 0x00, 0x7c
.byte 0x8e, 0xd8, 0x8e, 0xc0, 0xbe, 0x74, 0x7c, 0x8a
.byte 0x04, 0x83, 0xc6, 0x01, 0x3c, 0x00, 0x74, 0x09
.byte 0xb4, 0x0e, 0xbb, 0x0f, 0x00, 0xcd, 0x10, 0xeb
.byte 0xee, 0xf4, 0xeb, 0xfd

# メッセージ部分
.byte 0x0a, 0x0a
.ascii "hello, world"
.byte 0x0a
.byte 0

.org 0x1fe

.byte 0x55, 0xaa

# 以下はブートセクタ以外の部分の記述
.byte 0xf0, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00
.org .+4600
.byte 0xf0, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00
.org .+1469432

ふぅ,これで GAS 用に書き換えられました.
そうそう,インテル構文ではコメントは ; でしたが,AT&T構文では # を用います.

実行

まず上のアセンブラコードから以下のように OS イメージ(helloos2.img)を作成します.

$ as helloos2.s -o helloos2.o
$ objcopy -R .note.gnu.build-id -S -O binary helloos2.o helloos2.img

これを QEMU を使って動かします.

$ qemu-system-x86_64 -fda helloos2.img

-fda オプションはフロッピー起動のオプションです.

無事 Hello, world が表示されれば完成です.
お疲れ様でした.

コメント

このブログの人気の投稿

第1回 ラムダ抽象と関数適用

パソコンの Arch Linux に Emacs をインストール

パソコンの Arch Linux に Chrome をインストール