30日でできる！OS自作入門（５日目）[Ubuntu16.04/NASM]

# 記事一覧
<a href="https://qiita.com/pollenjp/items/b7e4392d945b8aa4ff98">30日でできる！OS自作入門（記事一覧）[Ubuntu16.04/NASM]</a>


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

![image.png](https://qiita-image-store.s3.amazonaws.com/0/195174/f19d798d-a943-c5a2-17a3-da10e56aee6c.png)

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


おおよそはテキストを読んでいただければ実行できると思うので今回特にうまく行かないところのみを紹介します。
5日目で突っかかる点
- harib02e : フォントを増やすときに`hankaku.bin`や`bin2obj.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`のソースコードのリンクを載せておきます。
ちなみにこのコードは次のサイトを参考にさせていただきました。<a href="http://bttb.s1.valueserver.jp/wordpress/blog/2017/12/13/makeos-5-1/">GDT（グローバルディスクリプタテーブル） | OS自作入門 5日目-1 【Linux】 - サラリーマンがハッカーを真剣に目指す</a>

- <a href="https://github.com/pollenjp/myHariboteOS/blob/ccfc4ae5322febb09fc99700384ed5f972de56a2/day05/harib02e/convHankakuTxt.c">convHankakuTxt.cのコード</a>


このコードでは`hankaku.txt`のファイル内容を各行読み込みバイトの文字列に変換したものを`hankaku.c`ファイルを作成して保存しています。
- <a href="https://github.com/pollenjp/myHariboteOS/blob/ccfc4ae5322febb09fc99700384ed5f972de56a2/day05/harib02e/convHankakuTxt.c">hankaku.cのコード</a>（コード名は都合上変えています。）

さて、では`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`最後の`clean`と`src_only`にも注意してください。
この２つを削除しないと万が一`convHankakuTxt.c`を更新したときに新しいファイルが作成されません。

```
rm hankaku.c
rm convHankakuTxt
```


## 実行結果
![image.png](https://qiita-image-store.s3.amazonaws.com/0/195174/99d2514f-1515-9fe5-5c13-8674830aed51.png)



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

## コード
`mysprintf.c`というファイルはsprintf関数を定義しています。
<a href="https://github.com/pollenjp/myHariboteOS/blob/bb932eec491c9aea0ba0969d1ed9ccfaf29c18ad/day05/harib02g/mysprintf.c">mysprintf.cのコード</a>

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
```

<a href="https://github.com/pollenjp/myHariboteOS/blob/087ba7b18b32fa3e8f8e6c285b393574839961cd/day05/harib02g/mysprintf.c">Makefileのコード</a>


## 実行結果
![image.png](https://qiita-image-store.s3.amazonaws.com/0/195174/8eda5f6b-079b-b98b-d643-16f16a598145.png)


## 最後に
　Ubuntuで実行しようとした時に苦戦するようなところは以上かと思います。ほかはテキスト通りに進めていけば大丈夫かと思います。
　ただ何かわからないことがあればコメントにおねがいします。迅速に対応できるように努めます。
　５日目のコードは以下から見ることができます。
- <a href="https://github.com/pollenjp/myHariboteOS/tree/087ba7b18b32fa3e8f8e6c285b393574839961cd/day05">５日目のコード</a>


# 参考・おすすめサイト
- <a href="http://bttb.s1.valueserver.jp/wordpress/blog/2017/12/13/makeos-5-1/">GDT（グローバルディスクリプタテーブル） | OS自作入門 5日目-1 【Linux】 - サラリーマンがハッカーを真剣に目指す</a>
- <a href="http://bttb.s1.valueserver.jp/wordpress/blog/2017/12/17/makeos-5-2/">sprintfを実装する | OS自作入門 5日目-2 【Linux】 - サラリーマンがハッカーを真剣に目指す</a>
- <a href="http://takeisamemo.blogspot.jp/2014/10/os30os-5-1.html">[OS作成]30日でできる！OS自作入門 5日目 (1) - takeisa memo</a>
- <a href="http://takeisamemo.blogspot.jp/2014/10/os30os-5-2.html">[OS作成]30日でできる！OS自作入門 5日目 (2) - takeisa memo</a>
- <a href="http://takeisamemo.blogspot.jp/2014/10/os30os-5-3.html">[OS作成]30日でできる！OS自作入門 5日目 (3) - takeisa memo</a>
- <a href="https://gcc.gnu.org/onlinedocs/gcc-4.5.3/gcc/i386-and-x86_002d64-Options.html">3.17.15 Intel 386 and AMD x86-64 Options</a>
- <a href="https://www.cyberciti.biz/tips/compile-32bit-application-using-gcc-64-bit-linux.html">HowTo Compile a 32-bit Application Using gcc On the 64-bit Linux Version</a>
- <a href="https://hikalium.com/page/note/20161202.md">Mac OSX におけるはりぼてOSの開発環境を（再）整備した話 - hikalium.com</a>