paging at boot works now!!!!

This commit is contained in:
Justus Wolff
2026-04-05 03:16:50 +02:00
parent ef151a8385
commit fd968a06ce
5 changed files with 105 additions and 50 deletions

View File

@@ -1,30 +1,25 @@
ENTRY(_start) ENTRY(_start)
KERNEL_VIRT_BASE = 0xC0000000;
KERNEL_PHYS_BASE = 0x00100000;
SECTIONS { SECTIONS {
. = ALIGN(8); . = KERNEL_VIRT_BASE;
.boot : {
KEEP(*(.multiboot)) .text : AT(KERNEL_PHYS_BASE) {
*(.text)
} }
. = 1M; /* Load kernel at 1MB */
.text BLOCK(4K) : ALIGN(4K) .rodata : AT(KERNEL_PHYS_BASE + (ADDR(.rodata) - KERNEL_VIRT_BASE)) {
{ *(.rodata)
*(.text) }
}
.rodata BLOCK(4K) : ALIGN(4K) .data : AT(KERNEL_PHYS_BASE + (ADDR(.data) - KERNEL_VIRT_BASE)) {
{ *(.data)
*(.rodata) }
}
.data BLOCK(4K) : ALIGN(4K) .bss : AT(KERNEL_PHYS_BASE + (ADDR(.bss) - KERNEL_VIRT_BASE)) {
{ *(COMMON)
*(.data) *(.bss)
} }
.bss BLOCK(4K) : ALIGN(4K)
{
*(COMMON)
*(.bss)
}
} }

View File

@@ -22,7 +22,7 @@ gdt_end:
gdt_descriptor: gdt_descriptor:
dw gdt_end - gdt_start - 1 dw gdt_end - gdt_start - 1
dd gdt_start dd gdt_start - 0xC0000000 + 0x00100000 ; paging, thank me later.
CODE_SEG equ gdt_code - gdt_start CODE_SEG equ gdt_code - gdt_start
DATA_SEG equ gdt_data - gdt_start DATA_SEG equ gdt_data - gdt_start

View File

@@ -1,8 +1,17 @@
; TODO:
; load GDT [x]
; enter long m. [x]
; enable paging [x]
; fix damn grub parameter passing [x]
; constants for multiboot ; constants for multiboot
MAGIC equ 0xE85250D6 MAGIC equ 0xE85250D6
ARCH equ 0 ; 0 for i386, 4 for MIPS ARCH equ 0 ; 0 for i386, 4 for MIPS
HDRLEN equ 24 ; Total length: 4 fields + end tag HDRLEN equ 24 ; Total length: 4 fields + end tag
CHECKSUM equ -(MAGIC + ARCH + HDRLEN) CHECKSUM equ -(MAGIC + ARCH + HDRLEN)
KERNEL_VIRT_BASE equ 0xC0000000
KERNEL_PHYS_BASE equ 0x00100000
KERNEL_OFFSET equ (-KERNEL_VIRT_BASE)+KERNEL_PHYS_BASE
section .multiboot_header section .multiboot_header
align 8 align 8
@@ -25,6 +34,16 @@ stack_bottom:
resb 16384 ; 16 KiB is reserved for stack resb 16384 ; 16 KiB is reserved for stack
stack_top: stack_top:
align 4096
PAG_mainPD:
resd 1024
align 4096
PAG_identityPT:
resd 1024
align 4096
PAG_kernelPT:
resd 1024
section .rodata section .rodata
%include "src/bootload/GDT.asm" %include "src/bootload/GDT.asm"
@@ -32,24 +51,12 @@ section .text ; entrypoint for bootloader
[BITS 32] [BITS 32]
global _start:function (_start.end - _start) global _start:function (_start.end - _start)
_start: _start:
; To set up a stack, we set the esp register to point to the top of our
; stack (as it grows downwards on x86 systems). This is necessarily done
; in assembly as languages such as C cannot function without a stack.
mov esp, stack_top
mov ebp, esp
mov ecx, eax ; move multiboot magic number to ecx
; TODO:
; load GDT [x]
; enter long m. [ ]
; init FPU [ ]
; load GDT
cli cli
lgdt [gdt_descriptor] lgdt [gdt_descriptor + KERNEL_OFFSET]
jmp CODE_SEG:.final ; if I get problems, check this line here, future me! jmp CODE_SEG:.final + KERNEL_OFFSET ; if I get problems, check this line here, future me!
.final: .final:
mov edx, eax ; we need the boot shit from grub still
; so now eax -> edx and ebx -> ebx
mov AX, DATA_SEG ; data segment selectors mov AX, DATA_SEG ; data segment selectors
mov DS, AX mov DS, AX
mov ES, AX mov ES, AX
@@ -57,8 +64,53 @@ _start:
mov GS, AX mov GS, AX
mov SS, AX mov SS, AX
push ecx ; magic number mov ecx, 1024 ; 1024 * 4KB = 4MB
push ebx ; info structure mov edi, PAG_identityPT + KERNEL_OFFSET
mov eax, 0
.fill_identity:
mov [edi], eax
or dword [edi], 0x3
add eax, 0x1000
add edi, 4
loop .fill_identity
mov ecx, 1024
mov edi, PAG_kernelPT + KERNEL_OFFSET
mov eax, KERNEL_PHYS_BASE
.fill_kernel:
mov [edi], eax
or dword [edi], 0x3
add eax, 0x1000
add edi, 4
loop .fill_kernel
; identity PT = entry 0
mov eax, PAG_identityPT + KERNEL_OFFSET
or eax, 0x3
mov [PAG_mainPD + KERNEL_OFFSET + 0*4], eax
; kernel PT = entry 768
mov eax, PAG_kernelPT + KERNEL_OFFSET
or eax, 0x3
mov [PAG_mainPD + KERNEL_OFFSET + 768*4], eax
mov eax, PAG_mainPD + KERNEL_OFFSET
mov cr3, eax
mov eax, cr0
or eax, 0x80000000
mov cr0, eax
jmp .pagingfinished
.pagingfinished
; fix stack once again and since we need to keep the contents, we just add an offset
mov esp, stack_top
mov ebp, stack_bottom
push edx
push ebx
extern kernel_main extern kernel_main
call kernel_main call kernel_main
add esp, 8 ; remove arguments add esp, 8 ; remove arguments

