So, consider the following (not working code):
Code: Select all
static void i386_lgdt(uint32 base, uint32 limit)
{
uint32 desc[2] = { limit << 16, base };
char *ptr = ( (char *) desc ) + 2;
__asm__ __volatile__
(
"lgdt (%0)\n"
"ljmp $0x08, $.i386_lgdt_jump\n"
".i386_lgdt_jump:\n"
"movw $0x10, %%ax\n"
"movw %%ax, %%ds\n"
"movw %%ax, %%es\n"
"movw %%ax, %%fs\n"
"movw %%ax, %%gs\n"
"movw %%ax, %%ss\n"
:
: "r" (ptr)
);
}
Code: Select all
load_gdtr:
push ebp
mov ebp, esp
sub esp, 6 ; need 6 bytes for data structure of LGDT
mov eax, param1 ; the address parameter
mov dword [ebp - 4], eax
mov eax, param2 ; the size parameter
dec eax ; limit = size - 1
mov word [ebp - 6], ax
lgdt [ebp - 6]
jmp dword CodeSel:.jump
.jump
mov ax, DataSel ; Kernel Data Selector
; load flat address data
mov ds, ax ; selector in every data
mov es, ax ; segment register
mov fs, ax ; GCC compiled code works
mov gs, ax ; with flat addressing mode
mov ax, StackSel
mov ss, ax
mov esp, ebp
pop ebp
ret
It pretty much sets up the table descriptor, gives it to LGDT, far jumps, and reloads the segment selectors. Bochs picks up an exception when it executes the LJMP instruction in the C function. I can't figure out what is going wrong.
