たなしょのメモ

日々勉強していることをつらつらと

OS作成奮闘記day38

例外を起こして悪い処理を強制終了させてみましょう。
bootpack.c

/* dsctbl.c */
struct SEGMENT_DESCRIPTOR {
    short limit_low, base_low;
    char base_mid, access_right;
    char limit_high, base_high;
};
struct GATE_DESCRIPTOR {
    short offset_low, selector;
    char dw_count, access_right;
    short offset_high;
};
void init_gdtidt(void);
void set_segmdesc(struct SEGMENT_DESCRIPTOR *sd, unsigned int limit, int base, int ar);
void set_gatedesc(struct GATE_DESCRIPTOR *gd, int offset, int selector, int ar);
#define ADR_IDT         0x0026f800
#define LIMIT_IDT       0x000007ff
#define ADR_GDT         0x00270000
#define LIMIT_GDT       0x0000ffff
#define ADR_BOTPAK      0x00280000
#define LIMIT_BOTPAK    0x0007ffff
#define AR_DATA32_RW    0x4092
#define AR_CODE32_ER    0x409a
#define AR_LDT          0x0082
#define AR_TSS32        0x0089
#define AR_INTGATE32    0x008e
struct TASK {
    int sel, flags; /* selはGDTの番号のこと */
    int level, priority;
    struct FIFO32 fifo;
    struct TSS32 tss;
    struct SEGMENT_DESCRIPTOR ldt[2];
    struct CONSOLE *cons;
    int ds_base, cons_stack;
};

mtask.c

struct TASK *task_init(struct MEMMAN *memman)
{
    int i;
    struct TASK *task, *idle;
    struct SEGMENT_DESCRIPTOR *gdt = (struct SEGMENT_DESCRIPTOR *) ADR_GDT;

