diff options
Diffstat (limited to 'src/kernel/core')
-rw-r--r-- | src/kernel/core/idt.c | 16 | ||||
-rw-r--r-- | src/kernel/core/kmain.c | 6 | ||||
-rw-r--r-- | src/kernel/core/kmalloc.c | 4 | ||||
-rw-r--r-- | src/kernel/core/paging.c | 2 | ||||
-rw-r--r-- | src/kernel/core/region.c | 18 | ||||
-rw-r--r-- | src/kernel/core/sys.c | 58 | ||||
-rw-r--r-- | src/kernel/core/thread.c | 31 |
7 files changed, 100 insertions, 35 deletions
diff --git a/src/kernel/core/idt.c b/src/kernel/core/idt.c index d963b4d..457e5ae 100644 --- a/src/kernel/core/idt.c +++ b/src/kernel/core/idt.c @@ -91,7 +91,8 @@ static isr_handler_t ex_handlers[32] = {0}; /* Called in interrupt.s when an exception fires (interrupt 0 to 31) */ void idt_ex_handler(registers_t *regs) { - dbg_printf("ex%d.", regs->int_no); + /*dbg_printf("ex%d.", regs->int_no);*/ + if (ex_handlers[regs->int_no] != 0) { ex_handlers[regs->int_no](regs); } else { @@ -115,7 +116,7 @@ void idt_ex_handler(registers_t *regs) { void idt_irq_handler(registers_t *regs) { int st = enter_critical(CL_EXCL); // if someone tries to yield(), an assert will fail - dbg_printf("irq%d.", regs->err_code); + if (regs->err_code != 0) dbg_printf("irq%d.", regs->err_code); if (regs->err_code > 7) { outb(0xA0, 0x20); @@ -278,15 +279,8 @@ void dbg_dump_registers(registers_t *regs) { dbg_printf("| EIP: 0x%p CS : 0x%p DS : 0x%p SS : 0x%p\n", regs->eip, regs->cs, regs->ds, regs->ss); dbg_printf("| EFl: 0x%p I# : 0x%p Err: 0x%p\n", regs->eflags, regs->int_no, regs->err_code); dbg_printf("- Stack trace:\n"); - - uint32_t ebp = regs->ebp, eip = regs->eip; - int i = 0; - while (ebp >= K_HIGHHALF_ADDR && eip >= K_HIGHHALF_ADDR && i++ < 10) { - dbg_printf("| 0x%p EIP: 0x%p\n", ebp, eip); - uint32_t *d = (uint32_t*)ebp; - ebp = d[0]; - eip = d[1]; - } + + kernel_stacktrace(regs->ebp, regs->eip); dbg_printf("\\\n"); } diff --git a/src/kernel/core/kmain.c b/src/kernel/core/kmain.c index 005f449..3ee2238 100644 --- a/src/kernel/core/kmain.c +++ b/src/kernel/core/kmain.c @@ -248,6 +248,12 @@ fs_t *setup_iofs(multiboot_info_t *mbd) { ASSERT(nullfs_add_ram_file(iofs, name, (char*)mods[i].mod_start, len, FM_READ | FM_MMAP)); + + if (strncmp(modname, "kernel.map", 10) == 0) { + // remark: load_kernel_symbol_map modifies the data region, + // which is not a problem because nullfs_add_ram_file copied the thing already + load_kernel_symbol_map((char*)mods[i].mod_start, len); + } } return iofs; diff --git a/src/kernel/core/kmalloc.c b/src/kernel/core/kmalloc.c index cc20487..53ac83c 100644 --- a/src/kernel/core/kmalloc.c +++ b/src/kernel/core/kmalloc.c @@ -8,7 +8,7 @@ #include <region.h> #include <freemem.h> -static void* page_alloc_fun_for_kmalloc(size_t bytes) { +void* page_alloc_fun_for_kmalloc(size_t bytes) { void* addr = region_alloc(bytes, "Core kernel heap"); if (addr == 0) return 0; @@ -59,7 +59,7 @@ void kmalloc_setup() { region_free_unmap_free); } -static void* malloc0(size_t sz) { +void* malloc0(size_t sz) { void* res = 0; mutex_lock(&malloc_mutex); diff --git a/src/kernel/core/paging.c b/src/kernel/core/paging.c index cefb8c3..fa22879 100644 --- a/src/kernel/core/paging.c +++ b/src/kernel/core/paging.c @@ -68,7 +68,6 @@ void page_fault_handler(registers_t *regs) { if ((size_t)vaddr < PAGE_SIZE) { dbg_printf("Null pointer dereference in kernel code (0x%p)\n", vaddr); dbg_dump_registers(regs); - dbg_print_region_info(); PANIC("Null pointer dereference in kernel code."); } else if ((size_t)vaddr < K_HIGHHALF_ADDR) { if (pd->user_pfh == 0) { @@ -110,7 +109,6 @@ void page_fault_handler(registers_t *regs) { dbg_printf("Kernel pagefault in region with no handler at 0x%p (%s region)\n", vaddr, region); dbg_dump_registers(regs); - dbg_print_region_info(); PANIC("Unhandled kernel space page fault"); } } diff --git a/src/kernel/core/region.c b/src/kernel/core/region.c index 1f1958f..c4c34d1 100644 --- a/src/kernel/core/region.c +++ b/src/kernel/core/region.c @@ -35,13 +35,13 @@ STATIC_MUTEX(ra_mutex); // region allocator mutex // HELPER FUNCTIONS FOR THE MANIPULATION OF THE REGION LISTS // // ========================================================= // -static void add_unused_descriptor(descriptor_t *d) { +void add_unused_descriptor(descriptor_t *d) { n_unused_descriptors++; d->unused_descriptor.next = first_unused_descriptor; first_unused_descriptor = d; } -static descriptor_t *get_unused_descriptor() { +descriptor_t *get_unused_descriptor() { descriptor_t *r = first_unused_descriptor; if (r != 0) { first_unused_descriptor = r->unused_descriptor.next; @@ -50,7 +50,7 @@ static descriptor_t *get_unused_descriptor() { return r; } -static void remove_free_region(descriptor_t *d) { +void remove_free_region(descriptor_t *d) { if (first_free_region_by_size == d) { first_free_region_by_size = d->free.next_by_size; } else { @@ -73,7 +73,7 @@ static void remove_free_region(descriptor_t *d) { } } -static void add_free_region(descriptor_t *d) { +void add_free_region(descriptor_t *d) { /*dbg_printf("Add free region 0x%p - 0x%p\n", d->free.addr, d->free.size + d->free.addr);*/ // Find position of region in address-ordered list // Possibly concatenate free region @@ -155,7 +155,7 @@ static void add_free_region(descriptor_t *d) { } } -static descriptor_t *find_used_region(void* addr) { +descriptor_t *find_used_region(void* addr) { for (descriptor_t *i = first_used_region; i != 0; i = i->used.next_by_addr) { if (addr >= i->used.i.addr && addr < i->used.i.addr + i->used.i.size) return i; if (i->used.i.addr > addr) break; @@ -163,7 +163,7 @@ static descriptor_t *find_used_region(void* addr) { return 0; } -static void add_used_region(descriptor_t *d) { +void add_used_region(descriptor_t *d) { descriptor_t *i = first_used_region; ASSERT(i->used.i.addr < d->used.i.addr); // first region by address is never free @@ -180,7 +180,7 @@ static void add_used_region(descriptor_t *d) { ASSERT(false); } -static void remove_used_region(descriptor_t *d) { +void remove_used_region(descriptor_t *d) { if (first_used_region == d) { first_used_region = d->used.next_by_addr; } else { @@ -220,7 +220,7 @@ void region_allocator_init(void* kernel_data_end) { first_used_region = u0; } -static void region_free_inner(void* addr) { +void region_free_inner(void* addr) { descriptor_t *d = find_used_region(addr); if (d == 0) return; @@ -237,7 +237,7 @@ void region_free(void* addr) { mutex_unlock(&ra_mutex); } -static void* region_alloc_inner(size_t size, char* type, bool use_reserve) { +void* region_alloc_inner(size_t size, char* type, bool use_reserve) { size = PAGE_ALIGN_UP(size); for (descriptor_t *i = first_free_region_by_size; i != 0; i = i->free.first_bigger) { diff --git a/src/kernel/core/sys.c b/src/kernel/core/sys.c index 8be6c7f..554c95e 100644 --- a/src/kernel/core/sys.c +++ b/src/kernel/core/sys.c @@ -1,6 +1,9 @@ #include <sys.h> #include <dbglog.h> #include <thread.h> +#include <string.h> + +#include <btree.h> // Kernel panic and kernel assert failure @@ -9,6 +12,15 @@ static void panic_do(const char* type, const char *msg, const char* file, int li asm volatile("cli;"); dbg_printf("/\n| %s:\t%s\n", type, msg); dbg_printf("| File: \t%s:%i\n", file, line); + + dbg_printf("- trace\n"); + dbg_printf("| current thread: 0x%p\n", current_thread); + uint32_t *ebp; + asm volatile("mov %%ebp, %0":"=r"(ebp)); + kernel_stacktrace(ebp[0], ebp[1]); + + dbg_print_region_info(); + dbg_printf("| System halted -_-'\n"); dbg_printf("\\---------------------------------------------------------/"); BOCHS_BREAKPOINT; @@ -26,4 +38,50 @@ void panic_assert(const char* assertion, const char* file, int line) { panic_do("ASSERT FAILED", assertion, file, line); } +// ---- kernel symbol map + +btree_t *kernel_symbol_map = 0; + +void load_kernel_symbol_map(char* text, size_t len) { + kernel_symbol_map = create_btree(id_key_cmp_fun, 0); + ASSERT (kernel_symbol_map != 0); + + dbg_printf("Loading kernel symbol map...\n"); + + char* it = text; + while (it < text + len) { + char* eol = it; + while (eol < text + len && *eol != 0 && *eol != '\n') eol++; + if (eol >= text + len) break; + *eol = 0; + + if (it[16] == '0' && it[17] == 'x' && it[34] == ' ' && it[49] == ' ') { + uint32_t addr = 0; + for (unsigned i = 18; i < 34; i++) { + addr *= 16; + if (it[i] >= '0' && it[i] <= '9') addr += it[i] - '0'; + if (it[i] >= 'a' && it[i] <= 'f') addr += it[i] - 'a' + 10; + } + btree_add(kernel_symbol_map, (void*)addr, it + 50); + } + + it = eol + 1; + } +} + +void kernel_stacktrace(uint32_t ebp, uint32_t eip) { + int i = 0; + while (ebp >= K_HIGHHALF_ADDR && eip >= K_HIGHHALF_ADDR && i++ < 10) { + char* sym = 0; + if (kernel_symbol_map != 0) sym = btree_lower(kernel_symbol_map, (void*)eip); + + dbg_printf("| 0x%p EIP: 0x%p %s\n", ebp, eip, sym); + + uint32_t *d = (uint32_t*)ebp; + ebp = d[0]; + eip = d[1]; + } +} + + /* vim: set ts=4 sw=4 tw=0 noet :*/ diff --git a/src/kernel/core/thread.c b/src/kernel/core/thread.c index 19ad6c8..1009ec7 100644 --- a/src/kernel/core/thread.c +++ b/src/kernel/core/thread.c @@ -120,7 +120,7 @@ void run_scheduler() { // At this point, interrupts are disabled // This function is expected NEVER TO RETURN - thread_t *prev_thread = current_thread; + /*thread_t *prev_thread = current_thread;*/ if (current_thread != 0 && current_thread->state == T_STATE_RUNNING) { current_thread->last_ran = get_kernel_time(); @@ -129,7 +129,7 @@ void run_scheduler() { } current_thread = dequeue_thread(); - if (current_thread != prev_thread) dbg_printf("[0x%p]\n", current_thread); + /*if (current_thread != prev_thread) dbg_printf("[0x%p]\n", current_thread);*/ if (current_thread != 0) { thread_t *ptr = current_thread; @@ -146,7 +146,7 @@ void run_scheduler() { } } -static void run_thread(void (*entry)(void*), void* data) { +void run_thread(void (*entry)(void*), void* data) { ASSERT(current_thread->state == T_STATE_RUNNING); dbg_printf("Begin thread 0x%p (in process %d)\n", @@ -210,6 +210,10 @@ thread_t *new_thread(entry_t entry, void* data) { t->next_in_proc = 0; t->user_ex_handler = 0; + t->waiting_on = 0; + t->n_waiting_on = 0; + t->next_waiter = 0; + return t; } @@ -285,11 +289,11 @@ bool wait_on_many(void** x, size_t n) { // ---- Set ourselves as the waiting thread for all the requested objets - dbg_printf("Wait on many:"); - for (size_t i = 0; i < n; i++) { - dbg_printf(" 0x%p", x[i]); - } - dbg_printf("\n"); + /*dbg_printf("Wait on many:");*/ + /*for (size_t i = 0; i < n; i++) {*/ + /*dbg_printf(" 0x%p", x[i]);*/ + /*}*/ + /*dbg_printf("\n");*/ current_thread->waiting_on = x; current_thread->n_waiting_on = n; @@ -310,8 +314,12 @@ bool wait_on_many(void** x, size_t n) { if (waiters == current_thread) { waiters = current_thread->next_waiter; } else { + ASSERT(waiters != 0); for (thread_t *w = waiters; w->next_waiter != 0; w = w->next_waiter) { - if (w->next_waiter == current_thread) w->next_waiter = current_thread->next_waiter; + if (w->next_waiter == current_thread) { + w->next_waiter = current_thread->next_waiter; + break; + } } } @@ -368,12 +376,12 @@ bool resume_on(void* x) { int st = enter_critical(CL_NOINT); - dbg_printf("Resume on 0x%p:", x); + /*dbg_printf("Resume on 0x%p:", x);*/ for (thread_t *t = waiters; t != 0; t = t->next_waiter) { for (int i = 0; i < t->n_waiting_on; i++) { if (t->waiting_on[i] == x) { - dbg_printf(" 0x%p", t); + /*dbg_printf(" 0x%p", t);*/ if (t->state == T_STATE_PAUSED) { t->state = T_STATE_RUNNING; @@ -386,6 +394,7 @@ bool resume_on(void* x) { } } } + /*dbg_printf("\n");*/ exit_critical(st); |