/* asm.h */ #ifndef _ASM_H #define _ASM_H typedef struct{ unsigned short limit; unsigned short base; } gdtptr; typedef struct { unsigned short limit_low; unsigned short base_low; unsigned char base_middle; unsigned char access; unsigned char granularity; unsigned char base_high; } gdtentry; volatile gdtptr gdtaddr; void pmode(void); #endif /* */ /* ----- protected_mode.S --- */ .text .globl _pmode, pmode pmode: _pmode: cli /* atomic */ lgdt gdtaddr /* point it */ mov %eax, %cr0 or %eax, 1 mov %cr0, %eax jmp somewhere_else /* to clear out the instruction prefetch queue */ nop somewhere_else: sti /* end of atomic */ ret /* */ /* -- kern_main.c -- */ #include #include void kern_main(unsigned long mbpointer) { volatile unsigned char *video; video = (unsigned char *) 0xB8052; *video = 0x48 & 0xFF; *(video+2) = 0x49 & 0xFF; gdtentry mygdt[3]; mygdt[0].limit_low = 0; mygdt[0].base_low = 0; mygdt[0].base_middle = 0; mygdt[0].access = 0; mygdt[0].granularity = 0; mygdt[0].base_high = 0; gdtaddr.base = &mygdt; gdtaddr.limit = (3 * sizeof(gdtentry)) - 1; mygdt[1].limit_low = (0xFFFFFFFF & 0xFFFF); mygdt[1].base_low = 0; mygdt[1].base_middle = 0; mygdt[1].access = 0x9A; mygdt[1].granularity = ((0xFFFFFFFF >> 16) & 0x0F); mygdt[1].granularity |= (0xCF & 0xF0); mygdt[1].base_high = 0; mygdt[2].limit_low = (0xFFFFFFFF & 0xFFFF); mygdt[2].base_low = 0; mygdt[2].base_middle = 0; mygdt[2].access = 0x92; mygdt[2].granularity = ((0xFFFFFFFF >> 16) & 0x0F); mygdt[2].granularity |= (0xCF & 0xF0); mygdt[2].base_high = 0; pmode(); *(video+8) = 0x4A & 0xFF; } /* */