[extern main] [extern _kernel_stack_loc] [extern _stage1_pagetable] enter_longmode: cli ; TODO check if a20 is already set mov al, 0x92 or al, 2 out 0x92, al lgdt [protected_gdt.descriptor] mov eax, cr0 or eax, 0x1 mov cr0, eax mov eax, 0x8 mov ds, eax jmp 0x8:init_longmode bits 32 init_longmode: mov ebp, 0xffff mov esp, ebp mov ax, PROTECTED_DATA_SEGMENT mov ds, ax mov ss, ax mov es, ax mov fs, ax mov gs, ax mov edi, _stage1_pagetable ; 0x3000 mov cr3, edi mov eax, 0 mov ecx, 0xc00 ; 0x1000 rep stosd mov edi, cr3 mov DWORD [edi], _stage1_pagetable + 0x1003 ; pml4e[0] = pdpe add edi, 0x1000 mov DWORD [edi], _stage1_pagetable + 0x2003 ; pdpe[0] = pde add edi, 0x1000 mov DWORD [edi], 0x83 ; pde[0] = pte mov eax, cr4 or eax, 0x620 mov cr4, eax ;end of setting up pages mov ecx, 0xc0000080 rdmsr or eax, 1 << 8 wrmsr mov eax, cr0 or eax, 1 << 31 | 1 << 0 ; this is where we set paging and protected mode (respectively)! mov cr0, eax mov ecx, 0xc0000080 rdmsr or eax, 1 << 8 wrmsr mov eax, cr0 and ax, 0xfffb or eax, 0x80000002 mov cr0, eax lgdt [long_gdt.descriptor] jmp LONG_CODE_SEGMENT:enter_kernel enter_kernel: bits 64 mov rbp, _kernel_stack_loc mov rsp, _kernel_stack_loc call main ; where we actually call the kernel jmp $ ret