KraKern

C++ Kernel
Log | Files | Refs | README | LICENSE | git clone https://git.ne02ptzero.me/git/KraKern

commit f8b5648587540b12d56f7d61baaa174225b3fe17
parent 63b86e321e26cd22e58a08988264fcd6039fa1a4
Author: Ne02ptzero <louis@ne02ptzero.me>
Date:   Mon, 18 Jan 2016 02:36:48 +0100

Fix(Processus): Beginning of multi-tasking

Diffstat:
Aincludes/core/Buffer.hpp | 26++++++++++++++++++++++++++
Mincludes/core/Kernel.hpp | 14++++++++------
Mincludes/core/Memory.hpp | 11+++++++++++
Mincludes/core/Process.hpp | 114++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
Aincludes/core/ProcessTable.hpp | 37+++++++++++++++++++++++++++++++++++++
Aincludes/core/signals.h | 53+++++++++++++++++++++++++++++++++++++++++++++++++++++
Mkern.img | 0
Mkernel/FileSystem.cpp | 49+++++++++++++++++++++++++++++++++++++++++++++++++
Mkernel/Kernel.cpp | 2++
Mkernel/Makefile | 2+-
Mkernel/Memory.cpp | 143+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
Mkernel/Process.cpp | 182+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Akernel/ProcessTable.cpp | 162+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Alib/Buffer.cpp | 56++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mlib/Makefile | 2+-
Dlib/baselib.o | 0
Dlib/cxx.o | 0
17 files changed, 842 insertions(+), 11 deletions(-)

