Add simple kernel logging and improve error messages

This commit is contained in:
2026-07-23 20:50:51 +03:00
parent 14c3262c14
commit ba9beebf8e
7 changed files with 66 additions and 6 deletions
+1
View File
@@ -74,6 +74,7 @@ kernel_sources = files([
'src/kernel/idt.c', 'src/kernel/idt.c',
'src/kernel/kernel.c', 'src/kernel/kernel.c',
'src/kernel/keyboard.c', 'src/kernel/keyboard.c',
'src/kernel/log.c',
'src/kernel/memory.c', 'src/kernel/memory.c',
'src/kernel/panic.c', 'src/kernel/panic.c',
'src/kernel/path.c', 'src/kernel/path.c',
+4
View File
@@ -38,3 +38,7 @@ void idt_set_entry(int vector, void (*handler)(struct interrupt_frame *), uint8_
idt[vector].offset_high = (addr >> 32) & 0xFFFFFFFF; idt[vector].offset_high = (addr >> 32) & 0xFFFFFFFF;
idt[vector].zero = 0; idt[vector].zero = 0;
} }
void idt_set_entry_ec(int vector, void (*handler)(struct interrupt_frame *, uint64_t error), uint8_t flags) {
idt_set_entry(vector, (void *)handler, flags);
}
+2
View File
@@ -13,3 +13,5 @@ struct interrupt_frame {
void idt_init(); void idt_init();
void idt_set_entry(int vector, void (*handler)(struct interrupt_frame *), uint8_t flags); void idt_set_entry(int vector, void (*handler)(struct interrupt_frame *), uint8_t flags);
void idt_set_entry_ec(int vector, void (*handler)(struct interrupt_frame *, uint64_t error), uint8_t flags);
+15 -5
View File
@@ -2,11 +2,13 @@
#include "src/kernel/gdt.h" #include "src/kernel/gdt.h"
#include "src/kernel/idt.h" #include "src/kernel/idt.h"
#include "src/kernel/keyboard.h" #include "src/kernel/keyboard.h"
#include "src/kernel/log.h"
#include "src/kernel/panic.h" #include "src/kernel/panic.h"
#include "src/kernel/path.h" #include "src/kernel/path.h"
#include "src/kernel/pic.h" #include "src/kernel/pic.h"
#include "src/kernel/pipe.h" #include "src/kernel/pipe.h"
#include "src/kernel/process.h" #include "src/kernel/process.h"
#include "src/kernel/stream.h"
#include "src/kernel/syscall.h" #include "src/kernel/syscall.h"
#include "src/kernel/timer.h" #include "src/kernel/timer.h"
#include "src/kernel/tss.h" #include "src/kernel/tss.h"
@@ -22,8 +24,14 @@ __attribute__((interrupt)) void isr_divide_by_zero(__attribute__((unused)) struc
; ;
} }
__attribute__((interrupt)) void isr_page_fault(__attribute__((unused)) struct interrupt_frame *frame) { __attribute__((interrupt)) void isr_page_fault(__attribute__((unused)) struct interrupt_frame *frame, uint64_t error_code) {
vga_set_string(VGA_HEIGHT - 1, 0, "EXCEPTION: page fault", 0x4F); uint64_t cr2;
__asm__ volatile("mov %%cr2, %0" : "=r"(cr2));
char msg[80];
string_format("EXCEPTION: page fault; addr=%x err=%x", 80, msg, cr2, error_code);
vga_set_string(VGA_HEIGHT - 1, 0, msg, 0x4F);
while (1) while (1)
; ;
} }
@@ -40,11 +48,14 @@ __attribute__((interrupt)) void isr_ata_primary(__attribute__((unused)) struct i
} }
void kernel_main() { void kernel_main() {
stream_t *vga = vga_init();
log_init(vga);
pic_init(); pic_init();
idt_init(); idt_init();
outb(0x21, inb(0x21) | 0x01); // mask out timer interrupt outb(0x21, inb(0x21) | 0x01); // mask out timer interrupt
idt_set_entry(0, isr_divide_by_zero, 0x8E); idt_set_entry(0, isr_divide_by_zero, 0x8E);
idt_set_entry(0x0E, isr_page_fault, 0x8E); idt_set_entry_ec(0x0E, isr_page_fault, 0x8E);
idt_set_entry(0x0D, isr_general_violation, 0x8E); idt_set_entry(0x0D, isr_general_violation, 0x8E);
idt_set_entry(46, isr_ata_primary, 0x8E); idt_set_entry(46, isr_ata_primary, 0x8E);
@@ -59,8 +70,7 @@ void kernel_main() {
kernel->user_stack = kernel->user_rsp = (uint8_t *)memory_allocate(PAGE_SIZE) + PAGE_SIZE; kernel->user_stack = kernel->user_rsp = (uint8_t *)memory_allocate(PAGE_SIZE) + PAGE_SIZE;
kernel->cwd = memory_allocate(sizeof(path_t)); kernel->cwd = memory_allocate(sizeof(path_t));
kernel->fds[STDIN] = keyboard_init(); kernel->fds[STDIN] = keyboard_init();
kernel->fds[STDOUT] = vga_init(); kernel->fds[STDOUT] = kernel->fds[STDERR] = vga;
kernel->fds[STDERR] = kernel->fds[STDOUT];
kernel->free_fd = STDERR + 1; kernel->free_fd = STDERR + 1;
kernel->code = EXIT_CODE_OK; kernel->code = EXIT_CODE_OK;
+8
View File
@@ -0,0 +1,8 @@
#include "src/kernel/log.h"
#include "src/kernel/stream.h"
stream_t *kernel_log;
void log_init(stream_t *log) {
kernel_log = log;
}
+20
View File
@@ -0,0 +1,20 @@
#pragma once
#include "src/kernel/stream.h"
#include "src/lib/memory.h"
#include "src/lib/string.h"
extern stream_t *kernel_log;
#define LOG(fmt, ...) \
do { \
uint64_t _size = string_length(fmt) * 2; \
char *_string = memory_allocate(_size); \
_size = string_format(fmt, _size, _string, ##__VA_ARGS__); \
kernel_log->write(kernel_log, _string, _size); \
memory_free(_string); \
} while (0)
#define TRACE(fmt, ...)
void log_init(stream_t *log);
+16 -1
View File
@@ -1,4 +1,5 @@
#include "src/kernel/memory.h" #include "src/kernel/memory.h"
#include "src/kernel/log.h"
#include "src/kernel/panic.h" #include "src/kernel/panic.h"
#include "src/lib/layout.h" #include "src/lib/layout.h"
#include "src/lib/memory.h" #include "src/lib/memory.h"
@@ -66,7 +67,10 @@ void memory_page_map(uint64_t *pml4, void *virt, void *phys, uint64_t flags) {
const uint64_t pd_index = (ivirt >> 21) & 0x1FF; const uint64_t pd_index = (ivirt >> 21) & 0x1FF;
const uint64_t pt_index = (ivirt >> 12) & 0x1FF; const uint64_t pt_index = (ivirt >> 12) & 0x1FF;
TRACE("memory_page_map: Mapping physical %x to virtual %x / [%u, %u, %u, %u]...\n", phys, virt, pml4_index, pdpt_index, pd_index, pt_index);
if (!(pml4[pml4_index] & PAGE_PRESENT)) { if (!(pml4[pml4_index] & PAGE_PRESENT)) {
TRACE("memory_page_map: PML4 entry %u does not exist, creating...\n", pml4_index);
uint64_t *pdpt = memory_page_allocate(); uint64_t *pdpt = memory_page_allocate();
memory_set(0, PAGE_SIZE, PHYS_TO_VIRT(pdpt)); memory_set(0, PAGE_SIZE, PHYS_TO_VIRT(pdpt));
pml4[pml4_index] = (uint64_t)pdpt | PAGE_PRESENT | PAGE_WRITABLE | PAGE_USER; pml4[pml4_index] = (uint64_t)pdpt | PAGE_PRESENT | PAGE_WRITABLE | PAGE_USER;
@@ -74,21 +78,32 @@ void memory_page_map(uint64_t *pml4, void *virt, void *phys, uint64_t flags) {
uint64_t *pdpt = PHYS_TO_VIRT(pml4[pml4_index] & ~(uint64_t)0xFFF); uint64_t *pdpt = PHYS_TO_VIRT(pml4[pml4_index] & ~(uint64_t)0xFFF);
if (!(pdpt[pdpt_index] & PAGE_PRESENT)) { if (!(pdpt[pdpt_index] & PAGE_PRESENT)) {
TRACE("memory_page_map: PDPT entry %u does not exist, creating...\n", pdpt_index);
uint64_t *pd = memory_page_allocate(); uint64_t *pd = memory_page_allocate();
memory_set(0, PAGE_SIZE, PHYS_TO_VIRT(pd)); memory_set(0, PAGE_SIZE, PHYS_TO_VIRT(pd));
pdpt[pdpt_index] = (uint64_t)pd | PAGE_PRESENT | PAGE_WRITABLE | PAGE_USER; pdpt[pdpt_index] = (uint64_t)pd | PAGE_PRESENT | PAGE_WRITABLE | PAGE_USER;
} }
uint64_t *pd = PHYS_TO_VIRT(pdpt[pdpt_index] & ~(uint64_t)0xFFF); uint64_t *pd = PHYS_TO_VIRT(pdpt[pdpt_index] & ~(uint64_t)0xFFF);
ASSERT(!(pd[pd_index] & 0x80), "memory_page_map: huge page in PD"); ASSERT(!(pd[pd_index] & 0x80), "memory_page_map: Huge page in PD.");
if (!(pd[pd_index] & PAGE_PRESENT)) { if (!(pd[pd_index] & PAGE_PRESENT)) {
TRACE("memory_page_map: PD entry %u does not exist, creating...\n", pd_index);
uint64_t *pt = memory_page_allocate(); uint64_t *pt = memory_page_allocate();
memory_set(0, PAGE_SIZE, PHYS_TO_VIRT(pt)); memory_set(0, PAGE_SIZE, PHYS_TO_VIRT(pt));
pd[pd_index] = (uint64_t)pt | PAGE_PRESENT | PAGE_WRITABLE | PAGE_USER; pd[pd_index] = (uint64_t)pt | PAGE_PRESENT | PAGE_WRITABLE | PAGE_USER;
} }
uint64_t *pt = PHYS_TO_VIRT(pd[pd_index] & ~(uint64_t)0xFFF); uint64_t *pt = PHYS_TO_VIRT(pd[pd_index] & ~(uint64_t)0xFFF);
ASSERT(!(pt[pt_index] & PAGE_PRESENT), "memory_page_map: Page already mapped.")
TRACE("memory_page_map: PT entry %u does not exist, creating...\n", pt_index);
pt[pt_index] = (uint64_t)phys | flags | PAGE_PRESENT; pt[pt_index] = (uint64_t)phys | flags | PAGE_PRESENT;
TRACE("memory_page_map: Created %x.\n", pt[pt_index]);
TRACE("memory_page_map: Done.\n");
} }
void memory_page_unmap(uint64_t *pml4, void *virt) { void memory_page_unmap(uint64_t *pml4, void *virt) {