Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 34 additions & 7 deletions arch/x86_64/asm/pxs.asm
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ start:
; Setup page tables
; Zero out the tables first
mov edi, pml4_table
mov ecx, 4096 * 3 ; 3 pages to clear (PML4, PDP, PD)
mov ecx, 4096 * 6 ; 6 pages to clear (PML4, PDP, PD1, PD2, PD3, PD4)
xor eax, eax
rep stosb

Expand All @@ -87,25 +87,49 @@ start:
mov cr3, eax
debug_print '4' ; CR3 Loaded

; Map the first 16MB of memory
; Map the first 4GB of memory
; PML4[0] -> PDP Table
mov edi, pml4_table
lea eax, [pdp_table + 3] ; Address of PDP table + Present, R/W flags
mov [edi], eax

; PDP[0] -> PD Table
; PDP[0] -> PD Table 1 (0-1GB)
mov edi, pdp_table
lea eax, [pd_table + 3] ; Address of PD table + Present, R/W flags
mov [edi], eax

; Map 8 * 2MB pages = 16MB in the Page Directory

; PDP[1] -> PD Table 2 (1-2GB)
lea eax, [pd_table2 + 3]
mov [edi + 8], eax

; PDP[2] -> PD Table 3 (2-3GB)
lea eax, [pd_table3 + 3]
mov [edi + 16], eax

; PDP[3] -> PD Table 4 (3-4GB)
lea eax, [pd_table4 + 3]
mov [edi + 24], eax

; Map 4GB total (4 * 512 * 2MB pages)
mov edi, pd_table
mov ecx, 8
mov eax, 0x83 ; Present, R/W, 2MB page size
mov ecx, 2048 ; 4 * 512 = 2048 entries for 4GB
mov eax, 0x83 ; Present, R/W, 2MB page size
.map_loop:
mov [edi], eax
add edi, 8
add eax, 0x200000 ; Next 2MB physical frame

; Check if we need to move to next PD table
cmp edi, pd_table2
jl .continue_loop
cmp edi, pd_table3
jl .continue_loop
cmp edi, pd_table4
jl .continue_loop
cmp edi, pd_table4 + 4096
jl .continue_loop

.continue_loop:
loop .map_loop
debug_print '5' ; Memory Mapped

Expand Down Expand Up @@ -247,6 +271,9 @@ align 4096
pml4_table: resb 4096
pdp_table: resb 4096
pd_table: resb 4096
pd_table2: resb 4096
pd_table3: resb 4096
pd_table4: resb 4096

