diff --git a/src/bios.S b/src/bios.S index 9601080..1d35336 100644 --- a/src/bios.S +++ b/src/bios.S @@ -87,6 +87,9 @@ bios_func: push %ebp // To support any interrupt number, we use self-modifying code. mov %al, _bf_int+1 + PROT16 + REAL + mov 0(%edi), %eax mov 4(%edi), %ecx mov 8(%edi), %edx @@ -95,17 +98,11 @@ bios_func: push %ebp mov 20(%edi), %esi mov 24(%edi), %edi - PROT16 - REAL - // This instruction will get written at runtime _bf_int: .byte 0xCD, 0 // INT imm8 push $0 pushf - PROT - PROT32 - push %edi mov 8+4(%ebp), %edi mov %eax, 0(%edi) @@ -117,6 +114,9 @@ _bf_int: .byte 0xCD, 0 // INT imm8 pop %eax mov %eax, 24(%edi) + PROT + PROT32 + pop %eax pop %esi diff --git a/src/main.c b/src/main.c index ef5d87a..6adb5ed 100644 --- a/src/main.c +++ b/src/main.c @@ -51,6 +51,28 @@ struct vesa_info { extern uint16_t bios_func(uint8_t inum, uint32_t reg[]); +#define PG_PRESENT 0x001 +#define PG_WRITE 0x002 +#define PG_USER 0x004 +#define PG_SIZE 0x080 +#define PG_GLOBAL 0x100 + +__attribute__((aligned(4096))) uint64_t pml4[512]; +__attribute__((aligned(4096))) uint64_t pdp[512]; +__attribute__((aligned(4096))) uint64_t pd[512]; + +uint64_t +pg_setup() +{ + pml4[0] = (uint64_t)(uint32_t)pdp | PG_WRITE | PG_PRESENT; + pdp[0] = (uint64_t)(uint32_t)pd | PG_WRITE | PG_PRESENT; + for (unsigned i = 0; i < 512; i++) { + pd[i] = (i * (uint64_t)0x200000) | PG_WRITE | PG_PRESENT | PG_SIZE; + } + uint64_t cr3 = (uint64_t)(uint32_t)pml4; + return cr3; +} + void main() { @@ -72,6 +94,8 @@ main() bios_write(buf); } + pg_setup(); + #if 0 char foo[24]; @@ -109,6 +133,8 @@ main() reg[6] = 0; bios_func(0x10, reg); + bios_write("what?\r\n"); + for (;;) { __asm__ ("hlt"); }