View File

@@ -0,0 +1,9 @@
#include "stddef.h"
#include "stdlib.h"
typedef uint32_t PAG_PT_entry_t;
typedef PAG_PT_entry_t PAG_PT_t[1024];
typedef PAG_PT_t PAG_PD_t[1024];
extern PAG_PD_t PAG_mainPD;

View File

@@ -32,15 +32,9 @@ void kernel_main(struct multiboot_info* header, uint32_t magic) {
kputstr("Hello JPOS, World!\n"); kputstr("Hello JPOS, World!\n");
if (magic != MULTIBOOT2_BOOTLOADER_MAGIC) {
kputstr("Invalid magic from bootloader.\n");
return;
}
kputstr("Got past magic check.\n");
kputstr("Entering Graphics mode: "); kputstr("Entering Graphics mode: ");
VGA_switch(VGA_values); VGA_switch(VGA_values);
*(uint8_t*)0xA0000 = 1;
kputstr("OK\n"); kputstr("OK\n");
VGA_clear((VGA_pixel){0xFF,0xFF,0xFF}); VGA_clear((VGA_pixel){0xFF,0xFF,0xFF});
@@ -56,6 +50,13 @@ void kernel_main(struct multiboot_info* header, uint32_t magic) {
} }
kputstr("OK\n"); kputstr("OK\n");
if (magic != MULTIBOOT2_BOOTLOADER_MAGIC) {
kputstr("Invalid magic from bootloader.\n");
return;
}
kputstr("Got past magic check.\n");
kputstr("Setting up IRQs: "); kputstr("Setting up IRQs: ");
for (uint8_t i=0;i<16;i++) { for (uint8_t i=0;i<16;i++) {
idt_set_descriptor(i+0x20, irq_stub_table[i], 0x8E); idt_set_descriptor(i+0x20, irq_stub_table[i], 0x8E);
@@ -86,7 +87,5 @@ void kernel_main(struct multiboot_info* header, uint32_t magic) {
IRQ_registerhandler(0x00, &tick); IRQ_registerhandler(0x00, &tick);
while (1) {} while (1) {}
} }