diff options
author | Alex AUVOLAT <alexis211@gmail.com> | 2013-07-10 21:17:50 +0200 |
---|---|---|
committer | Alex AUVOLAT <alexis211@gmail.com> | 2013-07-10 21:17:50 +0200 |
commit | 78d7ffce4861dea5624ff29ceb39f1643dff8235 (patch) | |
tree | 6b41c052e48398f7520013622f0b1b9b9190259a | |
parent | fadf399405ca5d918dd5e1182fadc3d82f6bc900 (diff) | |
download | TCE-78d7ffce4861dea5624ff29ceb39f1643dff8235.tar.gz TCE-78d7ffce4861dea5624ff29ceb39f1643dff8235.zip |
Serial port used for writing kernel output.
Project: give total control to userland over display/input devices.
-rw-r--r-- | Makefile | 4 | ||||
-rw-r--r-- | doc/directions.txt | 24 | ||||
-rw-r--r-- | doc/fwik.txt | 9 | ||||
-rw-r--r-- | doc/roadmap.txt | 11 | ||||
-rw-r--r-- | doc/terminal.txt | 1 | ||||
-rw-r--r-- | src/include/types.h | 7 | ||||
-rw-r--r-- | src/kernel/core/kmain.cpp | 38 | ||||
-rw-r--r-- | src/kernel/core/main.cpp | 0 | ||||
-rw-r--r-- | src/kernel/core/sys.cpp | 105 | ||||
-rw-r--r-- | src/kernel/core/sys.h | 9 | ||||
-rw-r--r-- | src/kernel/lib/std.cpp | 4 | ||||
-rw-r--r-- | src/kernel/mem/paging.cpp | 26 | ||||
-rw-r--r-- | src/kernel/task/idt.cpp | 4 | ||||
-rw-r--r-- | src/kernel/task/syscall.cpp | 2 | ||||
-rw-r--r-- | src/kernel/task/task.cpp | 26 | ||||
-rw-r--r-- | src/kernel/ui/vt.h | 3 | ||||
-rw-r--r-- | src/kernel/vfs/vdir.h | 2 | ||||
-rw-r--r-- | src/user/lib/libc/include/stdarg.h | 6 |
18 files changed, 178 insertions, 103 deletions
@@ -73,8 +73,8 @@ bochs: all $(Cdrom) bochs -f bochs.cfg qemu: all $(Cdrom) - $(QemuCmd) -cdrom $(Cdrom) -m 32 + $(QemuCmd) -cdrom $(Cdrom) -m 32 -serial stdio qemu-gdb: all $(Cdrom) - $(QemuCmd) -cdrom $(Cdrom) -m 32 -s -S & gdb src/kernel/kernel.elf -x gdb-cmd + $(QemuCmd) -cdrom $(Cdrom) -m 32 -serial stdio -s -S & gdb src/kernel/kernel.elf -x gdb-cmd diff --git a/doc/directions.txt b/doc/directions.txt new file mode 100644 index 0000000..31b6431 --- /dev/null +++ b/doc/directions.txt @@ -0,0 +1,24 @@ +Ideas for T/CE's future : + +1. Give control to userland + +- Provide IPC : we must implement FIFO's and sockets +- Do not provide VT emulation, instead provide direct write access to +the video memory. Also provide direct write access to the framebuffer +when that is implemented. Then, code a display server that does all the +emulating. + +2. Review file management syscalls + +- Should keeping track of file position be the job of the kernel ? +Not sure... +- Possibility of mmap'ing files. Consequence : shared memory. + +3. Review process management + +- fork/exec is cool. How does windows work ? +- Dynamic linking ? Environment variables ? Users ? + +4. Have a graphical user interface, just for fun. Then add a few simple +programs, just for fun.o + diff --git a/doc/fwik.txt b/doc/fwik.txt deleted file mode 100644 index d038b2a..0000000 --- a/doc/fwik.txt +++ /dev/null @@ -1,9 +0,0 @@ -FWIK - -FWIK (is not an acronym) is a C++ library for userland applications, built -especially to run on the T/CE kernel. - -It includes : -- I/O (files, directories, terminals) -- Strings, vectors, sets, maps -- ... diff --git a/doc/roadmap.txt b/doc/roadmap.txt deleted file mode 100644 index dabae61..0000000 --- a/doc/roadmap.txt +++ /dev/null @@ -1,11 +0,0 @@ -T/CE is a new project with a lot of ideas and not a lot of organization. - -Stuff to do : - -- remove useless code from grapes -- clean up existing code -- reorganize directories - -- document the new syscall (Interface/Class/Object) system -- basic implementation - diff --git a/doc/terminal.txt b/doc/terminal.txt index ebdc898..95e5e05 100644 --- a/doc/terminal.txt +++ b/doc/terminal.txt @@ -12,3 +12,4 @@ When keyboard echo is disabled: - what is written to keyboard is NEVER ECHOED - read returns after each keystroke (can also be an escape sequence) Default is keyboard echo disabled. + diff --git a/src/include/types.h b/src/include/types.h index 373a3b5..18efff8 100644 --- a/src/include/types.h +++ b/src/include/types.h @@ -15,4 +15,11 @@ typedef long int ptrdiff_t; #define NULL 0 +// Use internal GCC structures for variadic functions +#define va_start(v,l) __builtin_va_start(v,l) +#define va_arg(v,l) __builtin_va_arg(v,l) +#define va_end(v) __builtin_va_end(v) +#define va_copy(d,s) __builtin_va_copy(d,s) +typedef __builtin_va_list va_list; + #endif diff --git a/src/kernel/core/kmain.cpp b/src/kernel/core/kmain.cpp index 23b62e3..fdfb70a 100644 --- a/src/kernel/core/kmain.cpp +++ b/src/kernel/core/kmain.cpp @@ -27,6 +27,8 @@ extern "C" void kmain(multiboot_info_t* mbd, int32_t magic) { ASSERT(magic == MULTIBOOT_BOOTLOADER_MAGIC); + dbg_printf("\n------------------------------\nT/CE kernel booting, serial debugging enabled.\n"); + mem_placementAddr = ((size_t)&end & 0xFFFFF000) + 0x1000; mbd->cmdline += K_HIGHHALF_ADDR; mbd->mods_addr += K_HIGHHALF_ADDR; module_t *mods = (module_t*)mbd->mods_addr; @@ -42,6 +44,7 @@ extern "C" void kmain(multiboot_info_t* mbd, int32_t magic) { // Init memory managment functions idt_init(); size_t totalRam = ((mbd->mem_upper + mbd->mem_lower) * 1024); + dbg_printf("Total ram: %p\n", totalRam); paging_init(totalRam); gdt_init(); paging_cleanup(); @@ -56,36 +59,29 @@ extern "C" void kmain(multiboot_info_t* mbd, int32_t magic) { text_display = new vgatxt(dot_dev); dot_dev->add_child("vgatxt", text_display); - ke_vt = new vt(dot_ui, 80, 25); - dot_ui->add_child("klog", ke_vt); - ke_vt->outputTo(text_display); home_vt = new vt(dot_ui, 80, 25); dot_ui->add_child("home", home_vt); + home_vt->outputTo(text_display); dot_ui->add_child("vt1", new vt(dot_ui, 80, 25)); dot_ui->add_child("vt2", new vt(dot_ui, 80, 25)); dot_ui->add_child("vt3", new vt(dot_ui, 80, 25)); dot_ui->add_child("vt4", new vt(dot_ui, 80, 25)); // Say hello - ke_vt->fgcolor = TC_LIGHTGRAY; - *ke_vt << "Hello. This is "; - ke_vt->fgcolor = TC_WHITE; *ke_vt << K_OS_NAME; - ke_vt->fgcolor = TC_LIGHTGRAY; *ke_vt << " version "; - ke_vt->fgcolor = TC_WHITE; *ke_vt << K_OS_VER; - ke_vt->fgcolor = TC_LIGHTGRAY; *ke_vt << " codename '"; - ke_vt->fgcolor = TC_WHITE; *ke_vt << K_OS_CODENAME; - ke_vt->fgcolor = TC_LIGHTGRAY; *ke_vt << "'. Enjoy!\n"; + dbg_printf("%s version %s condename %s\n", K_OS_NAME, K_OS_VER, K_OS_CODENAME); // Init devices kbd = new ps2kbd(dot_dev); dot_dev->add_child("ps2kbd", kbd); - kbd->outputTo(ke_vt); + kbd->outputTo(home_vt); // Load modules - *ke_vt << "Loading modules :\n"; + dbg_printf("Loading modules :\n"); for (unsigned i = 0; i < mbd->mods_count; i++) { char* cmd = (char*)mods[i].string; - *ke_vt << " * " << cmd << " \t"; + + dbg_printf(" * %s \t", cmd); + if (elf_check((uint8_t*)mods[i].mod_start) == 0) { char *args[16] = { cmd, 0 }; @@ -107,10 +103,10 @@ extern "C" void kmain(multiboot_info_t* mbd, int32_t magic) { process *pr = elf_exec((uint8_t*)mods[i].mod_start, PL_USER, args); // todo add args if (pr == 0) { - *ke_vt << "Error loading\n"; + dbg_printf("Error loading\n"); } else { - pr->fd.set(0, ke_vt); - *ke_vt << "OK, pid=" << (int)pr->pid << "\n"; + pr->fd.set(0, home_vt); + dbg_printf("OK, pid = %d\n", pr->pid); } } else if (initrd_check((uint8_t*)mods[i].mod_start) == 0) { vdir* fs = new vdir(root); @@ -121,16 +117,16 @@ extern "C" void kmain(multiboot_info_t* mbd, int32_t magic) { if (*i == '/' || *i == ' ') name = i + 1; } root->add_child(name, fs); - *ke_vt << "OK, initrd as /" << name << "/\n"; + dbg_printf("OK,initrd as /%s/\n", name); } else { - *ke_vt << "initrd but error " << e << "\n"; + dbg_printf("initrd, but error %d\n", e); } } else { - *ke_vt << "Invalid file, neither ELF nor initrd.\n"; + dbg_printf("invalid, neither ELF nor initrd.\n"); } } - *ke_vt << "Giving control to userland processes.\n\n"; + dbg_printf("Giving control to userland processes.\n"); sti(); schedule(); PANIC("Should never happen. Something probably went wrong with multitasking."); diff --git a/src/kernel/core/main.cpp b/src/kernel/core/main.cpp deleted file mode 100644 index e69de29..0000000 --- a/src/kernel/core/main.cpp +++ /dev/null diff --git a/src/kernel/core/sys.cpp b/src/kernel/core/sys.cpp index 01a3c20..e27e0a6 100644 --- a/src/kernel/core/sys.cpp +++ b/src/kernel/core/sys.cpp @@ -31,8 +31,7 @@ uint16_t inw(uint16_t port) { void stack_trace(size_t bp) { uint32_t *stack = (uint32_t*)bp, i; for (i = 0; i < 5 && (size_t)stack > K_HIGHHALF_ADDR && (size_t)stack < (bp + 0x8000); i++) { - *ke_vt << " | " << (size_t)stack; - *ke_vt << "\tnext:" << stack[0] << "\t\tret:" << stack[1] << " \n"; + dbg_printf(" | %p\tnext:%p\t\tret:%p\n", stack, stack[0], stack[1]); stack = (uint32_t*)stack[0]; } } @@ -40,29 +39,21 @@ void stack_trace(size_t bp) { /* For internal use only. Used by panic and panic_assert. */ static void panic_do(char* file, int line) { asm volatile("cli;"); - *ke_vt << " \n File:\t\t" << file << ":" << line; - *ke_vt << " \nTrace: \n"; + dbg_printf("File:\t\t%s:%i\n", file, line); + dbg_printf("Trace:\n"); size_t bp; asm volatile("mov %%ebp,%0" : "=r"(bp)); stack_trace(bp); - *ke_vt << "\n\t\tSystem halted -_-'"; + dbg_printf("\t\tSystem halted -_-'\n"); asm volatile("hlt"); } /* These functions stop the system, reporting an error message, because something bad happenned. */ void panic(char* message, char* file, int line) { - ke_vt->fgcolor = TC_WHITE; - ke_vt->bgcolor = TC_BLUE; - ke_vt->outputTo(text_display); - *ke_vt << " * * * * * * * * * * * * * * * * * * * * * * * * * * "; - *ke_vt << "\nPANIC:\t" << message; + dbg_printf("#### PANIC ####\n"); panic_do(file, line); } void panic_assert(char* assertion, char* file, int line) { - ke_vt->fgcolor = TC_WHITE; - ke_vt->bgcolor = TC_RED; - ke_vt->outputTo(text_display); - *ke_vt << " * * * * * * * * * * * * * * * * * * * * * * * * * * "; - *ke_vt << "\nASSERT FAILED:\t" << assertion; + dbg_printf("#### ASSERT FAILED ####\n"); panic_do(file, line); } @@ -79,3 +70,87 @@ void sti() { if (if_locks > 0) if_locks--; if (if_locks == 0) asm volatile("sti"); } + +// Serial debugging + +#define SER_PORT 0x3F8 // COM1 +static int ser_init = 1; + +void ser_putc(const char c) { + if (ser_init) { + outb(SER_PORT + 1, 0x00); // disable interrupts + outb(SER_PORT + 3, 0x80); // set baud rate + outb(SER_PORT + 0, 0x03); // set divisor to 3 (38400 baud) + outb(SER_PORT + 1, 0x00); + outb(SER_PORT + 3, 0x03); // 8 bits, no parity, one stop bit + outb(SER_PORT + 2, 0xC7); // enable FIFO, clear them, with 14-byte threshold + ser_init = 0; + } + + while (!(inb(SER_PORT + 5) & 0x20)); + outb(SER_PORT, c); +} + +void ser_puts(const char *c) { + while (*c) { + ser_putc(*c); + c++; + } +} + +void ser_printf(const char *format, ...) { + va_list ap; + va_start(ap, format); + + while (*format) { + if (*format == '%') { + format++; + if (*format == 'd' || *format == 'i') { + // Output DEC + int v = va_arg(ap, int); + if (v == 0) { + ser_putc('0'); + } else { + if (v < 0) { + ser_putc('-'); + v = -v; + } + char s[20]; + char *b = s + 19; + *b = 0; + while (v) { + *(--b) = '0' + (v % 10); + v /= 10; + } + ser_puts(b); + } + } else if (*format == 'p') { + // Output HEX + uint32_t v = va_arg(ap, uint32_t); + const char *digits = "0123456789ABCDEF"; + char s[11]; + s[0] = '0'; + s[1] = 'x'; + s[10] = 0; + for (int i = 0; i < 8; i++) { + s[9 - i] = digits[v % 16]; + v /= 16; + } + ser_puts(s); + } else if (*format == 's') { + // Output STR + const char *s = va_arg(ap, const char*); + ser_puts(s); + } else if (*format == 'c') { + // Output CHR + char v = va_arg(ap, int); + ser_putc(v); + } + format++; + } else { + ser_putc(*(format++)); + } + } + + va_end(ap); +} diff --git a/src/kernel/core/sys.h b/src/kernel/core/sys.h index f429b44..a4e1680 100644 --- a/src/kernel/core/sys.h +++ b/src/kernel/core/sys.h @@ -3,6 +3,7 @@ #include "types.h" + void outb(uint16_t port, uint8_t value); void outw(uint16_t port, uint16_t value); uint8_t inb(uint16_t port); @@ -20,4 +21,12 @@ void panic_assert(char* assertion, char* file, int line); void cli(); //lock void sti(); //unlock +// Serial debugging + +void ser_putc(const char c); +void ser_puts(const char *c); +void ser_printf(const char *format, ...); +#define dbg_printf ser_printf + + #endif diff --git a/src/kernel/lib/std.cpp b/src/kernel/lib/std.cpp index c25f59c..ef93509 100644 --- a/src/kernel/lib/std.cpp +++ b/src/kernel/lib/std.cpp @@ -5,9 +5,7 @@ int errno = 0; void abort() { - *ke_vt << "\n\n ABORT - errno: "; - *ke_vt << errno; - *ke_vt <<"\n"; + dbg_printf("ABORT - errno %d\n", errno); PANIC("abort() called, probably a memory manager failure."); } diff --git a/src/kernel/mem/paging.cpp b/src/kernel/mem/paging.cpp index 5c5a929..436c888 100644 --- a/src/kernel/mem/paging.cpp +++ b/src/kernel/mem/paging.cpp @@ -136,22 +136,16 @@ uint32_t paging_fault(registers *regs) { } if (seg == 0) { - node *n = current_thread->process->fd.at(0); - vt *vt = (n && n->as_vt() ? n->as_vt() : ke_vt); - - vt->writeStr("\n"); - vt->writeStr("[ke:"); vt->writeStr(__FILE__); vt->writeStr(":"); - vt->writeDec(__LINE__); vt->writeStr("] "); - vt->writeStr("Unhandled Page Fault"); - - *vt << "\n\tPID: " << (int)current_thread->process->pid; - *vt << "\n\tcr2: " << addr; - *vt << "\n\tflags: "; - if (regs->err_code & 0x1) *vt << "present "; - if (regs->err_code & 0x2) *vt << "write "; - if (regs->err_code & 0x4) *vt << "user "; - if (regs->err_code & 0x8) *vt << "rsvd "; - if (regs->err_code & 0x10) *vt << "opfetch "; + dbg_printf("[ke:%s:%d] Unhandled page fault\n", __FILE__, __LINE__); + + dbg_printf("\tPID: %d\n", current_thread->process->pid); + dbg_printf("\tcr2: %p\n", addr); + dbg_printf("\tflags:"); + if (regs->err_code & 0x1) dbg_printf(" present"); + if (regs->err_code & 0x2) dbg_printf(" write"); + if (regs->err_code & 0x4) dbg_printf(" user"); + if (regs->err_code & 0x8) dbg_printf(" rsvd"); + if (regs->err_code & 0x10) dbg_printf(" opfetch"); return 1; } return 0; diff --git a/src/kernel/task/idt.cpp b/src/kernel/task/idt.cpp index 94a31b7..782bbd6 100644 --- a/src/kernel/task/idt.cpp +++ b/src/kernel/task/idt.cpp @@ -80,9 +80,7 @@ static struct irq_waiter { extern "C" void idt_isrHandler(registers regs) { if (regs.int_no != 14 || paging_fault(®s)) { if (tasking_handleException(®s) == 0) { - *ke_vt << "\nREALLY BAD THIS TIME\t\tUnhandled exception\t#"; - *ke_vt << regs.int_no; - *ke_vt << "\t@" << regs.eip; + dbg_printf("REALLY BAD THIS TIME: Unhandled exception #%d @%p\n", regs.int_no, regs.eip); PANIC("Unhandled Exception"); } } diff --git a/src/kernel/task/syscall.cpp b/src/kernel/task/syscall.cpp index 9e7c089..a3074b8 100644 --- a/src/kernel/task/syscall.cpp +++ b/src/kernel/task/syscall.cpp @@ -33,7 +33,7 @@ CALL2(process_waitpid, waitpid_sc); CALL1V(close, close_sc); static void printk_sc(registers *r) { - ke_vt->writeStr((char*)r->ebx); + dbg_printf("%s", (char*)r->ebx); } static void thread_new_sc(registers* r) { diff --git a/src/kernel/task/task.cpp b/src/kernel/task/task.cpp index 2af0441..2ad5447 100644 --- a/src/kernel/task/task.cpp +++ b/src/kernel/task/task.cpp @@ -104,40 +104,36 @@ void schedule() { /* Called when an exception happens. Provides a stack trace if it was in kernel land. Ends the thread for most exceptions, ends the whole process for page faults. */ uint32_t tasking_handleException(registers *regs) { - node *n = current_thread->process->fd.at(0); - vt *vt = (n && n->as_vt() ? n->as_vt() : ke_vt); - if (current_thread == 0) return 0; //No tasking yet - vt->writeStr("\n"); - vt->writeStr("[ke:"); vt->writeStr(__FILE__); vt->writeStr(":"); - vt->writeDec(__LINE__); vt->writeStr("] "); - vt->writeStr("Exception: "); + dbg_printf("[ke:%s:%d] Exception: ", __FILE__, __LINE__); char *exception_messages[] = {"Division By Zero","Debug","Non Maskable Interrupt","Breakpoint", "Into Detected Overflow","Out of Bounds","Invalid Opcode","No Coprocessor", "Double Fault", "Coprocessor Segment Overrun","Bad TSS","Segment Not Present","Stack Fault","General Protection Fault", "Page Fault","Unknown Interrupt","Coprocessor Fault","Alignment Check","Machine Check"}; - *vt << exception_messages[regs->int_no];; - *vt << "\n\tPID: " << (int)current_thread->process->pid; - *vt << "\n\teip: " << regs->eip; + + dbg_printf("%s\n", exception_messages[regs->int_no]); + dbg_printf("\tPID: %d\n", current_thread->process->pid); + dbg_printf("\teip: %p\n", regs->eip); + if (regs->eip >= K_HIGHHALF_ADDR) { - *vt << "\n\tException in kernel."; + dbg_printf("\tException in kernel\n"); stack_trace(regs->ebp); // useless } - *vt << "\n\tTrace:"; + dbg_printf("\tTrace:\n"); uint32_t *stack = (uint32_t*)regs->ebp, i; for (i = 0; i < 7 && (size_t)stack < (regs->ebp + 0x4000) && (size_t) stack >= regs->ebp; i++) { - *vt << "\n\t " << (size_t)stack << " next: " << stack[0] << " ret: " << stack[1]; + dbg_printf("\t%p\tnext: %p\tret: %p\n", stack, stack[0], stack[1]); stack = (uint32_t*)stack[0]; } if (regs->int_no == 14) { - *vt << "\n\tKilling process.\n"; + dbg_printf("\tKilling process.\n"); thread_exit_stackJmp(EX_PAGEFAULT); } else { - *vt << "\n\tKilling thread.\n"; + dbg_printf("\tKilling thread.\n"); thread_exit_stackJmp(EX_EXCEPTION); } PANIC("This should never have happened. Please report this."); diff --git a/src/kernel/ui/vt.h b/src/kernel/ui/vt.h index 8a169b4..ee991da 100644 --- a/src/kernel/ui/vt.h +++ b/src/kernel/ui/vt.h @@ -54,7 +54,8 @@ class vt : public node { virtual int link(node* to, int mode); }; -extern vt *ke_vt, *home_vt; +//extern vt *ke_vt; +extern vt *home_vt; #define NL ke_vt->writeStr("\n"); #define TAB ke_vt->writeStr("\t"); #define WHERE { ke_vt->writeStr("(ke:"); \ diff --git a/src/kernel/vfs/vdir.h b/src/kernel/vfs/vdir.h index 6aacc2f..47d7733 100644 --- a/src/kernel/vfs/vdir.h +++ b/src/kernel/vfs/vdir.h @@ -14,7 +14,7 @@ struct vdir_child { } virtual ~vdir_child() { - free(name); + kfree(name); } }; diff --git a/src/user/lib/libc/include/stdarg.h b/src/user/lib/libc/include/stdarg.h index 5cd74ff..141b04a 100644 --- a/src/user/lib/libc/include/stdarg.h +++ b/src/user/lib/libc/include/stdarg.h @@ -1,10 +1,6 @@ #ifndef DEF_STDARG_H #define DEF_STDARG_H -#define va_start(v,l) __builtin_va_start(v,l) -#define va_arg(v,l) __builtin_va_arg(v,l) -#define va_end(v) __builtin_va_end(v) -#define va_copy(d,s) __builtin_va_copy(d,s) -typedef __builtin_va_list va_list; +#include <types.h> #endif |