diff --git a/kernel/arch/gdt/gdt_entry.c b/kernel/arch/gdt/gdt_entry.c index c916918..147ce47 100644 --- a/kernel/arch/gdt/gdt_entry.c +++ b/kernel/arch/gdt/gdt_entry.c @@ -1,5 +1,9 @@ #include +#ifdef __TESTING__ +#include +#endif + uint64_t create_descriptor(uint32_t base, uint32_t limit, uint16_t flag) { uint64_t descriptor; @@ -16,3 +20,21 @@ uint64_t create_descriptor(uint32_t base, uint32_t limit, uint16_t flag) return descriptor; } + +void gdt_init(uint64_t* gdt) +{ +#ifdef __TESTING__ + kinfo("Initializing the GDT"); +#endif + gdt[0] = create_descriptor(0, 0, 0); // null + gdt[1] = create_descriptor(0, 0x000FFFFF, (GDT_CODE_PL0)); // kernel code + gdt[2] = create_descriptor(0, 0x000FFFFF, (GDT_DATA_PL0)); // kernel data + gdt[3] = create_descriptor(0, 0x000FFFFF, (GDT_CODE_PL3)); // user code + gdt[4] = create_descriptor(0, 0x000FFFFF, (GDT_DATA_PL3)); // user data + + setGdt((sizeof(uint64_t) * GDT_SIZE) - 1, &(gdt[0])); // limit, base + reloadSegments(); +#ifdef __TESTING__ + kinfo("Initialized the GDT"); +#endif +} diff --git a/kernel/include/kernel/x86/gdt.h b/kernel/include/kernel/x86/gdt.h index ef3a2ae..47d1af9 100644 --- a/kernel/include/kernel/x86/gdt.h +++ b/kernel/include/kernel/x86/gdt.h @@ -55,7 +55,8 @@ void setGdt(unsigned short limit, uint64_t* base); void reloadSegments(); uint64_t create_descriptor(uint32_t base, uint32_t limit, uint16_t flag); -void gdt_init(void); + +void gdt_init(uint64_t* gdt); #endif diff --git a/kernel/kmain.c b/kernel/kmain.c index c77cbc6..ff15439 100644 --- a/kernel/kmain.c +++ b/kernel/kmain.c @@ -10,33 +10,13 @@ uint64_t gdt[GDT_SIZE]; -void gdt_init() -{ -#ifdef __TESTING__ - kinfo("Initializing the GDT"); -#endif - gdt[0] = create_descriptor(0, 0, 0); // null - gdt[1] = create_descriptor(0, 0x000FFFFF, (GDT_CODE_PL0)); // kernel code - gdt[2] = create_descriptor(0, 0x000FFFFF, (GDT_DATA_PL0)); // kernel data - gdt[3] = create_descriptor(0, 0x000FFFFF, (GDT_CODE_PL3)); // user code - gdt[4] = create_descriptor(0, 0x000FFFFF, (GDT_DATA_PL3)); // user data - - setGdt((sizeof(uint64_t) * GDT_SIZE) - 1, &(gdt[0])); // limit, base - reloadSegments(); -#ifdef __TESTING__ - kinfo("Initialized the GDT"); -#endif -} - void kmain(void) { #ifdef __TESTING__ // important components should be declared first, but if we're testing we want to log all of that terminal_initialize(); serial_initialize(); #endif - - - gdt_init(); + gdt_init(gdt); idt_init(); PIC_remap(0x20, 0x28); @@ -46,6 +26,6 @@ void kmain(void) #endif - printf("Integer: %d\n", 10); + printf("Integer: %1\n", gdt[1]); printf("Hex Int: %x\n", 2); } diff --git a/libc/stdio/printf.c b/libc/stdio/printf.c index 818e87f..23c6cde 100644 --- a/libc/stdio/printf.c +++ b/libc/stdio/printf.c @@ -3,6 +3,7 @@ #include #include #include +#include #include @@ -19,6 +20,58 @@ static void reverse(char* buf, int len) } } +static char* s64toa(int64_t num, char* buf, int base) +{ + int i = 0; + bool neg = false; + + if (num == 0) { // Handle zero explicitly + buf[i++] = '0'; + buf[i] = '\0'; + return buf; + } + + if (num < 0 && base == 10) { // only handle negative on base10 + neg = true; + num = -num; + } + + while (num != 0) { + int rem = num % base; + buf[i++] = (rem > 9) ? (rem - 10) + 'a' : rem + '0'; + num = num / base; + } + + if (neg) // lets reapply the negative sign + buf[i++] = '-'; + + buf[i] = '\0'; + + reverse(buf, i); // reverse, since we did it backwards! + return buf; +} + +static char* u64toa(uint64_t num, char* buf, int base) +{ + int i = 0; + if (num == 0) { // Handle zero explicitly + buf[i++] = '0'; + buf[i] = '\0'; + return buf; + } + + while (num != 0) { + int rem = num % base; + buf[i++] = (rem > 9) ? (rem - 10) + 'a' : rem + '0'; + num = num / base; + } + + buf[i] = '\0'; + + reverse(buf, i); // reverse, since we did it backwards! + return buf; +} + static char* itoa(int num, char* buf, int base) { int i = 0; @@ -132,6 +185,30 @@ int printf(const char* restrict format, ...) { if (!print(buffer, len)) return -1; written += len; + } else if (*format == '1') { + format++; + uint64_t i = (uint64_t) va_arg(parameters, uint64_t); + u64toa(i, buffer, 16); + size_t len = strlen(buffer); + if (maxrem < len) { + // TODO: Set errno to EOVERFLOW. + return -1; + } + if (!print(buffer, len)) + return -1; + written += len; + } else if (*format == '2') { + format++; + int64_t i = (int64_t) va_arg(parameters, int64_t); + s64toa(i, buffer, 16); + size_t len = strlen(buffer); + if (maxrem < len) { + // TODO: Set errno to EOVERFLOW. + return -1; + } + if (!print(buffer, len)) + return -1; + written += len; } else { format = format_begun_at; size_t len = strlen(format);