diff options
Diffstat (limited to 'kernel/l0/loader.s')
-rw-r--r-- | kernel/l0/loader.s | 106 |
1 files changed, 58 insertions, 48 deletions
diff --git a/kernel/l0/loader.s b/kernel/l0/loader.s index a31fcf5..0f57549 100644 --- a/kernel/l0/loader.s +++ b/kernel/l0/loader.s @@ -1,69 +1,79 @@ -[EXTERN k_highhalf_addr] - +[EXTERN kmain] ; kmain is defined in kmain.c [GLOBAL loader] ; making entry point visible to linker -[EXTERN kmain] ; kmain is defined in kmain.c +; higher-half kernel setup +K_HIGHHALF_ADDR equ 0xC0000000 +K_PAGE_NUMBER equ (K_HIGHHALF_ADDR >> 22) ; loader stack size -LOADER_STACK_SIZE equ 0x8000 ; 8Kb +LOADER_STACK_SIZE equ 0x8000 ; 8Kb ; setting up the Multiboot header - see GRUB docs for details -MODULEALIGN equ 1<<0 ; align loaded modules on page boundaries -MEMINFO equ 1<<1 ; provide memory map -FLAGS equ MODULEALIGN | MEMINFO ; this is the Multiboot 'flag' field -MAGIC equ 0x1BADB002 ; 'magic number' lets bootloader find the header -CHECKSUM equ -(MAGIC + FLAGS) ; checksum required - -section .text +MODULEALIGN equ 1<<0 ; align loaded modules on page boundaries +MEMINFO equ 1<<1 ; provide memory map +FLAGS equ MODULEALIGN | MEMINFO ; this is the Multiboot 'flag' field +MAGIC equ 0x1BADB002 ; 'magic number' lets bootloader find the header +CHECKSUM equ -(MAGIC + FLAGS) ; checksum required + +[section .setup] align 4 -MultiBootHeader: - dd MAGIC - dd FLAGS - dd CHECKSUM - -section .setup -loader: ;here, we load our false GDT, used for having the kernel in higher half - lgdt [trickgdt] - mov cx, 0x10; - mov ds, cx; - mov es, cx; - mov fs, cx; - mov gs, cx; - mov ss, cx; - - jmp 0x08:higherhalf - -section .text -higherhalf: ; now we're running in higher half - mov esp, stack_top ; set up the stack +multiboot_header: + dd MAGIC + dd FLAGS + dd CHECKSUM - push eax ; pass Multiboot magic number - add ebx, k_highhalf_addr ; update the MB info structure so that it is in the new seg - push ebx ; pass Multiboot info structure +loader: + ; setup the boot page directory used for higher-half + mov ecx, boot_pagedir + mov cr3, ecx - call kmain ; call kernel proper + ; Set PSE bit in CR4 to enable 4MB pages. + mov ecx, cr4 + or ecx, 0x00000010 + mov cr4, ecx - cli ; disable interupts + ; Set PG bit in CR0 to enable paging. + mov ecx, cr0 + or ecx, 0x80000000 + mov cr0, ecx -hang: - hlt ; halt machine should kernel return - jmp hang + ; long jump required + lea ecx, [higherhalf] + jmp ecx -[section .setup] ; this is included in the .setup section, so that it thinks it is at 0x00100000 +align 0x1000 +boot_pagedir: + ; uses 4MB pages + ; identity-maps the first 4Mb of RAM, and also maps them with offset += k_highhalf_addr + dd 0x00000083 + times (K_PAGE_NUMBER - 1) dd 0 + dd 0x00000083 + times (1024 - K_PAGE_NUMBER - 1) dd 0 -trickgdt: ; our false GDT - dw gdt_end - gdt - 1 ; gdt limit - dd gdt ; gdt base +[section .text] +higherhalf: ; now we're running in higher half + ; unmap first 4Mb + mov dword [boot_pagedir], 0 + invlpg [0] + + mov esp, stack_top ; set up the stack -gdt: - dd 0, 0 ; null GDT entry - db 0xFF, 0xFF, 0, 0, 0, 10011010b, 11001111b, 0x40 ; kernel code segment - db 0xFF, 0xFF, 0, 0, 0, 10010010b, 11001111b, 0x40 ; kernel data segment + push eax ; pass Multiboot magic number + add ebx, K_HIGHHALF_ADDR ; update the MB info structure so that it is in higher half + push ebx ; pass Multiboot info structure -gdt_end: + call kmain ; call kernel proper + +hang: + ; halt machine should kernel return + cli + hlt + jmp hang [section .bss] align 4 stack_bottom: resb LOADER_STACK_SIZE stack_top: + +; vim: set ts=4 sw=4 tw=0 noet : |