OS自作入門 on Linux [day 2]

今回のコード。 https://github.com/zakuro9715-MiaOS-history/day02

 

二日目は、環境を整えたり、コードを綺麗にしたりします。機能の追加はありません。

基本的には本に書いてあるとおり進めるだけでOKですから、一日目に比べるとずいぶんと楽です。(Makefileの作成を一日目に移したからという理由もあります)

しかし、細かい違いはやはりあります。

 

まずnaskにはない .code16 命令があります。これは、16bitコードを吐いてね、と指示する命令です。

また、次のように、ラベルにダラーが付いている箇所があります。

movw	$hellomsg,	%si

 

これは、そのラベルのアドレスを表します。nask ではラベル名をそのまま書くだけで良いようですが、gas ではダラーが必要になります。

 

同じような小さな違いとしては、[SI] と書く代わりに、gas では (%si) と書きます。

レジスタに%をつけるのは前回書いたとおりで、() が [] と同じ働きをします。

 

nask では、org 命令でプログラムが読み込まれる場所を指定していますが、gas では org命令は別の役割を持っていました。

しかし、gas には nask の org 命令に対応する命令がありません。

どのようにしてプログラムが読み込まれる場所を指定するかは、少々複雑なので後の方に書くことにします。

 

次に、Makefileの変更点を見ていくことにしましょう。

大きく変わったように思えますが、実質的には追加されたのは次の部分だけです。

$(IMG): $(IPL)

mformat -f 1440 -C -B $(IPL) -i $(IMG) ::

 

mformat コマンドとは、MS-DOSフォーマットを行うコマンドです。

-f オプションでファイルサイズを1440kb に指定しています。-C オプションは、MS-DOSファイルシステムを作成するためのオプションです。

-B オプションは、ブートセクタを指定するオプションで、当然ながらコンパイルした ipl を渡します。

曲者なのが、-i オプションと、最後の :: です。

 

-i オプションに関しての情報が全く見つかりませんでした、私のgooglability が足りないのか、検索しても出てきませんし、help にも man にも載っていなかったので、結局ソースを見ました(余談ですが、なかなかにひどいコードでした)。

そしてどうやら、-i オプションは、書き出すイメージファイルを指定するオプションらしいです。

 

さて、最後の2つのコロンですが、help を見ると、drive: となっています。

おそらく、一つ目のコロンがドライブ名なのでしょう。

コロンは何もしないコマンドです。こういう使い方ができるのかはわかりませんが、ドライブ名を指定しない、ということでしょうか。動き方を見ると多分そうなのでしょう。

 

さて、プログラムが読み込まれる場所の指定ですが、これはリンカスクリプトで行います。

リンカスクリプトを見ると、追加されている点があるのがわかります。

SECTIONS

{

. = 0x7c00;

.text : {*(.text)}

}

SECTIONS でセクションを定義します。

セクションというのは、プログラムを配置するときのまとまりの単位のようなものですが、今はそれほど気にしなくても良いです。

 

中身をそれぞれ見ていくと

. = 0x7c00;

.(ドット)は、ロケーションカウンタと呼ばれるもので、現在どの位置にいるかを指定します。ここでは、0x7c00 に移動します。

 

.text : {*(.text)}

コロンの左が出力セクション名、右が入力です。

アスタリスクワイルドカードなので、単体で使用すると全ての入力ファイルにマッチします。

つまり、この部分は、すべての入力の .text セクションを .text セクションに配置する、という意味になります。

 

ところで、先ほどロケーションカウンタを 0x7c00 に設定しました。.text セクションは 0x7c00 に配置されます。

このアドレス、どこかで見たアドレスだと思いませんか?

そう、nask では org 命令で指定されていたアドレスです。

 

ここまでで、二日目は終わりです。後半が少し厄介でしたが(-i オプションに関しては、かなり探しまわったので結構大変でした)、それほど難しい内容ではなかったように思います。

 

今回参考にしたページ