プログラミング関連での備忘録なんかを載せています。
カレンダー
10 | 2024/11 | 12 |
S | M | T | W | T | F | S |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
プロフィール
HN:
たっく
年齢:
42
性別:
男性
誕生日:
1982/03/11
職業:
システムエンジニアなの?
おすすめ
最新コメント
最新記事
(11/15)
(11/15)
(11/15)
(11/08)
(11/07)
最新トラックバック
ブログ内検索
最古記事
(11/06)
(11/07)
(11/07)
(11/07)
(11/07)
アクセス解析
3日目 その2です。
更新が1週間空きましたが、別にサボっていたわけではありません。
著者製ツールを極力使わないという自分ルールに縛られていました。
具体的にいうと、ld等のリンカに当たる、obj2bim と bim2hrbというツールです。
このツールを使用せずに、アセンブラで作成したオブジェクトファイルと、
C言語で作成したオブジェクトファイルをリンクしようとしていました。
とりあえず、順番にいきます。
今までアセンブラのみでしたが、今回からC言語が加わっています。
それに伴って、OSの本体であるoslite.sysの作り方が大きく変わっています。
流れを書くと、
- アセンブラでOSのヘッダー部分を記述(asmhead.asm)
- C言語でOSの処理部分を記述(bootpack.c)
- アセンブラでC言語だけでは手に負えない部分を記述(nasmfanc.asm)
- 2と3ののファイルをリンカで結合してoslite.sysを作成
- 1のファイルと4で出来たファイルをcatコマンドで結合
- それを、フロッピーのイメージの中にファイルとして保存する
流れだけ書くとそんなに難しくない様に感じます・・・・・・が、
実際にやってみると、こんなに難しい物なのか!っていうのが分かりました。
※「30日でできる!OS自作入門」が難しいわけではありません。
私が変な部分にこだわっている事で難しくしてしまっただけの話です。
「30日でできる!OS自作入門」ではHRBという形式の、
独自の実行ファイル形式を作成していますが、
私はLinuxで使用されているELFという形式の実行ファイルを作りたくて、
調べたり、色々試してみたりしていたら、1週間たってしまいました。
結果としては、今の私では、手に負えませんでした。
HRB形式とELF形式の実行ファイルのヘッダ部分の取扱いの違いが
どうしても今の私には分かりませんでした。
と言うことで、落としどころとしてHRB形式の実行ファイルを使用するが、
著者製のツールは使用せず、ldにて出力する事にしました。
やり方は、すでに調べてくれている人がいた為、以下の方法で出力します。
まず初めに、startup.oというファイルを作成します。
これは、下にでてくるoslite.ldsに読み込まれせるもので、
どの関数が、最初に実行されるかを記述した物です。
(スタートアップルーチンって言う奴です。普段ならmainって書く関数です)
src/startup.cとして作成しました。
void LiteMain(void); void LiteStartup(void) { /* 将来LiteMainの実行に先立って何かしたくなったらここに書き足す*/ LiteMain(); /* 将来、LiteMainの終了後に何か処理をさせたくなったら、ここに書き足す*/ return; }
次に、ldsというディレクトリを作成し、
その中にoslite.ldsというファイルを作成する。
このファイルの中に「LONG(LiteStartup - 0x20)」と言う部分があり、上の「startup.c」とつながります。
oslite.ldsを開いて、以下のとおり記述します。
OUTPUT_FORMAT(binary) OUTPUT_ARCH(i386) INPUT(./bin/startup.o) SECTIONS { .head 0x0 : { LONG((ADDR(.bss) + SIZEOF(.bss) + 0xfff) & ~ 0xfff) BYTE(0x4f) BYTE(0x53) BYTE(0x4c) BYTE(0x69) LONG(0x0) LONG(ADDR(.data)) LONG(SIZEOF(.data)) LONG(LOADADDR(.data)) LONG(0xe9000000) LONG(LiteStartup - 0x20) LONG((ADDR(.bss) + SIZEOF(.bss) + 0xf) & ~ 0xf) } .text ADDR(.head) + SIZEOF(.head) : SUBALIGN (1) { *(.text) } .data 0x00000400 : AT ( LOADADDR(.text) + SIZEOF(.text) ) SUBALIGN (4) { *(.data) *(.rodata*) } .bss : AT ( LOADADDR(.data) + SIZEOF(.data) ) SUBALIGN (4) { *(.bss) } /DISCARD/ : { *(*) } }
で、保存をしたら、Makefileを以下の様に書き換えます。
Makefileは、「3日目 その1」からずいぶん色々な物が増えています
それと、フロッピーのイメージは「mformat」と「 mcopy」という
素敵なコマンドが見つかった為、そちらで作成することにしました。
(mformatがフロッピーのイメージを作成するコマンドで、
mcopyがフロッピーの中にファイルを入れるコマンドです)
NASM = nasm CC = gcc CFLAGS = -fno-builtin -fno-common -Os -Wall -nostdinc -I. -c SRC = ./src oslite.img : ./bin/ipl.bin ./bin/oslite.sys Makefile # フロッピーディスクのイメージを作成して、IPL部分を書き込む mformat -f 1440 -C -B ./bin/ipl.bin -i ./bin/fdimage/oslite.img :: # イメージファイルにoslite.sysを書き込み mcopy -i ./bin/fdimage/oslite.img ./bin/oslite.sys :: ./bin/ipl.bin : $(SRC)/ipl.asm Makefile $(NASM) -f bin -o ./bin/ipl.bin $(SRC)/ipl.asm -l ./lst/ipl.lst ./bin/oslite.sys : ./bin/asmhead.bin ./bin/oslite.bin Makefile cat ./bin/asmhead.bin ./bin/oslite.bin > ./bin/oslite.sys ./bin/oslite.bin : ./bin/bootpack.bin ./bin/nasmfunc.obj ./bin/startup.o Makefile ld -e LiteMain --Map ./map/oslite.map -n -Ttext 0xc200 -T ./lds/oslite.lds \ -static -o ./bin/oslite.bin ./bin/bootpack.bin ./bin/nasmfunc.obj ./bin/asmhead.bin : $(SRC)/asmhead.asm Makefile $(NASM) -f bin -o ./bin/asmhead.bin $(SRC)/asmhead.asm -l ./lst/asmhead.lst ./bin/bootpack.bin : $(SRC)/bootpack.c Makefile $(CC) $(CFLAGS) $(SRC)/bootpack.c -o ./bin/bootpack.bin ./bin/nasmfunc.obj : $(SRC)/nasmfunc.asm Makefile $(NASM) -f elf $(SRC)/nasmfunc.asm -o ./bin/nasmfunc.obj -l ./lst/nasmfunc.lst ./bin/startup.o : $(SRC)/startup.c Makefile $(CC) $(CFLAGS) $(SRC)/startup.c -o ./bin/startup.o clean : rm -f ./lst/*.lst rm -f ./bin/*.bin rm -f ./bin/*.o rm -f ./bin/*.obj rm -f ./bin/*.sys rm -f ./map/*.map rm -f ./bin/fdimage/*.img
これでmakeを実行してどうなるかを試します。
ちなみに、今までVMWareを使用していましたが、
今回からはqemuを使用します。
理由は、デバッグ出来るからです。
といっても、ソースレベルのデバッグではなく、
機械語(アセンブラ)レベルのデバッグです。
でも、これがあるのと無いのでは、大きく違います。
デバッグのやり方は、
$ qemu -s -S -fda ./bin/fdimage/oslite.img -redir tcp:5555:127.0.0.1:1234 &
でqemuを実行して、別のコンソールで
$ gdb
(gdb) target remote 127.0.0.1:1234
↑qemuに接続
(gdb) display/i $pc
↑アセンブリ言語に変換して表示
(gdb) break *0x00XXXXXX
↑メモリにブレークポイントをつける(XXXXの部分がアドレスになります)
(gdb) c
↑実行
(gdb) nexti
↑次のアドレスに移動
と言う感じです。
この方法が分かってから、一気にやりやすくなりました。
(同時に、ELF形式を使うのを諦められました)
ちなみに、実行している画面はというと・・・
まだ真っ黒なんです。これが。
と言う事で、3日目 その2は以上です。
ひじょ〜に難産でした。
次回は、4日目「C言語と画面表示の練習」です。
次は少し画面に色がつく予定です。
これから少しずつOSらしくなって行く様なので楽しみです。
PR
この記事にコメントする