M include/kernel/log.h => include/kernel/log.h +3 -0
@@ 8,6 8,9 @@
#define WARN "[\033[93m WARN " RESET "] "
#define ERROR "[\033[91m ERROR " RESET "] "
#define DEBUG "[\033[93m DEBUG " RESET "] "
+#define BRKPT "[\033[96m BRKPT " RESET "] "
+#define REACHED_HERE FORMAT_AT(__FILE__, __LINE__)
+#define FORMAT_AT(file, line) "@" file ":%d\n", line
void kprintf(const char *format, ...);
void kassert_int(bool condition, const char *message, const char *file,
M include/kernel/task.h => include/kernel/task.h +1 -0
@@ 23,6 23,7 @@ struct process
// NOTE: must be PAGE ALIGNED
uint last_stack_pos;
};
+
/**
* The smallest schedulable unit, a thread of a process.
*/
M src/kernel/idt.s => src/kernel/idt.s +2 -2
@@ 40,11 40,11 @@ ISRERR 13
ISRERR 14
ISRNOERR 15
ISRNOERR 16
-ISRNOERR 17
+ISRERR 17
ISRNOERR 18
ISRNOERR 19
ISRNOERR 20
-ISRNOERR 21
+ISRERR 21
ISRNOERR 22
ISRNOERR 23
ISRNOERR 24
M src/kernel/main.c => src/kernel/main.c +1 -1
@@ 65,7 65,7 @@ int kmain(struct multiboot_info *mboot)
asm("sti");
- // init_tasks();
+ init_tasks();
init_sync();
pci_init();
M src/kernel/paging.c => src/kernel/paging.c +8 -0
@@ 5,6 5,14 @@
#include "log.h"
#include "pic.h"
+/**
+ * NOTE: In order to understand this code you should have the paging
+ * section of the Intel IA-32 and 64 manual volume 3 open. Sadly I
+ * have littered this with magic numbers that you will need to consult
+ * the manual to understand.
+ * TODO: Fix this!
+ */
+
#define NUM_FRAMES 0xffffffff / 0x1000 / 32
/* frames bitset, 0 = free, 1 = used */
static uint frames[NUM_FRAMES];
M src/kernel/pic.c => src/kernel/pic.c +4 -2
@@ 33,7 33,8 @@ void irq_handler(struct registers regs)
if (interrupt_handlers[regs.interrupt_number])
interrupt_handlers[regs.interrupt_number](®s);
else
- kprintf(ERROR "Unhandled hardware interrupt: %d, called from %d\n", regs.interrupt_number, regs.eip);
+ kprintf(ERROR "Unhandled hardware interrupt: %d, called from %d\n",
+ regs.interrupt_number, regs.eip);
}
void isr_handler(struct registers regs)
@@ 41,7 42,8 @@ void isr_handler(struct registers regs)
if (interrupt_handlers[regs.interrupt_number])
interrupt_handlers[regs.interrupt_number](®s);
else
- kprintf(ERROR "Unhandled interrupt: %d, called from %d\n", regs.interrupt_number, regs.eip);
+ kprintf(ERROR "Unhandled interrupt: %d, called from %d\n",
+ regs.interrupt_number, regs.eip);
}
void add_interrupt_handler(uchar interrupt, void (*handler)(struct registers *))
M src/kernel/task.c => src/kernel/task.c +8 -1
@@ 81,6 81,8 @@ void spawn_thread(void (*function)(void *), void *data)
{
asm("cli");
+ kprintf(DEBUG "Spawning thread %p, data=%p\n", function, data);
+
struct process *proc = current_task->task.proc;
// Virtual address of page directory (in kernel memory)
uint *dir_v = PHYS_TO_VIRT(proc->page_directory_p);
@@ 93,11 95,14 @@ void spawn_thread(void (*function)(void *), void *data)
// Alloc a new page in the current process mapping to the new stack
alloc_page(dir_v, (void *)proc->last_stack_pos);
+ kprintf(INFO "new_stack_base_v = %p\n", new_stack_base_v);
new_stack_base_v -= sizeof(uint);
*((uint *)new_stack_base_v) = (size_t)data;
new_stack_base_v -= sizeof(uint);
*((uint *)new_stack_base_v) = (size_t)&kill_this_thread;
+ kprintf(DEBUG "Set stack\n");
+
struct ll_task_i *ll_task = malloc(sizeof(struct ll_task_i));
memset(ll_task, 0, sizeof(struct ll_task_i));
struct task *task = &ll_task->task;
@@ 175,9 180,11 @@ void switch_to_task(struct task *task)
void _do_switch_task(struct registers regs)
{
- // sti is called in switch_to_task
+ // Resetting eflags in _switch_to_task iret will switch this back
asm("cli");
+ kprintf(DEBUG "switching tasks\n");
+
// save context for this task
current_task->task.state = regs;
M src/kernel/task_api.s => src/kernel/task_api.s +0 -26
@@ 1,29 1,3 @@
- ;; This is very much the same as _switch_to_task, but we used iret
- ;; and switch to ring3.
- [global _switch_to_user_task]
- ;; _switch_to_user_task(uint page_directory, uint eip, uint ebp, uint esp)
-_switch_to_user_task: ; (page_directory, eip, ebp, esp)
- add esp, 4 ; We don't care about the return address
-
- pop ecx ; Page directory
- pop eax ; eip
- pop ebp
- pop ebx ; esp
-
- mov dx, 0x23 ; User mode data segment
- mov ds, dx
- mov es, dx
- mov fs, dx
- mov gs, dx
-
- mov cr3, ecx ; Set page directory
-
- push 0x23
- push ebx ; esp
-
- sti
- jmp eax ; Jump back to code
-
[global _switch_to_task]
_switch_to_task: ; (uint page_directory, struct
; registers regs)