diff options
author | Alex AUVOLAT <alexis211@gmail.com> | 2012-05-04 20:06:37 +0200 |
---|---|---|
committer | Alex AUVOLAT <alexis211@gmail.com> | 2012-05-04 20:06:37 +0200 |
commit | 277e4af4fa9e80816c809542d792ee6bebb7f202 (patch) | |
tree | 9abb7f207d185909427137e4861b81c057de1259 | |
parent | e9683297bf480f9590b0e5796f4520fb430e2e03 (diff) | |
download | TCE-277e4af4fa9e80816c809542d792ee6bebb7f202.tar.gz TCE-277e4af4fa9e80816c809542d792ee6bebb7f202.zip |
Migration to C++!
-rw-r--r-- | src/common.make | 11 | ||||
-rw-r--r-- | src/common/include/stdlib_common.h | 8 | ||||
-rw-r--r-- | src/common/include/string.h | 8 | ||||
-rw-r--r-- | src/common/include/types.h | 4 | ||||
-rw-r--r-- | src/kernel/config.h | 4 | ||||
-rw-r--r-- | src/kernel/core/kmain.cpp (renamed from src/kernel/core/kmain.c) | 10 | ||||
-rw-r--r-- | src/kernel/core/monitor.cpp (renamed from src/kernel/core/monitor.c) | 0 | ||||
-rw-r--r-- | src/kernel/core/sys.cpp (renamed from src/kernel/core/sys.c) | 4 | ||||
-rw-r--r-- | src/kernel/lib/bitset.c | 35 | ||||
-rw-r--r-- | src/kernel/lib/bitset.cpp | 35 | ||||
-rw-r--r-- | src/kernel/lib/bitset.h | 9 | ||||
-rw-r--r-- | src/kernel/lib/cpp.h | 16 | ||||
-rw-r--r-- | src/kernel/lib/std.cpp (renamed from src/kernel/lib/std.c) | 1 | ||||
-rw-r--r-- | src/kernel/lib/std.h | 5 | ||||
-rw-r--r-- | src/kernel/linker/elf.cpp (renamed from src/kernel/linker/elf.c) | 16 | ||||
-rw-r--r-- | src/kernel/linker/elf.h | 6 | ||||
-rw-r--r-- | src/kernel/mem/_dlmalloc.h | 3 | ||||
-rw-r--r-- | src/kernel/mem/gdt.cpp (renamed from src/kernel/mem/gdt.c) | 16 | ||||
-rw-r--r-- | src/kernel/mem/mem.cpp (renamed from src/kernel/mem/mem.c) | 10 | ||||
-rw-r--r-- | src/kernel/mem/mem.h | 12 | ||||
-rw-r--r-- | src/kernel/mem/paging.cpp (renamed from src/kernel/mem/paging.c) | 40 | ||||
-rw-r--r-- | src/kernel/mem/paging.h | 26 | ||||
-rw-r--r-- | src/kernel/mem/seg.cpp (renamed from src/kernel/mem/seg.c) | 50 | ||||
-rw-r--r-- | src/kernel/mem/seg.h | 24 | ||||
-rw-r--r-- | src/kernel/task/idt.cpp (renamed from src/kernel/task/idt.c) | 28 | ||||
-rw-r--r-- | src/kernel/task/idt.h | 2 | ||||
-rw-r--r-- | src/kernel/task/sched.cpp (renamed from src/kernel/task/sched.c) | 16 | ||||
-rw-r--r-- | src/kernel/task/sched.h | 4 | ||||
-rw-r--r-- | src/kernel/task/syscall.c | 45 | ||||
-rw-r--r-- | src/kernel/task/syscall.cpp | 50 | ||||
-rw-r--r-- | src/kernel/task/task.cpp (renamed from src/kernel/task/task.c) | 61 | ||||
-rw-r--r-- | src/kernel/task/task.h | 29 | ||||
-rw-r--r-- | src/kernel/task/timer.cpp (renamed from src/kernel/task/timer.c) | 10 |
33 files changed, 330 insertions, 268 deletions
diff --git a/src/common.make b/src/common.make index 438ff07..5ea9ae9 100644 --- a/src/common.make +++ b/src/common.make @@ -2,11 +2,14 @@ CC = i586-elf-gcc CFLAGS = -nostdlib -nostartfiles -nodefaultlibs -fno-builtin -fno-stack-protector -Wall -Wextra +CCFLAGS = +CXX = i586-elf-g++ +CXXFLAGS = -fno-rtti -fno-exceptions -Werror -Wno-write-strings -Wno-error=unused-parameter LD = i586-elf-ld .PHONY: clean, mrproper -LDFLAGS = +LDFLAGS = -oformat=elf32-i386 ASM = nasm AFLAGS = -f elf @@ -36,4 +39,8 @@ mrproper: clean %.o: %.c echo ""; echo "- $<" - $(CC) -c $< -o $@ $(CFLAGS) + $(CC) -c $< -o $@ $(CFLAGS) $(CCFLAGS) + +%.o: %.cpp + echo ""; echo "- $<" + $(CXX) -c $< -o $@ $(CFLAGS) $(CXXFLAGS) diff --git a/src/common/include/stdlib_common.h b/src/common/include/stdlib_common.h index 80c188f..dc40b96 100644 --- a/src/common/include/stdlib_common.h +++ b/src/common/include/stdlib_common.h @@ -6,9 +6,17 @@ #define MIN(a, b) ((a) < (b) ? (a) : (b)) #define MAX(a, b) ((a) > (b) ? (a) : (b)) +#ifdef __cplusplus +extern "C" { +#endif + void *memcpy(void *dest, const void *src, int count); void *memset(void *dest, int val, int count); uint16_t *memsetw(uint16_t *dest, uint16_t val, int count); +#ifdef __cplusplus +} +#endif + #endif diff --git a/src/common/include/string.h b/src/common/include/string.h index a41459e..e6aa86e 100644 --- a/src/common/include/string.h +++ b/src/common/include/string.h @@ -4,6 +4,10 @@ // #include <stdlib.h> #include <types.h> +#ifdef __cplusplus +extern "C" { +#endif + int strlen(const char *str); char *strcpy(char *dest, const char *src); // char *strdup(const char *src); // uses malloc, that's bad @@ -11,4 +15,8 @@ char *strchr(const char *str, char c); char *strcat(char *dest, const char *src); int strcmp(const char *s1, const char *s2); +#ifdef __cplusplus +} +#endif + #endif diff --git a/src/common/include/types.h b/src/common/include/types.h index ec24ce5..e7c1a35 100644 --- a/src/common/include/types.h +++ b/src/common/include/types.h @@ -2,7 +2,7 @@ #define DEF_TYPES_H typedef unsigned long long uint64_t; -typedef unsigned int uint32_t; +typedef unsigned long int uint32_t; typedef unsigned short uint16_t; typedef unsigned char uint8_t; typedef long long int64_t; @@ -10,7 +10,7 @@ typedef int int32_t; typedef short int16_t; typedef char int8_t; -typedef unsigned int size_t; +typedef long unsigned int size_t; #define NULL 0 diff --git a/src/kernel/config.h b/src/kernel/config.h index f021d9c..ee6141e 100644 --- a/src/kernel/config.h +++ b/src/kernel/config.h @@ -2,8 +2,8 @@ #define DEF_CONFIG_H #define K_OS_NAME "T/CE" -#define K_OS_VER "0.0.1" -#define K_OS_CODENAME "Nyanyanya" +#define K_OS_VER "0.0.2" +#define K_OS_CODENAME "CPLUSPLUS==\\o/" /* HEAP CODE TO USE : Two kernel heap implementations are available : diff --git a/src/kernel/core/kmain.c b/src/kernel/core/kmain.cpp index 8c36b54..0a5f2d8 100644 --- a/src/kernel/core/kmain.c +++ b/src/kernel/core/kmain.cpp @@ -17,7 +17,7 @@ It then loads the modules the kernel was given by the bootloader. This function never returns : once multitasking is started for good, the execution flow of this function is never returned to. */ -void kmain(struct multiboot_info_t* mbd, int32_t magic) { +extern "C" void kmain(multiboot_info_t* mbd, int32_t magic) { ASSERT(magic == MULTIBOOT_BOOTLOADER_MAGIC); size_t totalRam = 0; @@ -25,7 +25,7 @@ void kmain(struct multiboot_info_t* mbd, int32_t magic) { mem_placementAddr = ((size_t)&end & 0xFFFFF000) + 0x1000; mbd->cmdline += K_HIGHHALF_ADDR; mbd->mods_addr += K_HIGHHALF_ADDR; - struct module_t *mods = (struct module_t*)mbd->mods_addr; + module_t *mods = (module_t*)mbd->mods_addr; for (i = 0; i < mbd->mods_count; i++) { mods[i].mod_start += K_HIGHHALF_ADDR; mods[i].mod_end += K_HIGHHALF_ADDR; @@ -48,7 +48,7 @@ void kmain(struct multiboot_info_t* mbd, int32_t magic) { totalRam = ((mbd->mem_upper + mbd->mem_lower) * 1024); paging_init(totalRam); - _no_more_ksbrk = 1; + _no_more_ksbrk = true; gdt_init(); paging_cleanup(); @@ -56,14 +56,14 @@ void kmain(struct multiboot_info_t* mbd, int32_t magic) { timer_init(30); tasking_init(); - monitor_write("\n\nLoading modules :\n"); + monitor_write("\nLoading modules :\n"); for (i = 0; i < mbd->mods_count; i++) { monitor_write(" * "); monitor_write((char*)mods[i].string); if (elf_check((uint8_t*)mods[i].mod_start)) { monitor_write(" : Invalid ELF file\n"); } else { - struct process *pr = elf_exec((uint8_t*)mods[i].mod_start, PL_USER); + process *pr = elf_exec((uint8_t*)mods[i].mod_start, PL_USER); if (pr == 0) { monitor_write(" : Error loading\n"); } else { diff --git a/src/kernel/core/monitor.c b/src/kernel/core/monitor.cpp index ba2a6df..ba2a6df 100644 --- a/src/kernel/core/monitor.c +++ b/src/kernel/core/monitor.cpp diff --git a/src/kernel/core/sys.c b/src/kernel/core/sys.cpp index 2c2372d..d95b678 100644 --- a/src/kernel/core/sys.c +++ b/src/kernel/core/sys.cpp @@ -29,8 +29,8 @@ uint16_t inw(uint16_t port) { ////// void stack_trace(size_t bp) { uint32_t *stack = (uint32_t*)bp, i; - for (i = 0; i < 5 && stack > K_HIGHHALF_ADDR && stack < (bp + 0x8000); i++) { - monitor_write("| "); monitor_writeHex(stack); + for (i = 0; i < 5 && (size_t)stack > K_HIGHHALF_ADDR && (size_t)stack < (bp + 0x8000); i++) { + monitor_write("| "); monitor_writeHex((size_t)stack); monitor_write("\tnext:"); monitor_writeHex(stack[0]); monitor_write("\t\tret:"); monitor_writeHex(stack[1]); monitor_write("\n"); stack = (uint32_t*)stack[0]; diff --git a/src/kernel/lib/bitset.c b/src/kernel/lib/bitset.c deleted file mode 100644 index a6d334b..0000000 --- a/src/kernel/lib/bitset.c +++ /dev/null @@ -1,35 +0,0 @@ -#include "bitset.h" - -void bitset_set(struct bitset* t, uint32_t num) { - uint32_t idx = INDEX_FROM_BIT(num); - uint32_t off = OFFSET_FROM_BIT(num); - t->bits[idx] |= (0x1 << off); -} - -void bitset_clear(struct bitset* t, uint32_t num) { - uint32_t idx = INDEX_FROM_BIT(num); - uint32_t off = OFFSET_FROM_BIT(num); - t->bits[idx] &= ~(0x1 << off); -} - -uint32_t bitset_test(struct bitset* t, uint32_t num) { - uint32_t idx = INDEX_FROM_BIT(num); - uint32_t off = OFFSET_FROM_BIT(num); - return (t->bits[idx] & (0x1 << off)); -} - -uint32_t bitset_firstFree(struct bitset* t) { - uint32_t i, j; - for (i = 0; i < INDEX_FROM_BIT(t->size); i++) { - if (t->bits[i] != 0xFFFFFFFF) { - for (j = 0; j < 32; j++) { - uint32_t toTest = 0x1 << j; - if (!(t->bits[i] & toTest)) { - return i*4*8+j; - } - } - } - } - return (uint32_t) - 1; -} - diff --git a/src/kernel/lib/bitset.cpp b/src/kernel/lib/bitset.cpp new file mode 100644 index 0000000..2b3d2e9 --- /dev/null +++ b/src/kernel/lib/bitset.cpp @@ -0,0 +1,35 @@ +#include "bitset.h" + +void bitset::set(uint32_t num) { + uint32_t idx = INDEX_FROM_BIT(num); + uint32_t off = OFFSET_FROM_BIT(num); + bits[idx] |= (0x1 << off); +} + +void bitset::clear(uint32_t num) { + uint32_t idx = INDEX_FROM_BIT(num); + uint32_t off = OFFSET_FROM_BIT(num); + bits[idx] &= ~(0x1 << off); +} + +uint32_t bitset::test(uint32_t num) { + uint32_t idx = INDEX_FROM_BIT(num); + uint32_t off = OFFSET_FROM_BIT(num); + return (bits[idx] & (0x1 << off)); +} + +uint32_t bitset::firstFree() { + uint32_t i, j; + for (i = 0; i < INDEX_FROM_BIT(size); i++) { + if (bits[i] != 0xFFFFFFFF) { + for (j = 0; j < 32; j++) { + uint32_t toTest = 0x1 << j; + if (!(bits[i] & toTest)) { + return i*4*8+j; + } + } + } + } + return (uint32_t) - 1; +} + diff --git a/src/kernel/lib/bitset.h b/src/kernel/lib/bitset.h index fe9e8c2..f2441ce 100644 --- a/src/kernel/lib/bitset.h +++ b/src/kernel/lib/bitset.h @@ -9,11 +9,12 @@ struct bitset { uint32_t *bits; uint32_t size; + + void set(uint32_t num); + void clear(uint32_t num); + uint32_t test(uint32_t num); + uint32_t firstFree(); }; -void bitset_set(struct bitset* t, uint32_t num); -void bitset_clear(struct bitset* t, uint32_t num); -uint32_t bitset_test(struct bitset* t, uint32_t num); -uint32_t bitset_firstFree(struct bitset* t); #endif diff --git a/src/kernel/lib/cpp.h b/src/kernel/lib/cpp.h new file mode 100644 index 0000000..cf08ede --- /dev/null +++ b/src/kernel/lib/cpp.h @@ -0,0 +1,16 @@ +#ifndef DEF_CPPSUPPORT_H +#define DEF_CPPSUPPORT_H + +#include <mem/mem.h> + +inline void* operator new(size_t, void* p) throw() { return p; } +inline void* operator new[](size_t, void* p) throw() { return p; } +inline void operator delete (void*, void*) throw() { }; +inline void operator delete[](void*, void*) throw() { }; + +inline void* operator new (size_t size) { return kmalloc(size); } +inline void* operator new[] (size_t size) { return kmalloc(size); } +inline void operator delete (void* ptr) { return kfree(ptr); } +inline void operator delete[] (void* ptr) { return kfree(ptr); } + +#endif diff --git a/src/kernel/lib/std.c b/src/kernel/lib/std.cpp index 316dfa3..7ab4f64 100644 --- a/src/kernel/lib/std.c +++ b/src/kernel/lib/std.cpp @@ -1,5 +1,6 @@ #include "std.h" #include "core/sys.h" +#include "core/monitor.h" int errno = 0; diff --git a/src/kernel/lib/std.h b/src/kernel/lib/std.h index 51e0435..ced49b5 100644 --- a/src/kernel/lib/std.h +++ b/src/kernel/lib/std.h @@ -5,7 +5,12 @@ #include <types.h> /* For size_t */ +#ifdef __cplusplus +extern "C" void abort(); +#else void abort(); +#endif + #define sbrk ksbrk #define brk kbrk diff --git a/src/kernel/linker/elf.c b/src/kernel/linker/elf.cpp index af6d057..ab8e349 100644 --- a/src/kernel/linker/elf.c +++ b/src/kernel/linker/elf.cpp @@ -5,23 +5,23 @@ #include <core/sys.h> int elf_check(uint8_t *data) { - struct elf_ehdr *h = (struct elf_ehdr*)data; + elf_ehdr *h = (elf_ehdr*)data; if (h->e_ident[0] == 0x7F && h->e_ident[1] == 'E' && h->e_ident[2] == 'L' && h->e_ident[3] == 'F') return 0; return 1; } -thread_entry elf_load(uint8_t *data, struct process* process) { - struct elf_ehdr *ehdr = (struct elf_ehdr*)data; - struct elf_phdr *phdr; +thread_entry elf_load(uint8_t *data, process* process) { + elf_ehdr *ehdr = (elf_ehdr*)data; + elf_phdr *phdr; int i; size_t dataseg = 0; if (elf_check(data)) return 0; - struct page_directory *r = current_pagedir; + page_directory *r = current_pagedir; cli(); pagedir_switch(process->pagedir); - phdr = (struct elf_phdr*)((uint8_t*)(data + ehdr->e_phoff)); + phdr = (elf_phdr*)((uint8_t*)(data + ehdr->e_phoff)); for (i = 0; i < ehdr->e_phnum; i++) { if (phdr[i].p_type == PT_LOAD) { seg_map(simpleseg_make(phdr[i].p_vaddr, phdr[i].p_memsz, (phdr[i].p_flags & PF_W) != 0), process->pagedir, 0); @@ -44,10 +44,10 @@ thread_entry elf_load(uint8_t *data, struct process* process) { return (thread_entry)ehdr->e_entry; } -struct process* elf_exec(uint8_t *data, int privilege) { +process* elf_exec(uint8_t *data, int privilege) { if (elf_check(data)) return 0; - struct process* p = process_new(0, 0, privilege); + process* p = process_new(0, 0, privilege); thread_entry e = elf_load(data, p); diff --git a/src/kernel/linker/elf.h b/src/kernel/linker/elf.h index c32cce0..bb61795 100644 --- a/src/kernel/linker/elf.h +++ b/src/kernel/linker/elf.h @@ -52,12 +52,12 @@ struct elf_phdr { }; struct phdr { - struct elf_phdr h; + elf_phdr h; uint8_t* data; }; int elf_check(uint8_t *data); //0 if ok, 1 if not a valid ELF -thread_entry elf_load(uint8_t *data, struct process* process); //Load an ELF to a process, return entry point -struct process* elf_exec(uint8_t *data, int privilege); //Creates a new process and a thread for running ELF file +thread_entry elf_load(uint8_t *data, process* process); //Load an ELF to a process, return entry point +process* elf_exec(uint8_t *data, int privilege); //Creates a new process and a thread for running ELF file #endif diff --git a/src/kernel/mem/_dlmalloc.h b/src/kernel/mem/_dlmalloc.h index 7b2e2cc..a80273c 100644 --- a/src/kernel/mem/_dlmalloc.h +++ b/src/kernel/mem/_dlmalloc.h @@ -1,6 +1,7 @@ #ifndef DEF_DLMALLOC_H #define DEF_DLMALLOC_H +#include <types.h> #include "lib/std.h" #include <stdlib_common.h> #include <string.h> @@ -16,6 +17,8 @@ #define USE_LOCKS 2 + + /* Version identifier to allow people to support multiple versions */ #ifndef DLMALLOC_VERSION #define DLMALLOC_VERSION 20805 diff --git a/src/kernel/mem/gdt.c b/src/kernel/mem/gdt.cpp index 494aaf2..49fbd82 100644 --- a/src/kernel/mem/gdt.c +++ b/src/kernel/mem/gdt.cpp @@ -2,14 +2,14 @@ #include <stdlib_common.h> #include <core/monitor.h> -extern void gdt_flush(uint32_t); //ASM (imported from idt_.asm) -extern void tss_flush(); +extern "C" void gdt_flush(uint32_t); //ASM (imported from idt_.asm) +extern "C" void tss_flush(); #define GDT_ENTRIES 6 // The contents of each entry is defined in gdt_init. -static struct tss_entry tss_entry; -static struct gdt_entry gdt_entries[GDT_ENTRIES]; -static struct gdt_ptr gdt_ptr; +static tss_entry tss_entry; +static gdt_entry gdt_entries[GDT_ENTRIES]; +static gdt_ptr gdt_ptr; /* This function is called by the task_switch function on each context switch. It updates the TSS so that an interrupt will be handled on the correct kernel stack @@ -33,11 +33,11 @@ static void gdt_setGate(int num, uint32_t base, uint32_t limit, uint8_t access, /* For internal use only. Writes one entry of the GDT, that entry being a pointer to the TSS. */ static void gdt_writeTss(int num, uint32_t ss0, uint32_t esp0) { uint32_t base = (uint32_t)&tss_entry; - uint32_t limit = base + sizeof(struct tss_entry); + uint32_t limit = base + sizeof(tss_entry); gdt_setGate(num, base, limit, 0xE9, 0); - memset(&tss_entry, 0, sizeof(struct tss_entry)); + memset(&tss_entry, 0, sizeof(tss_entry)); tss_entry.ss0 = ss0; tss_entry.esp0 = esp0; @@ -47,7 +47,7 @@ static void gdt_writeTss(int num, uint32_t ss0, uint32_t esp0) { /* Write data to the GDT and enable it. */ void gdt_init() { - gdt_ptr.limit = (sizeof(struct gdt_entry) * GDT_ENTRIES) - 1; + gdt_ptr.limit = (sizeof(gdt_entry) * GDT_ENTRIES) - 1; gdt_ptr.base = (uint32_t)&gdt_entries; gdt_setGate(0, 0, 0, 0, 0); //Null segment diff --git a/src/kernel/mem/mem.c b/src/kernel/mem/mem.cpp index 3310b70..5e04de3 100644 --- a/src/kernel/mem/mem.c +++ b/src/kernel/mem/mem.cpp @@ -16,7 +16,7 @@ #define KHEAP_MAXSIZE 0x08000000 size_t mem_placementAddr; -int _no_more_ksbrk = 0; +bool _no_more_ksbrk = false; // ****************************** @@ -79,7 +79,7 @@ void kfree_page(void* ptr) { // ************************* void* ksbrk(size_t size) { - if (_no_more_ksbrk == 0) { // ksbrk is NOT being called by dlmalloc + if (!_no_more_ksbrk) { // ksbrk is NOT being called by dlmalloc if (size & 0x0FFF) { size = (size & 0xFFFFF000) + 0x1000; } @@ -103,7 +103,7 @@ void* ksbrk(size_t size) { er_end = mem_placementAddr; if (er_end & 0x0FFF) er_end = (er_end & 0xFFFFF000) + 0x1000; for (i = er_begin; i < er_end; i += 0x1000) { - struct page *p = pagedir_getPage(kernel_pagedir, i, 1); + page *p = pagedir_getPage(kernel_pagedir, i, 1); size_t f = frame_alloc(); page_map(p, f, 0, 0); /* (DBG) monitor_write("<map "); monitor_writeHex(i); monitor_write(" "); @@ -126,11 +126,11 @@ void* ksbrk(size_t size) { void kbrk(void* ptr) { monitor_write("<kbrk "); - monitor_writeHex(ptr); + monitor_writeHex((uint32_t)ptr); monitor_write(">\n"); if ((size_t)ptr > (size_t)&end) { - ksbrk(ptr - (size_t)mem_placementAddr); + ksbrk((size_t)ptr - (size_t)mem_placementAddr); } else { PANIC("INVALID KBRK."); } diff --git a/src/kernel/mem/mem.h b/src/kernel/mem/mem.h index cb9c396..085d9ce 100644 --- a/src/kernel/mem/mem.h +++ b/src/kernel/mem/mem.h @@ -11,19 +11,17 @@ void* kmalloc_page(size_t *phys); void kfree_page(void* page); // Internal, used by dlmalloc -void* ksbrk(size_t size); -void kbrk(void* ptr); +extern "C" void* ksbrk(size_t size); +extern "C" void kbrk(void* ptr); #define kmalloc dlmalloc #define kfree dlfree -void kheap_init(); - -extern int _no_more_ksbrk; +extern bool _no_more_ksbrk; extern size_t mem_placementAddr; -extern void end; //Symbol defined by linker : end of kernel code +extern "C" size_t end; //Symbol defined by linker : end of kernel code -extern void k_highhalf_addr; // Symbol defined by linker : high half position of the kerne +extern "C" size_t k_highhalf_addr; // Symbol defined by linker : high half position of the kerne // Should be at 0xC0000000 #define K_HIGHHALF_ADDR ((size_t)(&k_highhalf_addr)) diff --git a/src/kernel/mem/paging.c b/src/kernel/mem/paging.cpp index 0527f06..eb7e615 100644 --- a/src/kernel/mem/paging.c +++ b/src/kernel/mem/paging.cpp @@ -7,24 +7,24 @@ #include <core/sys.h> #include <task/task.h> -static struct bitset frames; +static bitset frames; -struct page_directory *kernel_pagedir, *current_pagedir; +page_directory *kernel_pagedir, *current_pagedir; /************************** PHYSICAL MEMORY ALLOCATION ************************/ /* Allocates a page of physical memory. */ uint32_t frame_alloc() { - uint32_t free = bitset_firstFree(&frames); + uint32_t free = frames.firstFree(); if (free == (uint32_t) -1) { PANIC("No more frames to allocate, system is out of memory!"); } - bitset_set(&frames, free); + frames.set(free); return free; } void frame_free(uint32_t id) { - bitset_clear(&frames, id); + frames.clear(id); } /************************* PAGING INITIALIZATION *****************************/ @@ -38,11 +38,11 @@ void paging_init(size_t totalRam) { uint32_t i; frames.size = totalRam / 0x1000; - frames.bits = ksbrk(INDEX_FROM_BIT(frames.size)); + frames.bits = (uint32_t*)ksbrk(INDEX_FROM_BIT(frames.size)); - kernel_pagedir = ksbrk(sizeof(struct page_directory)); + kernel_pagedir = (page_directory*)ksbrk(sizeof(page_directory)); kernel_pagedir->mappedSegs = 0; - kernel_pagedir->tablesPhysical = kmalloc_page(&kernel_pagedir->physicalAddr); + kernel_pagedir->tablesPhysical = (uint32_t*)kmalloc_page(&kernel_pagedir->physicalAddr); for (i = 0; i < 1024; i++) { kernel_pagedir->tables[i] = 0; kernel_pagedir->tablesPhysical[i] = 0; @@ -76,7 +76,7 @@ void paging_cleanup() { /* Switch to a page directory. Can be done if we are sure not to be interrupted by a task switch. Example use for cross-memory space writing in linker/elf.c */ -void pagedir_switch(struct page_directory *pd) { +void pagedir_switch(page_directory *pd) { current_pagedir = pd; asm volatile("mov %0, %%cr3" : : "r"(pd->physicalAddr)); uint32_t cr0; @@ -86,11 +86,11 @@ void pagedir_switch(struct page_directory *pd) { } /* Creates a new page directory for a process, and maps the kernel page tables on it. */ -struct page_directory *pagedir_new() { +page_directory *pagedir_new() { uint32_t i; - struct page_directory *pd = kmalloc(sizeof(struct page_directory)); - pd->tablesPhysical = kmalloc_page(&pd->physicalAddr); + page_directory *pd = new page_directory(); + pd->tablesPhysical = (uint32_t*)kmalloc_page(&pd->physicalAddr); pd->mappedSegs = 0; for (i = 0; i < 1024; i++) { @@ -106,7 +106,7 @@ struct page_directory *pagedir_new() { } /* Deletes a page directory, cleaning it up. */ -void pagedir_delete(struct page_directory *pd) { +void pagedir_delete(page_directory *pd) { uint32_t i; //Unmap segments while (pd->mappedSegs != 0) seg_unmap(pd->mappedSegs); @@ -121,9 +121,9 @@ void pagedir_delete(struct page_directory *pd) { /* Handle a paging fault. First, looks for the corresponding segment. If the segment was found and it handles the fault, return normally. Else, display informatinos and return an error. */ -uint32_t paging_fault(struct registers *regs) { +uint32_t paging_fault(registers *regs) { size_t addr; - struct segment_map *seg = 0; + segment_map *seg = 0; asm volatile("mov %%cr2, %0" : "=r"(addr)); seg = current_pagedir->mappedSegs; @@ -153,14 +153,14 @@ uint32_t paging_fault(struct registers *regs) { /* Gets the corresponding page in a page directory for a given address. If make is set, the necessary page table can be created. Can return 0 if make is not set. */ -struct page *pagedir_getPage(struct page_directory *pd, uint32_t address, int make) { +page *pagedir_getPage(page_directory *pd, uint32_t address, int make) { address /= 0x1000; uint32_t table_idx = address / 1024; if (pd->tables[table_idx]) { return &pd->tables[table_idx]->pages[address % 1024]; } else if (make) { - pd->tables[table_idx] = kmalloc_page(pd->tablesPhysical + table_idx); + pd->tables[table_idx] = (page_table*)kmalloc_page(pd->tablesPhysical + table_idx); memset((uint8_t*)pd->tables[table_idx], 0, 0x1000); pd->tablesPhysical[table_idx] |= 0x07; @@ -176,7 +176,7 @@ struct page *pagedir_getPage(struct page_directory *pd, uint32_t address, int ma } /* Modifies a page structure so that it is mapped to a frame. */ -void page_map(struct page *page, uint32_t frame, uint32_t user, uint32_t rw) { +void page_map(page *page, uint32_t frame, uint32_t user, uint32_t rw) { if (page != 0 && page->frame == 0 && page->present == 0) { page->present = 1; page->rw = (rw ? 1 : 0); @@ -186,7 +186,7 @@ void page_map(struct page *page, uint32_t frame, uint32_t user, uint32_t rw) { } /* Modifies a page structure so that it is no longer mapped to a frame. */ -void page_unmap(struct page *page) { +void page_unmap(page *page) { if (page != 0) { page->frame = 0; page->present = 0; @@ -194,7 +194,7 @@ void page_unmap(struct page *page) { } /* Same as above but also frees the frame. */ -void page_unmapFree(struct page *page) { +void page_unmapFree(page *page) { if (page != 0) { if (page->frame != 0) frame_free(page->frame); page->frame = 0; diff --git a/src/kernel/mem/paging.h b/src/kernel/mem/paging.h index 2d5713f..f91fe37 100644 --- a/src/kernel/mem/paging.h +++ b/src/kernel/mem/paging.h @@ -18,32 +18,32 @@ struct page { }; struct page_table { - struct page pages[1024]; + page pages[1024]; }; struct segment_map; struct page_directory { - struct page_table *tables[1024]; //Virtual addresses of page tables + page_table *tables[1024]; //Virtual addresses of page tables uint32_t *tablesPhysical; //Pointer to the virtual address of the page directory (contain phys addr of pt) uint32_t physicalAddr; //Physical address of info above - struct segment_map *mappedSegs; + segment_map *mappedSegs; }; -extern struct page_directory *kernel_pagedir, *current_pagedir; +extern page_directory *kernel_pagedir, *current_pagedir; uint32_t frame_alloc(); void frame_free(uint32_t id); void paging_init(size_t totalRam); void paging_cleanup(); -void pagedir_switch(struct page_directory *pd); -struct page_directory *pagedir_new(); //Creates a brand new empty page directory for a process, with kernel pages -void pagedir_delete(struct page_directory *pagedir); -struct page *pagedir_getPage(struct page_directory *pd, uint32_t address, int make); -void page_map(struct page *page, uint32_t frame, uint32_t user, uint32_t rw); -void page_unmap(struct page *page); -void page_unmapFree(struct page *page); - -uint32_t paging_fault(struct registers *regs); //returns a boolean : 1 if unhandled, 0 if ok +void pagedir_switch(page_directory *pd); +page_directory *pagedir_new(); //Creates a brand new empty page directory for a process, with kernel pages +void pagedir_delete(page_directory *pagedir); +page *pagedir_getPage(page_directory *pd, uint32_t address, int make); +void page_map(page *page, uint32_t frame, uint32_t user, uint32_t rw); +void page_unmap(page *page); +void page_unmapFree(page *page); + +uint32_t paging_fault(registers *regs); //returns a boolean : 1 if unhandled, 0 if ok #endif diff --git a/src/kernel/mem/seg.c b/src/kernel/mem/seg.cpp index 4a33db3..c29e94e 100644 --- a/src/kernel/mem/seg.c +++ b/src/kernel/mem/seg.cpp @@ -4,8 +4,8 @@ /* Call this function when mapping a segment to a page directory. Calls the appropriate map method and updates the segment's and pagedir's information. */ -struct segment_map *seg_map(struct segment* seg, struct page_directory *pagedir, size_t offset) { - struct segment_map *sm = seg->map(seg, pagedir, offset); +segment_map *seg_map(segment* seg, page_directory *pagedir, size_t offset) { + segment_map *sm = seg->map(seg, pagedir, offset); if (sm == 0) return 0; seg->mappings++; sm->seg = seg; @@ -18,18 +18,18 @@ struct segment_map *seg_map(struct segment* seg, struct page_directory *pagedir, /* Call this function when unmapping a segment from a page directory. The segment will automatically be deleted if it is not mapped. Calls the appropriate unmap method and updates the segment's and pagedir's information. */ -void seg_unmap(struct segment_map *map) { +void seg_unmap(segment_map *map) { map->seg->unmap(map); if (map->pagedir->mappedSegs == map) { map->pagedir->mappedSegs = map->pagedir->mappedSegs->next; } else { - struct segment_map *m = map->pagedir->mappedSegs; + segment_map *m = map->pagedir->mappedSegs; while (m->next != 0 && m->next != map) m = m->next; if (m->next == map) m->next = map->next; } map->seg->mappings--; if (map->seg->mappings == 0) { - map->seg->delete(map->seg); + map->seg->del(map->seg); kfree(map->seg->seg_data); kfree(map->seg); } @@ -38,37 +38,37 @@ void seg_unmap(struct segment_map *map) { // ************************************ SIMPLESEG stuff ************* -static struct segment_map* simpleseg_map(struct segment* seg, struct page_directory* pagedir, size_t offset); -static void simpleseg_unmap(struct segment_map*); -static void simpleseg_delete(struct segment *seg); -static int simpleseg_handleFault(struct segment_map* map, size_t addr, int write); +static segment_map* simpleseg_map(segment* seg, page_directory* pagedir, size_t offset); +static void simpleseg_unmap(segment_map*); +static void simpleseg_delete(segment *seg); +static int simpleseg_handleFault(segment_map* map, size_t addr, int write); /* Call this when creating a simpleseg. Creates the simpleseg structure and the segment structure and fills them up. */ -struct segment* simpleseg_make(size_t start, size_t len, int writable) { - struct simpleseg *ss = kmalloc(sizeof(struct simpleseg)); - struct segment *se = kmalloc(sizeof(struct segment)); +segment* simpleseg_make(size_t start, size_t len, int writable) { + simpleseg *ss = new simpleseg(); + segment *se = new segment(); se->seg_data = ss; se->mappings = 0; se->map = simpleseg_map; se->unmap = simpleseg_unmap; - se->delete = simpleseg_delete; + se->del = simpleseg_delete; se->handle_fault = simpleseg_handleFault; ss->writable = writable; ss->start = start; ss->len = len; return se; } /* For internal use only. Called when a simpleseg is mapped to a pagedirectory. */ -struct segment_map* simpleseg_map(struct segment* seg, struct page_directory* pagedir, size_t offset) { - struct segment_map *sm = kmalloc(sizeof(struct segment_map)); - sm->start = ((struct simpleseg*)(seg->seg_data))->start; - sm->len = ((struct simpleseg*)(seg->seg_data))->len; +segment_map* simpleseg_map(segment* seg, page_directory* pagedir, size_t offset) { + segment_map *sm = new segment_map(); + sm->start = ((simpleseg*)(seg->seg_data))->start; + sm->len = ((simpleseg*)(seg->seg_data))->len; return sm; } /* For internal use only. Called when a simpleseg is unmapped. Frees all the allocated pages. */ -void simpleseg_unmap(struct segment_map* sm) { +void simpleseg_unmap(segment_map* sm) { size_t i; for (i = sm->start; i < sm->start + sm->len; i += 0x1000) { page_unmapFree(pagedir_getPage(sm->pagedir, i, 0)); @@ -76,28 +76,28 @@ void simpleseg_unmap(struct segment_map* sm) { } /* For internal use only. Handles a page fault. Can allocate and map a frame if necessary. */ -int simpleseg_handleFault(struct segment_map* sm, size_t addr, int write) { - struct simpleseg *ss = sm->seg->seg_data; +int simpleseg_handleFault(segment_map* sm, size_t addr, int write) { + simpleseg *ss = (simpleseg*)sm->seg->seg_data; if (write && !ss->writable) return 1; addr &= 0xFFFFF000; - struct page *p = pagedir_getPage(sm->pagedir, addr, 1); + page *p = pagedir_getPage(sm->pagedir, addr, 1); if (p->frame != 0) return 1; page_map(p, frame_alloc(), 1, ss->writable); return 0; } /* For internal use only. Called when the simpleseg is deleted. Does nothing. */ -void simpleseg_delete(struct segment* seg) { +void simpleseg_delete(segment* seg) { } /* Call this to resize a simpleseg. Ajusts the size and frees pages if the new size is smaller.*/ -int simpleseg_resize(struct segment_map *map, size_t len) { +int simpleseg_resize(segment_map *map, size_t len) { size_t i; if (map == 0) return -1; - if (map->seg->delete != simpleseg_delete) return -2; //check segment is a simpleseg + if (map->seg->del != simpleseg_delete) return -2; //check segment is a simpleseg - struct simpleseg *s = (struct simpleseg*)map->seg->seg_data; + simpleseg *s = (simpleseg*)map->seg->seg_data; if (len & 0xFFF) len = (len & 0xFFFFF000) + 0x1000; if (len < map->len) { for (i = map->start + len; i < map->start + map->len; i += 0x1000) { diff --git a/src/kernel/mem/seg.h b/src/kernel/mem/seg.h index d37ba59..ea95dfa 100644 --- a/src/kernel/mem/seg.h +++ b/src/kernel/mem/seg.h @@ -12,23 +12,23 @@ struct segment { int mappings; // these 4 functions must not be used directly by anyone - struct segment_map* (*map)(struct segment* seg, struct page_directory* pagedir, size_t offset); - void (*unmap)(struct segment_map*); - void (*delete)(struct segment* seg); - int (*handle_fault)(struct segment_map* map, size_t addr, int write); //0 if ok, 1 if segfault + segment_map* (*map)(segment* seg, page_directory* pagedir, size_t offset); + void (*unmap)(segment_map*); + void (*del)(segment* seg); + int (*handle_fault)(segment_map* map, size_t addr, int write); //0 if ok, 1 if segfault }; struct segment_map { - struct segment* seg; - struct page_directory* pagedir; + segment* seg; + page_directory* pagedir; size_t start, len; - struct segment_map *next; + segment_map *next; }; //parameter offset in seg_map doesn't need to be used -struct segment_map *seg_map(struct segment* seg, struct page_directory* pagedir, size_t offset); -/* When unmapping a segment, the segment is deleted if it is not mapped anywhere anymore. */ -void seg_unmap(struct segment_map* map); +segment_map *seg_map(segment* seg, page_directory* pagedir, size_t offset); +// When unmapping a segment, the segment is deleted if it is not mapped anywhere anymore. +void seg_unmap(segment_map* map); /// ************************************* SIMPLESEG stuff ***************** @@ -37,7 +37,7 @@ struct simpleseg { size_t start, len; }; -struct segment* simpleseg_make(size_t start, size_t len, int writable); -int simpleseg_resize(struct segment_map *map, size_t len); +segment* simpleseg_make(size_t start, size_t len, int writable); +int simpleseg_resize(segment_map *map, size_t len); #endif diff --git a/src/kernel/task/idt.c b/src/kernel/task/idt.cpp index aed5ea8..ebc092d 100644 --- a/src/kernel/task/idt.c +++ b/src/kernel/task/idt.cpp @@ -2,12 +2,14 @@ #include <core/monitor.h> #include <core/sys.h> #include <mem/paging.h> -#include <mem/mem.h> +#include <lib/cpp.h> #include "task.h" #include "syscall.h" #include <stdlib_common.h> +extern "C" { + extern void isr0(); extern void isr1(); extern void isr2(); @@ -60,20 +62,22 @@ extern void irq15(); extern void syscall64(); -extern void idt_flush(int32_t ptr); +} + +extern "C" void idt_flush(int32_t ptr); -struct idt_entry idt_entries[256]; -struct idt_ptr idt_ptr; +idt_entry idt_entries[256]; +idt_ptr idt_ptr; static int_callback irq_handlers[16] = {0}; static struct irq_waiter { struct thread *thread; - struct irq_waiter *next; + irq_waiter *next; } *irq_wakeup[16] = {0}; /* Called in idt_.asm when an exception fires (interrupt 0 to 31). Tries to handle the exception, panics if fails. */ -void idt_isrHandler(struct registers regs) { +extern "C" void idt_isrHandler(registers regs) { if ((regs.int_no == 14 && paging_fault(®s) != 0) || regs.int_no != 14) { if (tasking_handleException(®s) == 0) { monitor_write("\nREALLY BAD THIS TIME\t\tUnhandled exception\t#"); @@ -86,14 +90,14 @@ void idt_isrHandler(struct registers regs) { /* Called in idt_.asm when an IRQ fires (interrupt 32 to 47) Possibly wakes up a thread that was waiting, possibly calls a handler. */ -void idt_irqHandler(struct registers regs) { +extern "C" void idt_irqHandler(registers regs) { uint32_t doSwitch = (regs.err_code == 0); //IRQ0 = timer if (regs.err_code > 7) { outb(0xA0, 0x20); } outb(0x20, 0x20); while (irq_wakeup[regs.err_code] != 0) { - struct irq_waiter *tmp = irq_wakeup[regs.err_code]; + irq_waiter *tmp = irq_wakeup[regs.err_code]; thread_wakeUp(tmp->thread); irq_wakeup[regs.err_code] = tmp->next; kfree(tmp); @@ -107,7 +111,7 @@ void idt_irqHandler(struct registers regs) { /* Called in idt_.asm on a system call (interrupt 64). Calls the correct syscall handler (if any). */ -void idt_syscallHandler(struct registers regs) { +extern "C" void idt_syscallHandler(registers regs) { if (regs.eax < NUMBER_OF_SYSCALLS && syscalls[regs.eax] != 0) { syscalls[regs.eax](®s); } @@ -125,10 +129,10 @@ static void idt_setGate(uint8_t num, uint32_t base, uint16_t sel, uint8_t flags) /* Remaps the IRQs. Sets up the IDT. */ void idt_init() { - idt_ptr.limit = (sizeof(struct idt_entry) * 256) - 1; + idt_ptr.limit = (sizeof(idt_entry) * 256) - 1; idt_ptr.base = (uint32_t)&idt_entries; - memset((uint8_t*)&idt_entries, 0, sizeof(struct idt_entry) * 256); + memset((uint8_t*)&idt_entries, 0, sizeof(idt_entry) * 256); //Remap the IRQ table outb(0x20, 0x11); @@ -209,7 +213,7 @@ void idt_handleIrq(int number, int_callback func) { /* Tells the IRQ handler to wake up the current thread when specified IRQ fires. */ void idt_waitIrq(int number) { if (number < 16 && number >= 0 && proc_priv() <= PL_KERNEL) { - struct irq_waiter *tmp = kmalloc(sizeof(struct irq_waiter)); + irq_waiter *tmp = new irq_waiter(); tmp->thread = current_thread; tmp->next = irq_wakeup[number]; irq_wakeup[number] = tmp; diff --git a/src/kernel/task/idt.h b/src/kernel/task/idt.h index 1ac03e2..849418e 100644 --- a/src/kernel/task/idt.h +++ b/src/kernel/task/idt.h @@ -29,7 +29,7 @@ struct registers { uint32_t eip, cs, eflags, useresp, ss; // Pushed by the processor automatically. }; -typedef void (*int_callback)(struct registers*); +typedef void (*int_callback)(registers*); void idt_init(); void idt_handleIrq(int number, int_callback func); //Set IRQ handler diff --git a/src/kernel/task/sched.c b/src/kernel/task/sched.cpp index aa41d5b..e773e97 100644 --- a/src/kernel/task/sched.c +++ b/src/kernel/task/sched.cpp @@ -6,12 +6,12 @@ #define PRIORITIES 3 // we have 4 priority levels #define PRIORITY(t) (t->process->privilege) //get priority for a thread -extern struct thread *idle_thread; +extern thread *idle_thread; -static struct thread *queue[PRIORITIES] = {0}, *last[PRIORITIES] = {0}; +static thread *queue[PRIORITIES] = {0}, *last[PRIORITIES] = {0}; /* For internal use only. Enqueues specified thread in specified priority queue. */ -static void sched_enqueueIn(struct thread *t, int qid) { +static void sched_enqueueIn(thread *t, int qid) { t->queue_next = 0; if (queue[qid] == 0) { queue[qid] = last[qid] = t; @@ -22,9 +22,9 @@ static void sched_enqueueIn(struct thread *t, int qid) { } /* For internal use only. Pops a thread from specified queue, if available. */ -static struct thread *sched_dequeueFrom(int qid) { +static thread *sched_dequeueFrom(int qid) { if (queue[qid] == 0) return 0; - struct thread *it = queue[qid]; + thread *it = queue[qid]; ASSERT((it->queue_next == 0 && it == last[qid]) || it != last[qid]); queue[qid] = it->queue_next; if (queue[qid] == 0) last[qid] = 0; @@ -32,14 +32,14 @@ static struct thread *sched_dequeueFrom(int qid) { } /* Used by task.c. Enqueus a thread in the corresponding priority queue. */ -void sched_enqueue(struct thread *t) { +void sched_enqueue(thread *t) { if (t == idle_thread) return; sched_enqueueIn(t, PRIORITY(t)); } /* Used by task.c. Pops a thread from the lowest priority non-empty queue. */ -struct thread *sched_dequeue() { - struct thread *it = 0; +thread *sched_dequeue() { + thread *it = 0; int i; for (i = 0; i < PRIORITIES; i++) { it = sched_dequeueFrom(i); diff --git a/src/kernel/task/sched.h b/src/kernel/task/sched.h index 1233a44..7d0dcd3 100644 --- a/src/kernel/task/sched.h +++ b/src/kernel/task/sched.h @@ -3,7 +3,7 @@ #include "task.h" -void sched_enqueue(struct thread *t); -struct thread *sched_dequeue(); +void sched_enqueue(thread *t); +thread *sched_dequeue(); #endif diff --git a/src/kernel/task/syscall.c b/src/kernel/task/syscall.c deleted file mode 100644 index bd27eba..0000000 --- a/src/kernel/task/syscall.c +++ /dev/null @@ -1,45 +0,0 @@ -#include "syscall.h" -#include "task.h" -#include <core/sys.h> - -#define CALL0(name, scname) static void scname(struct registers* r) { r->eax = name(); } -#define CALL1(name, scname) static void scname(struct registers* r) { \ - r->eax = name(r->ebx); } -#define CALL2(name, scname) static void scname(struct registers* r) { \ - r->eax = name(r->ebx, r->ecx); } -#define CALL3(name, scname) static void scname(struct registers* r) { \ - r->eax = name(r->ebx, r->ecx, r->edx); } -#define CALL0V(name, scname) static void scname(struct registers* r) { name(); } -#define CALL1V(name, scname) static void scname(struct registers* r) { name(r->ebx); } -#define CALL2V(name, scname) static void scname(struct registers* r) { name(r->ebx, r->ecx); } -#define CALL3V(name, scname) static void scname(struct registers* r) { name(r->ebx, r->ecx, r->edx); } -#define CALL4V(name, scname) static void scname(struct registers* r) { name(r->ebx, r->ecx, r->edx, r->esi); } - -CALL0V(thread_exit, thread_exit_sc); -CALL0V(schedule, schedule_sc); -CALL1V(thread_sleep, thread_sleep_sc); -CALL1V(process_exit, process_exit_sc); -CALL1(monitor_write, printk_sc); -CALL1V(idt_waitIrq, irq_wait_sc); -CALL0(proc_priv, proc_priv_sc); -CALL1(process_sbrk, proc_sbrk_sc); -CALL1V(process_brk, proc_brk_sc); - -static void thread_new_sc(struct registers* r) { - cli(); - thread_new(current_thread->process, (thread_entry)r->ebx, (void*)r->ecx, (void*)r->edx); - sti(); -} - -int_callback syscalls[NUMBER_OF_SYSCALLS] = { - thread_exit_sc, //0 - schedule_sc, - thread_sleep_sc, - process_exit_sc, - printk_sc, - thread_new_sc, //5 - irq_wait_sc, - proc_priv_sc, - proc_sbrk_sc, - proc_brk_sc, - 0 }; diff --git a/src/kernel/task/syscall.cpp b/src/kernel/task/syscall.cpp new file mode 100644 index 0000000..6880745 --- /dev/null +++ b/src/kernel/task/syscall.cpp @@ -0,0 +1,50 @@ +#include "syscall.h" +#include "task.h" +#include "timer.h" +#include <core/monitor.h> +#include <core/sys.h> + +#define CALL0(name, scname) static void scname(registers* r) { r->eax = name(); } +#define CALL1(name, scname) static void scname(registers* r) { \ + r->eax = name(r->ebx); } +#define CALL2(name, scname) static void scname(registers* r) { \ + r->eax = name(r->ebx, r->ecx); } +#define CALL3(name, scname) static void scname(registers* r) { \ + r->eax = name(r->ebx, r->ecx, r->edx); } +#define CALL0V(name, scname) static void scname(registers* r) { name(); } +#define CALL1V(name, scname) static void scname(registers* r) { name(r->ebx); } +#define CALL2V(name, scname) static void scname(registers* r) { name(r->ebx, r->ecx); } +#define CALL3V(name, scname) static void scname(registers* r) { name(r->ebx, r->ecx, r->edx); } +#define CALL4V(name, scname) static void scname(registers* r) { name(r->ebx, r->ecx, r->edx, r->esi); } + +CALL0V(thread_exit, thread_exit_sc); +CALL0V(schedule, schedule_sc); +CALL1V(thread_sleep, thread_sleep_sc); +CALL1V(process_exit, process_exit_sc); +CALL1V(idt_waitIrq, irq_wait_sc); +CALL0(proc_priv, proc_priv_sc); +CALL1(process_sbrk, proc_sbrk_sc); +CALL1V(process_brk, proc_brk_sc); + +static void printk_sc(registers *r) { + monitor_write((char*)r->ebx); +} + +static void thread_new_sc(registers* r) { + cli(); + thread_new(current_thread->process, (thread_entry)r->ebx, (void*)r->ecx, (void*)r->edx); + sti(); +} + +int_callback syscalls[NUMBER_OF_SYSCALLS] = { + thread_exit_sc, //0 + schedule_sc, + thread_sleep_sc, + process_exit_sc, + printk_sc, + thread_new_sc, //5 + irq_wait_sc, + proc_priv_sc, + proc_sbrk_sc, + proc_brk_sc, + 0 }; diff --git a/src/kernel/task/task.c b/src/kernel/task/task.cpp index 9d98165..b7c8f45 100644 --- a/src/kernel/task/task.c +++ b/src/kernel/task/task.cpp @@ -2,7 +2,7 @@ #include "sched.h" #include <core/sys.h> #include <core/monitor.h> -#include <mem/mem.h> +#include <lib/cpp.h> #include <mem/seg.h> #include <mem/gdt.h> #include "timer.h" @@ -12,16 +12,16 @@ //Static routines for handling threads exiting and all cleanup static void thread_exit_stackJmp(uint32_t reason); static void thread_exit2(uint32_t reason); -static void thread_delete(struct thread *th); -static void process_delete(struct process *pr); +static void thread_delete(thread *th); +static void process_delete(process *pr); //From task_.asm -extern uint32_t read_eip(); -extern void task_idle(void*); +extern "C" uint32_t read_eip(); +extern "C" void task_idle(void*); static uint32_t nextpid = 1; -struct process *processes = 0, *kernel_process; -struct thread *current_thread = 0, *idle_thread = 0; +process *processes = 0, *kernel_process; +thread *current_thread = 0, *idle_thread = 0; uint32_t tasking_tmpStack[KSTACKSIZE]; @@ -29,7 +29,7 @@ uint32_t tasking_tmpStack[KSTACKSIZE]; Creates a kernel process and an IDLE thread in it. */ void tasking_init() { cli(); - kernel_process = kmalloc(sizeof(struct process)); //This process must be hidden to users + kernel_process = new process(); //This process must be hidden to users kernel_process->pid = kernel_process->uid = kernel_process->thread_count = 0; kernel_process->privilege = PL_KERNEL; kernel_process->parent = kernel_process; @@ -44,9 +44,9 @@ void tasking_init() { /* Called by the paging functions when a page table is allocated in the kernel space (>K_HIGHHALF_ADDR). Updates the page directories of all the processes. */ -void tasking_updateKernelPagetable(uint32_t idx, struct page_table *table, uint32_t tablephysical) { +void tasking_updateKernelPagetable(uint32_t idx, page_table *table, uint32_t tablephysical) { if (idx < FIRST_KERNEL_PAGETABLE) return; - struct process* it = processes; + process* it = processes; while (it != 0) { it->pagedir->tables[idx] = table; it->pagedir->tablesPhysical[idx] = tablephysical; @@ -94,7 +94,7 @@ 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(struct registers *regs) { +uint32_t tasking_handleException(registers *regs) { if (current_thread == 0) return 0; //No tasking yet NL; WHERE; monitor_write("exception:`"); char *exception_messages[] = {"Division By Zero","Debug","Non Maskable Interrupt","Breakpoint", @@ -126,7 +126,7 @@ void thread_goInactive() { } /* Wakes up the given thread. */ -void thread_wakeUp(struct thread* t) { +void thread_wakeUp(thread* t) { if (t->state == TS_WAKEWAIT) { t->state = TS_RUNNING; sched_enqueue(t); @@ -147,9 +147,10 @@ void thread_exit2(uint32_t reason) { //See EX_TH_* defines in task.h * if reason == EX_TH_EXCEPTION, it is just one thread exiting because of an exception * if reason is none of the two cases above, it is the whole process exiting (with error code = reason) */ - struct thread *th = current_thread; + thread *th = current_thread; + process* pr; if (th == 0 || th->process == 0) goto retrn; - struct process *pr = th->process; + pr = th->process; if ((reason == EX_TH_NORMAL || reason == EX_TH_EXCEPTION) && pr->thread_count > 1) { thread_delete(th); } else { @@ -191,10 +192,10 @@ void process_exit(size_t retval) { /* For internal use only. This is called when a newly created thread first runs (its address is the value given for EIP). It switches to user mode if necessary and calls the entry point. */ -static void thread_run(void* u_esp, struct thread *thread, thread_entry entry_point, void *data) { +static void thread_run(void* u_esp, thread *thread, thread_entry entry_point, void *data) { pagedir_switch(thread->process->pagedir); if (thread->process->privilege >= PL_USER) { //User mode ! - uint32_t *stack = u_esp; + uint32_t *stack = (uint32_t*)u_esp; stack--; *stack = (uint32_t)data; stack--; *stack = 0; @@ -230,14 +231,14 @@ static void thread_run(void* u_esp, struct thread *thread, thread_entry entry_po asm volatile("sti"); entry_point(data); } - thread_exit(0); + thread_exit(); } /* Creates a new thread for given process. Allocates a kernel stack and a user stack if necessary. Sets up the kernel stack for values to be passed to thread_run. */ -struct thread *thread_new(struct process *proc, thread_entry entry_point, void *data, void *u_esp) { - struct thread *t = kmalloc(sizeof(struct thread)); +thread *thread_new(process *proc, thread_entry entry_point, void *data, void *u_esp) { + thread *t = new thread(); t->process = proc; t->next = 0; proc->thread_count++; @@ -265,7 +266,7 @@ struct thread *thread_new(struct process *proc, thread_entry entry_point, void * if (proc->threads == 0) { proc->threads = t; } else { - struct thread *i = proc->threads; + thread *i = proc->threads; while (i->next != 0) i = i->next; i->next = t; } @@ -273,8 +274,8 @@ struct thread *thread_new(struct process *proc, thread_entry entry_point, void * } /* Creates a new process. Creates a struct process and fills it up. */ -struct process *process_new(struct process* parent, uint32_t uid, uint32_t privilege) { - struct process* p = kmalloc(sizeof(struct process)); +process *process_new(process* parent, uint32_t uid, uint32_t privilege) { + process* p = new process(); p->pid = (nextpid++); p->uid = uid; p->thread_count = 0; @@ -298,11 +299,11 @@ struct process *process_new(struct process* parent, uint32_t uid, uint32_t privi } /* Deletes given thread, freeing the stack(s). */ -static void thread_delete(struct thread *th) { +static void thread_delete(thread *th) { if (th->process->threads == th) { th->process->threads = th->next; } else { - struct thread *it = th->process->threads; + thread *it = th->process->threads; while (it) { if (it->next == th) { it->next = th->next; @@ -318,8 +319,8 @@ static void thread_delete(struct thread *th) { } /* Deletes a process. First, deletes all its threads. Also deletes the corresponding page directory. */ -static void process_delete(struct process *pr) { - struct thread *it = pr->threads; +static void process_delete(process *pr) { + thread *it = pr->threads; while (it != 0) { thread_delete(it); it = it->next; @@ -327,7 +328,7 @@ static void process_delete(struct process *pr) { if (processes == pr) { processes = pr->next; } else { - struct process *it = processes; + process *it = processes; while (it) { if (it->next == pr) { it->next = pr->next; @@ -363,7 +364,7 @@ static void process_delete(struct process *pr) { }*/ size_t process_sbrk(size_t size) { - struct process *p = current_thread->process; + process *p = current_thread->process; if (p->data == 0) return -1; ASSERT(p->data < K_HIGHHALF_ADDR); if (p->data + size >= K_HIGHHALF_ADDR) return -1; @@ -375,7 +376,7 @@ size_t process_sbrk(size_t size) { size_t end = start + size; if (end & 0x0FFF) end = (end & 0xFFFFF000) + 0x1000; - struct segment *s = simpleseg_make(start, end - start, 1); + segment *s = simpleseg_make(start, end - start, 1); if (s == 0) return -5; p->dataseg = seg_map(s, p->pagedir, 0); if (p->dataseg == 0) return -1; @@ -402,7 +403,7 @@ size_t process_sbrk(size_t size) { } void process_brk(size_t ptr) { - struct process *p = current_thread->process; + process *p = current_thread->process; ASSERT(ptr < K_HIGHHALF_ADDR); process_sbrk(ptr - p->data); diff --git a/src/kernel/task/task.h b/src/kernel/task/task.h index 63cb35a..47d7632 100644 --- a/src/kernel/task/task.h +++ b/src/kernel/task/task.h @@ -20,16 +20,17 @@ typedef void (*thread_entry)(void*); +struct thread; struct process { uint32_t pid, uid, privilege, thread_count; - struct process *parent; - struct page_directory *pagedir; + process *parent; + page_directory *pagedir; size_t stack, data; - struct segment_map *dataseg; + segment_map *dataseg; - struct process *next; //Forms a linked list - struct thread *threads; + process *next; //Forms a linked list + thread *threads; }; struct thread { @@ -40,21 +41,25 @@ struct thread { void* kernelStack_addr; uint32_t kernelStack_size; - struct thread *next, *queue_next; //queue_next is used in sched.c + thread *next, *queue_next; //queue_next is used in sched.c }; -extern struct thread *current_thread; +extern thread *current_thread; void tasking_init(); +#ifdef __cplusplus +extern "C" void schedule(); +#else void schedule(); -void tasking_updateKernelPagetable(uint32_t idx, struct page_table *table, uint32_t tablePhysical); -uint32_t tasking_handleException(struct registers *regs); +#endif +void tasking_updateKernelPagetable(uint32_t idx, page_table *table, uint32_t tablePhysical); +uint32_t tasking_handleException(registers *regs); void thread_goInactive(); //Blocks the current thread. it is then waked up by another thread or a system event. -void thread_wakeUp(struct thread *t); +void thread_wakeUp(thread *t); int proc_priv(); //Returns current privilege level -struct thread * thread_new(struct process *proc, thread_entry entry_point, void *data, void *u_esp); -struct process* process_new(struct process *parent, uint32_t uid, uint32_t privilege); +thread * thread_new(process *proc, thread_entry entry_point, void *data, void *u_esp); +process* process_new(process *parent, uint32_t uid, uint32_t privilege); void thread_exit(); //syscall void process_exit(size_t retval); //syscall diff --git a/src/kernel/task/timer.c b/src/kernel/task/timer.cpp index 35a94f9..05c4550 100644 --- a/src/kernel/task/timer.c +++ b/src/kernel/task/timer.cpp @@ -7,7 +7,7 @@ static uint32_t tick = 0, frequency = 0, uptime = 0; -static void timer_callback(struct registers *regs); +static void timer_callback(registers *regs); static void timer_wakeUpSleepingThreads(); /* Called by kmain. Sets up the PIT and the IRQ0 handler. */ @@ -37,7 +37,7 @@ uint32_t timer_time() { /* Called when IRQ0 fires. Updates the uptime variable. DOES NOT provoke a task switch. The task switch is called in idt.c (IRQ handler). */ -void timer_callback(struct registers *regs) { +void timer_callback(registers *regs) { tick++; if (tick == frequency) { uptime++; @@ -51,14 +51,14 @@ void timer_callback(struct registers *regs) { static struct sleeping_thread { uint32_t wakeup_time; struct thread *thread; - struct sleeping_thread *next; + sleeping_thread *next; } *sleeping_threads = 0; /* Makes the current thread sleep. */ void thread_sleep(uint32_t msecs) { if (current_thread == 0) return; // Create the sleeping_thread structure - struct sleeping_thread *sf = kmalloc(sizeof(struct sleeping_thread)), *tmp; + sleeping_thread *sf = (sleeping_thread*)kmalloc(sizeof(sleeping_thread)), *tmp; sf->wakeup_time = timer_time() + msecs; sf->thread = current_thread; //Insert it at the right place @@ -83,7 +83,7 @@ void thread_sleep(uint32_t msecs) { void timer_wakeUpSleepingThreads() { uint32_t time = timer_time(); while (sleeping_threads != 0 && sleeping_threads->wakeup_time <= time) { - struct sleeping_thread *tmp = sleeping_threads; + sleeping_thread *tmp = sleeping_threads; thread_wakeUp(tmp->thread); sleeping_threads = tmp->next; kfree(tmp); |