Witam. Pisze sobie kod inicjujący jądro mojego nowego OS'a (IDYLLA OS) i napotkałem pewien problem podczas inicjalizacji GDT. Oto kod inicjujący jądro:

MBOOT_MODULEALIGN  equ 1 << 1
MBOOT_MEMINFO      equ 1 << 1
MBOOT_FLAGS        equ MBOOT_MODULEALIGN | MBOOT_MEMINFO
MBOOT_MAGIC        equ 0x1BADB002
MBOOT_CHECKSUM     equ -(MBOOT_MAGIC + MBOOT_FLAGS)

KERNEL_VIRT_ADDR   equ 0xC0100000
KERNEL_PHYS_ADDR   equ 0x00100000
KERNEL_VIRT_BASE   equ 0xC0000000
KERNEL_PAGE_NUMBER equ (KERNEL_VIRT_BASE >> 22)

KERNEL_CODE_SEL    equ 0x08
KERNEL_DATA_SEL    equ 0x10

KERNEL_STACK_SIZE  equ 0x1000
GDT_SIZE           equ 0x10000
IDT_SIZE           equ 0x800

GLOBAL _i586_loader
GLOBAL gdt
GLOBAL idt
GLOBAL kernel_pg_dir
EXTERN kmain, reroute_irqs, setup_gdt

[BITS 32]
[SECTION .text]
ALIGN 4
mboot_header:
       dd MBOOT_MAGIC
       dd MBOOT_FLAGS
       dd MBOOT_CHECKSUM

_i586_loader:
       mov ecx, (kernel_pg_dir - KERNEL_VIRT_BASE)
       mov cr3, ecx ;Load Page Dir

       mov ecx, cr4
       or ecx, 0x00000010 ; Set PSE bit in cr4
       mov cr4, ecx
       
       mov ecx, cr0
       or ecx, 0x80000000 ; Set PE bit in cr0
       mov cr0, ecx
       
       jmp KERNEL_CODE_SEL:after_paging
       
after_paging:       
       ;setup stack
       mov esp, kstack + KERNEL_STACK_SIZE
       
       ;Set eflags register
       push DWORD 0x2
       popfd
       
       push ebx
       push eax       
       
       call setup_gdt
       lgdt [gdt_descr]
       
       mov DWORD [kernel_pg_dir], 0 ;Unmap first 4 MB
       invlpg [0]
       
       jmp KERNEL_CODE_SEL:after_gdt
       
after_gdt:       
       call reroute_irqs
       lidt [idt_descr]
       
       call kmain
       
halt:
       inc BYTE [0xC00B8000]
       jmp halt

[SECTION .data]
kernel_pg_dir: ;Kernel page dir
       dd 0x00000083
       times (KERNEL_PAGE_NUMBER - 1) dd 0x00000000
       dd 0x00000083
       times (1024 - KERNEL_PAGE_NUMBER - 1) dd 0x00000000
       
gdt_descr:
       dw GDT_SIZE - 1
       dd (gdt - KERNEL_VIRT_BASE)

idt_descr:
       dw IDT_SIZE - 1
       dd (idt - KERNEL_VIRT_BASE)
       
[SECTION .bss]
ALIGN 32
kstack: resb KERNEL_STACK_SIZE
gdt:    resb GDT_SIZE
idt:    resb IDT_SIZE

Jednak po wykonaniu tego kodu otrzymuje Page Fault :/
Gdy zakomentuje lgdt to wszystko działa OK. Gdy ładuje GDT, ale nie odmapowuje pierwszych 4MB też jest OK. GDT test ustwaiane przez funkcje C setup_gdt i jest ono poprawne. Czy ktoś wie czemu tak się dzieje??
Korzystam ze stron o rozmiarze 4MB