    taskctl = (struct TASKCTL *) memman_alloc_4k(memman, sizeof (struct TASKCTL));
    for (i = 0; i < MAX_TASKS; i++) {
        taskctl->tasks0[i].flags = 0;
        taskctl->tasks0[i].sel = (TASK_GDT0 + i) * 8;
        taskctl->tasks0[i].tss.ldtr = (TASK_GDT0 + MAX_TASKS + i) * 8;
        set_segmdesc(gdt + TASK_GDT0 + i, 103, (int) &taskctl->tasks0[i].tss, AR_TSS32);
        set_segmdesc(gdt + TASK_GDT0 + MAX_TASKS + i, 15, (int) taskctl->tasks0[i].ldt, AR_LDT);
    }
    for (i = 0; i < MAX_TASKLEVELS; i++) {
        taskctl->level[i].running = 0;
        taskctl->level[i].now = 0;
    }
struct TASK *task_alloc(void)
{
    int i;
    struct TASK *task;
    for (i = 0; i < MAX_TASKS; i++) {
        if (taskctl->tasks0[i].flags == 0) {
            task = &taskctl->tasks0[i];
            task->flags = 1; /* 使用中マーク */
            task->tss.eflags = 0x00000202; /* IF = 1; */
            task->tss.eax = 0; /* とりあえず0にしておくことにする */
            task->tss.ecx = 0;
            task->tss.edx = 0;
            task->tss.ebx = 0;
            task->tss.ebp = 0;
            task->tss.esi = 0;
            task->tss.edi = 0;
            task->tss.es = 0;
            task->tss.ds = 0;
            task->tss.fs = 0;
            task->tss.gs = 0;
            task->tss.iomap = 0x40000000;
            task->tss.ss0 = 0;
            return task;
        }
    }
    return 0; /* もう全部使用中 */
}

console.c

int cmd_app(struct CONSOLE *cons, int *fat, char *cmdline)
{
    struct MEMMAN *memman = (struct MEMMAN *) MEMMAN_ADDR;
    struct FILEINFO *finfo;
    char name[18], *p, *q;
    struct TASK *task = task_now();
    int i, segsiz, datsiz, esp, dathrb;
    struct SHTCTL *shtctl;
    struct SHEET *sht;

    /* コマンドラインからファイル名を生成 */
    for (i = 0; i < 13; i++) {
        if (cmdline[i] <= ' ') {
            break;
        }
        name[i] = cmdline[i];
    }
    name[i] = 0; /* とりあえずファイル名の後ろを0にする */

    /* ファイルを探す */
    finfo = file_search(name, (struct FILEINFO *) (ADR_DISKIMG + 0x002600), 224);
    if (finfo == 0 && name[i - 1] != '.') {
        /* 見つからなかったので後ろに".HRB"をつけてもう一度探してみる */
        name[i    ] = '.';
        name[i + 1] = 'H';
        name[i + 2] = 'R';
        name[i + 3] = 'B';
        name[i + 4] = 0;
        finfo = file_search(name, (struct FILEINFO *) (ADR_DISKIMG + 0x002600), 224);
    }

    if (finfo != 0) {
        /* ファイルが見つかった場合 */
        p = (char *) memman_alloc_4k(memman, finfo->size);
        file_loadfile(finfo->clustno, finfo->size, p, fat, (char *) (ADR_DISKIMG + 0x003e00));
        if (finfo->size >= 36 && strncmp(p + 4, "Hari", 4) == 0 && *p == 0x00) {
            segsiz = *((int *) (p + 0x0000));
            esp    = *((int *) (p + 0x000c));
            datsiz = *((int *) (p + 0x0010));
            dathrb = *((int *) (p + 0x0014));
            q = (char *) memman_alloc_4k(memman, segsiz);
            task->ds_base = (int) q;
            set_segmdesc(task->ldt + 0, finfo->size - 1, (int) p, AR_CODE32_ER + 0x60);
            set_segmdesc(task->ldt + 1, segsiz - 1,      (int) q, AR_DATA32_RW + 0x60);
            for (i = 0; i < datsiz; i++) {
                q[esp + i] = p[dathrb + i];
            }
            start_app(0x1b, 0 * 8 + 4, esp, 1 * 8 + 4, &(task->tss.esp0));
            shtctl = (struct SHTCTL *) *((int *) 0x0fe4);
            for (i = 0; i < MAX_SHEETS; i++) {
                sht = &(shtctl->sheets0[i]);
                if ((sht->flags & 0x11) == 0x11 && sht->task == task) {
                    /* アプリが開きっぱなしにした下じきを発見 */
                    sheet_free(sht);    /* 閉じる */
                }
            }
            timer_cancelall(&task->fifo);
            memman_free_4k(memman, (int) q, segsiz);
        } else {
            cons_putstr0(cons, ".hrb file format error.\n");
        }
        memman_free_4k(memman, (int) p, finfo->size);
        cons_newline(cons);
        return 1;
    }
    /* ファイルが見つからなかった場合 */
    return 0;
}

アプリのサイズを変更していきます。
api001~api020はa_nask.nasを分解したものなので記載を省きます。

Makefile

OBJS_BOOTPACK = bootpack.obj naskfunc.obj hankaku.obj graphic.obj dsctbl.obj \
                int.obj fifo.obj keybord.obj mouse.obj memory.obj sheet.obj timer.obj \
                mtask.obj window.obj console.obj file.obj

OBJS_API =  api001.obj api002.obj api003.obj api004.obj api005.obj api006.obj \
            api007.obj api008.obj api009.obj api010.obj api011.obj api012.obj \
            api013.obj api014.obj api015.obj api016.obj api017.obj api018.obj \
            api019.obj api020.obj

TOOLPATH = ..\..\z_tools\\

INCPATH  = ..\..\z_tools\haribote\\

MAKE     = $(TOOLPATH)make.exe -r
NASK     = $(TOOLPATH)nask.exe
CC1      = $(TOOLPATH)cc1.exe -I$(INCPATH) -Os -Wall -quiet
GAS2NASK = $(TOOLPATH)gas2nask.exe -a
OBJ2BIM  = $(TOOLPATH)obj2bim.exe
MAKEFONT = $(TOOLPATH)makefont.exe
BIN2OBJ  = $(TOOLPATH)bin2obj
BIM2HRB  = $(TOOLPATH)bim2hrb.exe
RULEFILE = $(TOOLPATH)haribote\haribote.rul
EDIMG    = $(TOOLPATH)edimg.exe
IMGTOL   = $(TOOLPATH)imgtol.com
COPY     = cmd.exe /C copy
DEL      = rm -f

# default operation

default :
    $(MAKE) img

# file making rule

ipl10.bin : ipl10.nas Makefile
    $(NASK) ipl10.nas ipl10.bin ipl10.lst

asmhead.bin : asmhead.nas Makefile
    $(NASK) asmhead.nas asmhead.bin asmhead.lst

hankaku.bin : hankaku.txt Makefile
    $(MAKEFONT) hankaku.txt hankaku.bin

hankaku.obj : hankaku.bin Makefile
    $(BIN2OBJ) hankaku.bin hankaku.obj _hankaku

bootpack.bim : $(OBJS_BOOTPACK) Makefile
    $(OBJ2BIM) @$(RULEFILE) out:bootpack.bim stack:3136k map:bootpack.map \
        $(OBJS_BOOTPACK)
# 3MB+64KB=3136KB

bootpack.hrb : bootpack.bim Makefile
    $(BIM2HRB) bootpack.bim bootpack.hrb 0

haribote.sys : asmhead.bin bootpack.hrb Makefile
    cat asmhead.bin bootpack.hrb > haribote.sys

hello.hrb : hello.nas Makefile
    $(NASK) hello.nas hello.hrb hello.lst

hello2.hrb : hello2.nas Makefile
    $(NASK) hello2.nas hello2.hrb hello2.lst

a.bim : a.obj $(OBJS_API) Makefile
    $(OBJ2BIM) @$(RULEFILE) out:a.bim map:a.map a.obj $(OBJS_API)

a.hrb : a.bim Makefile
    $(BIM2HRB) a.bim a.hrb 0

hello3.bim : hello3.obj $(OBJS_API) Makefile
    $(OBJ2BIM) @$(RULEFILE) out:hello3.bim map:hello3.map hello3.obj $(OBJS_API)

hello3.hrb : hello3.bim Makefile
    $(BIM2HRB) hello3.bim hello3.hrb 0

hello4.bim : hello4.obj $(OBJS_API) Makefile
    $(OBJ2BIM) @$(RULEFILE) out:hello4.bim stack:1k map:hello4.map \
        hello4.obj $(OBJS_API)

hello4.hrb : hello4.bim Makefile
    $(BIM2HRB) hello4.bim hello4.hrb 0

hello5.bim : hello5.obj Makefile
    $(OBJ2BIM) @$(RULEFILE) out:hello5.bim stack:1k map:hello5.map hello5.obj

hello5.hrb : hello5.bim Makefile
    $(BIM2HRB) hello5.bim hello5.hrb 0

winhelo.bim : winhelo.obj $(OBJS_API) Makefile
    $(OBJ2BIM) @$(RULEFILE) out:winhelo.bim stack:1k map:winhelo.map \
        winhelo.obj $(OBJS_API)

winhelo.hrb : winhelo.bim Makefile
    $(BIM2HRB) winhelo.bim winhelo.hrb 0

winhelo2.bim : winhelo2.obj $(OBJS_API) Makefile
    $(OBJ2BIM) @$(RULEFILE) out:winhelo2.bim stack:1k map:winhelo2.map \
        winhelo2.obj $(OBJS_API)

winhelo2.hrb : winhelo2.bim Makefile
    $(BIM2HRB) winhelo2.bim winhelo2.hrb 0

winhelo3.bim : winhelo3.obj $(OBJS_API) Makefile
    $(OBJ2BIM) @$(RULEFILE) out:winhelo3.bim stack:1k map:winhelo3.map \
        winhelo3.obj $(OBJS_API)

winhelo3.hrb : winhelo3.bim Makefile
    $(BIM2HRB) winhelo3.bim winhelo3.hrb 40k

star1.bim : star1.obj $(OBJS_API) Makefile
    $(OBJ2BIM) @$(RULEFILE) out:star1.bim stack:1k map:star1.map \
        star1.obj $(OBJS_API)

star1.hrb : star1.bim Makefile
    $(BIM2HRB) star1.bim star1.hrb 47k

stars.bim : stars.obj $(OBJS_API) Makefile
    $(OBJ2BIM) @$(RULEFILE) out:stars.bim stack:1k map:stars.map \
        stars.obj $(OBJS_API)

stars.hrb : stars.bim Makefile
    $(BIM2HRB) stars.bim stars.hrb 47k

stars2.bim : stars2.obj $(OBJS_API) Makefile
    $(OBJ2BIM) @$(RULEFILE) out:stars2.bim stack:1k map:stars2.map \
        stars2.obj $(OBJS_API)

stars2.hrb : stars2.bim Makefile
    $(BIM2HRB) stars2.bim stars2.hrb 47k

lines.bim : lines.obj $(OBJS_API) Makefile
    $(OBJ2BIM) @$(RULEFILE) out:lines.bim stack:1k map:lines.map \
        lines.obj $(OBJS_API)

lines.hrb : lines.bim Makefile
    $(BIM2HRB) lines.bim lines.hrb 48k

walk.bim : walk.obj $(OBJS_API) Makefile
    $(OBJ2BIM) @$(RULEFILE) out:walk.bim stack:1k map:walk.map \
        walk.obj $(OBJS_API)

walk.hrb : walk.bim Makefile
    $(BIM2HRB) walk.bim walk.hrb 48k

noodle.bim : noodle.obj $(OBJS_API) Makefile
    $(OBJ2BIM) @$(RULEFILE) out:noodle.bim stack:1k map:noodle.map \
        noodle.obj $(OBJS_API)

noodle.hrb : noodle.bim Makefile
    $(BIM2HRB) noodle.bim noodle.hrb 40k

beepdown.bim : beepdown.obj $(OBJS_API) Makefile
    $(OBJ2BIM) @$(RULEFILE) out:beepdown.bim stack:1k map:beepdown.map \
        beepdown.obj $(OBJS_API)

beepdown.hrb : beepdown.bim Makefile
    $(BIM2HRB) beepdown.bim beepdown.hrb 40k

color.bim : color.obj $(OBJS_API) Makefile
    $(OBJ2BIM) @$(RULEFILE) out:color.bim stack:1k map:color.map \
        color.obj $(OBJS_API)

color.hrb : color.bim Makefile
    $(BIM2HRB) color.bim color.hrb 56k

color2.bim : color2.obj $(OBJS_API) Makefile
    $(OBJ2BIM) @$(RULEFILE) out:color2.bim stack:1k map:color2.map \
        color2.obj $(OBJS_API)

実装過程
・ 263c0739ac9b6f0e93847f64c69427b338b2397a