1stステップ(動作確認の環境構築)
まだ「30日でできる!OS自作入門」を進めているので具体的なところには手を出してないが、知りたい事があって書籍を購入後、結局周辺機器も購入した。
最初にやったことだけ記載しておく。
購入したのは秋月電子で、半田付けが必要なキット版。
http://akizukidenshi.com/catalog/g/gK-00209/
上記を動かすためのACアダプタも同時に購入。
http://akizukidenshi.com/catalog/g/gM-06096/
PCと接続するためのRS-232C用ケーブルのみヨドバシカメラで購入。
エレコムのUC-SGT1。
購入したボードがキットだったため、正しく部品が付いてるか気になり、とりあえず動作確認をするために環境だけは整えた。
参考にしたのは以下。ほぼこの通り。
https://qiita.com/Shohei_miyasako/items/6e0e1a9f298bd8db3369
一応やったことを下に書いていく。
Windows10にRS-232C用ケーブルのドライバをメーカーホームページからダウンロードしてインストール。
開発環境はCygwinの32bitをインストール。(setup-x86.exe)
インストール時に必要なソフトウェアにチェックを入れておく。上記ページの画像参照。
binutils: 2.29-1
gcc:7.3.0-3
make: 4.2.1-2
patch:0.3.4-1
必要なファイルをダウンロードしておく。
圧縮ファイルは末尾がbz2だったとしてもgzと同じコマンドで解凍できるので、とにかく同じバージョンを探す。
binutils-2.19.1( http://www.ring.gr.jp/pub/GNU/binutils/ )
gcc-3.4.6( http://www.ring.gr.jp/pub/GNU/gcc/ )
ダウンロードしたファイルはC:\cygwin\home\ユーザ名の下に置く。
それぞれをインストール。時間がかかる。
$ tar xvf binutils-2.19.1.tar.bz2
$ cd binutils-2.19.1 $ mkdir build
$ cd build
$ ../configure --target=h8300-elf --disable-nls --disable-werror
$ make
$ make install
$ tar xvf gcc-3.4.6.tar.gz
$ cd gcc-3.4.6
本書のパッチファイルをダウンロード。
http://kozos.jp/books/makeos/patch-gcc-3.4.6-x64-h8300.txt
同じフォルダに上記ファイルをpatch.txtとリネームしたものを置く。
gcc\collect2.cの1537行目を本書を参照して修正。
パッチを当てる。
$ patch -p0 < patch.txt
$ ../configure --target=h8300-elf --disable-nls --disable-threads --disable-shared --enable-languages=c --disable-werror
$ make
$ make install
準備ができたら、本書のソースコードをダウンロード。
http://kozos.jp/kozos/osbook/osbook_03.zip
解凍し、フォルダ構成を編集。
最初のHelllo Worldのフォルダの場合、
C:¥cygwin¥home¥ユーザ名¥osbook¥src¥01¥bootload¥
書き込みツールのkz_h8writeをダウンロード。
https://ja.osdn.net/projects/kz-h8write/
これも配置を編集。
C:¥cygwin¥home¥ユーザ名¥osbook¥src¥tools¥kz_h8write.exe
これに合わせてbootloadフォルダにあるMakefile内のフォルダ構成も編集。
Makefileのあるフォルダでmakeを実行。
$ make
$ make image
ボードを接続し、ポートを確認。
Makefileの
H8WRITE_SERDEV = comXX
のところを編集。自分の場合はcom3になった。
ボードのスイッチを書き込み用にして、
$ make write
で、書き込み。
Teratermを
https://ja.osdn.net/projects/ttssh2/releases/
からダウンロードし、インストール。
起動後「設定」「シリアルポート」にし本書の通りに設定。
今度はフラッシュROMからの起動用にボードのスイッチを変更。
接続後、リセットボタンを押すとTeratermの画面に
Hello World!
と、出てくるはず。(リセットボタンを押すたびに増える)
これでハードウェアの動作は確認できた。
でも本書の内容はまだ読み込んでないので、引き続き学習する。
6日目(bootpack.cとMakefileの整理)
Makefileは独自のルールでやってきたので、いざbootpack.cを分割すると言われると対応に混乱するが、手順は本書の通りに進める。
とにかくbootpack.cを分ける。
bootpack.h:ヘッダファイル
graphic.c : 画面表示
dsctbl.c: descriptor table関係
bootpack.c: それ以外
しかしmake runするとどうしてもgccでエラーが出る。
dsctbl.o: 関数 `init_gdtidt' 内:
dsctbl.c:(.text+0x8c): `load_gdtr' に対する定義されていない参照です
dsctbl.c:(.text+0xd5): `load_idtr' に対する定義されていない参照です
というような感じ。関数のところはいろいろ。
他の方のMakefileを見ながら、改めて整理。
結局原因はMakefileやdsctbl.cではなく、nasmfunc.nasに増えた関数を記載忘れ&ミスタイプしてただけだった。
nasmfunc.nasの一部抜粋。
section .textのところに追加。
GLOBAL load_gdtr
GLOBAL load_idtr
GLOBAL asm_inthandler21
GLOBAL asm_inthandler27
GLOBAL asm_inthandler2c
EXTERN inthandler21
EXTERN inthandler27
EXTERN inthandler2c
(以下略)
関数は上記だけでなく、かなり行が増えているのに注意。
ついでに以下、現状のMakefileの内容。ファイル名も一部変更。
---
# 6日目終了 現在のファイル
# Makefile (このファイル)
# bootpack.c (分割後)
# dsctbl.c
# graphic.c
# bootpack.h (Makefileに記載はない)
# har.ld (リンカファイル)
# hankaku.c (半角フォント)
# my_sprintf.c (sprintf関数)
# haribote.nas
# nasmfunc.nas
# nasmhead.nas
# ipl.nas
# int.c
# デフォルト動作
default:
make img
# ファイル生成規則
nasmhead.bin : nasmhead.nas
nasm nasmhead.nas -o nasmhead.bin -l nasmhead.lst
nasmfunc.o : nasmfunc.nas # nasmfunc.nasのバイナリファイル
nasm -g -f elf nasmfunc.nas -o nasmfunc.o
bootpack.bin: bootpack.o hankaku.o nasmfunc.o my_sprintf.o dsctbl.o graphic.o int.o
ld -m elf_i386 -e HariMain -o bootpack.bin -T har.ld bootpack.o graphic.o dsctbl.o hankaku.o nasmfunc.o my_sprintf.o int.o
haribote.sys : nasmhead.bin bootpack.bin
cat nasmhead.bin bootpack.bin > haribote.sys
ipl.bin : ipl.nas Makefile
nasm ipl.nas -o ipl.bin -l ipl.lst
haribote.img : ipl.bin haribote.sys #最終的なimgファイル
mformat -f 1440 -C -B ipl.bin -i haribote.img ::
mcopy haribote.sys -i haribote.img ::
# bootpack.hrb : bootpack.c har.ld nasmfunc.o Makefile # リンカスクリプト使用
# gcc -march=i486 -m32 -nostdlib -T har.ld -fno-pic bootpack.c hankaku.c nasmfunc.o -o bootpack.hrb
%.o: %.c
gcc -c -m32 -fno-pic -nostdlib -o $*.o $*.c
# コマンド
hankaku : # conv_hankaku.cでhankaku.cを作る
gcc -o conv_hankaku conv_hankaku.c
./conv_hankaku
asm :
make -r ipl.bin
img :
make -r haribote.img
run :
make img
qemu-system-i386 -fda haribote.img # -fda追加
clean :
rm *.lst *.bin *.sys *.img *.hrb *.o
---
これは他の方のブログでまとめられた内容がとても役にたった。
「%.o: %.c」のところが最初わからなかったが、調べたところ、
---
サフィックスルール
また,C言語では必ず.cから.oファイルが作られる,ということを利用し, これをルール化したのがサフィックスルールである.サフィックスとは拡張子のことです..c.o: というターゲットは,.oというファイルが必要になれば,これを.cからつくる というルールである.自動変数である $< をつかっている.
---
と、いうことだった。
Ubuntu上で作業していると、Makefileは本書とは多少離れて対応する必要がある。
無理せず、自分が解りやすい範囲の記述でまとめた。
make runには成功したが、肝心の6日目後半の内容は正直全く理解できなかったので、少し進めてまた戻って読むのを繰り返すことにする。
今回参照させて頂いたサイト:
https://qiita.com/lrf141/items/9ba070a2a1c3e5faf71c
http://www.jsk.t.u-tokyo.ac.jp/~k-okada/makefile
https://github.com/harrybotter30/haribote/blob/master/doc/chapter6.md
https://inakadeikinaosu.com/shumi/os_nyumon_13/
http://bttb.s1.valueserver.jp/wordpress/blog/2017/12/21/makeos-6-1/
5日目(sprintf対策)
今回はharib02fから。
その前に、このところmake runすると普通に画面は出るけどワーニングが多かった。
よく見ると、intt_screenやputfont8など、あとで追加した関数が最初のところ(void)で宣言されてなかった。
(このミスは最後まで尾を引いた)
bootpack.cを見直した上で、harib02fのものを参照して写経。
エラーが出るので見直していたら、最後に追加されているvoid putfonts8_ascのところを忘れていた。
追加してここまでは成功。
次に#include <stdio.h>を追加して、sprintf(s, "scrnx = %d", binfo->scrnx);を追加。
他にもchar s[40];が増えてたりと、よく見ると違いがある。
最初のエラーが出る。
gcc -march=i486 -m32 -nostdlib -T har.ld -fno-pic bootpack.c hankaku.c nasmfunc.o -o bootpack.hrb
In file included from bootpack.c:1:0:
/usr/include/stdio.h:27:10: fatal error: bits/libc-header-start.h: そのようなファイルやディレクトリはありません
#include <bits/libc-header-start.h>
^~~~~~~~~~~~~~~~~~~~~~~~~~
これは必要なファイルをインストール。
$ sudo apt install gcc-multilib g++-multilib
もう一度make run。今度は、
/tmp/ccJ9cdjO.o: 関数 `HariMain' 内:
bootpack.c:(.text+0xc3): `sprintf' に対する定義されていない参照です
collect2: error: ld returned 1 exit status
これがubuntuで開発している人には有名な、sprintfの問題。
わからないところはとりあえず保留し、まずはエラーを除くことに尽力したいので、他の方が作っているsprintf関数をコピペしmy_sprintf.cとして保存。
Makefileのgccのところに以下のように追加。
bootpack.hrb : bootpack.c har.ld hankaku.c my_sprintf.c nasmfunc.o Makefile # リンカスクリプト使用
gcc -march=i486 -m32 -nostdlib -T har.ld -fno-pic bootpack.c hankaku.c my_sprintf.c nasmfunc.o -o bootpack.hrb
これでワーニングはあるものの、成功した。
しかしharib02hでトラップ。
「init_screen」がいつの間にか「init_screen8」になっていて、違いに気づかずしばらく苦労した。
関数名を修正して、成功。
5日目最後のharib02iは変更点を追記したと思ったのだが、どこかでタイプミスをしたらしく、何度直してもエラーになった。
なので公式のharib02iのbootpack.cをそのまま持ってきてしまった。
するとエラーもなく、ワーニングも減って無事に実行できた。(出てくる画面に変化はない)
ずっとどこかで間違えたままになっていたようなので、以後はこれを使う。
今回参照させて頂いたサイト:
https://thinline196.hatenablog.com/entry/2018/07/05/234715
http://bttb.s1.valueserver.jp/wordpress/blog/2017/12/17/makeos-5-2/