diff --git a/05_day/bootpack.c b/05_day/bootpack.c index 6914c8e..1d576bb 100644 --- a/05_day/bootpack.c +++ b/05_day/bootpack.c @@ -38,6 +38,24 @@ struct BOOTINFO { char *vram; }; +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); +void load_gdtr(int limit, int addr); +void load_idtr(int limit, int addr); + void HariMain(void) { struct BOOTINFO *binfo = (struct BOOTINFO *) 0x0ff0; @@ -217,4 +235,52 @@ void putblock8_8(char *vram, int vxsize, int pxsize, } } return; -} \ No newline at end of file +} + +void init_gdtidt(void) +{ + struct SEGMENT_DESCRIPTOR *gdt = (struct SEGMENT_DESCRIPTOR *) 0x00270000; + struct GATE_DESCRIPTOR *idt = (struct GATE_DESCRIPTOR *) 0x0026f800; + int i; + + /* GDT初始化 */ + for (i = 0; i < 8192; i++) { + set_segmdesc(gdt + i, 0, 0, 0); + } + set_segmdesc(gdt + 1, 0xffffffff, 0x00000000, 0x4092); + set_segmdesc(gdt + 2, 0x0007ffff, 0x00280000, 0x409a); + load_gdtr(0xffff, 0x00270000); + + /* IDT初始化 */ + for (i = 0; i < 256; i++) { + set_gatedesc(idt + i, 0, 0, 0); + } + load_idtr(0x7ff, 0x0026f800); + + return; +} + +void set_segmdesc(struct SEGMENT_DESCRIPTOR *sd, unsigned int limit, int base, int ar) +{ + if (limit > 0xfffff) { + ar |= 0x8000; /* G_bit = 1 */ + limit /= 0x1000; + } + sd->limit_low = limit & 0xffff; + sd->base_low = base & 0xffff; + sd->base_mid = (base >> 16) & 0xff; + sd->access_right = ar & 0xff; + sd->limit_high = ((limit >> 16) & 0x0f) | ((ar >> 8) & 0xf0); + sd->base_high = (base >> 24) & 0xff; + return; +} + +void set_gatedesc(struct GATE_DESCRIPTOR *gd, int offset, int selector, int ar) +{ + gd->offset_low = offset & 0xffff; + gd->selector = selector; + gd->dw_count = (ar >> 8) & 0xff; + gd->access_right = ar & 0xff; + gd->offset_high = (offset >> 16) & 0xffff; + return; +} diff --git a/05_day/naskfunc.nas b/05_day/naskfunc.nas index aefada7..32d1b1b 100644 --- a/05_day/naskfunc.nas +++ b/05_day/naskfunc.nas @@ -10,6 +10,7 @@ GLOBAL _io_in8, _io_in16, _io_in32 GLOBAL _io_out8, _io_out16, _io_out32 GLOBAL _io_load_eflags, _io_store_eflags + GLOBAL _load_gdtr, _load_idtr [SECTION .text] @@ -75,3 +76,15 @@ _io_store_eflags: ; void io_store_eflags(int eflags); PUSH EAX POPFD ; POP EFLAGS RET + +_load_gdtr: ; void load_gdtr(int limit, int addr); + MOV AX,[ESP+4] ; limit + MOV [ESP+6],AX + LGDT [ESP+6] + RET + +_load_idtr: ; void load_idtr(int limit, int addr); + MOV AX,[ESP+4] ; limit + MOV [ESP+6],AX + LIDT [ESP+6] + RET \ No newline at end of file