summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex AUVOLAT <alexis211@gmail.com>2013-07-10 21:17:50 +0200
committerAlex AUVOLAT <alexis211@gmail.com>2013-07-10 21:17:50 +0200
commit78d7ffce4861dea5624ff29ceb39f1643dff8235 (patch)
tree6b41c052e48398f7520013622f0b1b9b9190259a
parentfadf399405ca5d918dd5e1182fadc3d82f6bc900 (diff)
downloadTCE-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--Makefile4
-rw-r--r--doc/directions.txt24
-rw-r--r--doc/fwik.txt9
-rw-r--r--doc/roadmap.txt11
-rw-r--r--doc/terminal.txt1
-rw-r--r--src/include/types.h7
-rw-r--r--src/kernel/core/kmain.cpp38
-rw-r--r--src/kernel/core/main.cpp0
-rw-r--r--src/kernel/core/sys.cpp105
-rw-r--r--src/kernel/core/sys.h9
-rw-r--r--src/kernel/lib/std.cpp4
-rw-r--r--src/kernel/mem/paging.cpp26
-rw-r--r--src/kernel/task/idt.cpp4
-rw-r--r--src/kernel/task/syscall.cpp2
-rw-r--r--src/kernel/task/task.cpp26
-rw-r--r--src/kernel/ui/vt.h3
-rw-r--r--src/kernel/vfs/vdir.h2
-rw-r--r--src/user/lib/libc/include/stdarg.h6
18 files changed, 178 insertions, 103 deletions
diff --git a/Makefile b/Makefile
index f4c878a..1fa8b05 100644
--- a/Makefile
+++ b/Makefile
@@ -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(&regs)) {
if (tasking_handleException(&regs) == 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