Skip to content
This repository has been archived by the owner on Jan 12, 2025. It is now read-only.

Commit

Permalink
[feature] higher half kernel
Browse files Browse the repository at this point in the history
  • Loading branch information
lvntky committed Nov 10, 2023
1 parent 12b5865 commit 816c368
Show file tree
Hide file tree
Showing 8 changed files with 89 additions and 34 deletions.
76 changes: 57 additions & 19 deletions boot/loader.asm
Original file line number Diff line number Diff line change
Expand Up @@ -5,41 +5,79 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

[BITS 32]
[global loader]
[extern kernel_main] ; comes from kernel.c
[extern end_of_kernel] ; comes from linker.ld
global loader ; the entry point for the linker

extern kernel_main ; kmain is defined in kmain.c
extern end_of_kernel

; Setting up multibootheaders for GRUB
MODULEALIGN equ 1<<0 ; align loaded modules on page boundary
; setting up the multiboot headers for GRUB
MODULEALIGN equ 1<<0 ; align loaded modules on page
; boundaries
MEMINFO equ 1<<1 ; provide memory map
FLAGS equ MODULEALIGN | MEMINFO ; the multiboot flag field
MAGIC equ 0x1BADB002 ; magic number for bootloader to
; find the header
CHECKSUM equ -(MAGIC + FLAGS) ; checksum required

MEMINFO equ 1<<1 ; provide memory map
FLAGS equ MODULEALIGN | MEMINFO
MAGIC equ 0x1BADB002
; paging for the kernel
KERNEL_VIRTUAL_BASE equ 0xC0000000 ; we start at 3GB
KERNEL_PAGE_IDX equ (KERNEL_VIRTUAL_BASE >> 22) ; PDT index for 4MB PDE

CHECKSUM equ -(MAGIC + FLAGS) ; checksum required
; the page directory used to boot the kernel into the higher half
section .data
align 4096 ; align on 4kB blocks
boot_page_directory:
dd 00000000000000000000000010001011b ; identity mapped first 4MB
times (KERNEL_PAGE_IDX-1) dd 0 ; no pages here
dd 00000000000000000000000010001011b ; map 0xC0000000 to the first 4MB
times (1024-KERNEL_PAGE_IDX-1) dd 0 ; no more pages

section .text

section .text
align 4
dd MAGIC
dd FLAGS
dd CHECKSUM

; the entry point, called by GRUB
loader:
mov esp, stack+STACKSIZE ; set up the stack pointer
push end_of_kernel
push eax ; eax holds the MAGIC number
push ebx ; ebx holds the Multiboot info
mov ecx, (boot_page_directory-KERNEL_VIRTUAL_BASE)
and ecx, 0xFFFFF000 ; we only care about the upper 20 bits
or ecx, 0x08 ; PWT, enable page write through?
mov cr3, ecx ; load pdt

mov ecx, cr4 ; read current config from cr4
or ecx, 0x00000010 ; set bit enabling 4MB pages
mov cr4, ecx ; enable it by writing to cr4

call kernel_main
mov ecx, cr0 ; read current config from cr0
or ecx, 0x80000000 ; the highest bit controls paging
mov cr0, ecx ; enable paging by writing config to cr0

lea ecx, [higher_half] ; store the address higher_half in ecx
jmp ecx ; now we jump into 0xC0100000

; code executing from here on uses the page table, and is accessed through
; the upper half, 0xC0100000
higher_half:
mov DWORD [boot_page_directory], 0 ; erase identity mapping of kernel
invlpg [0] ; and flush any tlb-references to it

mov esp, stack+STACKSIZE ; sets up the stack pointer
push end_of_kernel
push eax ; eax contains the MAGIC number
push ebx ; ebx contains the multiboot data
; structure
call kernel_main ; call the main function of the kernel

hang:
jmp hang ; loop forever
jmp hang ; loop forever

; reserving initial stack size
STACKSIZE equ 0x4000 ; 16kB
; reserve initial stack space
STACKSIZE equ 0x4000 ; 16kB

section .bss
align 4
stack:
resb STACKSIZE ; reserve memory for stack on doubleworded memory
resb STACKSIZE ; reserve memory for stack on
; doubleworded memory
7 changes: 7 additions & 0 deletions kernel/include/common.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#ifndef _COMMON_H_
#define _COMMON_H_

