summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/common.make11
-rw-r--r--src/common/include/stdlib_common.h8
-rw-r--r--src/common/include/string.h8
-rw-r--r--src/common/include/types.h4
-rw-r--r--src/kernel/config.h4
-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.c35
-rw-r--r--src/kernel/lib/bitset.cpp35
-rw-r--r--src/kernel/lib/bitset.h9
-rw-r--r--src/kernel/lib/cpp.h16
-rw-r--r--src/kernel/lib/std.cpp (renamed from src/kernel/lib/std.c)1
-rw-r--r--src/kernel/lib/std.h5
-rw-r--r--src/kernel/linker/elf.cpp (renamed from src/kernel/linker/elf.c)16
-rw-r--r--src/kernel/linker/elf.h6
-rw-r--r--src/kernel/mem/_dlmalloc.h3
-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.h12
-rw-r--r--src/kernel/mem/paging.cpp (renamed from src/kernel/mem/paging.c)40
-rw-r--r--src/kernel/mem/paging.h26
-rw-r--r--src/kernel/mem/seg.cpp (renamed from src/kernel/mem/seg.c)50
-rw-r--r--src/kernel/mem/seg.h24
-rw-r--r--src/kernel/task/idt.cpp (renamed from src/kernel/task/idt.c)28
-rw-r--r--src/kernel/task/idt.h2
-rw-r--r--src/kernel/task/sched.cpp (renamed from src/kernel/task/sched.c)16
-rw-r--r--src/kernel/task/sched.h4
-rw-r--r--src/kernel/task/syscall.c45
-rw-r--r--src/kernel/task/syscall.cpp50
-rw-r--r--src/kernel/task/task.cpp (renamed from src/kernel/task/task.c)61
-rw-r--r--src/kernel/task/task.h29
-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(&regs) != 0) || regs.int_no != 14) {
if (tasking_handleException(&regs) == 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](&regs);
}
@@ -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);