diff options
-rw-r--r-- | doc/syscalls.txt | 2 | ||||
-rw-r--r-- | src/stem/Makefile | 2 | ||||
-rw-r--r-- | src/stem/core/loader_.asm | 10 | ||||
-rw-r--r-- | src/stem/mem/paging.c | 48 | ||||
-rw-r--r-- | src/stem/mem/paging.h | 5 | ||||
-rw-r--r-- | src/stem/mem/seg.c | 73 | ||||
-rw-r--r-- | src/stem/mem/seg.h | 40 | ||||
-rw-r--r-- | src/stem/stem.map | 223 | ||||
-rw-r--r-- | src/stem/task/idt.c | 2 | ||||
-rw-r--r-- | src/stem/task/syscall.c | 2 | ||||
-rw-r--r-- | src/stem/task/task.c | 50 | ||||
-rw-r--r-- | src/stem/task/task.h | 11 |
12 files changed, 334 insertions, 134 deletions
diff --git a/doc/syscalls.txt b/doc/syscalls.txt index f0e3f62..542ec8b 100644 --- a/doc/syscalls.txt +++ b/doc/syscalls.txt @@ -8,4 +8,4 @@ id=eax Name Parameters Description 1 schedule none Switch to next thread (might be the current one) 2 thread_sleep ebx: time (int) msecs Tell kernel to put current thread to sleep 3 process_exit ebx: return value (int) Tell kernel to end current process, cleaning up everything - + 4 printk ebx: addr of a string Print a message to screen diff --git a/src/stem/Makefile b/src/stem/Makefile index c72f06b..d212216 100644 --- a/src/stem/Makefile +++ b/src/stem/Makefile @@ -12,7 +12,7 @@ OBJECTS = core/loader_.o core/kmain.o core/sys.o \ core/monitor.o task/timer.o \ task/idt.o task/idt_.o task/task.o task/task_.o task/syscall.o \ lib/stdlib.o lib/bitset.o \ - mem/mem.o mem/paging.o mem/gdt.o mem/heap.o + mem/mem.o mem/paging.o mem/gdt.o mem/heap.o mem/seg.o OUT = stem.elf all: $(OBJECTS) diff --git a/src/stem/core/loader_.asm b/src/stem/core/loader_.asm index e1031b4..d3b92cf 100644 --- a/src/stem/core/loader_.asm +++ b/src/stem/core/loader_.asm @@ -1,8 +1,7 @@ [GLOBAL loader] ; making entry point visible to linker [EXTERN kmain] ; kmain is defined in kmain.c +[EXTERN tasking_tmpStack] ; a temporary 4k stack used by tasking, and used when setting up kernel stuff -STACKSIZE equ 0x4000 ; that's 16k. - ; setting up the Multiboot header - see GRUB docs for details MODULEALIGN equ 1<<0 ; align loaded modules on page boundaries MEMINFO equ 1<<1 ; provide memory map @@ -32,7 +31,7 @@ loader: ;here, we load our false GDT, used for having the kernel in higher half section .text higherhalf: ; now we're running in higher half - mov esp, stack+STACKSIZE ; set up the stack + mov esp, tasking_tmpStack+0x4000 ; set up the stack push eax ; pass Multiboot magic number add ebx, 0xE0000000 ; update the MB info structure so that it is in the new seg push ebx ; pass Multiboot info structure @@ -56,8 +55,3 @@ gdt: db 0xFF, 0xFF, 0, 0, 0, 10010010b, 11001111b, 0x20 ; kernel data segment gdt_end: - -[section .bss] -align 32 -stack: - resb STACKSIZE ; reserve 16k stack on a quadword boundary diff --git a/src/stem/mem/paging.c b/src/stem/mem/paging.c index 5ce3aae..4cc861c 100644 --- a/src/stem/mem/paging.c +++ b/src/stem/mem/paging.c @@ -3,7 +3,9 @@ #include <stdlib.h> #include <core/monitor.h> #include "mem.h" +#include "seg.h" #include <core/sys.h> +#include <task/task.h> static struct bitset frames; @@ -66,17 +68,45 @@ void pagedir_switch(struct page_directory *pd) { asm volatile("mov %0, %%cr0" : : "r"(cr0)); } +struct page_directory *pagedir_new() { + uint32_t i; + + struct page_directory *pd = kmalloc(sizeof(struct page_directory)); + pd->tablesPhysical = kmalloc_page(&pd->physicalAddr); + + for (i = 768; i < 1024; i++) { + pd->tables[i] = kernel_pagedir->tables[i]; + pd->tablesPhysical[i] = kernel_pagedir->tablesPhysical[i]; + } + + return pd; +} + uint32_t paging_fault(struct registers *regs) { size_t addr; + struct segment_map *seg = 0; asm volatile("mov %%cr2, %0" : "=r"(addr)); - monitor_write("PageFault "); - if (regs->err_code & 0x1) monitor_write("present "); - if (regs->err_code & 0x2) monitor_write("write "); - if (regs->err_code & 0x4) monitor_write("user "); - if (regs->err_code & 0x8) monitor_write("rsvd "); - if (regs->err_code & 0x10) monitor_write("instructionfetch "); - monitor_write("@"); monitor_writeHex(addr); monitor_write("\n"); - PANIC("Page fault"); + + seg = current_pagedir->mappedSegs; + while (seg) { + if (seg->start >= addr && seg->start + seg->len < addr) break; + seg = seg->next; + } + + if (seg != 0) { + if (seg->seg->handle_fault(seg, addr, (regs->err_code & 0x2)) != 0) seg = 0; + } + + if (seg == 0) { + monitor_write("PageFault "); + if (regs->err_code & 0x1) monitor_write("present "); + if (regs->err_code & 0x2) monitor_write("write "); + if (regs->err_code & 0x4) monitor_write("user "); + if (regs->err_code & 0x8) monitor_write("rsvd "); + if (regs->err_code & 0x10) monitor_write("instructionfetch "); + monitor_write("@"); monitor_writeHex(addr); monitor_write("\n"); + return 1; + } return 0; } @@ -88,6 +118,8 @@ struct page *pagedir_getPage(struct page_directory *pd, uint32_t address, int ma return &pd->tables[table_idx]->pages[address % 1024]; } else if (make) { pd->tables[table_idx] = kmalloc_page(pd->tablesPhysical + table_idx); + if (table_idx >= 768) + tasking_updateKernelPagetable(table_idx, pd->tables[table_idx], pd->tablesPhysical[table_idx]); memset((uint8_t*)pd->tables[table_idx], 0, 0x1000); pd->tablesPhysical[table_idx] |= 0x07; return &pd->tables[table_idx]->pages[address % 1024]; diff --git a/src/stem/mem/paging.h b/src/stem/mem/paging.h index 72078cf..9ee6c4c 100644 --- a/src/stem/mem/paging.h +++ b/src/stem/mem/paging.h @@ -18,10 +18,12 @@ struct page_table { struct page pages[1024]; }; +struct segment_map; struct page_directory { struct 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; }; extern struct page_directory *kernel_pagedir; @@ -32,11 +34,12 @@ 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 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 +uint32_t paging_fault(struct registers *regs); //returns a boolean : 1 if unhandled, 0 if ok #endif diff --git a/src/stem/mem/seg.c b/src/stem/mem/seg.c new file mode 100644 index 0000000..f340c63 --- /dev/null +++ b/src/stem/mem/seg.c @@ -0,0 +1,73 @@ +#include "seg.h" +#include "mem.h" + +struct segment_map *seg_map(struct segment* seg, struct page_directory *pagedir) { + struct segment_map *sm = seg->map(seg, pagedir); + if (sm == 0) return 0; + seg->mappings++; + sm->seg = seg; + sm->pagedir = pagedir; + sm->next = pagedir->mappedSegs; + pagedir->mappedSegs = sm->next; + return sm; +} + +void seg_unmap(struct 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; + 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); + kfree(map->seg->seg_data); + kfree(map->seg); + } + kfree (map); +} + +// ************************************ SIMPLESEG stuff ************* + +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)); + se->seg_data = ss; + se->mappings = 0; + se->map = simpleseg_map; + se->unmap = simpleseg_unmap; + se->delete = simpleseg_delete; + se->handle_fault = simpleseg_handleFault; + ss->writable = writable; ss->start = start; ss->len = len; + return se; +} + +struct segment_map* simpleseg_map(struct segment* seg, struct page_directory* pagedir) { + 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; + return sm; +} + +void simpleseg_unmap(struct 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)); + } +} + +int simpleseg_handleFault(struct segment_map* sm, size_t addr, int write) { + struct simpleseg *ss = sm->seg->seg_data; + if (write && !ss->writable) return 1; + addr &= 0xFFFFF000; + struct page *p = pagedir_getPage(sm->pagedir, addr, 1); + if (p->frame != 0) return 1; + page_map(p, frame_alloc(), 1, ss->writable); + return 0; +} + +void simpleseg_delete(struct segment* seg) { +} diff --git a/src/stem/mem/seg.h b/src/stem/mem/seg.h new file mode 100644 index 0000000..022d38e --- /dev/null +++ b/src/stem/mem/seg.h @@ -0,0 +1,40 @@ +#ifndef DEF_SEG_H +#define DEF_SEG_H + +#include "paging.h" + +struct segment_map; +struct segment { + void* seg_data; + int mappings; + + struct segment_map* (*map)(struct segment* seg, struct page_directory* pagedir); + 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 +}; + +struct segment_map { + struct segment* seg; + struct page_directory* pagedir; + size_t start, len; + struct segment_map *next; +}; + +struct segment_map *seg_map(struct segment* seg, struct page_directory* pagedir); +void seg_unmap(struct segment_map* map); + +/// ************************************* SIMPLESEG stuff ***************** + +struct simpleseg { + int writable; + size_t start, len; +}; + +struct segment* simpleseg_make(size_t start, size_t len, int writable); +struct segment_map* simpleseg_map(struct segment* seg, struct page_directory* pagedir); +void simpleseg_unmap(struct segment_map*); +void simpleseg_delete(struct segment *seg); +int simpleseg_handleFault(struct segment_map* map, size_t addr, int write); + +#endif diff --git a/src/stem/stem.map b/src/stem/stem.map index dca785f..a2d1d98 100644 --- a/src/stem/stem.map +++ b/src/stem/stem.map @@ -4,7 +4,10 @@ Common symbol size file idt_ptr 0x6 task/idt.o mem_placementAddr 0x4 mem/mem.o +tasking_tmpStack 0x10000 task/task.o idt_entries 0x800 task/idt.o +kernel_process 0x4 task/task.o +idle_thread 0x4 task/task.o current_pagedir 0x4 mem/paging.o kernel_pagedir 0x4 mem/paging.o @@ -23,7 +26,7 @@ Linker script and memory map 0x00100000 loader 0xe010003a . = (. + 0xe0000000) -.text 0xe0100040 0x29b0 load address 0x00100040 +.text 0xe0100040 0x2eed load address 0x00100040 *(.text) .text 0xe0100040 0x25 core/loader_.o *fill* 0xe0100065 0x3 00 @@ -111,61 +114,72 @@ Linker script and memory map 0xe01012df irq15 0xe01012e9 syscall64 *fill* 0xe01012f3 0x1 00 - .text 0xe01012f4 0x2e8 task/task.o + .text 0xe01012f4 0x3dd task/task.o 0xe01012f4 tasking_init - 0xe01013e7 tasking_switch - 0xe0101479 tasking_handleException - 0xe01014f9 thread_new - *fill* 0xe01015dc 0x4 00 - .text 0xe01015e0 0xa task/task_.o - 0xe01015e0 read_eip - 0xe01015e3 task_idle - *fill* 0xe01015ea 0x2 00 - .text 0xe01015ec 0x15 task/syscall.o - *fill* 0xe0101601 0x3 00 - .text 0xe0101604 0xca lib/stdlib.o - 0xe0101604 memcpy - 0xe0101641 memset - 0xe0101670 memsetw - 0xe01016a6 strlen - *fill* 0xe01016ce 0x2 00 - .text 0xe01016d0 0x173 lib/bitset.o - 0xe01016d0 bitset_set - 0xe0101724 bitset_clear - 0xe010177a bitset_test - 0xe01017bc bitset_firstFree - *fill* 0xe0101843 0x1 00 - .text 0xe0101844 0x29f mem/mem.o - 0xe01019aa kmalloc_page - 0xe01019f1 kfree_page - 0xe0101a2c kheap_init - 0xe0101a81 kmalloc - 0xe0101abf kfree - *fill* 0xe0101ae3 0x1 00 - .text 0xe0101ae4 0x513 mem/paging.o - 0xe0101ae4 frame_alloc - 0xe0101b11 frame_free - 0xe0101b2c paging_init - 0xe0101cc4 paging_cleanup - 0xe0101d1f pagedir_switch - 0xe0101d4e paging_fault - 0xe0101e29 pagedir_getPage - 0xe0101f08 page_map - 0xe0101f90 page_unmap - 0xe0101fb3 page_unmapFree - *fill* 0xe0101ff7 0x1 00 - .text 0xe0101ff8 0x19f mem/gdt.o - 0xe0102087 gdt_init - *fill* 0xe0102197 0x1 00 - .text 0xe0102198 0x858 mem/heap.o - 0xe0102328 heap_create - 0xe01026fb heap_alloc - 0xe010285c heap_free + 0xe0101410 tasking_switch + 0xe01014a2 tasking_updateKernelPagetable + 0xe01014ec tasking_handleException + 0xe010156c thread_new + 0xe0101661 process_new + *fill* 0xe01016d1 0xf 00 + .text 0xe01016e0 0xa task/task_.o + 0xe01016e0 read_eip + 0xe01016e3 task_idle + *fill* 0xe01016ea 0x2 00 + .text 0xe01016ec 0x33 task/syscall.o + *fill* 0xe010171f 0x1 00 + .text 0xe0101720 0xca lib/stdlib.o + 0xe0101720 memcpy + 0xe010175d memset + 0xe010178c memsetw + 0xe01017c2 strlen + *fill* 0xe01017ea 0x2 00 + .text 0xe01017ec 0x173 lib/bitset.o + 0xe01017ec bitset_set + 0xe0101840 bitset_clear + 0xe0101896 bitset_test + 0xe01018d8 bitset_firstFree + *fill* 0xe010195f 0x1 00 + .text 0xe0101960 0x29f mem/mem.o + 0xe0101ac6 kmalloc_page + 0xe0101b0d kfree_page + 0xe0101b48 kheap_init + 0xe0101b9d kmalloc + 0xe0101bdb kfree + *fill* 0xe0101bff 0x1 00 + .text 0xe0101c00 0x645 mem/paging.o + 0xe0101c00 frame_alloc + 0xe0101c2d frame_free + 0xe0101c48 paging_init + 0xe0101de0 paging_cleanup + 0xe0101e3b pagedir_switch + 0xe0101e6a pagedir_new + 0xe0101ef2 paging_fault + 0xe010203f pagedir_getPage + 0xe0102156 page_map + 0xe01021de page_unmap + 0xe0102201 page_unmapFree + *fill* 0xe0102245 0x3 00 + .text 0xe0102248 0x19f mem/gdt.o + 0xe01022d7 gdt_init + *fill* 0xe01023e7 0x1 00 + .text 0xe01023e8 0x858 mem/heap.o + 0xe0102578 heap_create + 0xe010294b heap_alloc + 0xe0102aac heap_free + .text 0xe0102c40 0x2ed mem/seg.o + 0xe0102c40 seg_map + 0xe0102cae seg_unmap + 0xe0102d8d simpleseg_make + 0xe0102e0a simpleseg_map + 0xe0102e40 simpleseg_unmap + 0xe0102e93 simpleseg_handleFault + 0xe0102f28 simpleseg_delete -.iplt 0xe01029f0 0x0 load address 0x001029f0 +.iplt 0xe0102f30 0x0 load address 0x00102f2d .iplt 0x00000000 0x0 core/loader_.o -.rodata 0xe0103000 0x1bb load address 0x00103000 +.rodata 0xe0103000 0x1a3 load address 0x00103000 *(.rodata) .rodata 0xe0103000 0x52 core/kmain.o .rodata 0xe0103052 0x2c core/sys.o @@ -174,14 +188,14 @@ Linker script and memory map .rodata 0xe0103090 0x78 task/idt.o .rodata 0xe0103108 0x12 task/task.o .rodata 0xe010311a 0x10 mem/mem.o - .rodata 0xe010312a 0x89 mem/paging.o - .rodata 0xe01031b3 0x8 mem/gdt.o + .rodata 0xe010312a 0x71 mem/paging.o + .rodata 0xe010319b 0x8 mem/gdt.o -.rel.dyn 0xe01031bc 0x0 load address 0x001031bb +.rel.dyn 0xe01031a4 0x0 load address 0x001031a3 .rel.iplt 0x00000000 0x0 core/loader_.o .rel.text 0x00000000 0x0 core/loader_.o -.data 0xe0104000 0x20 load address 0x00104000 +.data 0xe0104000 0x24 load address 0x00104000 *(.data) .data 0xe0104000 0x0 core/kmain.o .data 0xe0104000 0x4 core/sys.o @@ -189,56 +203,61 @@ Linker script and memory map .data 0xe0104008 0x0 task/timer.o .data 0xe0104008 0x0 task/idt.o .data 0xe0104008 0x4 task/task.o - 0xe0104008 nextpid - .data 0xe010400c 0x14 task/syscall.o + .data 0xe010400c 0x18 task/syscall.o 0xe010400c syscalls - .data 0xe0104020 0x0 lib/stdlib.o - .data 0xe0104020 0x0 lib/bitset.o - .data 0xe0104020 0x0 mem/mem.o - .data 0xe0104020 0x0 mem/paging.o - .data 0xe0104020 0x0 mem/gdt.o - .data 0xe0104020 0x0 mem/heap.o + .data 0xe0104024 0x0 lib/stdlib.o + .data 0xe0104024 0x0 lib/bitset.o + .data 0xe0104024 0x0 mem/mem.o + .data 0xe0104024 0x0 mem/paging.o + .data 0xe0104024 0x0 mem/gdt.o + .data 0xe0104024 0x0 mem/heap.o + .data 0xe0104024 0x0 mem/seg.o -.igot.plt 0xe0104020 0x0 load address 0x00104020 +.igot.plt 0xe0104024 0x0 load address 0x00104024 .igot.plt 0x00000000 0x0 core/loader_.o -.bss 0xe0104020 0x4950 load address 0x00104020 - 0xe0104020 sbss = . +.bss 0xe0104040 0x10970 load address 0x00104040 + 0xe0104040 sbss = . *(COMMON) - COMMON 0xe0104020 0x820 task/idt.o - 0xe0104020 idt_ptr - 0xe0104040 idt_entries - COMMON 0xe0104840 0x4 mem/mem.o - 0xe0104840 mem_placementAddr - COMMON 0xe0104844 0x8 mem/paging.o - 0xe0104844 current_pagedir - 0xe0104848 kernel_pagedir + COMMON 0xe0104040 0x820 task/idt.o + 0xe0104040 idt_ptr + 0xe0104060 idt_entries + COMMON 0xe0104860 0x10008 task/task.o + 0xe0104860 tasking_tmpStack + 0xe0114860 kernel_process + 0xe0114864 idle_thread + COMMON 0xe0114868 0x4 mem/mem.o + 0xe0114868 mem_placementAddr + COMMON 0xe011486c 0x8 mem/paging.o + 0xe011486c current_pagedir + 0xe0114870 kernel_pagedir *(.bss) - .bss 0xe010484c 0x4000 core/loader_.o - .bss 0xe010884c 0x0 core/kmain.o - .bss 0xe010884c 0x0 core/sys.o - .bss 0xe010884c 0x8 core/monitor.o - .bss 0xe0108854 0xc task/timer.o - .bss 0xe0108860 0x40 task/idt.o - .bss 0xe01088a0 0xc task/task.o - 0xe01088a0 processes - 0xe01088a4 threads - 0xe01088a8 current_thread - .bss 0xe01088ac 0x0 task/syscall.o - .bss 0xe01088ac 0x0 lib/stdlib.o - .bss 0xe01088ac 0x0 lib/bitset.o - *fill* 0xe01088ac 0x14 00 - .bss 0xe01088c0 0x60 mem/mem.o - 0xe01088c0 freepagecount - .bss 0xe0108920 0x8 mem/paging.o - *fill* 0xe0108928 0x18 00 - .bss 0xe0108940 0x2e mem/gdt.o - *fill* 0xe010896e 0x2 00 - .bss 0xe0108970 0x0 mem/heap.o - 0xe0108970 ebss = . - 0xe0108970 end = . - 0xe0108970 _end = . - 0xe0108970 __end = . + .bss 0xe0114874 0x0 core/kmain.o + .bss 0xe0114874 0x0 core/sys.o + .bss 0xe0114874 0x8 core/monitor.o + .bss 0xe011487c 0xc task/timer.o + *fill* 0xe0114888 0x18 00 + .bss 0xe01148a0 0x40 task/idt.o + .bss 0xe01148e0 0xc task/task.o + 0xe01148e0 processes + 0xe01148e4 threads + 0xe01148e8 current_thread + .bss 0xe01148ec 0x0 task/syscall.o + .bss 0xe01148ec 0x0 lib/stdlib.o + .bss 0xe01148ec 0x0 lib/bitset.o + *fill* 0xe01148ec 0x14 00 + .bss 0xe0114900 0x60 mem/mem.o + 0xe0114900 freepagecount + .bss 0xe0114960 0x8 mem/paging.o + *fill* 0xe0114968 0x18 00 + .bss 0xe0114980 0x2e mem/gdt.o + *fill* 0xe01149ae 0x2 00 + .bss 0xe01149b0 0x0 mem/heap.o + .bss 0xe01149b0 0x0 mem/seg.o + 0xe01149b0 ebss = . + 0xe01149b0 end = . + 0xe01149b0 _end = . + 0xe01149b0 __end = . LOAD core/loader_.o LOAD core/kmain.o LOAD core/sys.o @@ -255,6 +274,7 @@ LOAD mem/mem.o LOAD mem/paging.o LOAD mem/gdt.o LOAD mem/heap.o +LOAD mem/seg.o OUTPUT(stem.elf elf32-i386) .comment 0x00000000 0x11 @@ -272,6 +292,7 @@ OUTPUT(stem.elf elf32-i386) .comment 0x00000000 0x12 mem/paging.o .comment 0x00000000 0x12 mem/gdt.o .comment 0x00000000 0x12 mem/heap.o + .comment 0x00000000 0x12 mem/seg.o .note.GNU-stack 0x00000000 0x0 @@ -301,3 +322,5 @@ OUTPUT(stem.elf elf32-i386) 0x00000000 0x0 mem/gdt.o .note.GNU-stack 0x00000000 0x0 mem/heap.o + .note.GNU-stack + 0x00000000 0x0 mem/seg.o diff --git a/src/stem/task/idt.c b/src/stem/task/idt.c index 7c05e2e..4866550 100644 --- a/src/stem/task/idt.c +++ b/src/stem/task/idt.c @@ -67,7 +67,7 @@ struct idt_ptr idt_ptr; static int_callback irq_handlers[16] = {0}; void idt_isrHandler(struct registers regs) { - if ((regs.int_no == 14 && paging_fault(®s) == 0) || regs.int_no != 14) { + if ((regs.int_no == 14 && paging_fault(®s) != 0) || regs.int_no != 14) { if (tasking_handleException(®s) == 0) { monitor_write(" >> >> SOMETHING BAD HAPPENNED << <<\n"); monitor_write("Unhandled exception "); diff --git a/src/stem/task/syscall.c b/src/stem/task/syscall.c index 281d680..6964b34 100644 --- a/src/stem/task/syscall.c +++ b/src/stem/task/syscall.c @@ -7,10 +7,12 @@ r->eax = name(r->ebx, r->ecx); } CALL0(tasking_switch, schedule_sc); +CALL1(monitor_write, printk_sc); int_callback syscalls[] = { 0, //Syscall 0 will be thread_exit schedule_sc, 0, //Syscall 2 will be thread_sleep 0, //Syscall 3 will be process_exit + printk_sc, 0 }; diff --git a/src/stem/task/task.c b/src/stem/task/task.c index 39c2482..8ed5190 100644 --- a/src/stem/task/task.c +++ b/src/stem/task/task.c @@ -12,21 +12,24 @@ extern void task_idle(void*); static uint32_t thread_runnable(struct thread *th); -uint32_t nextpid = 1; +static uint32_t nextpid = 1; -struct process *processes = 0; -struct thread *threads = 0, *current_thread = 0; +struct process *processes = 0, *kernel_process; +struct thread *threads = 0, *current_thread = 0, *idle_thread; + +uint32_t tasking_tmpStack[0x4000]; void tasking_init(thread_entry whereToGo, void *data) { cli(); - struct process *pr = kmalloc(sizeof(struct process)); //This process must be hidden to users - pr->pid = pr->uid = 0; - pr->parent = pr; - pr->pagedir = kernel_pagedir; - pr->next = 0; + kernel_process = kmalloc(sizeof(struct process)); //This process must be hidden to users + kernel_process->pid = kernel_process->uid = kernel_process->threads = 0; + kernel_process->privilege = PL_KERNEL; + kernel_process->parent = kernel_process; + kernel_process->pagedir = kernel_pagedir; + kernel_process->next = 0; current_thread = 0; - thread_new(pr, task_idle, 0); - thread_new(pr, whereToGo, data); + thread_new(kernel_process, task_idle, 0); + thread_new(kernel_process, whereToGo, data); sti(); monitor_write("Tasking starting\n"); tasking_switch(); @@ -75,6 +78,15 @@ void tasking_switch() { : : "r"(current_thread->ebp), "r"(current_thread->esp), "r"(current_thread->eip)); } +void tasking_updateKernelPagetable(uint32_t idx, struct page_table *table, uint32_t tablephysical) { + struct process* it = processes; + while (it != 0) { + it->pagedir->tables[idx] = table; + it->pagedir->tablesPhysical[idx] = tablephysical; + it = it->next; + } +} + uint32_t tasking_handleException(struct registers *regs) { if (threads == 0) return 0; //No tasking yet return 0; @@ -87,15 +99,16 @@ static uint32_t thread_runnable(struct thread *t) { } static void thread_run(struct thread *thread, thread_entry entry_point, void *data) { - pagedir_switch(thread->process->pagedir); + pagedir_switch(thread->process->pagedir); //TODO : take into account privilege level asm volatile("sti"); entry_point(data); asm volatile("int $64"); } -void thread_new(struct process *proc, thread_entry entry_point, void *data) { +struct thread *thread_new(struct process *proc, thread_entry entry_point, void *data) { struct thread *t = kmalloc(sizeof(struct thread)); t->process = proc; + proc->threads++; t->kernelStack_addr = kmalloc(KSTACKSIZE); t->kernelStack_size = KSTACKSIZE; @@ -119,5 +132,18 @@ void thread_new(struct process *proc, thread_entry entry_point, void *data) { while (i->next != 0) i = i->next; i->next = t; } + return t; } +struct process *process_new(struct process* parent, uint32_t uid, uint32_t privilege) { + struct process* p = kmalloc(sizeof(struct process)); + p->pid = (nextpid++); + p->uid = uid; + p->threads = 0; + p->privilege = privilege; + p->parent = parent; + p->pagedir = pagedir_new(); + p->next = processes; + processes = p; + return p; +} diff --git a/src/stem/task/task.h b/src/stem/task/task.h index e91aa8b..f59bb2b 100644 --- a/src/stem/task/task.h +++ b/src/stem/task/task.h @@ -6,7 +6,7 @@ #include "idt.h" struct process { - uint32_t pid, uid; + uint32_t pid, uid, privilege, threads; struct process *parent; struct page_directory *pagedir; @@ -17,6 +17,11 @@ struct process { #define TS_SLEEPING 1 //Sleeping for a defined amount of time #define TS_WAIKWAIT 2 //Waiting to be waked up by something precise (thread currently blocked) +#define PL_USER 3 +#define PL_SERVICE 2 +#define PL_DRIVER 1 +#define PL_KERNEL 0 + typedef void (*thread_entry)(void*); struct thread { @@ -34,8 +39,10 @@ extern struct thread *current_thread; void tasking_init(thread_entry whereToGo, void *data); void tasking_switch(); +void tasking_updateKernelPagetable(uint32_t idx, struct page_table *table, uint32_t tablePhysical); uint32_t tasking_handleException(struct registers *regs); -void thread_new(struct process *proc, thread_entry entry_point, void *data); +struct thread * thread_new(struct process *proc, thread_entry entry_point, void *data); +struct process* process_new(struct process *parent, uint32_t uid, uint32_t privilege); #endif |