diff --git a/includes/core/Buffer.hpp b/includes/core/Buffer.hpp @@ -0,0 +1,26 @@ +#ifndef __BUFFER__ +# define __BUFFER__ + +# include <os.h> + +class Buffer { + public: + Buffer(char *n, u32 size); + Buffer(void); + ~Buffer(void); + + void add(u8 *c, u32 s); + u32 get(u8 *c, u32 s); + void clear(void); + u32 is_empty(void); + + Buffer &operator>>(char *c); + + private: + u32 _size; + char *_map; +}; + +# include <Kernel.hpp> + +#endif diff --git a/includes/core/Kernel.hpp b/includes/core/Kernel.hpp @@ -8,6 +8,7 @@ # include <Memory.hpp> # include <Keyboard.hpp> # include <FileSystem.hpp> +# include <ProcessTable.hpp> class Kernel { public: @@ -16,12 +17,13 @@ class Kernel { void init(multiboot_info *mbi); void welcome(void); - Io io; - GDT gdt; - IDT idt; - Memory mem; - Keyboard keyboard; - FileSystem fs; + Io io; + GDT gdt; + IDT idt; + Memory mem; + Keyboard keyboard; + FileSystem fs; + ProcessTable pt; }; #endif diff --git a/includes/core/Memory.hpp b/includes/core/Memory.hpp @@ -64,10 +64,21 @@ class Memory { void kfree(void *v_addr); u32 ksize(void *v_addr); + struct page *get_page_from_heap(void); + struct page_directory *pd_copy(struct page_directory *pfather); + struct page_directory *pd_create(void); + void release_page_frame(u32 p_addr); + int release_page_from_heap(char *v_addr); + int pd_remove_page(char *v_addr); + int pd_destroy(struct page_directory *pd); + + u32 *get_pd0(void); + private: void _init_memory(u32 hm); char *_get_page_frame(void); int _pd0_add_page(char *v_addr, char *p_addr, int flags); + char *_get_p_addr(char *v_addr); char *_kern_heap; list_head _kern_free_vm; diff --git a/includes/core/Process.hpp b/includes/core/Process.hpp @@ -1,8 +1,120 @@ #ifndef __PROCESS__ # define __PROCESS__ -class Process { +# include <os.h> +# include <File.hpp> +# include <Buffer.hpp> +# include <signals.h> +# define KERNELMODE 0 +# define USERMODE 1 +# define MAX_CONFIG_FILE 32 +# define API_PROC_GET_PID 0x5200 +# define API_PROC_GET_INFO 0x5201 +# define P_ZOMBIE PROC_STATE_ZOMBIE +# define P_CHILD PROC_STATE_RUN + +extern "C" { + struct process_st { + int pid; + struct { + u32 eax, ecx, edx, ebx; + u32 esp, ebp, esi, edi; + u32 eip, eflags; + u32 cs:16, ss:16, ds:16, es:16, fs:16, gs:16; + u32 cr3; + } regs __attribute__ ((packed)); + struct { + u32 esp0; + u16 ss0; + } kstack __attribute__ ((packed)); + struct page_directory *pd; + list_head pglist; + char *b_exec; + char *e_exec; + char *b_bss; + char *e_bss; + char *b_heap; + char *e_heap; + u32 signal; + void* sigfn[32]; + void* vinfo; + } __attribute__ ((packed)); +} + +struct proc_info{ + char name[32]; + unsigned int pid; + unsigned int tid; + unsigned char state; + unsigned int vmem; + unsigned int pmem; +}; + +enum { + PROC_STATE_RUN = 0, + PROC_STATE_ZOMBIE = 1, + PROC_STATE_THREAD = 2, +}; + +struct o_file { + u32 mode; + u32 ptr; + File *fp; +}; + +class Process : public File { + public: + Process(char *n); + ~Process(void); + + u32 open(u32 flag); + u32 close(void); + u32 read(u32 pos, u8 *buffer, u32 size); + u32 write(u32 pos, u8 *buffer, u32 size); + u32 ioctl(u32 id, u8 *buffer); + u32 remove(void); + void scan(void); + + u32 create(char *f, int ac, char **av); + void send_signal(int sig); + u32 wait(void); + void exit(void); + int fork(void); + + u32 add_file(File *fp, u32 m); + File *get_file(u32 fd); + void delete_file(u32 fd); + o_file *get_file_info(u32 fd); + void set_state(u8 st); + u8 get_state(void); + void set_file(u32 fd, File *fp, u32 ptr, u32 mode); + void set_pid(u32 st); + u32 get_pid(void); + void set_p_next(Process *p); + + Process *schedule(void); + Process *get_p_next(void); + Process *get_p_parent(void); + process_st *get_p_info(void); + void set_p_parent(Process *p); + void reset_p_info(void); + File *get_current_dir(void); + void set_current_dir(File *fp); + + protected: + static u32 _proc_pid; + u32 _pid; + u8 _state; + Process *_pparent; + Process *_pnext; + o_file _openfp[MAX_CONFIG_FILE]; + proc_info _pinfo; + File *_dir; + Buffer *_ipc; + + private: + process_st _info; }; #endif diff --git a/includes/core/ProcessTable.hpp b/includes/core/ProcessTable.hpp @@ -0,0 +1,37 @@ +#ifndef __PROCESS_TABLE__ +# define __PROCESS_TABLE__ + +# include <os.h> + +class Process; +struct process_st; + +class ProcessTable { + public: + void init(void); + + void add_process(Process *p); + void fork(process_st *info, process_st *father); + int create_proc(process_st *info, char *f, int ac, char **av); + void destroy_process(Process *p); + void change_process_father(Process *p, Process *f); + void destroy_all_zombies(void); + + Process *get_current(void); + Process *get_list(void); + + void set_current(Process *p); + + private: + void _init_info(process_st *info, u32 stackp, struct page *kstack, u32 e_entry); + Process *_first; + Process *_current; + Process *_list; + u32 *_ret_reg[5]; + +}; + +# include <Kernel.hpp> +# include <Process.hpp> + +#endif diff --git a/includes/core/signals.h b/includes/core/signals.h @@ -0,0 +1,53 @@ +#ifndef __SIGNALS__ +# define __SIGNALS__ + +# include <os.h> + + #define SIGHUP 1 /* Hangup (POSIX). */ + #define SIGINT 2 /* Interrupt (ANSI). */ + #define SIGQUIT 3 /* Quit (POSIX). */ + #define SIGILL 4 /* Illegal instruction (ANSI). */ + #define SIGTRAP 5 /* Trace trap (POSIX). */ + #define SIGABRT 6 /* Abort (ANSI). */ + #define SIGIOT 6 /* IOT trap (4.2 BSD). */ + #define SIGBUS 7 /* BUS error (4.2 BSD). */ + #define SIGFPE 8 /* Floating-point exception (ANSI). */ + #define SIGKILL 9 /* Kill, unblockable (POSIX). */ + #define SIGUSR1 10 /* User-defined signal 1 (POSIX). */ + #define SIGSEGV 11 /* Segmentation violation (ANSI). */ + #define SIGUSR2 12 /* User-defined signal 2 (POSIX). */ + #define SIGPIPE 13 /* Broken pipe (POSIX). */ + #define SIGALRM 14 /* Alarm clock (POSIX). */ + #define SIGTERM 15 /* Termination (ANSI). */ + #define SIGSTKFLT 16 /* Stack fault. */ + #define SIGCLD SIGCHLD /* Same as SIGCHLD (System V). */ + #define SIGCHLD 17 /* Child status has changed (POSIX). */ + #define SIGCONT 18 /* Continue (POSIX). */ + #define SIGSTOP 19 /* Stop, unblockable (POSIX). */ + #define SIGTSTP 20 /* Keyboard stop (POSIX). */ + #define SIGTTIN 21 /* Background read from tty (POSIX). */ + #define SIGTTOU 22 /* Background write to tty (POSIX). */ + #define SIGURG 23 /* Urgent condition on socket (4.2 BSD). */ + #define SIGXCPU 24 /* CPU limit exceeded (4.2 BSD). */ + #define SIGXFSZ 25 /* File size limit exceeded (4.2 BSD). */ + #define SIGVTALRM 26 /* Virtual alarm clock (4.2 BSD). */ + #define SIGPROF 27 /* Profiling alarm clock (4.2 BSD). */ + #define SIGWINCH 28 /* Window size change (4.3 BSD, Sun). */ + #define SIGPOLL SIGIO /* Pollable event occurred (System V). */ + #define SIGIO 29 /* I/O now possible (4.2 BSD). */ + #define SIGPWR 30 /* Power failure restart (System V). */ + #define SIGSYS 31 /* Bad system call. */ + + #define SIGEVENT SIGPOLL + #define SIGIPC SIGUSR1 + + + + #define SIG_DFL 0 /* default signal handling */ + #define SIG_IGN 1 /* ignore signal */ + + #define set_signal(mask, sig) *(mask) |= ((u32) 1 << (sig - 1)) + #define clear_signal(mask, sig) *(mask) &= ~((u32) 1 << (sig - 1)) + #define is_signal(mask, sig) (mask & ((u32) 1 << (sig - 1))) + +#endif diff --git a/kern.img b/kern.img Binary files differ. diff --git a/kernel/FileSystem.cpp b/kernel/FileSystem.cpp @@ -15,3 +15,52 @@ void FileSystem::init(void) { sysd->create_child("sockets", TYPE_DIRECTORY); __kern.io.done(); } + +File *FileSystem::path(char *p) { + File *fp = this->_root; + char *name, *beg_p, *end_p; + + if (p[0] == '/') { + fp = this->_root; + } else { + if (__kern.pt.get_current()) + fp = __kern.pt.get_current()->get_current_dir(); + } + beg_p = p; + while (*beg_p == '/') + beg_p++; + end_p = beg_p + 1; + while (*beg_p) { + if (fp->get_type() != TYPE_DIRECTORY) + return 0x0; + while (*end_p != 0 && *end_p != '/') + end_p++; + name = (char *)__kern.mem.kmalloc(end_p - beg_p + 1); + memcpy(name, beg_p, end_p - beg_p); + name[end_p - beg_p] = 0; + if (!strcmp("..", name)) { + fp = fp->get_parent(); + } else if (strcmp(".", name)) { + fp->scan(); + if (!(fp = fp->find(name))) { + __kern.mem.kfree(name); + return 0; + } + if (fp->get_type() == TYPE_LINK && (fp->get_link())) + fp = fp->get_link(); + } + beg_p = end_p; + while (*beg_p == '/') + beg_p++; + end_p = beg_p + 1; + __kern.mem.kfree(name); + } + return fp; +} + +u32 FileSystem::add_file(char *dir, File *fp) { + File *fdir = this->path(dir); + return fdir->add_child(fp); +} + +File *FileSystem::get_root(void) { return this->_root; }; diff --git a/kernel/Kernel.cpp b/kernel/Kernel.cpp @@ -25,6 +25,8 @@ void Kernel::init(multiboot_info *mbi) { this->keyboard.init(); this->fs = *(new FileSystem()); this->fs.init(); + this->pt = *(new ProcessTable()); + this->pt.init(); while (1); } diff --git a/kernel/Makefile b/kernel/Makefile @@ -1 +1 @@ -OBJS += kernel/main.o kernel/Io.o kernel/Kernel.o kernel/Memory.o kernel/Keyboard.o kernel/Process.o kernel/File.o kernel/FileSystem.o +OBJS += kernel/main.o kernel/Io.o kernel/Kernel.o kernel/Memory.o kernel/Keyboard.o kernel/Process.o kernel/File.o kernel/FileSystem.o kernel/ProcessTable.o diff --git a/kernel/Memory.cpp b/kernel/Memory.cpp @@ -144,9 +144,8 @@ char *Memory::_get_page_frame(void) { int Memory::_pd0_add_page(char *v_addr, char *p_addr, int flags) { u32 *pde, *pte; - if (v_addr > (char *)USER_OFFSET) { + if (v_addr > (char *)USER_OFFSET) __kern.io.panic("_pd0_add_page(): Address not in kernel space"); - } pde = (u32 *)(0xFFFFF000 | (((u32)v_addr & 0xFFC00000) >> 20)); if (!(*pde & PG_PRESENT)) __kern.io.panic("_pd0_add_page(): Page asked can't be found"); @@ -155,3 +154,143 @@ int Memory::_pd0_add_page(char *v_addr, char *p_addr, int flags) { this->_mem_bitmap[((u32)p_addr) / 8] |= (1 << (((u32)p_addr) % 8)); return 0; } + +// Not working +struct page_directory *Memory::pd_copy(struct page_directory *pfather) { + struct page_directory *pd; + u32 *pdir; + int i; + + pd = (struct page_directory *)this->kmalloc(sizeof(struct page_directory)); + pd->base = this->get_page_from_heap(); + pdir = (u32 *)pd->base->v_addr; + for (i = 0; i < 256; i++) + pdir[i] = this->_pd0[i]; + for (i = 256; i < 1023; i++) + pdir[i] = 0; + pdir[1023] = ((u32)pd->base->p_addr | (PG_PRESENT | PG_WRITE)); + INIT_LIST_HEAD(&pd->pt); + return pd; +} + +struct page_directory *Memory::pd_create(void) { + struct page_directory *pd; + u32 *pdir; + int i; + + pd = (struct page_directory *)this->kmalloc(sizeof(struct page_directory)); + pd->base = this->get_page_from_heap(); + pdir = (u32 *)pd->base->v_addr; + for (i = 0; i < 256; i++) + pdir[i] = this->_pd0[i]; + for (i = 256; i < 1023; i++) + pdir[i] = 0; + pdir[1023] = ((u32)pd->base->p_addr | (PG_PRESENT | PG_WRITE)); + INIT_LIST_HEAD(&pd->pt); + return pd; +} + +struct page *Memory::get_page_from_heap(void) { + struct page *pg; + struct vm_area *area; + char *v_addr, *p_addr; + + p_addr = this->_get_page_frame(); + if ((int)p_addr < 0) + __kern.io.panic("get_page_from_heap(): No page frame available."); + if (list_empty(&this->_kern_free_vm)) + __kern.io.panic("get_page_from_heap(): No memory left in page heap."); + area = list_first_entry(&this->_kern_free_vm, vm_area, list); + v_addr = area->vm_start; + area->vm_start += PAGESIZE; + if (area->vm_start == area->vm_end) { + list_del(&area->list); + this->kfree(area); + } + this->_pd0_add_page(v_addr, p_addr, 0); + pg = (struct page *)this->kmalloc(sizeof(struct page)); + pg->v_addr = v_addr; + pg->p_addr = p_addr; + pg->list.next = 0x0; + pg->list.prev = 0x0; + return pg; +} + +void Memory::release_page_frame(u32 p_addr) { + this->_mem_bitmap[((u32)p_addr) / 8] |= (1 << (((u32)p_addr) % 8)); +} + +int Memory::release_page_from_heap(char *v_addr) { + struct vm_area *next_area, *prev_area, *new_area; + char *p_addr; + + p_addr = this->_get_p_addr(v_addr); + if (p_addr) + this->release_page_frame((u32)p_addr); + else + __kern.io.panic("release_page_from_heap(): No page frame associated."); + this->pd_remove_page(v_addr); + list_for_each_entry(next_area, &this->_kern_free_vm, list) { + if (next_area->vm_start > v_addr) + break ; + } + prev_area = list_entry(next_area->list.prev, struct vm_area, list); + if (prev_area->vm_end == v_addr) { + prev_area->vm_end += PAGESIZE; + if (prev_area->vm_end == next_area->vm_start) { + prev_area->vm_end = next_area->vm_end; + list_del(&next_area->list); + kfree(next_area); + } + } else if (next_area->vm_start == v_addr + PAGESIZE) { + next_area->vm_start = v_addr; + } else if (next_area->vm_start > v_addr + PAGESIZE) { + new_area = (struct vm_area *)this->kmalloc(sizeof(struct vm_area)); + new_area->vm_start = v_addr; + new_area->vm_end = v_addr + PAGESIZE; + list_add(&new_area->list, &prev_area->list); + } else { + __kern.io.panic("release_page_from_heap(): Corrupted linked list."); + } + return 0; +} + +char *Memory::_get_p_addr(char *v_addr) { + u32 *pde, *pte; + + pde = (u32 *) (0xFFFFF000 | (((u32) v_addr & 0xFFC00000) >> 20)); + if ((*pde & PG_PRESENT)) { + pte = (u32 *) (0xFFC00000 | (((u32) v_addr & 0xFFFFF000) >> 10)); + if ((*pte & PG_PRESENT)) + return (char *) ((*pte & 0xFFFFF000) + (VADDR_PG_OFFSET((u32) v_addr))); + } + return 0; +} + +int Memory::pd_remove_page(char *v_addr) { + u32 *pte; + + if (this->_get_p_addr(v_addr)) { + pte = (u32 *) (0xFFC00000 | (((u32) v_addr & 0xFFFFF000) >> 10)); + *pte = (*pte & (~PG_PRESENT)); + asm("invlpg %0"::"m"(v_addr)); + } + return 0; +} + +int Memory::pd_destroy(struct page_directory *pd) { + struct page *pg; + struct list_head *p, *n; + + list_for_each_safe(p, n, &pd->pt) { + pg = list_entry(p, struct page, list); + this->release_page_from_heap(pg->v_addr); + list_del(p); + this->kfree(pg); + } + this->release_page_from_heap(pd->base->v_addr); + this->kfree(pd); + return 0; +} + +u32 *Memory::get_pd0(void) { return this->_pd0; }; diff --git a/kernel/Process.cpp b/kernel/Process.cpp @@ -1 +1,183 @@ # include <Process.hpp> + +Process::Process(char *n) : File(n, TYPE_PROCESS) { + __kern.fs.add_file("/proc/", this); + this->_pparent = __kern.pt.get_current(); + this->_pid = Process::_proc_pid++; + if (this->_pparent) + this->_dir = this->_pparent->get_current_dir(); + else + this->_dir = __kern.fs.get_root(); + __kern.pt.add_process(this); + this->_info.vinfo = (void *)this; + for (int i = 0; i < MAX_CONFIG_FILE; i++) + this->_openfp[i].fp = 0x0; + this->_ipc = new Buffer(); +} + +Process::~Process(void) { + delete this->_ipc; + __kern.pt.change_process_father(this, this->_pparent); +} + +u32 Process::open(u32 flag) { return 0; }; +u32 Process::close(void) { return 0; }; +void Process::scan(void) { return ; }; + +u32 Process::read(u32 pos, u8 *buffer, u32 size) { + u32 ret = 0; + asm("sti"); + while (this->_ipc->is_empty()); + ret = this->_ipc->get(buffer, size); + asm("cli"); + return ret; +} + +u32 Process::write(u32 pos, u8 *buffer, u32 size) { + this->_ipc->add(buffer, size); + return size; +} + +u32 Process::ioctl(u32 id, u8 *buffer) { + u32 ret = 0; + + switch (id) { + case API_PROC_GET_PID: ret = this->_pid; break; + case API_PROC_GET_INFO: + this->reset_p_info(); + memcpy((char *)buffer, (char *)&this->_pinfo, sizeof(proc_info)); + break; + default: ret = -1; break; + } + return ret; +} + +int Process::fork(void) { + if (this->_pparent) + this->_pparent->send_signal(SIGCHLD); + return 0; +} + +u32 Process::wait(void) { + asm("sti"); + while (is_signal(this->_info.signal, SIGCHLD) == 0); + clear_signal(&(this->_info.signal), SIGCHLD); + __kern.pt.destroy_all_zombies(); + asm("cli"); + return 1; +} + +u32 Process::remove(void) { + delete this; + return 0; +} + +void Process::exit(void) { + this->set_state(P_ZOMBIE); + if (this->_pparent) + this->_pparent->send_signal(SIGCHLD); +} + +u32 Process::create(char *f, int ac, char **av) { + int ret = __kern.pt.create_proc(&this->_info, f, ac, av); + + if (ret == 1) + this->set_state(P_CHILD); + else + this->set_state(P_ZOMBIE); + if (this->_pparent) { + memcpy((char *)&this->_openfp[0], (char *)this->_pparent->get_file_info(0), sizeof(struct o_file)); + memcpy((char *)&this->_openfp[1], (char *)this->_pparent->get_file_info(1), sizeof(struct o_file)); + memcpy((char *)&this->_openfp[2], (char *)this->_pparent->get_file_info(2), sizeof(struct o_file)); + } else { + this->add_file(__kern.fs.path("/dev/tty"), 0); + this->add_file(__kern.fs.path("/dev/tty"), 0); + this->add_file(__kern.fs.path("/dev/tty"), 0); + } + return 0; +} + +void Process::set_file(u32 fd, File *fp, u32 ptr, u32 mode) { + if (fd > MAX_CONFIG_FILE) + return ; + this->_openfp[fd].fp = fp; + this->_openfp[fd].ptr = ptr; + this->_openfp[fd].mode = mode; +} + +u32 Process::add_file(File *f, u32 m) { + for (int i = 0; i < MAX_CONFIG_FILE; i++) { + if (this->_openfp[i].fp == 0x0 && f != NULL) { + this->_openfp[i].fp = f; + this->_openfp[i].mode = m; + this->_openfp[i].ptr = 0; + return i; + } + } + return 0; +} + +File *Process::get_file(u32 fd) { + if (fd > MAX_CONFIG_FILE) + return 0x0; + return this->_openfp[fd].fp; +} + +o_file *Process::get_file_info(u32 fd) { + if (fd > MAX_CONFIG_FILE) + return 0x0; + return &this->_openfp[fd]; +} + +void Process::delete_file(u32 fd) { + if (fd > MAX_CONFIG_FILE) + return ; + this->_openfp[fd].fp = 0x0; + this->_openfp[fd].mode = 0x0; + this->_openfp[fd].ptr = 0x0; +} + +Process *Process::schedule(void) { + Process *n = this->get_p_next(); + int out = 1; + + while (out) { + if (!n) { + n = __kern.pt.get_list(); + } if (n->get_state() != P_ZOMBIE) { + out = 0; + } else { + n = n->get_p_next(); + } + } + __kern.pt.set_current(n); + return n; +} + +void Process::send_signal(int sig) { + set_signal(&(this->_info.signal), sig); +} + +void Process::reset_p_info(void) { + strncpy(this->_pinfo.name, this->_name, 32); + this->_pinfo.pid = this->_pid; + this->_pinfo.tid = 0; + this->_pinfo.state = this->_state; + this->_pinfo.vmem = 10 * 1024 * 1024; + this->_pinfo.pmem = 10 * 1024 * 1024; +} + +Process *Process::get_p_parent(void) { return this->_pparent; }; +process_st *Process::get_p_info(void) { return &this->_info; }; +Process *Process::get_p_next(void) { return this->_pnext; }; +File *Process::get_current_dir(void) { return this->_dir; }; +u8 Process::get_state(void) { return this->_state; }; +u32 Process::get_pid(void) { return this->_pid; }; + +void Process::set_p_parent(Process *p) { this->_pparent = p; }; +void Process::set_p_next(Process *p) { this->_pnext = p; }; +void Process::set_current_dir(File *f) { this->_dir = f; }; +void Process::set_state(u8 s) { this->_state = s; }; +void Process::set_pid(u32 st) { this->_pid = st; }; + +u32 Process::_proc_pid = 0; diff --git a/kernel/ProcessTable.cpp b/kernel/ProcessTable.cpp @@ -0,0 +1,162 @@ +# include <ProcessTable.hpp> + +void ProcessTable::init(void) { + __kern.io.loading("Process Table ..."); + this->_first = new Process("kernel"); + this->_first->set_state(P_ZOMBIE); + this->_first->add_file(__kern.fs.path("/dev/tty"), 0); + this->_list = this->_first; + this->_current = this->_first; + this->_current->set_p_next(0x0); + __kern.io.done(); +} + +void ProcessTable::add_process(Process *p) { + p->set_p_next(this->_list); + this->_list = p; +} + +void ProcessTable::fork(process_st *info, process_st *father) { + memcpy((char *)info, (char *)father, sizeof(process_st)); + info->pd = __kern.mem.pd_copy(father->pd); +} + +int ProcessTable::create_proc(process_st *info, char *f, int ac, char **av) { + struct page *kstack; + process_st *previous, *current; + char **param, **uparam; + u32 stackp, e_entry; + int pid, i; + + pid = 1; + info->pid = pid; + if (ac) { + param = (char **)__kern.mem.kmalloc(sizeof(char *) * (ac + 1)); + for (i = 0; i < ac; i++) { + param[i] = (char *)__kern.mem.kmalloc(strlen(av[i]) + 1); + strcpy(param[i], av[i]); + } + param[i] = 0x0; + } + info->pd = __kern.mem.pd_create(); + INIT_LIST_HEAD(&(info->pglist)); + previous = this->_current->get_p_info(); + current = info; + asm("mov %0, %%eax; mov %%eax, %%cr3"::"m"((info->pd)->base->p_addr)); + e_entry = 0; // ELF HERE + stackp = USER_STACK - 16; + if (ac) { + uparam = (char **)__kern.mem.kmalloc(sizeof(char *) * ac); + for (i = 0; i < ac; i++) { + stackp -= strlen(param[i]) + 1; + strcpy((char *)stackp, param[i]); + uparam[i] = (char *)stackp; + } + stackp &= 0xFFFFFFF0; + stackp -= sizeof(char *); + *((char **)stackp) = 0; + for (i = ac - 1; i >= 0; i--) { + stackp -= sizeof(char *); + *((char **)stackp) = uparam[i]; + } + stackp -= sizeof(char *); + *((char **)stackp) = (char *)(stackp + 4); + stackp -= sizeof(char *); + *((int *)stackp) = ac; + stackp -= sizeof(char *); + for (i = 0; i < ac; i++) + __kern.mem.kfree(param[i]); + __kern.mem.kfree(param); + __kern.mem.kfree(uparam); + } + kstack = __kern.mem.get_page_from_heap(); + this->_init_info(info, stackp, kstack, e_entry); + this->_current = (Process *)previous->vinfo; + current = this->_current->get_p_info(); + asm("mov %0, %%eax ;mov %%eax, %%cr3":: "m"(current->regs.cr3)); + return 1; +} + +void ProcessTable::_init_info(process_st *info, u32 stackp, struct page *kstack, u32 e_entry) { + info->regs.ss = 0x33; + info->regs.esp = stackp; + info->regs.eflags = 0x0; + info->regs.cs = 0x23; + info->regs.eip = e_entry; + info->regs.ds = info->regs.es = info->regs.fs = info->regs.gs = 0x2B; + info->regs.cr3 = (u32)info->pd->base->p_addr; + info->kstack.ss0 = 0x18; + info->kstack.esp0 = (u32)kstack->v_addr + PAGESIZE - 16; + info->regs.eax = info->regs.ecx = info->regs.edx = info->regs.ebx = + info->regs.ebp = info->regs.esi = info->regs.edi = 0; + info->b_heap = (char *)((u32)info->e_bss & 0xFFFFF000) + PAGESIZE; + info->e_heap = info->b_heap; + info->signal = 0; + for (int i = 0; i < 32; i++) + info->sigfn[i] = 0; +} + +void ProcessTable::destroy_process(Process *pp) { + asm("sti"); + u16 kss; + u32 kesp, accr3; + list_head *p, *n; + struct page *pg; + process_st *proc_current = this->_current->get_p_info(), *pid_proc = pp->get_p_info(); + u32 *pd0; + + asm("mov %0, %%eax ;mov %%eax, %%cr3"::"m" (pid_proc->regs.cr3)); + list_for_each_safe(p, n, &pid_proc->pglist) { + pg = list_entry(p, struct page, list); + __kern.mem.release_page_frame((u32)pg->p_addr); + list_del(p); + __kern.mem.kfree(pg); + } + pd0 = __kern.mem.get_pd0(); + __kern.mem.release_page_from_heap((char *) ((u32)pid_proc->kstack.esp0 & 0xFFFFF000)); + asm("mov %0, %%eax; mov %%eax, %%cr3"::"m"(pd0)); + __kern.mem.pd_destroy(pid_proc->pd); + asm("mov %0, %%eax ;mov %%eax, %%cr3"::"m" (proc_current->regs.cr3)); + if (this->_list == pp) { + this->_list = pp->get_p_next(); + } else { + Process *l = this->_list, *ol = this->_list; + + while (l) { + if (l == pp) + ol->set_p_next(pp->get_p_next()); + ol = l; + l = l->get_p_next(); + } + } + asm("cli"); +} + +void ProcessTable::change_process_father(Process *pe, Process *f) { + Process *p = this->_list, *pn = 0x0; + + while (p) { + pn = p->get_p_next(); + if (p->get_p_parent() == pe) + p->set_p_parent(f); + p = pn; + } +} + +void ProcessTable::destroy_all_zombies(void) { + Process *p = this->_list, *pn = 0x0; + + while (p) { + pn = p->get_p_next(); + if (p->get_state() == P_ZOMBIE && p->get_pid() != 1) { + this->destroy_process(p); + delete p; + } + p = pn; + } +} + +Process *ProcessTable::get_current(void) { return this->_current; }; +Process *ProcessTable::get_list(void) { return this->_list; }; + +void ProcessTable::set_current(Process *p) { this->_current = p; }; diff --git a/lib/Buffer.cpp b/lib/Buffer.cpp @@ -0,0 +1,56 @@ +# include <Buffer.hpp> + +Buffer::Buffer(char *n, u32 size) { + this->_map = (char *)__kern.mem.kmalloc(size); + this->_size = size; + memcpy(this->_map, n, size); +} + +Buffer::Buffer(void) : _size(0), _map(0x0) { + return ; +} + +Buffer::~Buffer(void) { + if (this->_map) + __kern.mem.kfree(this->_map); +} + +void Buffer::add(u8 *c, u32 s) { + char *old = this->_map; + + this->_map = (char *)__kern.mem.kmalloc(s + this->_size); + memcpy(this->_map, old, this->_size); + __kern.mem.kfree(old); + memcpy((char *)(this->_map + this->_size), (char *)c, s); + this->_size += s; +} + +u32 Buffer::get(u8 *c, u32 s) { + char *old = this->_map; + + if (s > this->_size) + s = this->_size; + memcpy((char *)c, (char *)(this->_map + (this->_size - s)), s); + this->_map = (char *)__kern.mem.kmalloc(this->_size - s); + memcpy(this->_map, old, (this->_size - s)); + __kern.mem.kfree(old); + this->_size -= s; + return s; +} + +void Buffer::clear(void) { + this->_size = 0; + if (this->_map) + __kern.mem.kfree(this->_map); +} + +u32 Buffer::is_empty(void) { + if (!this->_size) + return 1; + return 0; +} + +Buffer &Buffer::operator>>(char *c) { + memcpy(c, this->_map, this->_size); + return *this; +} diff --git a/lib/Makefile b/lib/Makefile @@ -1 +1 @@ -OBJS += lib/baselib.o lib/cxx.o +OBJS += lib/baselib.o lib/cxx.o lib/Buffer.o diff --git a/lib/baselib.o b/lib/baselib.o Binary files differ. diff --git a/lib/cxx.o b/lib/cxx.o Binary files differ.