align 16
stack_bottom: resb 8192 ; 8KB stack
Expand Down
28 changes: 8 additions & 20 deletions kernel/core/Kernel.c
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,7 @@ void KernelMain(const uint32_t magic, const uint32_t info) {
PrintKernelHex(magic);
PrintKernel(", Info: ");
PrintKernelHex(info);
PrintKernel("\n\n");
PrintKernel("\n");
ParseMultibootInfo(info);

// Initialize physical memory manager first
Expand All @@ -270,49 +270,37 @@ void KernelMain(const uint32_t magic, const uint32_t info) {
void* pml4_phys = AllocPage();
if (!pml4_phys) PANIC("Failed to allocate PML4");

// Validate allocated page before use
if ((uint64_t)pml4_phys & 0xFFF) PANIC("PML4 not page-aligned");
if ((uint64_t)pml4_phys < 0x100000) PANIC("PML4 in low memory");

FastZeroPage(pml4_phys);
uint64_t pml4_addr = (uint64_t)pml4_phys;

PrintKernelSuccess("[SYSTEM] Bootstrap: Identity mapping low memory...\n");
// Batch allocate pages for better performance
uint32_t pages_needed = IDENTITY_MAP_SIZE / PAGE_SIZE;
PrintKernel("[INFO] Mapping ");
PrintKernelInt(pages_needed);
PrintKernel(" pages for identity mapping\n");
PrintKernelSuccess("[SYSTEM] Bootstrap: Identity mapping 1GB...\n");
// Map 1GB instead of 3GB to avoid the crash but still have plenty of memory
uint32_t pages_needed = (1024 * 1024 * 1024) / PAGE_SIZE; // 1GB

for (uint64_t paddr = 0; paddr < IDENTITY_MAP_SIZE; paddr += PAGE_SIZE) {
for (uint64_t paddr = 0; paddr < (1024ULL * 1024 * 1024); paddr += PAGE_SIZE) {
BootstrapMapPage(pml4_addr, paddr, paddr, PAGE_WRITABLE);

// Progress indicator for large mappings
if ((paddr / PAGE_SIZE) % 1024 == 0) {
PrintKernel(".");
}
}
PrintKernel("\n");

PrintKernelSuccess("[SYSTEM] Bootstrap: Mapping kernel...\n");
uint64_t kernel_start = (uint64_t)_kernel_phys_start & ~0xFFF; // Page-align
uint64_t kernel_end = ((uint64_t)_kernel_phys_end + 0xFFF) & ~0xFFF; // Round up
uint64_t kernel_start = (uint64_t)_kernel_phys_start & ~0xFFF;
uint64_t kernel_end = ((uint64_t)_kernel_phys_end + 0xFFF) & ~0xFFF;
for (uint64_t paddr = kernel_start; paddr < kernel_end; paddr += PAGE_SIZE) {
BootstrapMapPage(pml4_addr, paddr + KERNEL_VIRTUAL_OFFSET, paddr, PAGE_WRITABLE);
}

PrintKernelSuccess("[SYSTEM] Bootstrap: Mapping kernel stack with guard pages...\n");
PrintKernelSuccess("[SYSTEM] Bootstrap: Mapping kernel stack...\n");
uint64_t stack_phys_start = (uint64_t)kernel_stack & ~0xFFF;
uint64_t stack_phys_end = ((uint64_t)kernel_stack + KERNEL_STACK_SIZE + 0xFFF) & ~0xFFF;

// Map actual stack
for (uint64_t paddr = stack_phys_start; paddr < stack_phys_end; paddr += PAGE_SIZE) {
BootstrapMapPage(pml4_addr, paddr + KERNEL_VIRTUAL_OFFSET, paddr, PAGE_WRITABLE);
}

// Create guard page AFTER stack (unmapped)
PrintKernel("[GUARD] Stack guard page after stack (unmapped)\n");

PrintKernelSuccess("[SYSTEM] Page tables prepared. Switching to virtual addressing...\n");
const uint64_t new_stack_top = ((uint64_t)kernel_stack + KERNEL_VIRTUAL_OFFSET) + KERNEL_STACK_SIZE;
const uint64_t higher_half_entry = (uint64_t)&KernelMainHigherHalf + KERNEL_VIRTUAL_OFFSET;
Expand Down
13 changes: 12 additions & 1 deletion kernel/etc/Console.c
Original file line number Diff line number Diff line change
@@ -1,10 +1,18 @@
#include "Console.h"

#include "Io.h"
#include "Serial.h"
#include "Spinlock.h"
#include "stdbool.h"
#include "stdint.h"

static void UpdateCursor(void) {
uint16_t pos = console.line * VGA_WIDTH + console.column;
outb(0x3D4, 0x0F);
outb(0x3D5, (uint8_t)(pos & 0xFF));
outb(0x3D4, 0x0E);
outb(0x3D5, (uint8_t)((pos >> 8) & 0xFF));
}

static volatile int lock = 0;
// Inline functions for better performance
static void ConsoleSetColor(uint8_t color) {
Expand Down Expand Up @@ -37,6 +45,7 @@ void ClearScreen(void) {

console.line = 0;
console.column = 0;
UpdateCursor();
SpinUnlock(&lock);;
}

Expand Down Expand Up @@ -93,6 +102,8 @@ static void ConsolePutchar(char c) {
ConsoleScroll();
console.line = VGA_HEIGHT - 1;
}

UpdateCursor();
}

// Modern string output with length checking
Expand Down
Loading