Ubuntu
OS
自作OS
ubuntu16.04
Ubuntu16.04LTS

30日でできる!OS自作入門(5日目)[Ubuntu16.04/NASM]

記事一覧

30日でできる!OS自作入門(記事一覧)[Ubuntu16.04/NASM]

目的

"30日でできる!OS自作入門"の内容をUbuntu(Linux)で実行するには本の内容だけでは厳しいので調べた結果をメモ。(リンクと動作確認済みコード・コメント)

image.png

このテキストを読む上でUbuntuとnasmを使う方の参考になればと思っております。
(テキストが無いと厳しいです)
Ubuntu 16.04 LTS

おおよそはテキストを読んでいただければ実行できると思うので今回特にうまく行かないところのみを紹介します。
5日目で突っかかる点
- harib02e : フォントを増やすときにhankaku.binbin2obj.exeとかいう新しいやつが出てきた。
- harib02g : -nostdlibでコンパイルしているためsprinft()を読みだすことができない。

フォントを増やしたい - harib02e

 テキストではhankaku.txt変換用のファイルを用いていますがUbuntuで実行している私にはそのまま実行できません。そこで同じ挙動をするCファイルを作成します。

目的

hankaku.txtファイルの内容を各文字を示すバイトの文字列として格納していくことをします。
例えば以下のようなデータ(16x8)を

........
...**...
...**...
...**...
...**...
..*..*..
..*..*..
..*..*..
..*..*..
.******.
.*....*.
.*....*.
.*....*.
***..***
........
........

以下のようなバイトの文字列のような形にします。

char hankaku[4096] =  {
    // 何バイト目の情報か(8bit)
    // 1     2     3     4     5     6     7     8     9    10    11    12    13    14    15    16
    ...
    ...
    0x00, 0x18, 0x18, 0x18, 0x18, 0x24, 0x24, 0x24, 0x26, 0x7e, 0x42, 0x42, 0x42, 0xe7, 0x00, 0x00,
    ...
    ...
};

これは一行ずつ読み込んで'.'と'*'を判別していけば良さそうですね。

コード

ということで以下に変換するファイルconvHankakuTxt.cのソースコードのリンクを載せておきます。
ちなみにこのコードは次のサイトを参考にさせていただきました。GDT(グローバルディスクリプタテーブル) | OS自作入門 5日目-1 【Linux】 - サラリーマンがハッカーを真剣に目指す

このコードではhankaku.txtのファイル内容を各行読み込みバイトの文字列に変換したものをhankaku.cファイルを作成して保存しています。
- hankaku.cのコード(コード名は都合上変えています。)

さて、ではMakefileを書き換えましょう。
主な変更点は

#--------------------
#   hankaku char
#--------------------
convHankakuTxt : convHankakuTxt.c
    $(CC) $< -o $@

hankaku.c : hankaku.txt convHankakuTxt
    ./convHankakuTxt

以下の必要ファイルにhankaku.cを加えるのをお忘れなく。

bootpack.hrb : bootpack.c har.ld hankaku.c nasmfunc.o Makefile
gcc -march=i486 -m32 -nostdlib -T har.ld bootpack.c hankaku.c nasmfunc.o -o bootpack.hrb

また、Makefile最後のcleansrc_onlyにも注意してください。
この2つを削除しないと万が一convHankakuTxt.cを更新したときに新しいファイルが作成されません。

rm hankaku.c
rm convHankakuTxt

実行結果

image.png

変数値表示 - harib02g

 この節ではどうやら標準ライブラリのsprintf関数を使用するようなのですがエラーが発生しました。エラー内容は次のサイトと同様です。(sprintfを実装する | OS自作入門 5日目-2 【Linux】 - サラリーマンがハッカーを真剣に目指す)
 ここでエラーが発生している原因としては自分の場合.soファイルなのですが、このファイルは特定のリンカでリンクするためのオブジェクトファイルらしいです。
 いろいろ調べはしたのですが現段階の自分の力ではどうにもできなかったので今回は先のサイトで紹介してくださっている自作sprintf関数をお借りすることにしました。

コード

mysprintf.cというファイルはsprintf関数を定義しています。
mysprintf.cのコード

Makefileも書き換えましょう。

mysprintf.o : mysprintf.c
    $(CC) $(CFLAGS) -nostdlib $^ -o $@

bootpack.hrb : bootpack.c hankaku.o nasmfunc.o mysprintf.o har.ld
    $(CC) -m32 -march=i486 -nostdlib -nostdinc -T har.ld bootpack.c hankaku.o nasmfunc.o mysprintf.o -o bootpack.hrb

これとは別にldコマンドを使うと以下のようになります。

mysprintf.o : mysprintf.c
    $(CC) $(CFLAGS) -nostdlib $^ -o $@

bootpack.o : bootpack.c
    $(CC) $(CFLAGS) bootpack.c -o bootpack.o

bootpack.hrb : bootpack.o hankaku.o nasmfunc.o mysprintf.o har.ld
    ld -m elf_i386 -T har.ld bootpack.o hankaku.o nasmfunc.o mysprintf.o -o bootpack.hrb

Makefileのコード

実行結果

image.png

最後に

 Ubuntuで実行しようとした時に苦戦するようなところは以上かと思います。ほかはテキスト通りに進めていけば大丈夫かと思います。
 ただ何かわからないことがあればコメントにおねがいします。迅速に対応できるように努めます。
 5日目のコードは以下から見ることができます。
- 5日目のコード

参考・おすすめサイト