From 417d5b17b8054a73c2a41ae4aabefb4654e05fad Mon Sep 17 00:00:00 2001 From: trimill Date: Mon, 29 Jan 2024 21:10:29 -0500 Subject: [PATCH] refactor, improve exception message --- include/lib.h | 61 +++++++++++++-------- src/arch/amd64/idt.S | 8 ++- src/arch/amd64/idt.c | 119 +++++++++++++++++++++++------------------ src/arch/amd64/panic.c | 5 +- src/kmain.c | 11 ++-- src/lib.c | 11 ++++ 6 files changed, 130 insertions(+), 85 deletions(-) diff --git a/include/lib.h b/include/lib.h index 43b95a6..1b6d1f4 100644 --- a/include/lib.h +++ b/include/lib.h @@ -1,92 +1,111 @@ #pragma once +#include + /** * The memcmp() function compares the first n bytes (each interpreted as unsigned char) of the memory * areas s1 and s2. */ -extern int memcmp(const void *restrict s1, const void *restrict s2, unsigned long n); +int memcmp(const void *restrict s1, const void *restrict s2, unsigned long n); /** * The memcpy() function copies n bytes from memory area src to memory area dest. * The memory areas must not overlap. */ -extern void *memcpy(void *restrict dest, const void *restrict src, unsigned long n); +void *memcpy(void *restrict dest, const void *restrict src, unsigned long n); /** * The memmove() function copies n bytes from memory area src to memory area dest. The memory areas * may overlap: copying takes place as though the bytes in src are first copied into a temporary array * that does not overlap src or dest, and the bytes are then copied from the temporary array to dest. */ -extern void *memmove(void *dest, const void *src, unsigned long n); +void *memmove(void *dest, const void *src, unsigned long n); /** * The memset() function fills the first n bytes of the memory area pointed to by s with the constant * byte c. */ -extern void *memset(void *restrict dest, int c, unsigned long n); +void *memset(void *restrict dest, int c, unsigned long n); /** * The strcmp() function compares the two strings s1 and s2. The locale is not taken into account * (for a locale-aware comparison, see strcoll(3)). The comparison is done using unsigned characters. */ -extern int strncmp(const char *restrict s1, const char *restrict s2, unsigned long n); +int strncmp(const char *restrict s1, const char *restrict s2, unsigned long n); /** * Copys the string pointed to by src , into a string at the buffer pointer to by dest. * The dest buffer must be long enough to hold src. */ -extern char *strcpy(char *restrict dest, const char *restrict src); +char *strcpy(char *restrict dest, const char *restrict src); /** * Copys the string pointed to by src , into a string at the buffer pointer to by dest. * The dest buffer must be long enough to hold src or size n. */ -extern char *strncpy(char *restrict dest, const char *restrict src, unsigned long n); +char *strncpy(char *restrict dest, const char *restrict src, unsigned long n); + +/** + * Calculates the length of the string pointed to by str, excluding + * the terminating null byte + * @param str - the string pointer + * @returns the length of the string in bytes + */ +size_t strlen(const char *str); + +/** + * Concatenate the string pointed to by src after the string pointed + * to by dst. + * @param dst - the pointer to the destination string + * @param src - the pointer to the source string + * @returns dst + */ +char *strcat(char *restrict dst, const char *restrict src); /** * @returns 1 if c is a space */ -extern int isspace(int c); +int isspace(int c); /** * @returns 1 if c is a digit (0 - 9) */ -extern int isdigit(int c); +int isdigit(int c); /** * converts single digit int to base 36 * @param i - int * @returns c - base 36 char */ -extern char itoc(int i); +char itoc(int i); /** * converts single base 36 chat into int * @param c - base 36 char * @returns i - int */ -extern int ctoi(char c); +int ctoi(char c); /** * Converts the initial portiion of the string pointed to by s to int. * @param s - the string to convert * @returns the number inside s or 0 on error */ -extern int atoi(const char* s); +int atoi(const char* s); /** * Converts the initial portiion of the string pointed to by s to long. * @param s - the string to convert * @returns the number inside s or 0 on error */ -extern long int atol(const char* s); +long int atol(const char* s); /** * Converts the initial portiion of the string pointed to by s to long long. * @param s - the string to convert * @returns the number inside s or 0 on error */ -extern long long int atoll(const char* s); +long long int atoll(const char* s); /** * Converts a integer to asci inside a string with a given radix (base). @@ -94,7 +113,7 @@ extern long long int atoll(const char* s); * @param buffer - the string buffer * @param radix - the base to convert */ -extern char *itoa(int n, char *buffer, int radix); +char *itoa(int n, char *buffer, int radix); /** * Converts a long to asci inside a string with a given radix (base). @@ -102,7 +121,7 @@ extern char *itoa(int n, char *buffer, int radix); * @param buffer - the string buffer * @param radix - the base to convert */ -extern char *ltoa(long int n, char *buffer, int radix); +char *ltoa(long int n, char *buffer, int radix); /** * Converts a unsigned integer to asci inside a string with a given radix (base). @@ -110,7 +129,7 @@ extern char *ltoa(long int n, char *buffer, int radix); * @param buffer - the string buffer * @param radix - the base to convert */ -extern char *utoa(unsigned int n, char *buffer, int radix); +char *utoa(unsigned int n, char *buffer, int radix); /** * Converts a unsigned long to asci inside a string with a given radix (base). @@ -118,7 +137,7 @@ extern char *utoa(unsigned int n, char *buffer, int radix); * @param buffer - the string buffer * @param radix - the base to convert */ -extern char *ultoa(unsigned long int n, char *buffer, int radix); +char *ultoa(unsigned long int n, char *buffer, int radix); /** * Converts the string in str to an int value based on the given base. @@ -128,7 +147,7 @@ extern char *ultoa(unsigned long int n, char *buffer, int radix); * @param base - the base to convert to * @returns 0 on error or success, error if endptr is still equal to str */ -extern int strtoi(const char *str, char **endptr, int base); +int strtoi(const char *str, char **endptr, int base); /** * Converts the string in str to an long value based on the given base. @@ -138,7 +157,7 @@ extern int strtoi(const char *str, char **endptr, int base); * @param base - the base to convert to * @returns 0 on error or success, error if endptr is still equal to str */ -extern long int strtol(const char *str, char **endptr, int base); +long int strtol(const char *str, char **endptr, int base); /** * Converts the string in str to an long long value based on the given base. @@ -148,4 +167,4 @@ extern long int strtol(const char *str, char **endptr, int base); * @param base - the base to convert to * @returns 0 on error or success, error if endptr is still equal to str */ -extern long long int strtoll(const char *str, char **endptr, int base); +long long int strtoll(const char *str, char **endptr, int base); diff --git a/src/arch/amd64/idt.S b/src/arch/amd64/idt.S index 1098057..32670c8 100644 --- a/src/arch/amd64/idt.S +++ b/src/arch/amd64/idt.S @@ -7,11 +7,13 @@ extern idt_pic_mouse extern idt_pic_eoi %macro PUSHALL 0 + push rax push rbx push rcx push rdx - push rsi + push rbp push rdi + push rsi push r8 push r9 push r10 @@ -31,11 +33,13 @@ extern idt_pic_eoi pop r10 pop r9 pop r8 - pop rdi pop rsi + pop rdi + pop rbp pop rdx pop rcx pop rbx + pop rax %endmacro ; call the exception handler with the interrupt number diff --git a/src/arch/amd64/idt.c b/src/arch/amd64/idt.c index 5c6261c..83b792c 100644 --- a/src/arch/amd64/idt.c +++ b/src/arch/amd64/idt.c @@ -73,68 +73,81 @@ void idt_init(void) { // Intel manual vol 3 ch 6.3.1 char *EXCEPTIONS[] = { - "Exception 0x00 Divide Error", - "Exception 0x01 Debug Exception", - "Exception 0x02 NMI Interrupt", - "Exception 0x03 Breakpoint", - "Exception 0x04 Overflow", - "Exception 0x05 BOUND Range Exceeded", - "Exception 0x06 Invalid Opcode", - "Exception 0x07 Device Not Available", - "Exception 0x08 Double Fault", - "Exception 0x09 Coprocessor Segment Overrun", - "Exception 0x0A Invalid TSS", - "Exception 0x0B Segment Not Present", - "Exception 0x0C Stack-Segment Fault", - "Exception 0x0D General Protection", - "Exception 0x0E Page Fault", - "Exception 0x0F Reserved", - "Exception 0x10 x87 FPU Floating-Point Error", - "Exception 0x11 Alignment Check", - "Exception 0x12 Machine Check", - "Exception 0x13 SIMD Floaing-Point Exception", - "Exception 0x14 Virtualization Exception", - "Exception 0x15 Control Protection Exception", - "Exception 0x16 Reserved", - "Exception 0x17 Reserved", - "Exception 0x18 Reserved", - "Exception 0x19 Reserved", - "Exception 0x1A Reserved", - "Exception 0x1B Reserved", - "Exception 0x1C Reserved", - "Exception 0x1D Reserved", - "Exception 0x1E Reserved", - "Exception 0x1F Reserved", + "0x00 Division Error", + "0x01 Debug", + "0x02 NMI", + "0x03 Breakpoint", + "0x04 Overflow", + "0x05 BOUND Range Exceeded", + "0x06 Invalid Opcode", + "0x07 Device Not Available", + "0x08 Double Fault", + "0x09 Coprocessor Segment Overrun", + "0x0A Invalid TSS", + "0x0B Segment Not Present", + "0x0C Stack-Segment Fault", + "0x0D General Protection Fault", + "0x0E Page Fault", + "0x0F Reserved", + "0x10 x87 Floating-Point Error", + "0x11 Alignment Check", + "0x12 Machine Check", + "0x13 SIMD Floaing-Point Exception", + "0x14 Virtualization Exception", + "0x15 Control Protection Exception", + "0x16 Reserved", + "0x17 Reserved", + "0x18 Reserved", + "0x19 Reserved", + "0x1A Reserved", + "0x1B Reserved", + "0x1C Hypervisor Injection Exception", + "0x1D VMM Communication Exception", + "0x1E Security Exception", + "0x1F Reserved", }; +void idt_exception_handler(uint64_t exception, uint64_t code) { + // TODO don't just panic + char buf[24]; + char msg[256] = "Exception "; + + strcat(msg, EXCEPTIONS[exception]); + + strcat(msg, "\nError code 0x"); + ultoa(code, buf, 16); + strcat(msg, buf); + + // page faults store the offending address in cr2 + if(exception == 0x0E) { + strcat(msg, "\nPage fault address: 0x"); + void *addr; + __asm__ volatile ("mov %%cr2, %0" : "=r"(addr)); + ultoa((size_t)addr, buf, 16); + strcat(msg, buf); + } + + panic(msg); +} + void idt_pic_eoi(uint8_t exception) { pic_eoi(exception - PIC_REMAP_OFFSET); } -static size_t timer = 0; +int counter = 0; void idt_pic_timer(void) { - timer += 1; - char buf[20]; - ltoa(timer, buf, 10); - serial_out_str(buf); - serial_out_str("\n"); + // print a message once we know the timer works + // but avoid spamming the logs + if (counter == 3) { + serial_out_str("pic timer!\n"); + } + if (counter <= 3) { + counter++; + } } -void idt_pic_keyboard(void) { - serial_out_str("ps2 kbd"); -} +void idt_pic_keyboard(void) {} -void idt_pic_mouse(void) { - serial_out_str("ps2 mouse"); -} - -void idt_exception_handler(uint64_t exception, uint64_t code) { - // TODO don't just panic - char buf[80]; - char *end = strcpy(buf, EXCEPTIONS[exception]); - end = strcpy(end, "\nError code 0x"); - ltoa(code, end, 16); - panic(buf); -} +void idt_pic_mouse(void) {} diff --git a/src/arch/amd64/panic.c b/src/arch/amd64/panic.c index 227ecce..c034b90 100644 --- a/src/arch/amd64/panic.c +++ b/src/arch/amd64/panic.c @@ -6,11 +6,12 @@ _Noreturn void _panic_impl(char *line, char *file, char *msg) { cli(); serial_out_str("\n\n!!! PANIC !!!\n"); - serial_out_str(msg); - serial_out_str("\nin file "); + serial_out_str("In file "); serial_out_str(file); serial_out_str(" at line "); serial_out_str(line); + serial_out_str(":\n"); + serial_out_str(msg); serial_out('\n'); while (1) { halt(); diff --git a/src/kmain.c b/src/kmain.c index 701c135..d5bee56 100644 --- a/src/kmain.c +++ b/src/kmain.c @@ -5,14 +5,11 @@ #include void kmain(struct boot_info *info) { - char buf[20]; - *(char*)0xB8000 = 'c'; memory_init(info->map); - //*(char*)(0xB8002 + 0x20'0000) = 'd'; - itoa((long)info, buf, 16); - itoa(*(long*)info, buf, 16); - //fb_init(1024, 768); - serial_out_str(buf); + serial_out_str("entered kmain\n"); + *(char*)(0xB8000 + 0x144) = 'h'; + *(char*)(0xB8000 + 0x146) = 'i'; + //fb_init(1024, 768); while (1) { // loop so we dont halt // this allows interrupts to fire diff --git a/src/lib.c b/src/lib.c index 1f57f83..d01252d 100644 --- a/src/lib.c +++ b/src/lib.c @@ -54,6 +54,17 @@ char *strncpy(char *restrict dest, const char *restrict src, unsigned long n) { return dest; } +size_t strlen(const char *str) { + const char *p; + for(p = str; *p != 0; p++) {} + return p - str; +} + +char *strcat(char *restrict dst, const char *restrict src) { + strcpy(dst + strlen(dst), src); + return dst; +} + int isspace(int c) { switch (c) { case ' ':