IPLとOS本体を含むイメージファイルを作成するには、筆者作成のedimg.exeを使うと簡単であるが、ここ や ここ を参考にすると、UbuntuやDebianのmtoolsパッケージに含まれるmformatコマンドを使ってFDイメージを作成しているので、同様の手順で作成することにした。
mformatコマンドを使うとイメージファイルを次のコマンドで作成できる。
$ mformat -f 1440 -B ブートセクタファイル -C -i イメージファイル名 ::ipl.binはブートセクタのファイルをBオプションで指定できる。
なお、man mformatを見ても、iオプションの説明は無かった。
OS本体をイメージファイルにコピーするには、
$ mcopy OS本体 -i イメージファイル名 ::とする。
それぞれのコマンドの後ろにtarget directoryとして :: としているが、イメージファイルの場合は、これを指定するようだ。
Makefileは以下のようになった。
Makefile
image_file=tinyos.img ipl.bin: ipl.s lnk.ls gcc -nostdlib -o $@ -Tlnk.ls ipl.s gcc -Tlnk.ls -c -g -Wa,-a,-ad ipl.s > ipl.lst tinyos.sys: tinyos.s lnk.ls gcc -nostdlib -o $@ -Tlnk.ls tinyos.s gcc -Tlnk.ls -c -g -Wa,-a,-ad tinyos.s > tinyos.lst image_file: ipl.bin tinyos.sys mformat -f 1440 -B ipl.bin -C -i ${image_file} :: mcopy tinyos.sys -i ${image_file} :: img: make image_file run: qemu-system-i386 -m 32 -localtime -vga std -fda ${image_file}
書籍通りに、まずは簡単なコードで確認する。
tinyos.s
fin: hlt jmp fin
make img でイメージを作成してみる。
なお、tinyos.sのリスティングファイル(アセンブル結果)は以下の通り。
tinyos.lst
1 fin: 2 0000 F4 hlt 3 0001 EBFD jmp fin
書籍の通りに、0x2600にファイル情報がある。
00002600: 5449 4e59 4f53 2020 5359 5320 1800 e9b5 TINYOS SYS .... 00002610: 3445 3445 0000 e9b5 3445 0200 0300 0000 4E4E....4E......0x4200からOS本体のコードがある。
00004200: f4eb fd00 0000 0000 0000 0000 0000 0000 ................イメージを0x8000から読み込ませているので、
イメージの0x4200からのコードを実行するには、
0x8000 + 0x4200 = 0xC200 になる。
ipl.s を修正して、FDの読み込み処理後に
jmp 0xC200 # 0x8000 + 0x4200 = 0xC200を追加した。
IPL用のリンカスクリプトとは別に、OS本体用のリンカスクリプトも必要だ。
tinyos_lnk.ls
OUTPUT_FORMAT("binary"); SECTIONS { . = 0xC200; }Makefileを、これに合わせて修正する。
image_file=tinyos.img ipl.bin: ipl.s lnk.ls gcc -nostdlib -o $@ -Tipl_lnk.ls ipl.s gcc -Tipl_lnk.ls -c -g -Wa,-a,-ad ipl.s > ipl.lst tinyos.sys: tinyos.s lnk.ls gcc -nostdlib -o $@ -Ttinyos_lnk.ls tinyos.s gcc -Ttinyos_lnk.ls -c -g -Wa,-a,-ad tinyos.s > tinyos.lst image_file: ipl.bin tinyos.sys mformat -f 1440 -B ipl.bin -C -i ${image_file} :: mcopy tinyos.sys -i ${image_file} :: img: make image_file run: qemu-system-i386 -m 32 -localtime -vga std -fda ${image_file}
だんだん汚なくなってきた。そのうち綺麗に書き直そう。
make imgしてイメージを作成後、qemuで試してみる。
が、正しく動かない。load errorと出てしまう。
JMPがすっとばされているのか?
リスティングファイルを確認する。
ipl.lst
83 00ac E90000 jmp 0xC200 # 0x8000 + 0x4200 = 0xC200どこにもC200が無い。これでは駄目だ。
いろいろ調べて、試行錯誤してみると、
ipl.s
jmp *0xC200 # 0x8000 + 0x4200 = 0xC200
ipl.lst
83 00ac FF2600C2 jmp *0xC200 # 0x8000 + 0x4200 = 0xC200うーむ。*0xC200と書くのが正しいのか。
(実は、最初は指定アドレスは即値なので$0xC200と書いて怒られた。)
きちんとGASのリファレンスを読んだほうが良さそうだな。
これで試してみると、一応見かけ上は動いているみたい。
今日はここまで。
9/21 追記
この後、ビデオモードを変更する処理を書いてみたが、どうも上のコードでは、0xC200へjmpしていないようだ。
0xC200へJMPさせるには、どう書けば良いのか?うーむ。
0 件のコメント:
コメントを投稿