diff --git a/Makefile b/Makefile index a4cd1ae..6f8ddf3 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ # or maybe add it to a bash script instead? im not sure CC = i686-elf-gcc -CFLAGS = -m32 -ffreestanding -Wall -Wextra -Werror -Wpedantic --sysroot=$(PWD)/sysroot -isystem=/usr/include -Iinclude -MD +CFLAGS = -m32 -ffreestanding -Wall -Wextra -Werror -Wpedantic --sysroot=$(PWD)/sysroot -isystem=/usr/include -Iinclude -MD -D__TESTING__ AS = nasm ASFLAGS = -f elf diff --git a/kernel/arch/gdt/gdt_entry.c b/kernel/arch/gdt/gdt_entry.c index e8a298f..c916918 100644 --- a/kernel/arch/gdt/gdt_entry.c +++ b/kernel/arch/gdt/gdt_entry.c @@ -16,4 +16,3 @@ uint64_t create_descriptor(uint32_t base, uint32_t limit, uint16_t flag) return descriptor; } - diff --git a/kernel/arch/idt/idt.c b/kernel/arch/idt/idt.c index 1125d0e..2288e91 100644 --- a/kernel/arch/idt/idt.c +++ b/kernel/arch/idt/idt.c @@ -1,5 +1,8 @@ #include +#ifdef __TESTING__ +#include +#endif #include __attribute__((aligned(0x10))) @@ -29,6 +32,9 @@ void idt_set_descriptor(uint8_t vector, void *isr, uint8_t flags) extern void* isr_stub_table[]; void idt_init(void) { +#ifdef __TESTING__ + kinfo("Initializing the IDT"); +#endif idtr.base = (uintptr_t)&idt[0]; idtr.limit = (uint16_t) sizeof(idt_entry_t) * IDT_MAX_DESCRIPTORS - 1; @@ -40,5 +46,8 @@ void idt_init(void) // The "m" indicates actual data, not a pointer __asm__ volatile("lidt %0" : : "m"(idtr)); // load the new IDT __asm__ volatile("sti"); // set the interrupt flag +#ifdef __TESTING__ + kinfo("Initialized the IDT"); +#endif } diff --git a/kernel/arch/pic/pic.c b/kernel/arch/pic/pic.c index dfe1f55..ef093ed 100644 --- a/kernel/arch/pic/pic.c +++ b/kernel/arch/pic/pic.c @@ -1,3 +1,6 @@ +#ifdef __TESTING__ +#include +#endif #include #include @@ -10,6 +13,9 @@ void PIC_sendEOI(uint8_t irq) void PIC_remap(int offset1, int offset2) { +#ifdef __TESTING__ + kinfo("Remapping the PIC..."); +#endif // The io_wait calls are necessary for older machines, to give the PIC time to react // // After the init, the PIC requires 3 init words @@ -38,12 +44,19 @@ void PIC_remap(int offset1, int offset2) // Unmask the PICs outb(PIC1_DATA, 0); outb(PIC2_DATA, 0); + +#ifdef __TESTING__ + kinfo("Remapped the PIC!"); +#endif } void pic_disable(void) { // Mask the PIC interrupts to disable them outb(PIC1_DATA, 0xFF); outb(PIC2_DATA, 0xFF); +#ifdef __TESTING__ + kinfo("Disabled the PIC"); +#endif } void IRQ_set_mask(uint8_t IRQline) // Masked IRQlines are ignored by the PIC, masked IRQ2 will fully ignore the slave diff --git a/kernel/include/kernel/x86/gdt.h b/kernel/include/kernel/x86/gdt.h index 0d428df..ef3a2ae 100644 --- a/kernel/include/kernel/x86/gdt.h +++ b/kernel/include/kernel/x86/gdt.h @@ -47,13 +47,15 @@ SEG_PRIV(3) | SEG_DATA_RDWR +#define GDT_SIZE 5 + 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); #endif diff --git a/kernel/klog.c b/kernel/klog.c index 7907840..42df3e2 100644 --- a/kernel/klog.c +++ b/kernel/klog.c @@ -2,6 +2,7 @@ #include #include +#include enum log_mode { LOG_ERR, @@ -14,16 +15,22 @@ void klog(const char* buf, enum log_mode mode) switch(mode) { case LOG_ERR: serial_writestring("ERROR: "); + terminal_writestring("ERROR: "); break; case LOG_WARN: serial_writestring("WARNING: "); + terminal_writestring("WARNING: "); break; case LOG_INFO: serial_writestring("INFO: "); + terminal_writestring("INFO: "); break; } serial_writestring(buf); + terminal_writestring(buf); + serial_writestring("\n"); + terminal_writestring("\n"); } void kerror(const char* buf) diff --git a/kernel/kmain.c b/kernel/kmain.c index d207c6c..c77cbc6 100644 --- a/kernel/kmain.c +++ b/kernel/kmain.c @@ -1,19 +1,20 @@ #include #include +#include #include #include #include #include #include -#define GDT_SIZE 5 - uint64_t gdt[GDT_SIZE]; - -void gdt_init(void) +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 @@ -22,25 +23,29 @@ void gdt_init(void) setGdt((sizeof(uint64_t) * GDT_SIZE) - 1, &(gdt[0])); // limit, base reloadSegments(); +#ifdef __TESTING__ + kinfo("Initialized the GDT"); +#endif } -#undef GDT_SIZE - void kmain(void) { - gdt_init(); - idt_init(); - - PIC_remap(0x20, 0x28); - - +#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 - terminal_writestring("test"); + gdt_init(); + idt_init(); + PIC_remap(0x20, 0x28); - serial_writestring("test!"); +#ifndef __TESTING__ + terminal_initialize(); + serial_initialize(); +#endif - printf("test.."); + + printf("Integer: %d\n", 10); + printf("Hex Int: %x\n", 2); } diff --git a/libc/stdio/printf.c b/libc/stdio/printf.c index f1f95ba..818e87f 100644 --- a/libc/stdio/printf.c +++ b/libc/stdio/printf.c @@ -4,11 +4,56 @@ #include #include +#include + +static void reverse(char* buf, int len) +{ + int start = 0; + int end = len - 1; + while (start < end) { + char tmp = buf[start]; + buf[start] = buf[end]; + buf[end] = tmp; + end--; + start++; + } +} + +static char* itoa(int 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 bool print(const char* data, size_t length) { const unsigned char* bytes = (const unsigned char*) data; for (size_t i = 0; i < length; i++) - if (putchar(bytes[i]) == EOF) - return false; + if (putchar(bytes[i]) == EOF) return false; return true; } @@ -18,6 +63,8 @@ int printf(const char* restrict format, ...) { int written = 0; + char buffer[512]; + while (*format != '\0') { size_t maxrem = INT_MAX - written; @@ -61,6 +108,30 @@ int printf(const char* restrict format, ...) { if (!print(str, len)) return -1; written += len; + } else if (*format == 'd') { + format++; + int i = (int) va_arg(parameters, int); + itoa(i, buffer, 10); + 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 == 'x') { + format++; + int i = (int) va_arg(parameters, int); + itoa(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);