非情報系インフラエンジニアの情報系お勉強

OS自作、ネットワーク、セキュリティの備忘録

OS自作入門 8日目/30日(マウス制御)

OS自作入門 8日目/30日(マウス制御)

1.はじめに

8日目では、マウスの制御を行う

自作sprintf関数が負の数を表示できるものではなかったので、表示できるように改良した。そのほかについては、特に躓くところはなし。

2.harib05a,b,c

マウスからの信号を解読し、情報を画面に出力する。

  1. bootpack.cの追記・修正
  2. orisprintf.cの修正

修正内容は下記の通り

No. 対象ファイル 修正内容
1 bootpack.c struct MOUSE_DEC構造体の宣言
関数enable_mouseの修正
関数mouse_decodeの追加
2 orisprintf.c 負の数に対応していなかったため、負の数に対応できるように修正5日目に使用した''sprintf''の代替関数(負の数未対応)

3.harib05d

harib05cで情報の解読まではできていたが、マウスは動いてなかった。 今回の改良で実際にマウスが動くようになる。

  1. bootpack.cの追記・修正

修正内容は本の通りであるため、省略

OS自作入門 7日目/30日(バッファの実装とマウスの割り込み)

OS自作入門 7日目/30日(バッファの実装とマウスの割り込み)

1.はじめに

7日目では、キーボードとマウスの割り込みによって取得できるデータを画面に表示する。データを取得するにあたり、バッファの実装を行う。

7日目も特に躓くところはなし。

2.harib04a

キーボードの割り込みを検知し、16進数を表示する。

  1. int.cの修正
  2. 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関数内で実施するように変更

  1. int.cの修正
  2. bootpack.cの追記・修正
  3. 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

バッファを実装

  1. int.cの修正
  2. bootpack.cの追記・修正
  3. bootpack.hの追記・修正

修正内容は下記の通り

No. 対象ファイル 修正内容
1 int.c バッファへの書き込みの処理を追記
2 bootpack.c バッファからの読み出しの処理を追記
3 bootpack.h struct KEYBUF の要素を変更

5.harib04e

FIFOバッファの整理

マウスでもFIFOを利用できるように、書き直す。やる内容は下記の通り

  1. fifo.cの作成
  2. int.cの修正
  3. bootpack.cの追記・修正
  4. bootpack.hの追記・修正
  5. 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を利用できるように、書き直す。やる内容は下記の通り

  1. int.cの修正
  2. 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)の初期化するコードを実装する。

やること

  1. int.cの作成
  2. bootpack.hへ追記
  3. 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

キーボードとマウスの割り込みを有効化するコードを実装する。

やること

  1. int.cの追記
  2. asmfunc.asmへ追記(30日本ではnaskfunc.nas
  3. dsctbl.cの修正
  4. bootpack.hへ追記
  5. bootpack.cへ追記

特に躓くところはなし。30日本の追記・編集箇所と同じ個所を追記・編集する

OS自作入門 5日目/30日(文字出力)

OS自作入門 5日目/30日(文字出力)

1.はじめに

5日目では、文字の出力を行う。躓きどころは下記の2点

  1. フォントの作成
  2. sprintf

フォントの作成についても、著者オリジナル実行ファイルを使用せずに、作成する。

sprintfについては、ソースファイルをそのまま実行するとエラーになるため、sprintfの代わりの関数を作成する。

2.harib02e

スクリーンへ文字の出力を行う。

harib02eでも著者のオリジナル実行ファイルが使用されているので、自作本とは異なる方法でimgファイルを作成する。

自作本でのimgファイルの作成手順

  1. フォントtextファイルから、makefont.exe(著者オリジナル)でbinファイルを作成
  2. bin2obj.exe(著者オリジナル)でbinファイルからobjファイルを作成
  3. 他のオブジェクトファイルと合体させ、bimファイルを作成(以降は、前回説明した流れと同じ)
  4. bimファイルからhrbファイルを作成
  5. bimファイルとbinファイルからsysファイルを作成
  6. sysファイルとブートローダ部のbinファイルからimgファイルを作成

著者オリジナルのファイルを使用しない、imgファイルを作成手順

  1. フォントtextファイルを、フォントcファイルに変換
  2. 作成したフォントcファイルと他のファイルをリンクさせ、bootpackのhrbファイルを作成(以降は、前回説明した流れと同じ)
  3. hrbファイルとbinファイルからsysファイルを作成
  4. 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に記載を変更

hrb.osask.jp

解決できていない疑問点

アセンブリで記述した関数を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ファイルが適切な場所に組み込まれる。 出力イメージファイルについても、元の容量から変化がない。いろいろ調べたが不明。

qiita.com

4.harib00i

書籍では、作者オリジナルのソフトが使用されており、下記の手順でイメージファイルが作成されている。

  1. cファイルからgasファイルを作成
  2. gasファイルからnasファイルを作成
  3. nasファイル(3個) からobjファイル(bootpack)とbinファイル(ipl,asmhead)を作成
  4. objファイルからbimファイルを作成
  5. bimファイルからhrbファイルを作成
  6. hrbファイルとbinファイルを結合し、sysファイルを作成
  7. sysファイルとbinファイルから、imgファイルを作成

今回もオリジナルのファイルは使わない方法で作成する。手順は下記の通り

  1. asmファイル(2個) からbinファイル(ipl,asmhead)を作成
  2. cファイルからhrbファイルを作成
  3. hrbファイルとbinファイルを結合し、sysファイルを作成
  4. sysファイルとbinファイルから、imgファイルを作成

躓きどころ

asmhead.asmについて下記のように修正する

行数 修正前 修正後
58 [INSTRSET "i486p"] 削除
134,145 ALIGNB 16 ALIGN 16, DB 0

www.nasm.us

hrb.osask.jp

リンカ

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) }

}

vanya.jp.net

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 コンパイルを実行し、オブジェクトファイルを出力する

bttb.s1.valueserver.jp

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

bttb.s1.valueserver.jp

qiita.com

コマンドライン上でファイルをダンプ

書式
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] 削除

hrb.osask.jp

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に指定する

ja.wikipedia.org

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命令については、下記リンクを参照

www.nasm.us

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のマニュアルについては下記を参照

manpages.ubuntu.com

そのほか参考にしたページ

yuh.hatenadiary.jp

4.Make, Makefileについて

Make, Makefileとは?

Makeはプログラムのビルドを自動化するツールであり、ビルドの方法はMakefileに記述する。

make - Wikipedia

WSLのubuntu初期設定ではmakeはインストールされていないため、下記コマンドでインストールを行う。

$ sudo apt install make

基本的な書式

Makefileの基本的な書式①

target: prerequisite
  recipe
名前 説明
target 出力するファイル名。makeコマンドを実行する際の引数でも使用する。targetの後には:を記述する
prerequisite targetを出力する際の入力ファイル。複数の場合は半角スペースで区切る
recipe コマンドを記載する。prerequisiteが一つでも変更されていれば実行する。行頭は必ずTABを入力しなければならない

Makefileの基本的な書式②

clean:
  recipe
名前 説明
clean targetはcleanprerequisiteはとらない
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 iplipl.binを作成し、make imghelloos.imgを作成した。

targetを省略するとMakefileの先頭targetを実施する。

GNUのmakeマニュアル

www.gnu.org

その他参考にしたページ

shin.hateblo.jp