OS自作入門 8日目/30日(マウス制御)
OS自作入門 8日目/30日(マウス制御)
1.はじめに
8日目では、マウスの制御を行う
自作sprintf
関数が負の数を表示できるものではなかったので、表示できるように改良した。そのほかについては、特に躓くところはなし。
2.harib05a,b,c
マウスからの信号を解読し、情報を画面に出力する。
bootpack.c
の追記・修正orisprintf.c
の修正
修正内容は下記の通り
No. | 対象ファイル | 修正内容 |
---|---|---|
1 | bootpack.c | struct MOUSE_DEC 構造体の宣言関数 enable_mouse の修正関数 mouse_decode の追加 |
2 | orisprintf.c | 負の数に対応していなかったため、負の数に対応できるように修正5日目に使用した''sprintf''の代替関数(負の数未対応) |
3.harib05d
harib05cで情報の解読まではできていたが、マウスは動いてなかった。 今回の改良で実際にマウスが動くようになる。
bootpack.c
の追記・修正
修正内容は本の通りであるため、省略
OS自作入門 7日目/30日(バッファの実装とマウスの割り込み)
OS自作入門 7日目/30日(バッファの実装とマウスの割り込み)
1.はじめに
7日目では、キーボードとマウスの割り込みによって取得できるデータを画面に表示する。データを取得するにあたり、バッファの実装を行う。
7日目も特に躓くところはなし。
2.harib04a
キーボードの割り込みを検知し、16進数を表示する。
int.c
の修正bootpack.h
の追記・修正
修正内容は下記の通り
No. | 対象ファイル | 修正内容 |
---|---|---|
1 | int.c | void inthandler21(int *esp) 関数の修正#define PORT_KEYDAT 0x0060 の追記自作関数の sprintf(s, "%02X", data); をsprintf(s, "%x", data); へ変更 |
2 | bootpack.h | int io_in8(int port); 関数宣言の追記 |
3.harib04b
harib04aの文字表示を割り込み処理関数ではなく、Main関数内で実施するように変更
int.c
の修正bootpack.c
の追記・修正bootpack.h
の追記・修正
修正内容は下記の通り
No. | 対象ファイル | 修正内容 |
---|---|---|
1 | int.c | #define PORT_KEYDAT 0x0060 の追記struct KEYBUF keybuf; の追記void inthandler21(int *esp) 関数の修正 |
2 | bootpack.c | extern struct KEYBUF keybuf; 関数の宣言for 分の追加 |
3 | bootpack.h | void io_stihlt(void); 関数宣言の追記struct KEYBUF 構造体の宣言 |
4.harib04c,d
バッファを実装
int.c
の修正bootpack.c
の追記・修正bootpack.h
の追記・修正
修正内容は下記の通り
No. | 対象ファイル | 修正内容 |
---|---|---|
1 | int.c | バッファへの書き込みの処理を追記 |
2 | bootpack.c | バッファからの読み出しの処理を追記 |
3 | bootpack.h | struct KEYBUF の要素を変更 |
5.harib04e
FIFOバッファの整理
マウスでもFIFOを利用できるように、書き直す。やる内容は下記の通り
fifo.c
の作成int.c
の修正bootpack.c
の追記・修正bootpack.h
の追記・修正Makefile
の修正
修正内容は下記の通り
No. | 対象ファイル | 修正内容 |
---|---|---|
1 | fifo.c | 新規作成 |
2 | int.c | struct FIFO8 keyfifo; へ構造体名を変更void inthandler21(int *esp) の関数の変更 |
3 | bootpack.c | extern struct FIFO8 keyfifo; へ修正配列 keybuf[32] の追加fifo8_init(&keyfifo, 32, keybuf); の追加for 分の修正 |
4 | bootpack.h | struct FIFO8 の追加struct KEYBUF の削除 |
5 | Makefile | fifo.c を含めてコンパイルを実行するように変更 |
Makefileは下記の通り
# --- オプション CFLAGS = -c -m32 -march=i486 -fno-pic -nostdlib # --- ファイル名 IMG=haribote.img IPL=ipl.bin HD=asmhead.bin FASM=asmfunc.asm FOB=asmfunc.o BT=bootpack.c BHRB=bootpack.hrb LD=har.ld HSYS=haribote.sys MFONT=makefont.c OFONT=makefont.o FONT=font.c CSPR=orisprintf.c OTBL=dsctbl.o OGRA=graphic.o OINT=int.o OFIFO=fifo.o MAKEBHRB=$(BT) $(FOB) $(FONT) $(CSPR) $(OTBL) $(OGRA) $(OINT) $(OFIFO) #--- フォントの作成 $(OFONT) : $(MFONT) gcc $(MFONT) -o $(OFONT) $(FONT) : $(OFONT) ./$(OFONT) #--- イメージファイルの作成 $(FOB) : $(FASM) nasm -g -f elf $(FASM) -o $(FOB) $(BHRB) : $(LD) $(MAKEBHRB) gcc -march=i486 -m32 -fno-pic -nostdlib -T $(LD) -g $(MAKEBHRB) -o $(BHRB) $(HSYS) : $(HD) $(BHRB) cat $(HD) $(BHRB) > $(HSYS) $(IMG) : $(IPL) $(HSYS) mformat -f 1440 -C -B $(IPL) -i $(IMG) :: mcopy $(HSYS) -i $(IMG) :: # 一般規則 %.bin : %.asm nasm $*.asm -o $*.bin %.o : %.c gcc $*.c $(CFLAGS) -o $*.o # コマンド img : make $(IMG) dump : hexdump -C $(IMG) clean : rm -f *.lst *.bin *.sys *.img *.hrb *.o $(OFONT) $(FONT) $(OSPR)
6.harib04f,g
マウスでもFIFOを利用できるように、書き直す。やる内容は下記の通り
int.c
の修正bootpack.c
の追記・修正
修正内容は下記の通り
No. | 対象ファイル | 修正内容 |
---|---|---|
1 | int.c | struct FIFO8 mousefifo; 構造体の宣言関数 void inthandler2c(int *esp) の変更 |
2 | bootpack.c | 変数mousefifo の追加関数 enable_mouse````init_keyboard の追加ほか |
OS自作入門 6日目/30日(割り込み処理)
OS自作入門 6日目/30日(割り込み処理)
1.はじめに
6日目では、bootpack.c
を機能ごとに分割する。また、キーボードの割り込みとマウスの割り込みを実装する。
※割り込みを検知するのみで、何が押されたのかは判断できない。
6日目も5日目と同様に、特に躓くところはなし。
2.使用したアセンブラの命令
NASKの命令(30日本著者作成のアセンブラ) NASMの命令(今回使用のフリーのアセンブラ) において違いなし
命令 | 名前 | 内容 |
---|---|---|
PUSHAD | push all double | EAX, ECX, EDX, EBX, ESP, EBP, ESI, EDIの8つのレジスタをPUSHする |
POPAD | pop all double | EAX, ECX, EDX, EBX, ESP, EBP, ESI, EDIの8つのレジスタへPOPする |
CALL | call | 関数を呼び出す |
IRETD | Interrupt return (32-bit operand size) | Returns program control from an exception or interrupt handler |
3.harib03a,b,c
機能毎にソースファイルの分割したり、Makefileに新しい記法を用いたり、ヘッダファイルの整理し不要な記述を省く。
特に躓くようなところはなし。
Makefileは下記の通り
# --- オプション CFLAGS = -c -m32 -march=i486 -fno-pic -nostdlib # --- ファイル名 IMG=haribote.img IPL=ipl.bin HD=asmhead.bin FASM=asmfunc.asm FOB=asmfunc.o BT=bootpack.c BHRB=bootpack.hrb LD=har.ld HSYS=haribote.sys MFONT=makefont.c OFONT=makefont.o FONT=font.c CSPR=orisprintf.c OTBL=dsctbl.o OGRA=graphic.o MAKEBHRB=$(BT) $(FOB) $(FONT) $(CSPR) $(OTBL) $(OGRA) #--- フォントの作成 $(OFONT) : $(MFONT) gcc $(MFONT) -o $(OFONT) $(FONT) : $(OFONT) ./$(OFONT) #--- イメージファイルの作成 $(FOB) : $(FASM) nasm -g -f elf $(FASM) -o $(FOB) $(BHRB) : $(LD) $(MAKEBHRB) gcc -march=i486 -m32 -fno-pic -nostdlib -T $(LD) -g $(MAKEBHRB) -o $(BHRB) $(HSYS) : $(HD) $(BHRB) cat $(HD) $(BHRB) > $(HSYS) $(IMG) : $(IPL) $(HSYS) mformat -f 1440 -C -B $(IPL) -i $(IMG) :: mcopy $(HSYS) -i $(IMG) :: # 一般規則 %.bin : %.asm nasm $*.asm -o $*.bin %.o : %.c gcc $*.c $(CFLAGS) -o $*.o # コマンド img : make $(IMG) dump : hexdump -C $(IMG) clean : rm -f *.lst *.bin *.sys *.img *.hrb *.o $(FONT)
4.harib03d
PIC(programmable interrupt controller)の初期化するコードを実装する。
やること
int.c
の作成bootpack.h
へ追記Makefile
の修正
特に躓くところはなし。Makefile
を下記に示す。
# --- オプション CFLAGS = -c -m32 -march=i486 -fno-pic -nostdlib # --- ファイル名 IMG=haribote.img IPL=ipl.bin HD=asmhead.bin FASM=asmfunc.asm FOB=asmfunc.o BT=bootpack.c BHRB=bootpack.hrb LD=har.ld HSYS=haribote.sys MFONT=makefont.c OFONT=makefont.o FONT=font.c CSPR=orisprintf.c OTBL=dsctbl.o OGRA=graphic.o OINT=int.o MAKEBHRB=$(BT) $(FOB) $(FONT) $(CSPR) $(OTBL) $(OGRA) $(OINT) #--- フォントの作成 $(OFONT) : $(MFONT) gcc $(MFONT) -o $(OFONT) $(FONT) : $(OFONT) ./$(OFONT) #--- イメージファイルの作成 $(FOB) : $(FASM) nasm -g -f elf $(FASM) -o $(FOB) $(BHRB) : $(LD) $(MAKEBHRB) gcc -march=i486 -m32 -fno-pic -nostdlib -T $(LD) -g $(MAKEBHRB) -o $(BHRB) $(HSYS) : $(HD) $(BHRB) cat $(HD) $(BHRB) > $(HSYS) $(IMG) : $(IPL) $(HSYS) mformat -f 1440 -C -B $(IPL) -i $(IMG) :: mcopy $(HSYS) -i $(IMG) :: # 一般規則 %.bin : %.asm nasm $*.asm -o $*.bin %.o : %.c gcc $*.c $(CFLAGS) -o $*.o # コマンド img : make $(IMG) dump : hexdump -C $(IMG) clean : rm -f *.lst *.bin *.sys *.img *.hrb *.o $(OFONT) $(FONT) $(OSPR)
5.harib03e
キーボードとマウスの割り込みを有効化するコードを実装する。
やること
int.c
の追記asmfunc.asm
へ追記(30日本ではnaskfunc.nas
)dsctbl.c
の修正bootpack.h
へ追記bootpack.c
へ追記
特に躓くところはなし。30日本の追記・編集箇所と同じ個所を追記・編集する
OS自作入門 5日目/30日(文字出力)
OS自作入門 5日目/30日(文字出力)
1.はじめに
5日目では、文字の出力を行う。躓きどころは下記の2点
- フォントの作成
sprintf
フォントの作成についても、著者オリジナル実行ファイルを使用せずに、作成する。
sprintf
については、ソースファイルをそのまま実行するとエラーになるため、sprintf
の代わりの関数を作成する。
2.harib02e
スクリーンへ文字の出力を行う。
harib02eでも著者のオリジナル実行ファイルが使用されているので、自作本とは異なる方法でimgファイルを作成する。
自作本でのimgファイルの作成手順
- フォントtextファイルから、makefont.exe(著者オリジナル)でbinファイルを作成
- bin2obj.exe(著者オリジナル)でbinファイルからobjファイルを作成
- 他のオブジェクトファイルと合体させ、bimファイルを作成(以降は、前回説明した流れと同じ)
- bimファイルからhrbファイルを作成
- bimファイルとbinファイルからsysファイルを作成
- sysファイルとブートローダ部のbinファイルからimgファイルを作成
著者オリジナルのファイルを使用しない、imgファイルを作成手順
- フォントtextファイルを、フォントcファイルに変換
- 作成したフォントcファイルと他のファイルをリンクさせ、bootpackのhrbファイルを作成(以降は、前回説明した流れと同じ)
- hrbファイルとbinファイルからsysファイルを作成
- sysファイルとブートローダ部のbinファイルからimgファイルを作成
最初の手順1. フォントtextファイルを、フォントcファイルに変換は、CD内のhankaku.txtを使用する。textファイルからcファイルの変換については、下記サイトを参考にプログラムを新規に作成。
GDT(グローバルディスクリプタテーブル) | OS自作入門 5日目-1 【Linux】 | サラリーマンがハッカーを真剣に目指す
今回のMakefileは、次の通り
IMG=haribote.img IPL=ipl.bin IASM=ipl.asm HD=asmhaed.bin HASM=asmhead.asm FASM=asmfunc.asm FOB=asmfunc.o BT=bootpack.c BHRB=bootpack.hrb LD=har.ld HSYS=haribote.sys MFONT=makefont.c #【今回追加】 OFONT=font.o #【今回追加】 FONT=font.c #【今回追加】 #--- 【今回追加始まり】フォントの作成 $(OFONT) : $(MFONT) gcc $(MFONT) -o $(OFONT) $(FONT) : $(OFONT) ./$(OFONT) #--- 【今回追加終わり】 #--- イメージファイルの作成 $(IPL) : $(IASM) nasm $(IASM) -o $(IPL) $(HD) : $(HASM) nasm $(HASM) -o $(HD) $(FOB) : $(FASM) nasm -g -f elf $(FASM) -o $(FOB) $(BHRB) : $(BT) $(LD) $(FOB) $(FONT) #【今回修正】 gcc -march=i486 -m32 -fno-pic -nostdlib -T $(LD) -g $(BT) $(FONT) $(FOB) -o $(BHRB) $(HSYS) : $(HD) $(BHRB) cat $(HD) $(BHRB) > $(HSYS) $(IMG) : $(IPL) $(HSYS) mformat -f 1440 -C -B $(IPL) -i $(IMG) :: mcopy $(HSYS) -i $(IMG) :: img : make $(IMG) dump : hexdump -C $(IMG) clean : rm -f *.lst *.bin *.sys *.img *.hrb *.o
3.harib02g
変数の内容を表示する。
変更箇所は下記の通り。
bootpack.c
変更前 | 変更後 | 説明 |
---|---|---|
#include<stdio.h> | 削除 | |
extern void orisprintf(char str, char fmt, ...); | 新たにorisprintfのソースファイルを作成したので、変数定義箇所に追記 |
orisprintf.c
sprintf
が使用できないため、代わりにorisprintf
関数を作成
下記サイトを参考、関数名は適当に変更
sprintfを実装する | OS自作入門 5日目-2 【Linux】 | サラリーマンがハッカーを真剣に目指す
Makefileは下記の通り
IMG=haribote.img IPL=ipl.bin IASM=ipl.asm HD=asmhaed.bin HASM=asmhead.asm FASM=asmfunc.asm FOB=asmfunc.o BT=bootpack.c BHRB=bootpack.hrb LD=har.ld HSYS=haribote.sys MFONT=makefont.c OFONT=font.o FONT=font.c CSPR=orisprintf.c #--- フォントの作成 $(OFONT) : $(MFONT) gcc $(MFONT) -o $(OFONT) $(FONT) : $(OFONT) ./$(OFONT) #--- イメージファイルの作成 $(IPL) : $(IASM) nasm $(IASM) -o $(IPL) $(HD) : $(HASM) nasm $(HASM) -o $(HD) $(FOB) : $(FASM) nasm -g -f elf $(FASM) -o $(FOB) $(BHRB) : $(BT) $(LD) $(FOB) $(FONT) $(CSPR) gcc -march=i486 -m32 -fno-pic -nostdlib -T $(LD) -g $(BT) $(FONT) $(FOB) $(CSPR) -o $(BHRB) $(HSYS) : $(HD) $(BHRB) cat $(HD) $(BHRB) > $(HSYS) $(IMG) : $(IPL) $(HSYS) mformat -f 1440 -C -B $(IPL) -i $(IMG) :: mcopy $(HSYS) -i $(IMG) :: img : make $(IMG) dump : hexdump -C $(IMG) clean : rm -f *.lst *.bin *.sys *.img *.hrb *.o $(OFONT) $(FONT) $(OSPR)
4.harib02h
関数の追加等があるが、特に躓くところはなく、今までの修正内容の通りで問題なし
OS自作入門 4日目/30日(画面の出力)
OS自作入門 4日目/30日(画面の出力)
1.はじめに
4日目では、新規のアセンブリ命令及びソースコードの変更点ついて解説を行う。
4日目のコード自体は特に詰まるところはなし。
2.使用したアセンブラの命令
NASKの命令(30日本著者作成のアセンブラ) NASMの命令(今回使用のフリーのアセンブラ) において違いなし
命令 | 名前 | 内容 |
---|---|---|
CLI | clear interrupt flag | interrupt flagを0にする |
STI | set interrupt flag | interrupt flagを立てる |
PUSHFD | push flags double-word | flagをdouble-wordでプッシュする |
POPFD | pop flags double-word | flagをdouble-wordでポップする |
3.harib01f
編集箇所は下記の通り
変更前 | 変更後 | 内容 |
---|---|---|
[FORMAT "WCOFF"] | 削除 | |
[INSTRSET "i486p"] | 削除 | |
[BITS 32] | 削除 | |
[FILE "naskfunc.nas"] | 削除 | |
[SECTION .text] | section .textに記載を変更 |
解決できていない疑問点
アセンブリで記述した関数をC言語で呼ぶ出す場合、アセンブリ側の関数は、先頭に_を記載しなければいけないが、記載をするとエラーを吐く。
下記のエラーの内容は、io_hlt
は定義されていないである。この際のアセンブリ側の関数名は_io_hlt
である。
undefined reference to `io_hlt' (略)
アセンブリ側の関数名の先頭から_を削除することで解消する。
この問題については、解決次第追記予定。
OS自作入門 3日目/30日(32ビットモードとC言語)
OS自作入門 3日目/30日(32ビットモードとC言語)
1.はじめに
3日目では、新たなアセンブラの命令やリンカの作成方法やデバッグの方法について解説を行う。3日目も作者オリジナルのプログラムが登場するが、オリジナルプログラムを使用せずに実行する。
<躓きどころ>
今までは、qemuを実行するのは下記命令でよかったが、
qemu-system-i386 helloos.img
フロッピーディスクから読み込むことを明示するため、-fdaを追加する。
qemu-system-i386 -fda helloos.img
2.新しく使用したアセンブラの命令
NASKの命令(30日本著者作成のアセンブラ) NASMの命令(今回使用のフリーのアセンブラ) において違いなし
命令 | 名前 | 内容 |
---|---|---|
JC | jump if carry | キャリーフラグが立っている場合、ジャンプする |
JNC | jump if not carry | キャリーフラグが立っていない場合、ジャンプする |
JBE | jump if below or equal | 比較した結果、それ以下の場合ジャンプする |
JB | jump if below | 比較した結果、それより小さい場合ジャンプする |
EQU | equal | 定数を宣言する際に使用 |
OUT | Output Data to I/O Port | データをレジスタ等に出力する |
NOP | No Operation | 何も実行しない |
CALL | call subroutine | サブルーチン(関数)を呼び出す |
LGDT | Load Descriptor Tables | global descriptor table registerにアドレスを読み込む |
AND | Bitwise AND | 論理積を計算する |
OR | Bitwise OR | 論理和を計算する |
JNZ | jumps only if the zero flag is not set | zero flagがセットされていない場合jumpする |
SHR | Bitwise Logical Shift Right | 右へ指定bitシフト演算する |
JZ | jumps only if the zero flag is set | zero flagがセットされている場合jumpする |
RET | Return from Procedure Call | 呼び出し元に戻る |
ALIGNB | Data Alignment | アライメントを行う |
3.harib00e,f,g
使用したMakefile(harib00e)
IMG=haribote.img IPL=ipl.bin IASM=ipl.asm HSYS=haribote.sys HASM=haribote.asm $(IMG): $(IPL) $(HSYS) mformat -f 1440 -C -B $(IPL) -i $(IMG) :: mcopy $(HSYS) -i $(IMG) :: $(IPL): $(IASM) nasm $(IASM) -o $(IPL) $(HSYS): $(HASM) nasm $(HASM) -o $(HSYS) img: make $(IMG) clean: rm -f $(IMG) $(IPL) $(HSYS)
今回、新たに使用する命令mcopy
の書式は下記の通り
mcopy システムファイル -i 出力イメージファイル ::
オプションの解説
オプション名 | 説明 |
---|---|
-i | マニュアルに記載なし。下記を参照 |
mcopyの引数である、システムファイル
と出力イメージファイル
をそれぞれテキストファイルにした場合は、出力イメージファイル
にシステムファイル
の中身を上書きするが、
sysファイル
とimgファイル
の組み合わせの場合、imgファイルにsysファイルが適切な場所に組み込まれる。
出力イメージファイルについても、元の容量から変化がない。いろいろ調べたが不明。
4.harib00i
書籍では、作者オリジナルのソフトが使用されており、下記の手順でイメージファイルが作成されている。
- cファイルからgasファイルを作成
- gasファイルからnasファイルを作成
- nasファイル(3個) からobjファイル(bootpack)とbinファイル(ipl,asmhead)を作成
- objファイルからbimファイルを作成
- bimファイルからhrbファイルを作成
- hrbファイルとbinファイルを結合し、sysファイルを作成
- sysファイルとbinファイルから、imgファイルを作成
今回もオリジナルのファイルは使わない方法で作成する。手順は下記の通り
- asmファイル(2個) からbinファイル(ipl,asmhead)を作成
- cファイルからhrbファイルを作成
- hrbファイルとbinファイルを結合し、sysファイルを作成
- sysファイルとbinファイルから、imgファイルを作成
躓きどころ
asmhead.asmについて下記のように修正する
行数 | 修正前 | 修正後 |
---|---|---|
58 | [INSTRSET "i486p"] | 削除 |
134,145 | ALIGNB 16 | ALIGN 16, DB 0 |
リンカ
cファイルからhrbファイルを作成する際にリンカが必要になるため作成する。
現時点で作成方法等がわからなかったため、下記サイトを参照した。
OUTPUT_FORMAT("binary"); OUTPUT_ARCH(i386) SECTIONS { .head 0x0 : { LONG(64 * 1024) /* 0 : stack+.data+heap の大きさ(4KBの倍数) */ LONG(0x69726148) /* 4 : シグネチャ "Hari" */ LONG(0) /* 8 : mmarea の大きさ(4KBの倍数) */ LONG(0x310000) /* 12 : スタック初期値&.data転送先 */ LONG(SIZEOF(.data)) /* 16 : .dataサイズ */ LONG(LOADADDR(.data)) /* 20 : .dataの初期値列のファイル位置 */ LONG(0xE9000000) /* 24 : 0xE9000000 */ LONG(HariMain - 0x20) /* 28 : エントリアドレス - 0x20 */ LONG(0) /* 32 : heap領域(malloc領域)開始アドレス */ } .text : { *(.text) } .data 0x310000 : AT ( ADDR(.text) + SIZEOF(.text) ) { *(.data) *(.rodata*) *(.bss) } /DISCARD/ : { *(.eh_frame) } }
Makefile
リンカが増えたことでMakefaileに変更を加えた。
hrbファイルを作成する際に、gcc
を使用する必要があるため、ubuntuにインストールする
sudo apt install gcc
以下に、Makefileの内容を記載する。
主な変更点として、gccによるコンパイルの行の追加とcatによるsysファイルの作成とdumpの追加の3点である。
3点目については必須項目ではなく、出力したimgファイルのバイナリを簡単に確認するためMakefile内に記載した。
IMG=haribote.img IPL=ipl.bin IASM=ipl.asm HD=asmhead.bin HASM=asmhead.asm BT=bootpack.c BHRB=bootpack.hrb LD=har.ld HSYS=haribote.sys $(IPL) : $(IASM) nasm $(IASM) -o $(IPL) $(HD) : $(HASM) nasm $(HASM) -o $(HD) $(BHRB) : $(BT) $(LD) gcc -march=i486 -m32 -fno-pic -nostdlib -T $(LD) $(BT) -o $(BHRB) $(HSYS) : $(HD) $(BHRB) cat $(HD) $(BHRB) > $(HSYS) $(IMG) : $(IPL) $(HSYS) mformat -f 1440 -C -B $(IPL) -i $(IMG) :: mcopy $(HSYS) -i $(IMG) :: img : make $(IMG) dump : hexdump -C $(IMG) clean : rm -f *.lst *.bin *.sys *.img *.hrb
gcc引数 | 説明 |
---|---|
-march=i486 | i486向けのコードを生成する |
-m32 | IA(Intel Architecture) 32向けにコードを生成するようコンパイラーに指示 |
-fno-pic | Generate position-independent code (PIC)を用いない。 |
-nostdlib | リンク時に標準システムスタートアップファイルや標準システムライブラリを使用しない |
-T | 後に続く引数をリンカスクリプトとして使用 |
-o | コンパイルを実行し、オブジェクトファイルを出力する |
degug
degug用に新たにバッチファイルを作成した。qemuで動作確認用のバッチファイルから新たに3つの引数を追加する。
追加引数 | 説明 |
---|---|
-gdb | gdbでデバックするための引数 |
tcp::22222 | デバックするために |
-S | qemu起動時点で動作を停止するため |
debug用batファイル
qemu-system-i386 -m 32 -fda haribote.img -gdb tcp::22222 -S
使い方は、imgファイルをmakeした後、debug用batファイルを使用する。qemuが起動したことを確認し、新たに別のプロンプトを立ち上げ下記コマンドを入力する。
>gdb GNU gdb (GDB) 7.8.1 (いろいろ出力されるが省略) (gdb) target remote localhost:22222 Remote debugging using localhost:22222 0x0000fff0 in ?? ()
上記で、新たに立ち上げたプロンプトからデバックを行うことができる。参考にいくつか実行例を下記に示す。
①ブレイクポイントの設定
iplの読み込み先頭アドレスにブレークポイントを設定
(gdb) b *0x7c00 Breakpoint 1 at 0x7c00
②ブレイクポイントまで実行
設定したブレイクポイントまで実行。0x7c00のブレイクポイントまで進んだことを確認できる。
(gdb) c Continuing. Breakpoint 1, 0x00007c00 in ??
③命令の確認
ブレイクポイントの命令内容を確認。jmp 0x7c50であることを確認できる。
(gdb) x/i $eip => 0x7c00: jmp 0x7c50
コマンドライン上でファイルをダンプ
書式 |
---|
hexdump [オプション] [ファイル名...] |
hexdump haribote.img 0000000 4eeb 4890 5241 4249 544f 0045 0102 0001 0000010 e002 4000 f00b 0009 0012 0002 0000 0000 0000020 0000 0000 0000 5d29 ab8c 4e03 204f 414e 0000030 454d 2020 2020 4146 3154 2032 2020 0000 0000040 0000 0000 0000 0000 0000 0000 0000 0000 0000050 00b8 8e00 bcd0 7c00 d88e 20b8 8e08 b5c0 (以下略)
5.harib00j
asmfunc.asmを新たに作成して、HLTを実装する。新たにアセンブリファイルが増えたので、Makefile等の修正を行う。
asmhead.asmについて下記のように修正する
行数 | 修正前 | 修正後 |
---|---|---|
4 | [FORMAT "WCOFF"] | 削除 |
5 | [BITS 32] | 削除 |
10 | [FILE "naskfunc.nas"] | 削除 |
17 | [SECTION .text] | 削除 |
asmhead.asm追加に伴いMakefileを修正する。
IMG=haribote.img IPL=ipl.bin IASM=ipl.asm HD=asmhed.bin HASM=asmhead.asm FASM=asmfunc.asm FOB=asmfunc.o BT=bootpack.c BHRB=bootpack.hrb LD=har.ld HSYS=haribote.sys $(IPL) : $(IASM) nasm $(IASM) -o $(IPL) $(HD) : $(HASM) nasm $(HASM) -o $(HD) $(FOB) : $(FASM) nasm -g -f elf $(FASM) -o $(FOB) $(BHRB) : $(BT) $(LD) $(FOB) gcc -march=i486 -m32 -fno-pic -nostdlib -T $(LD) -g $(BT) $(FOB) -o $(BHRB) $(HSYS) : $(HD) $(BHRB) cat $(HD) $(BHRB) > $(HSYS) $(IMG) : $(IPL) $(HSYS) mformat -f 1440 -C -B $(IPL) -i $(IMG) :: mcopy $(HSYS) -i $(IMG) :: img : make $(IMG) dump : hexdump -C $(IMG) clean : rm -f *.lst *.bin *.sys *.img *.hrb *.o
nasm引数 | 説明 |
---|---|
-g | Enabling Debug Information. デバッグ情報の出力を有効にする。 |
-f elf | 出力するデバックのファイル形式をelfに指定する |
gcc引数 | 説明 |
---|---|
-g | コンパイル時にデバッグ情報の生成を有効にする。 |
6.harib00iとharib00jの比較
horib00iとharib00jそれぞれのimgファイルを作成し、バイナリがどのように異なるかを確認する。
差異箇所 | harib00i | harib00j | 解説 |
---|---|---|---|
0x0027-0x002D | 49 B5 FD 36 | 5D 8C AB 03 | ブートローダ部 |
0x260E-0x260F | 86 08 | DD 06 | 分かったら追記予定 |
0x2616-0x2617 | 86 08 | DD 06 | 分かったら追記予定 |
0x261C | 59 | 72 | 分かったら追記予定 |
0x4344 | 29 | 42 | 分かったら追記予定 |
0x434C | 04 | 10 | 分かったら追記予定 |
0x4354-0x4358 | 55 89 E5 EB FE | ALL 00 | 分かったら追記予定 |
0x4360-0x4371 | ALL 00 | 55 89 E5 EB FE 66 90 66 90 66 90 66 90-66 90 90 F4 C3 | 分かったら追記予定 |
OS自作入門 2日目/30日(Makefile作成)
OS自作入門 2日目/30日(Makefile作成)
1.はじめに
2日目では、使用するソースファイルの中身についての解説とMakefileについて解説を行う。
その前に、helloos5の躓きどころとして、58行目のRESB 0x7dfe-$
を書き換えるときに、
TIMES 0x7dfe-($-$$) DB 0
としてしまい、正しく実行できない。
正しくは、TIMES 0x7dfe-0x7c00-($-$$) DB 0
ORG命令でメモリの0x7c00から読み込むように指定されているため、その分引く必要がある。
2.使用したアセンブラの命令
NASKの命令(30日本著者作成のアセンブラ) NASMの命令(今回使用のフリーのアセンブラ) において違いなし
命令 | 名前 | 内容 |
---|---|---|
ORG | origin | プログラムの始まりのメモリを明示する |
JMP | jump | 指定のラベルにジャンプする |
MOV | move | 代入を実行 MOV A,Bと記載した場合、A=Bを行う |
ADD | add | 足し算を実行 ADD A,Bと記載した場合、A=A+Bを行う |
CMP | compare | 比較を行う |
JE | jump if equal | 比較命令CMPの結果が正しければ指定のラベルにジャンプ |
HLT | halt | 外部の変化があるまで待機 |
ORG命令については、下記リンクを参照
3.edimg.exeの代役
イメージファイルをブートセクタとその他に分けて作成する方法へ切り替える。利点は、ブートセクタは今後編集する機会が少ないため。
具体的には、ブートセクタをnasm(ファイル名はipl.asmとする)で作成し、残りの部分については別で作成する。その際に、30日本では著者作成のオリジナルツールを使用していたが、代替としてmformat
を使用する。
WSLのubuntu初期設定ではmformatはインストールされていないため、下記コマンドでインストールを行う。
$ sudo apt install mtools
今回使用するmformatの書式は下記の通り
$ mformat -f 1440 -C -B ブートファイル -i 出力ファイル ::
オプションの解説
オプション名 | 説明 |
---|---|
-f | ファイルサイズを指定。1440を指定すると1440kBとなる |
-C | MS-DOSファイルシステムをインストールする用のファイルを作成 |
-B | 指定されたブートストアを書き込む |
-i | マニュアルに記載なし。下記を参照 |
mformatのマニュアルについては下記を参照
そのほか参考にしたページ
4.Make, Makefileについて
Make, Makefileとは?
Makeはプログラムのビルドを自動化するツールであり、ビルドの方法はMakefileに記述する。
WSLのubuntu初期設定ではmakeはインストールされていないため、下記コマンドでインストールを行う。
$ sudo apt install make
基本的な書式
Makefileの基本的な書式①
target: prerequisite recipe
名前 | 説明 |
---|---|
target | 出力するファイル名。makeコマンドを実行する際の引数でも使用する。targetの後には: を記述する |
prerequisite | targetを出力する際の入力ファイル。複数の場合は半角スペースで区切る |
recipe | コマンドを記載する。prerequisiteが一つでも変更されていれば実行する。行頭は必ずTABを入力しなければならない |
Makefileの基本的な書式②
clean: recipe
名前 | 説明 |
---|---|
clean | targetはcleanでprerequisiteはとらない |
recipe | コマンドを記載する。一般的にrm -f 消去したいファイル名 。行頭は必ずTABを入力しなければならない |
Makefileの基本的な書式③
IPL=ipl.bin ipl: ipl.asm nasm ipl.asm -o $(IPL)
任意の文字列を変数として扱うことができる。1行目でIPLを変数として、ipl.binを代入している。 4行目の$(IPL)では、IPLを展開している。4行目は下記と同じ意味になる。
nasm ipl.asm -o ipl.bin
使用したMakefile
IMG=helloos.img IPL=ipl.bin ipl: ipl.asm nasm ipl.asm -o $(IPL) img: $(IPL) mformat -f 1440 -C -B $(IPL) -i $(IMG) :: clean: rm -f $(IMG) $(IPL)
Makeコマンドの使い方
基本的なコマンドは下記の通り
$make target
今回は、make ipl
でipl.binを作成し、make img
でhelloos.imgを作成した。
targetを省略するとMakefileの先頭targetを実施する。
GNUのmakeマニュアル
その他参考にしたページ