From fbbcb04f9e3197976d6ab4a79c45aa0a84e39aba Mon Sep 17 00:00:00 2001 From: Jake Mannens Date: Mon, 25 Jun 2018 03:57:22 +1000 Subject: Added the header asm/interrupt.h which includes a prototype for the assembly function register_isr making it usable within the C portions of the source. Added a new file panic.s with the function panic that will print a panic message, disable interrupts and halt the system. Created the skeleton framework for paging in the new file page.s. The new function paging_init (called in kboot) will setup a simple page directory with two tables covering all addresses 0-8MB. It will also mark pages from 0-1MB as 'supervisor-only' to protect the kernel. NOTE: The function paging_init must be called before initialising the IDT as it does not disable interrupts! Modified the page fault handler to print the offending linear address along with the supplied error code. Following that, the handler will initiate a kernel panic. This function (along with panic) assumes console I/O to be operational. Modified the userspace test code to deliberately intiate a page fault by accessing an unmapped page. --- Makefile | 2 +- include/asm/interrupt.h | 1 + include/kernel/kernel.h | 1 + kernel/boot.s | 2 ++ kernel/kmain.c | 1 - kernel/page.s | 55 +++++++++++++++++++++++++++++++++++++++++++++++++ kernel/panic.s | 20 ++++++++++++++++++ kernel/traps.s | 13 ++++++++++++ usrbin/main.c | 2 ++ 9 files changed, 95 insertions(+), 2 deletions(-) create mode 100644 include/asm/interrupt.h create mode 100644 include/kernel/kernel.h create mode 100644 kernel/page.s create mode 100644 kernel/panic.s diff --git a/Makefile b/Makefile index 15f76ec..c45c277 100644 --- a/Makefile +++ b/Makefile @@ -18,7 +18,7 @@ clean: $(MAKE) -C usrbin clean rm -f $(TARGET) -run: +run: $(TARGET) qemu-system-x86_64 -s -kernel $(TARGET) .FORCE: diff --git a/include/asm/interrupt.h b/include/asm/interrupt.h new file mode 100644 index 0000000..5e0178b --- /dev/null +++ b/include/asm/interrupt.h @@ -0,0 +1 @@ +void register_isr(uint8_t n, uint8_t dpl, void *handler); diff --git a/include/kernel/kernel.h b/include/kernel/kernel.h new file mode 100644 index 0000000..d0131cf --- /dev/null +++ b/include/kernel/kernel.h @@ -0,0 +1 @@ +volatile void panic(void); diff --git a/kernel/boot.s b/kernel/boot.s index bc42a5d..80f8be9 100644 --- a/kernel/boot.s +++ b/kernel/boot.s @@ -4,6 +4,7 @@ global kboot global register_isr global tss extern kmain +extern paging_init extern syscall_init extern timer_init extern traps_init @@ -24,6 +25,7 @@ kboot: mov esp, 0x80000 ; setup descriptor tables call flush_gdt + call paging_init call flush_idt ; last minute setup, then transfer to kmain call timer_init diff --git a/kernel/kmain.c b/kernel/kmain.c index 4bfd129..ece7012 100644 --- a/kernel/kmain.c +++ b/kernel/kmain.c @@ -3,7 +3,6 @@ #include #include - uint32_t ticks = 0; extern void userspace_init(void); diff --git a/kernel/page.s b/kernel/page.s new file mode 100644 index 0000000..4e40822 --- /dev/null +++ b/kernel/page.s @@ -0,0 +1,55 @@ +global paging_init + +align 4096 +page_dir: + times 4096 db 0 + +align 4096 +page_tables: + ; two page tables + times 4096 db 0 + times 4096 db 0 +.end: + +; here, we initialize paging. since the IDT +; has yet to be populated, we must take extra +; care as we can't afford to trigger a page +; fault. +paging_init: + push ebp + mov ebp, esp + push ebx + ; populate the page directory + mov eax, page_tables + or eax, 0x007 + mov [page_dir], eax + mov eax, (page_tables+4096) + or eax, 0x007 + mov [page_dir+4], eax + ; populate the page tables + mov ebx, page_tables + mov ecx, ((page_tables.end-page_tables)/4) + mov edx, 0 +.loop: + mov eax, edx + or eax, 0x003 + cmp edx, 0x100000 + jb .skip + or eax, 0x004 +.skip: + mov [ebx], eax + dec ecx + jz .end + add ebx, 4 + add edx, 4096 + jmp .loop +.end: + ; load the page directory and enable paging + mov eax, page_dir + mov cr3, eax + mov eax, cr0 + or eax, 0x80000000 + mov cr0, eax + pop ebx + pop ebp + ret diff --git a/kernel/panic.s b/kernel/panic.s new file mode 100644 index 0000000..f4e0f26 --- /dev/null +++ b/kernel/panic.s @@ -0,0 +1,20 @@ +; +; panic.s - provides panic() which disables +; interrupts and halts the system. currently used +; mainly for debugging, will eventually be expanded +; to display some useful information on the +; console. +; + +global panic +extern printf + +panic: + push ebp + mov ebp, esp + push .msg + call printf + add esp, 4 + cli + hlt +.msg: db "Kernel panic!", 10, 0 diff --git a/kernel/traps.s b/kernel/traps.s index ba9814c..0381ee8 100644 --- a/kernel/traps.s +++ b/kernel/traps.s @@ -7,6 +7,8 @@ global syscall_init global traps_init extern call_table extern idt +extern panic +extern printf extern register_isr %macro SAVE 0 @@ -179,7 +181,18 @@ exc_gprot: exc_pagef: SAVE_ERR + + push ebx + mov ebx, cr2 + push ebx + push .fmt + call printf + add esp, 8 + call panic + RESTORE_ERR +.fmt: + db "Page Fault (illegal memory access: 0x%08x:0x%02x)", 10, 0 exc_mathf: SAVE diff --git a/usrbin/main.c b/usrbin/main.c index 5cc7567..d2ea633 100644 --- a/usrbin/main.c +++ b/usrbin/main.c @@ -4,4 +4,6 @@ extern int print(char*); void main(void) { print("We did it ma!\n"); + + char c = *((char*) 0x80BEEF); } -- cgit v1.3