aboutsummaryrefslogtreecommitdiff
path: root/kernel/l0/loader.s
diff options
context:
space:
mode:
authorAlex Auvolat <alex.auvolat@ens.fr>2014-12-01 17:24:38 +0100
committerAlex Auvolat <alex.auvolat@ens.fr>2014-12-01 17:24:38 +0100
commit0921a33fc9f3724cb36a03a24b58b0a5bfc519b1 (patch)
tree6f3db52ba8c38928749806cb2d94ca548b3b19bd /kernel/l0/loader.s
parent6f11c9e5c15cc8ef936741e5ee7575b731a47e0f (diff)
downloadkogata-0921a33fc9f3724cb36a03a24b58b0a5bfc519b1.tar.gz
kogata-0921a33fc9f3724cb36a03a24b58b0a5bfc519b1.zip
Advance HH, GDT, IDT (details below)
- Implement higher-half in loader with paging (using 4Mb pages) - Add GDT installation code - Add IDT installation code (spend a loong time debugging the ISRs!) - Add CDROM generation scripts - Add scripts to launch bochs (debug) and qemu (debug)
Diffstat (limited to 'kernel/l0/loader.s')
-rw-r--r--kernel/l0/loader.s106
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 :