Add simple kernel logging and improve error messages
This commit is contained in:
@@ -74,6 +74,7 @@ kernel_sources = files([
|
||||
'src/kernel/idt.c',
|
||||
'src/kernel/kernel.c',
|
||||
'src/kernel/keyboard.c',
|
||||
'src/kernel/log.c',
|
||||
'src/kernel/memory.c',
|
||||
'src/kernel/panic.c',
|
||||
'src/kernel/path.c',
|
||||
|
||||
@@ -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].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);
|
||||
}
|
||||
|
||||
@@ -13,3 +13,5 @@ struct interrupt_frame {
|
||||
void idt_init();
|
||||
|
||||
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
@@ -2,11 +2,13 @@
|
||||
#include "src/kernel/gdt.h"
|
||||
#include "src/kernel/idt.h"
|
||||
#include "src/kernel/keyboard.h"
|
||||
#include "src/kernel/log.h"
|
||||
#include "src/kernel/panic.h"
|
||||
#include "src/kernel/path.h"
|
||||
#include "src/kernel/pic.h"
|
||||
#include "src/kernel/pipe.h"
|
||||
#include "src/kernel/process.h"
|
||||
#include "src/kernel/stream.h"
|
||||
#include "src/kernel/syscall.h"
|
||||
#include "src/kernel/timer.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) {
|
||||
vga_set_string(VGA_HEIGHT - 1, 0, "EXCEPTION: page fault", 0x4F);
|
||||
__attribute__((interrupt)) void isr_page_fault(__attribute__((unused)) struct interrupt_frame *frame, uint64_t error_code) {
|
||||
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)
|
||||
;
|
||||
}
|
||||
@@ -40,11 +48,14 @@ __attribute__((interrupt)) void isr_ata_primary(__attribute__((unused)) struct i
|
||||
}
|
||||
|
||||
void kernel_main() {
|
||||
stream_t *vga = vga_init();
|
||||
log_init(vga);
|
||||
|
||||
pic_init();
|
||||
idt_init();
|
||||
outb(0x21, inb(0x21) | 0x01); // mask out timer interrupt
|
||||
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(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->cwd = memory_allocate(sizeof(path_t));
|
||||
kernel->fds[STDIN] = keyboard_init();
|
||||
kernel->fds[STDOUT] = vga_init();
|
||||
kernel->fds[STDERR] = kernel->fds[STDOUT];
|
||||
kernel->fds[STDOUT] = kernel->fds[STDERR] = vga;
|
||||
kernel->free_fd = STDERR + 1;
|
||||
kernel->code = EXIT_CODE_OK;
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
@@ -1,4 +1,5 @@
|
||||
#include "src/kernel/memory.h"
|
||||
#include "src/kernel/log.h"
|
||||
#include "src/kernel/panic.h"
|
||||
#include "src/lib/layout.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 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)) {
|
||||
TRACE("memory_page_map: PML4 entry %u does not exist, creating...\n", pml4_index);
|
||||
uint64_t *pdpt = memory_page_allocate();
|
||||
memory_set(0, PAGE_SIZE, PHYS_TO_VIRT(pdpt));
|
||||
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);
|
||||
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();
|
||||
memory_set(0, PAGE_SIZE, PHYS_TO_VIRT(pd));
|
||||
pdpt[pdpt_index] = (uint64_t)pd | PAGE_PRESENT | PAGE_WRITABLE | PAGE_USER;
|
||||
}
|
||||
|
||||
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)) {
|
||||
TRACE("memory_page_map: PD entry %u does not exist, creating...\n", pd_index);
|
||||
uint64_t *pt = memory_page_allocate();
|
||||
memory_set(0, PAGE_SIZE, PHYS_TO_VIRT(pt));
|
||||
pd[pd_index] = (uint64_t)pt | PAGE_PRESENT | PAGE_WRITABLE | PAGE_USER;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
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) {
|
||||
|
||||
Reference in New Issue
Block a user