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

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

OS自作入門 15日目/30日(マルチタスク)

OS自作入門 15日目/30日(マルチタスク

1.はじめに

15日目では、マルチタスクを実装する。

2.新しい単語とか

TSS(Task Status Segment)

タスクスイッチをする際に、レジスタの内容をメモリに書き出したり、メモリからレジスタに読み込む際に使用するセグメント。intが26個で構成されている。(4*26=104byte)

struct TSS32 {
    int backlink, esp0, ss0, esp1, ss1, esp2, ss2, cr3; /*タスクの設定に関する情報*/
    int eip, eflags, eax, ecx, edx, ebx, esp, ebp, esi, edi; /*32bitのレジスタ*/
    int es, cs, ss, ds, fs, gs; /*16bitのレジスタ*/
    int ldtr, iomap; /*タスクの設定に関する情報*/
};

EIP(Extend Instruction Pointer)

次に実行する命令のアドレスを保持するレジスタ

TR(Task Register)

実行しているタスクの値を保持するレジスタ

3.harib12a,b,c,d

マルチタスク(2つのタスク)を実装する。

  1. bootpack.cの修正
  2. bootpack.hの修正
  3. asmfunc.asmを修正
No. 対象ファイル 修正内容
1 bootpack.c task_b_mainや、tssの初期設定などマルチタスクに必要な処理を追記
2 bootpack.h void load_tr(int tr);#define AR_TSS32 0x0089の追記
3 asmfunc.asm 関数load_tr, farjmpの実装

4.harib12e,f,g

mt_taskswitch関数を用いたマルチタスク(2つのタスク)を実装する。

  1. mtask.cの新規作成
  2. bootpack.cの修正
  3. bootpack.hの修正
  4. timer.cを修正
No. 対象ファイル 修正内容
1 mtask.c マルチタスク用のソースファイルの作成
1 bootpack.c 上記追加に伴う修正
2 bootpack.h mtask.c用の宣言等を追記
3 timer.c 関数void inthandler20(int *esp)の処理を修正
6 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
OKEY=keyboard.o
OMOUSE=mouse.o
OMEM=memory.o
OSHEET=sheet.o
OTIMER=timer.o
OMTASK=mtask.o

MAKEBHRB=$(BT) $(FOB) $(FONT) $(CSPR) $(OTBL) $(OGRA) $(OINT) $(OFIFO) $(OKEY) $(OMOUSE) $(OMEM) $(OSHEET) $(OTIMER) $(OMTASK)

#--- フォントの作成
$(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)

テキストの通りに修正をすると13日目と同じように、動作が非常に遅くなった。解決策として

void task_b_main(struct SHEET *sht_back)関数内のforループの直下に下記内容を追記した。

(略)
    for (;;) {
        count++;
        orisprintf(s, "%d", count);  ///////////追加
        putfonts8_asc_sht(sht_back, 0, 160, COL8_FFFFFF, COL8_008484, s, 11);  ///////////追加
        io_cli();
        if (fifo32_status(&fifo) == 0) {
(略)

一応、それっぽく実行できるが、根本的な解決にはなっていない。

OS自作入門 14日目/30日(画面の高解像度化)

OS自作入門 14日目/30日(画面の高解像度化)

1.はじめに

14日目では、画面の解像度を320×240から変更する。

2.harib11d

画面の解像度を640×480に変更する。

  1. 上記のためにasmhead.asmの修正
No. 対象ファイル 修正内容
1 asmhead.asm テキストの通りに修正

テキストの通りに実行すると、何も表示されない。小一時間ほど調べたが解決できなかったため、harib11eを実施。
※この問題については、harib11eの中で解決

3.harib11e

任意の解像度を設定する。任意の解像度が設定できない場合、320×240の解像度で起動する。

  1. harib11dと同じくasmhead.asmの修正
No. 対象ファイル 修正内容
1 asmhead.asm テキストの通りに修正

4.harib11dの問題解決

正常に動作したharib11eVRAMのアドレスをint型で画面に出力したところ-50331648を示した。これを16進数に変換する手順は下記の通り

No. 処理 結果
1 -1を掛けて正の数にする 50331648
2 16進数に変換する 0x03000000
3 基数を求める(bit反転して1を足す) 0xfd000000

3の手順については、2の補数表現で検索

上記より、VRAMのアドレスを求めることができたので、harib11eVRAM0xfd000000で実行する。

5.harib11f,g

キーボードの入力をwindowに出力する。harib11gの時点では1文字のみの出力

  1. 上記のためにbootpack.cの修正
No. 対象ファイル 修正内容
1 bootpack.c テキストの通りに修正

6.harib11h,i

キーボードの入力をwindowに出力する。harib11gから進化し、文字列として表示することができ削除もできる。

  1. 上記のためにbootpack.cの修正
No. 対象ファイル 修正内容
1 bootpack.c テキストの通りに修正

OS自作入門 13日目/30日(タイマーの改良)

OS自作入門 13日目/30日(タイマーの改良)

1.はじめに

13日目では、コードとタイマーを改良する。

問題点はharib09c,d,e,f,g,h,iの際に、CDの想定通りの挙動を示さない。現時点で、原因は不明。パッチ的な対応で動作させることはできた。詳しい内容については下記を参照

2.harib10a,b

複数の関数を一つにまとめたり、FIFOバッファを改良する

  1. 上記のためにbootpack.cの修正
No. 対象ファイル 修正内容
1 bootpack.c void putfonts8_asc_shtへの集約やFIFO部分の修正

3.harib09c,d,e,f,g,h,i

FIFOバッファの見直し等を行い、プログラムの高速化を図る。内容については、本のみで理解できたので、harib10iのみ実装

harib10bからの修正内容は下記の通り

  1. timer.cの修正
  2. bootpack.cの修正
  3. bootpack.hの修正
  4. fifo.cを修正
  5. keyboard.cを修正
  6. mouse.cを修正
No. 対象ファイル 修正内容
1 timer.c 線形リストや番兵実装他を実装
2 bootpack.c 同上実装に伴う修正
3 bootpack.h 同上実装に伴う修正
4 fifo.c FIFOバッファの32bit対応
5 keyboard.c FIFOバッファの32bit対応
6 mouse.c FIFOバッファの32bit対応

上記の内容を、テキストの通りに実施したが、10秒経ってもウィンドウにカウントが表示されない。また、キーボードを押しても非常に反応が鈍い(数秒遅れ)。問題点の切り分けを行ったところ、bootpack.cのfor文ループの初めに下記命令を記入すると、正常に割り込みが動作する。

テキストの記載

  for (;;) {
    count++;    
        io_cli();
    ~(略)~

切り分け

  for (;;) {
    count++;
    orisprintf(s, "%d", count); 
    putfonts8_asc_sht(sht_win, 40, 28, COL8_000000, COL8_C6C6C6, s, 10);
    io_cli();
    ~(略)~

原因を検討したが、全くわからなかった。割り込み禁止が不適切な状態になっているのではないかなど考えたが、正常に動作していた過去のプログラムと比較しても問題と思われるところが見つからなかった。

OS自作入門 12日目/30日(タイマー)

OS自作入門 12日目/30日(タイマー)

1.はじめに

12日目では、タイマーを実装する。

特に躓くところはないが、追加するコード量が多いため、タイプミスには気を付けたい。

2.harib09a,b

タイマーを実装して、ウィンドウ内に表示

  1. timer.cの追加
  2. 上記用にbootpack.cの修正
  3. 同上の理由でbootpack.hの修正
  4. 上記作成に伴うdsctbl.cを修正
  5. 上記作成に伴うasmfunc.asmを修正
  6. 上記作成に伴うMakefileを修正
No. 対象ファイル 修正内容
1 timer.c timer.cを作成
2 bootpack.c init_pit();や、io_out8(PIC0_IMR, 0xf8);を追記
3 bootpack.h void asm_inthandler20(void);timer.cに必要な記述を追加
4 dsctbl.c timerのイベントハンドラIDTに登録するための命令を追記
5 asmfunc.asm 関数asm_inthandler20, inthandler20の実装
6 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
OKEY=keyboard.o
OMOUSE=mouse.o
OMEM=memory.o
OSHEET=sheet.o
OTIMER=timer.o

MAKEBHRB=$(BT) $(FOB) $(FONT) $(CSPR) $(OTBL) $(OGRA) $(OINT) $(OFIFO) $(OKEY) $(OMOUSE) $(OMEM) $(OSHEET) $(OTIMER)

#--- フォントの作成
$(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)

3.harib09c,e,f,g

タイムアウト機能の実装、複数のタイマーの設定、割り込み処理の高速化をまとめて実施

harib09bからの修正内容は下記の通り

  1. timer.cの修正
  2. bootpack.cの修正
  3. 同上の理由でbootpack.hの修正
No. 対象ファイル 修正内容
1 timer.c 新たに関数を作成したり、処理の書き換え
2 bootpack.c 複数のタイマーを追記したり、FIFOの内容を新規に追加
3 bootpack.h timer.c用の宣言等を追加

OS自作入門 11日目/30日(ウィンドウ)

OS自作入門 11日目/30日(ウィンドウ)

1.はじめに

11日目では、コードの整理をしたあとウィンドウを作成する。

特に躓くところはないが、追加するコード量が多いため、タイプミスには気を付けたい。

2.harib08a,b,c

画面外のサポートを実施した後、コードの整理

  1. コードを整理するためbootpack.cの修正
  2. 上記作成に伴うbootpack.hの修正
  3. 上記作成に伴うsheet.cを修正
No. 対象ファイル 修正内容
1 bootpack.c 各関数からshtcltを削除
2 bootpack.h 上記に伴う修正
3 sheet.c 上記に伴う修正

3.harib08d,e,f,g,h

ウィンドウの表示から、カウンタ表示、ちらつき解消までをまとめて実施

harib07cからの修正内容は下記の通り

  1. bootpack.cの修正
  2. bootpack.hの追記
  3. sheet.cの修正
No. 対象ファイル 修正内容
1 bootpack.c 関数make_window8の実装、その他修正等
2 bootpack.h struct SHTCTLunsigned char *vram, *map;を追記
3 sheet.c 多々修正

OS自作入門 10日目/30日(重ね合わせ処理)

OS自作入門 10日目/30日(重ね合わせ処理)

1.はじめに

10日目では、重ね合わせ処理を行う。

特に躓くところはないが、追加するコード量が多いため、タイプミスには気を付けたい。

2.harib07a

メモリ管理部分のソースファイルを整理する。

  1. memory.cの作成
  2. 上記作成に伴うbootpack.hの修正
  3. 同上に伴うbootpack.cの修正
  4. ソースファイルの整理に伴い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
OKEY=keyboard.o
OMOUSE=mouse.o
OMEM=memory.o

MAKEBHRB=$(BT) $(FOB) $(FONT) $(CSPR) $(OTBL) $(OGRA) $(OINT) $(OFIFO) $(OKEY) $(OMOUSE) $(OMEM)

#--- フォントの作成
$(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)

3.harib07b,c,d

重ね合わせ処理の実装を行う。STEPは下記の通り

  1. 再描画時に画面すべてを書き換える(harib007b)
  2. 文字とマウス箇所のみ書き換えるが、if文を全画面範囲で実行してしまう(harib007c)
  3. 再描画必要箇所のみ書き換える(harib007d)

harib07aからの修正内容は下記の通り

  1. sheet.cの作成
  2. bootpack.cの修正
  3. bootpack.hの追記
  4. Makefileの修正
No. 対象ファイル 修正内容
1 asmfunc.asm 関数load_cr0, store_cr0, memtest_subの実装
2 bootpack.c sheet.cに関する修正ほか
3 bootpack.h sheet.cに関する情報を追記
4 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
OKEY=keyboard.o
OMOUSE=mouse.o
OMEM=memory.o
OSHEET=sheet.o

MAKEBHRB=$(BT) $(FOB) $(FONT) $(CSPR) $(OTBL) $(OGRA) $(OINT) $(OFIFO) $(OKEY) $(OMOUSE) $(OMEM) $(OSHEET)

#--- フォントの作成
$(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)

OS自作入門 9日目/30日(メモリ管理)

OS自作入門 9日目/30日(メモリ管理)

1.はじめに

9日目では、ソースファイルの整理とメモリ管理を行う

特に躓くところはなし。

2.harib06a

ソースファイルを整理する。

  1. keyboard.cの作成(bootpack.cint.cの分割)
  2. mouse.cの作成(bootpack.cint.cの分割)
  3. bootpack.hの修正
  4. ソースファイルの整理に伴い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
OKEY=keyboard.o
OMOUSE=mouse.o

MAKEBHRB=$(BT) $(FOB) $(FONT) $(CSPR) $(OTBL) $(OGRA) $(OINT) $(OFIFO) $(OKEY) $(OMOUSE)

#--- フォントの作成
$(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)

3.harib06b,c

メモリの容量を確認する。C言語で記述すると、コンパイルした際にコードが最適化され確認できないため、アセンブラで記述する。

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

修正内容は下記の通り

No. 対象ファイル 修正内容
1 asmfunc.asm 関数load_cr0, store_cr0, memtest_subの実装
2 bootpack.c unsigned int memtest(unsigned int start, unsigned int end);の追加
3 bootpack.h 関数load_cr0, store_cr0, memtest_subの宣言

4.harib06d

使用可能なメモリの領域を管理し、使用可能なメモリの総量を確認する。

  1. bootpack.cの追記・修正

修正内容は下記の通り

No. 対象ファイル 修正内容
1 bootpack.c memman_init, memman_total, memman_alloc, memman_freeの実装