diff --git a/bootpack.c b/bootpack.c index ba8f5fd..20ec184 100644 --- a/bootpack.c +++ b/bootpack.c @@ -4,6 +4,9 @@ void io_out8(int port, int data); int io_load_eflags(void); void io_store_eflags(int eflags); +void load_gdtr(int limit, int addr); +void load_idtr(int limit, int addr); + const int COL8_BLACK = 0; const int COL8_WHITE = 7; const int COL8_GRAY = 8; @@ -175,7 +178,59 @@ struct BOOTINFO { unsigned 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 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; +} + +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; +} + +void init_gdtidt(void) { + struct SEGMENT_DESCRIPTOR* gdt = (struct SEGMENT_DESCRIPTOR*)0x00270000; + struct GATE_DESCRIPTOR* idt = (struct GATE_DESCRIPTOR*)0x0026f800; + + // Init GDT. + for (int 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); + + // Init IDT. + for (int i = 0; i < 256; ++i) + set_gatedesc(idt + i, 0, 0, 0); + load_idtr(0x7ff, 0x0026f800); +} + + void HariMain(void) { + init_gdtidt(); init_palette(); struct BOOTINFO* binfo = (struct BOOTINFO*)0x0ff0; diff --git a/naskfunc.s b/naskfunc.s index c4a5a17..30639c0 100644 --- a/naskfunc.s +++ b/naskfunc.s @@ -2,6 +2,7 @@ .globl io_in8, io_in16, io_in32 .globl io_out8, io_out16, io_out32 .globl io_load_eflags, io_store_eflags +.globl load_gdtr, load_idtr # void io_hlt(void) io_hlt: @@ -77,3 +78,17 @@ io_store_eflags: push %eax popfl # pop eflags ret + +# void load_gdtr(int limit, int addr) +load_gdtr: + mov 4(%esp), %ax + mov %ax, 6(%esp) + lgdt 6(%esp) + ret + +# void load_idtr(int limit, int addr) +load_idtr: + mov 4(%esp), %ax + mov %ax, 6(%esp) + lidt 6(%esp) + ret