#define UNUSED_ARGUMENT(x) (void)x;
#define KERNEL_BASE_ADDR 0xC0000000

#endif
3 changes: 2 additions & 1 deletion kernel/include/kernel.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

#include "multiboot_util.h"
#include "system.h"
#include "common.h"
#include "../libc/include/stdio.h"
#include "tty.h"
#include "qemu_debug.h"
Expand All @@ -19,6 +20,6 @@
#include "../../gui/render_image.h"
#include "options.h"

void kernel_main(multiboot_info_t *, uint32_t, uint32_t);
void kernel_main(uint32_t, uint32_t, uint32_t);

#endif
2 changes: 2 additions & 0 deletions kernel/include/multiboot_util.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@

#include <stdbool.h>
#include "multiboot.h"
#include "common.h"
#include "../libc/include/stdio.h"
#include "qemu_debug.h"
#include "panic.h"

void display_memory_info(multiboot_info_t *, uint32_t);
void check_mboot_bootloader_magic(uint32_t);
multiboot_info_t *remap_multiboot_info(uint32_t);

#endif
3 changes: 2 additions & 1 deletion kernel/include/tty.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@
#include "../libc/include/stdio.h"
#include "qemu_debug.h"
#include "config.h"
#include "common.h"
#include <stddef.h>
#include <stdint.h>

#define VIDEO_MEM_ADDRESS 0xB8000
#define VIDEO_MEM_ADDRESS 0xB8000 + KERNEL_BASE_ADDR
#define VGA_WIDTH 80
#define VGA_HEIGHT 25

Expand Down
6 changes: 3 additions & 3 deletions kernel/src/kernel.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ void test_idt()
__asm__("int $0x04");
}

void kernel_main(multiboot_info_t *mbinfo, uint32_t mbmagic,
uint32_t end_of_kernel)
void kernel_main(uint32_t mbaddr, uint32_t mbmagic, uint32_t end_of_kernel)
{
multiboot_info_t *mbinfo = remap_multiboot_info(mbaddr);
terminal_init();
gdt_init();
idt_init();
Expand All @@ -24,7 +24,7 @@ void kernel_main(multiboot_info_t *mbinfo, uint32_t mbmagic,
keyboard_init();
check_mboot_bootloader_magic(mbmagic);
display_memory_info(mbinfo, end_of_kernel);
paging_init(end_of_kernel);
//paging_init(end_of_kernel);

#if TEST_IDT
test_idt();
Expand Down
10 changes: 10 additions & 0 deletions kernel/src/multiboot_util.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
#include "../include/multiboot_util.h"

multiboot_info_t *remap_multiboot_info(uint32_t mbinfo_addr)
{
multiboot_info_t *mbinfo =
(multiboot_info_t *)(mbinfo_addr + KERNEL_BASE_ADDR);

mbinfo->mmap_addr += KERNEL_BASE_ADDR;

return mbinfo;
}

void display_memory_info(multiboot_info_t *mbinfo, uint32_t end_of_kernel)
{
qemu_write_string("\n%s %s START\n", DEBUG_OUTPUT, MEMORY_OUTPUT);
Expand Down
16 changes: 6 additions & 10 deletions linker.ld
Original file line number Diff line number Diff line change
Expand Up @@ -2,31 +2,27 @@ ENTRY(loader)

SECTIONS
{
. = 0x00100000;
. = 0xC0100000;

.text ALIGN (0x1000) :
.text ALIGN (0x1000) : AT(ADDR(.text)-0xC0000000)
{
*(.text)
}

.rodata ALIGN (0x1000) :
.rodata ALIGN (0x1000) : AT(ADDR(.rodata)-0xC0000000)
{
*(.rodata*)
}

.data ALIGN (0x1000) :
.data ALIGN (0x1000) : AT(ADDR(.data)-0xC0000000)
{
*(.data)
}

.bss :
.bss : AT(ADDR(.bss)-0xC0000000)
{
*(COMMON)
*(.bss)
}

. :
{
end_of_kernel = ALIGN(0x1000);
end_of_kernel = .;
}
}

0 comments on commit 816c368

Please sign in to comment.