summaryrefslogtreecommitdiff
path: root/src/stem
diff options
context:
space:
mode:
Diffstat (limited to 'src/stem')
-rw-r--r--src/stem/core/kmain.c12
-rw-r--r--src/stem/core/sys.c2
-rw-r--r--src/stem/lib/stdlib.c18
-rw-r--r--src/stem/mem/paging.c14
-rw-r--r--src/stem/mem/paging.h1
-rw-r--r--src/stem/stem.map432
-rw-r--r--src/stem/task/idt.c6
-rw-r--r--src/stem/task/syscall.c6
-rw-r--r--src/stem/task/task.c108
-rw-r--r--src/stem/task/task.h23
10 files changed, 383 insertions, 239 deletions
diff --git a/src/stem/core/kmain.c b/src/stem/core/kmain.c
index dbec8bd..28c2df7 100644
--- a/src/stem/core/kmain.c
+++ b/src/stem/core/kmain.c
@@ -10,13 +10,21 @@
#include <mem/mem.h>
void kmain_othertask(void *data) {
- while(1) monitor_write("2task ");
+ uint32_t i;
+ for(i = 0; i < 100; i++) {
+ monitor_write("2task ");
+ thread_sleep(0);
+ }
+ process_exit(0);
}
void kmain_stage2(void *data) {
sti();
thread_new(current_thread->process, kmain_othertask, 0);
- while (1) monitor_write("TASK1 ");
+ while (1) {
+ monitor_write("TASK1 ");
+ thread_sleep(0);
+ }
}
void kmain(struct multiboot_info_t* mbd, int32_t magic) {
diff --git a/src/stem/core/sys.c b/src/stem/core/sys.c
index 71d1c31..36ed6d0 100644
--- a/src/stem/core/sys.c
+++ b/src/stem/core/sys.c
@@ -36,6 +36,6 @@ void cli() {
}
void sti() {
- if_locks--;
+ if (if_locks > 0) if_locks--;
if (if_locks == 0) asm volatile("sti");
}
diff --git a/src/stem/lib/stdlib.c b/src/stem/lib/stdlib.c
index 904126e..f4ebd33 100644
--- a/src/stem/lib/stdlib.c
+++ b/src/stem/lib/stdlib.c
@@ -1,12 +1,19 @@
#include "stdlib.h"
-void *memcpy(void *dest, const void *src, int count) {
- int i;
- uint8_t *d = (uint8_t*)dest, *s = (uint8_t*)src;
- for (i = 0; i < count; i++) {
+void *memcpy(void *vd, const void *vs, int count) {
+ uint8_t *dest = vd, *src = vs;
+ uint32_t f = count % 4, n = count / 4, i;
+ const uint32_t* s = (uint32_t*)src;
+ uint32_t* d = (uint32_t*)dest;
+ for (i = 0; i < n; i++) {
d[i] = s[i];
}
- return dest;
+ if (f != 0) {
+ for (i = count - f; i < count; i++) {
+ dest[i] = src[i];
+ }
+ }
+ return vd;
}
uint8_t *memset(uint8_t *dest, uint8_t val, int count) {
@@ -14,6 +21,7 @@ uint8_t *memset(uint8_t *dest, uint8_t val, int count) {
for (i = 0; i < count; i++) {
dest[i] = val;
}
+ return dest;
}
uint16_t *memsetw(uint16_t *dest, uint16_t val, int count) {
diff --git a/src/stem/mem/paging.c b/src/stem/mem/paging.c
index 4cc861c..4d98e75 100644
--- a/src/stem/mem/paging.c
+++ b/src/stem/mem/paging.c
@@ -30,6 +30,7 @@ void paging_init(size_t totalRam) {
frames.bits = kmalloc(INDEX_FROM_BIT(frames.size));
kernel_pagedir = kmalloc(sizeof(struct page_directory));
+ kernel_pagedir->mappedSegs = 0;
kernel_pagedir->tablesPhysical = kmalloc_page(&kernel_pagedir->physicalAddr);
for (i = 0; i < 1024; i++) {
kernel_pagedir->tables[i] = 0;
@@ -73,6 +74,7 @@ struct page_directory *pagedir_new() {
struct page_directory *pd = kmalloc(sizeof(struct page_directory));
pd->tablesPhysical = kmalloc_page(&pd->physicalAddr);
+ pd->mappedSegs = 0;
for (i = 768; i < 1024; i++) {
pd->tables[i] = kernel_pagedir->tables[i];
@@ -82,6 +84,18 @@ struct page_directory *pagedir_new() {
return pd;
}
+void pagedir_delete(struct page_directory *pd) {
+ uint32_t i;
+ //Unmap segments
+ while (pd->mappedSegs != 0) seg_unmap(pd->mappedSegs);
+ //Cleanup page tables
+ for (i = 0; i < 768; i++) {
+ kfree_page(pd->tables[i]);
+ }
+ kfree_page(pd->tablesPhysical);
+ kfree(pd);
+}
+
uint32_t paging_fault(struct registers *regs) {
size_t addr;
struct segment_map *seg = 0;
diff --git a/src/stem/mem/paging.h b/src/stem/mem/paging.h
index 9ee6c4c..cb76cd6 100644
--- a/src/stem/mem/paging.h
+++ b/src/stem/mem/paging.h
@@ -35,6 +35,7 @@ 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);
diff --git a/src/stem/stem.map b/src/stem/stem.map
index a2d1d98..c35b1ee 100644
--- a/src/stem/stem.map
+++ b/src/stem/stem.map
@@ -26,238 +26,242 @@ Linker script and memory map
0x00100000 loader
0xe010003a . = (. + 0xe0000000)
-.text 0xe0100040 0x2eed load address 0x00100040
+.text 0xe0100040 0x3395 load address 0x00100040
*(.text)
.text 0xe0100040 0x25 core/loader_.o
*fill* 0xe0100065 0x3 00
- .text 0xe0100068 0xef core/kmain.o
+ .text 0xe0100068 0x126 core/kmain.o
0xe0100068 kmain_othertask
- 0xe010007c kmain_stage2
- 0xe01000b4 kmain
- *fill* 0xe0100157 0x1 00
- .text 0xe0100158 0xed core/sys.o
- 0xe0100158 outb
- 0xe0100176 outw
- 0xe0100196 inb
- 0xe01001b3 inw
- 0xe01001d2 panic
- 0xe0100216 cli
- 0xe0100229 sti
- *fill* 0xe0100245 0x3 00
- .text 0xe0100248 0x310 core/monitor.o
- 0xe0100359 monitor_put
- 0xe0100465 monitor_clear
- 0xe01004c2 monitor_write
- 0xe01004eb monitor_writeHex
- .text 0xe0100558 0x104 task/timer.o
- 0xe0100558 timer_callback
- 0xe0100590 timer_uptime
- 0xe010059a timer_time
- 0xe01005d1 timer_init
- .text 0xe010065c 0x9fa task/idt.o
- 0xe010065c idt_isrHandler
- 0xe01006f4 idt_irqHandler
- 0xe0100795 idt_syscallHandler
- 0xe0100816 idt_init
- 0xe0101044 idt_handleIrq
- *fill* 0xe0101056 0xa 00
- .text 0xe0101060 0x293 task/idt_.o
- 0xe0101060 gdt_flush
- 0xe010107d idt_flush
- 0xe0101115 isr0
- 0xe010111f isr1
- 0xe0101129 isr2
- 0xe0101133 isr3
- 0xe010113d isr4
- 0xe0101147 isr5
- 0xe0101151 isr6
- 0xe010115b isr7
- 0xe0101165 isr8
- 0xe010116d isr9
- 0xe0101177 isr10
- 0xe010117f isr11
- 0xe0101187 isr12
- 0xe010118f isr13
- 0xe0101197 isr14
- 0xe010119f isr15
- 0xe01011a9 isr16
- 0xe01011b3 isr17
- 0xe01011bd isr18
- 0xe01011c7 isr19
- 0xe01011d1 isr20
- 0xe01011db isr21
- 0xe01011e5 isr22
- 0xe01011ef isr23
- 0xe01011f9 isr24
- 0xe0101203 isr25
- 0xe010120d isr26
- 0xe0101217 isr27
- 0xe0101221 isr28
- 0xe010122b isr29
- 0xe0101235 isr30
- 0xe010123f isr31
- 0xe0101249 irq0
- 0xe0101253 irq1
- 0xe010125d irq2
- 0xe0101267 irq3
- 0xe0101271 irq4
- 0xe010127b irq5
- 0xe0101285 irq6
- 0xe010128f irq7
- 0xe0101299 irq8
- 0xe01012a3 irq9
- 0xe01012ad irq10
- 0xe01012b7 irq11
- 0xe01012c1 irq12
- 0xe01012cb irq13
- 0xe01012d5 irq14
- 0xe01012df irq15
- 0xe01012e9 syscall64
- *fill* 0xe01012f3 0x1 00
- .text 0xe01012f4 0x3dd task/task.o
- 0xe01012f4 tasking_init
- 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
+ 0xe01000a7 kmain_stage2
+ 0xe01000eb kmain
+ *fill* 0xe010018e 0x2 00
+ .text 0xe0100190 0xf6 core/sys.o
+ 0xe0100190 outb
+ 0xe01001ae outw
+ 0xe01001ce inb
+ 0xe01001eb inw
+ 0xe010020a panic
+ 0xe010024e cli
+ 0xe0100261 sti
+ *fill* 0xe0100286 0x2 00
+ .text 0xe0100288 0x310 core/monitor.o
+ 0xe0100399 monitor_put
+ 0xe01004a5 monitor_clear
+ 0xe0100502 monitor_write
+ 0xe010052b monitor_writeHex
+ .text 0xe0100598 0x104 task/timer.o
+ 0xe0100598 timer_callback
+ 0xe01005d0 timer_uptime
+ 0xe01005da timer_time
+ 0xe0100611 timer_init
+ .text 0xe010069c 0xa26 task/idt.o
+ 0xe010069c idt_isrHandler
+ 0xe0100734 idt_irqHandler
+ 0xe01007d5 idt_syscallHandler
+ 0xe0100882 idt_init
+ 0xe01010b0 idt_handleIrq
+ *fill* 0xe01010c2 0xe 00
+ .text 0xe01010d0 0x293 task/idt_.o
+ 0xe01010d0 gdt_flush
+ 0xe01010ed idt_flush
+ 0xe0101185 isr0
+ 0xe010118f isr1
+ 0xe0101199 isr2
+ 0xe01011a3 isr3
+ 0xe01011ad isr4
+ 0xe01011b7 isr5
+ 0xe01011c1 isr6
+ 0xe01011cb isr7
+ 0xe01011d5 isr8
+ 0xe01011dd isr9
+ 0xe01011e7 isr10
+ 0xe01011ef isr11
+ 0xe01011f7 isr12
+ 0xe01011ff isr13
+ 0xe0101207 isr14
+ 0xe010120f isr15
+ 0xe0101219 isr16
+ 0xe0101223 isr17
+ 0xe010122d isr18
+ 0xe0101237 isr19
+ 0xe0101241 isr20
+ 0xe010124b isr21
+ 0xe0101255 isr22
+ 0xe010125f isr23
+ 0xe0101269 isr24
+ 0xe0101273 isr25
+ 0xe010127d isr26
+ 0xe0101287 isr27
+ 0xe0101291 isr28
+ 0xe010129b isr29
+ 0xe01012a5 isr30
+ 0xe01012af isr31
+ 0xe01012b9 irq0
+ 0xe01012c3 irq1
+ 0xe01012cd irq2
+ 0xe01012d7 irq3
+ 0xe01012e1 irq4
+ 0xe01012eb irq5
+ 0xe01012f5 irq6
+ 0xe01012ff irq7
+ 0xe0101309 irq8
+ 0xe0101313 irq9
+ 0xe010131d irq10
+ 0xe0101327 irq11
+ 0xe0101331 irq12
+ 0xe010133b irq13
+ 0xe0101345 irq14
+ 0xe010134f irq15
+ 0xe0101359 syscall64
+ *fill* 0xe0101363 0x1 00
+ .text 0xe0101364 0x6f6 task/task.o
+ 0xe0101364 tasking_init
+ 0xe01014af tasking_switch
+ 0xe0101556 tasking_updateKernelPagetable
+ 0xe01015a0 tasking_handleException
+ 0xe0101611 thread_sleep
+ 0xe01016f5 thread_exit
+ 0xe0101709 process_exit
+ 0xe01017a5 thread_new
+ 0xe010189a process_new
+ *fill* 0xe0101a5a 0x6 00
+ .text 0xe0101a60 0xa task/task_.o
+ 0xe0101a60 read_eip
+ 0xe0101a63 task_idle
+ *fill* 0xe0101a6a 0x2 00
+ .text 0xe0101a6c 0x66 task/syscall.o
+ *fill* 0xe0101ad2 0x2 00
+ .text 0xe0101ad4 0x13a lib/stdlib.o
+ 0xe0101ad4 memcpy
+ 0xe0101b7e memset
+ 0xe0101bb0 memsetw
+ 0xe0101be6 strlen
+ *fill* 0xe0101c0e 0x2 00
+ .text 0xe0101c10 0x173 lib/bitset.o
+ 0xe0101c10 bitset_set
+ 0xe0101c64 bitset_clear
+ 0xe0101cba bitset_test
+ 0xe0101cfc bitset_firstFree
+ *fill* 0xe0101d83 0x1 00
+ .text 0xe0101d84 0x29f mem/mem.o
+ 0xe0101eea kmalloc_page
+ 0xe0101f31 kfree_page
+ 0xe0101f6c kheap_init
+ 0xe0101fc1 kmalloc
+ 0xe0101fff kfree
+ *fill* 0xe0102023 0x1 00
+ .text 0xe0102024 0x6cc mem/paging.o
+ 0xe0102024 frame_alloc
+ 0xe0102051 frame_free
+ 0xe010206c paging_init
+ 0xe0102213 paging_cleanup
+ 0xe010226e pagedir_switch
+ 0xe010229d pagedir_new
+ 0xe0102332 pagedir_delete
+ 0xe010239d paging_fault
+ 0xe01024ea pagedir_getPage
+ 0xe0102601 page_map
+ 0xe0102689 page_unmap
+ 0xe01026ac page_unmapFree
+ .text 0xe01026f0 0x19f mem/gdt.o
+ 0xe010277f gdt_init
+ *fill* 0xe010288f 0x1 00
+ .text 0xe0102890 0x858 mem/heap.o
+ 0xe0102a20 heap_create
+ 0xe0102df3 heap_alloc
+ 0xe0102f54 heap_free
+ .text 0xe01030e8 0x2ed mem/seg.o
+ 0xe01030e8 seg_map
+ 0xe0103156 seg_unmap
+ 0xe0103235 simpleseg_make
+ 0xe01032b2 simpleseg_map
+ 0xe01032e8 simpleseg_unmap
+ 0xe010333b simpleseg_handleFault
+ 0xe01033d0 simpleseg_delete
-.iplt 0xe0102f30 0x0 load address 0x00102f2d
+.iplt 0xe01033d8 0x0 load address 0x001033d5
.iplt 0x00000000 0x0 core/loader_.o
-.rodata 0xe0103000 0x1a3 load address 0x00103000
+.rodata 0xe0104000 0x395 load address 0x00104000
*(.rodata)
- .rodata 0xe0103000 0x52 core/kmain.o
- .rodata 0xe0103052 0x2c core/sys.o
- .rodata 0xe010307e 0xf task/timer.o
- *fill* 0xe010308d 0x3 00
- .rodata 0xe0103090 0x78 task/idt.o
- .rodata 0xe0103108 0x12 task/task.o
- .rodata 0xe010311a 0x10 mem/mem.o
- .rodata 0xe010312a 0x71 mem/paging.o
- .rodata 0xe010319b 0x8 mem/gdt.o
+ .rodata 0xe0104000 0x52 core/kmain.o
+ .rodata 0xe0104052 0x2c core/sys.o
+ .rodata 0xe010407e 0xf task/timer.o
+ *fill* 0xe010408d 0x3 00
+ .rodata 0xe0104090 0x8a task/idt.o
+ *fill* 0xe010411a 0x6 00
+ .rodata 0xe0104120 0x1ec task/task.o
+ .rodata 0xe010430c 0x10 mem/mem.o
+ .rodata 0xe010431c 0x71 mem/paging.o
+ .rodata 0xe010438d 0x8 mem/gdt.o
-.rel.dyn 0xe01031a4 0x0 load address 0x001031a3
+.rel.dyn 0xe0104398 0x0 load address 0x00104395
.rel.iplt 0x00000000 0x0 core/loader_.o
.rel.text 0x00000000 0x0 core/loader_.o
-.data 0xe0104000 0x24 load address 0x00104000
+.data 0xe0105000 0x24 load address 0x00105000
*(.data)
- .data 0xe0104000 0x0 core/kmain.o
- .data 0xe0104000 0x4 core/sys.o
- .data 0xe0104004 0x4 core/monitor.o
- .data 0xe0104008 0x0 task/timer.o
- .data 0xe0104008 0x0 task/idt.o
- .data 0xe0104008 0x4 task/task.o
- .data 0xe010400c 0x18 task/syscall.o
- 0xe010400c syscalls
- .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
+ .data 0xe0105000 0x0 core/kmain.o
+ .data 0xe0105000 0x4 core/sys.o
+ .data 0xe0105004 0x4 core/monitor.o
+ .data 0xe0105008 0x0 task/timer.o
+ .data 0xe0105008 0x0 task/idt.o
+ .data 0xe0105008 0x4 task/task.o
+ .data 0xe010500c 0x18 task/syscall.o
+ 0xe010500c syscalls
+ .data 0xe0105024 0x0 lib/stdlib.o
+ .data 0xe0105024 0x0 lib/bitset.o
+ .data 0xe0105024 0x0 mem/mem.o
+ .data 0xe0105024 0x0 mem/paging.o
+ .data 0xe0105024 0x0 mem/gdt.o
+ .data 0xe0105024 0x0 mem/heap.o
+ .data 0xe0105024 0x0 mem/seg.o
-.igot.plt 0xe0104024 0x0 load address 0x00104024
+.igot.plt 0xe0105024 0x0 load address 0x00105024
.igot.plt 0x00000000 0x0 core/loader_.o
-.bss 0xe0104040 0x10970 load address 0x00104040
- 0xe0104040 sbss = .
+.bss 0xe0105040 0x10970 load address 0x00105040
+ 0xe0105040 sbss = .
*(COMMON)
- 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
+ COMMON 0xe0105040 0x820 task/idt.o
+ 0xe0105040 idt_ptr
+ 0xe0105060 idt_entries
+ COMMON 0xe0105860 0x10008 task/task.o
+ 0xe0105860 tasking_tmpStack
+ 0xe0115860 kernel_process
+ 0xe0115864 idle_thread
+ COMMON 0xe0115868 0x4 mem/mem.o
+ 0xe0115868 mem_placementAddr
+ COMMON 0xe011586c 0x8 mem/paging.o
+ 0xe011586c current_pagedir
+ 0xe0115870 kernel_pagedir
*(.bss)
- .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 = .
+ .bss 0xe0115874 0x0 core/kmain.o
+ .bss 0xe0115874 0x0 core/sys.o
+ .bss 0xe0115874 0x8 core/monitor.o
+ .bss 0xe011587c 0xc task/timer.o
+ *fill* 0xe0115888 0x18 00
+ .bss 0xe01158a0 0x40 task/idt.o
+ .bss 0xe01158e0 0xc task/task.o
+ 0xe01158e0 processes
+ 0xe01158e4 threads
+ 0xe01158e8 current_thread
+ .bss 0xe01158ec 0x0 task/syscall.o
+ .bss 0xe01158ec 0x0 lib/stdlib.o
+ .bss 0xe01158ec 0x0 lib/bitset.o
+ *fill* 0xe01158ec 0x14 00
+ .bss 0xe0115900 0x60 mem/mem.o
+ 0xe0115900 freepagecount
+ .bss 0xe0115960 0x8 mem/paging.o
+ *fill* 0xe0115968 0x18 00
+ .bss 0xe0115980 0x2e mem/gdt.o
+ *fill* 0xe01159ae 0x2 00
+ .bss 0xe01159b0 0x0 mem/heap.o
+ .bss 0xe01159b0 0x0 mem/seg.o
+ 0xe01159b0 ebss = .
+ 0xe01159b0 end = .
+ 0xe01159b0 _end = .
+ 0xe01159b0 __end = .
LOAD core/loader_.o
LOAD core/kmain.o
LOAD core/sys.o
diff --git a/src/stem/task/idt.c b/src/stem/task/idt.c
index 4866550..360ac91 100644
--- a/src/stem/task/idt.c
+++ b/src/stem/task/idt.c
@@ -95,7 +95,11 @@ void idt_irqHandler(struct registers regs) {
}
void idt_syscallHandler(struct registers regs) {
- syscalls[regs.eax](&regs);
+ if (syscalls[regs.eax] != 0) {
+ syscalls[regs.eax](&regs);
+ } else {
+ PANIC("unhandled syscall");
+ }
}
static void idt_setGate(uint8_t num, uint32_t base, uint16_t sel, uint8_t flags) {
diff --git a/src/stem/task/syscall.c b/src/stem/task/syscall.c
index 6964b34..0878b30 100644
--- a/src/stem/task/syscall.c
+++ b/src/stem/task/syscall.c
@@ -6,13 +6,15 @@
#define CALL2(name, scname) static void scname(struct registers* r) { \
r->eax = name(r->ebx, r->ecx); }
+CALL0(thread_exit, thread_exit_sc);
CALL0(tasking_switch, schedule_sc);
+CALL1(process_exit, process_exit_sc);
CALL1(monitor_write, printk_sc);
int_callback syscalls[] = {
- 0, //Syscall 0 will be thread_exit
+ thread_exit_sc,
schedule_sc,
0, //Syscall 2 will be thread_sleep
- 0, //Syscall 3 will be process_exit
+ process_exit_sc,
printk_sc,
0 };
diff --git a/src/stem/task/task.c b/src/stem/task/task.c
index 8ed5190..5ab001c 100644
--- a/src/stem/task/task.c
+++ b/src/stem/task/task.c
@@ -6,6 +6,12 @@
#define KSTACKSIZE 0x8000
+//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);
+
//From task_.asm
extern uint32_t read_eip();
extern void task_idle(void*);
@@ -28,15 +34,16 @@ void tasking_init(thread_entry whereToGo, void *data) {
kernel_process->pagedir = kernel_pagedir;
kernel_process->next = 0;
current_thread = 0;
- thread_new(kernel_process, task_idle, 0);
+ idle_thread = thread_new(kernel_process, task_idle, 0);
+ threads = 0; //Do not include idle thread in threads
thread_new(kernel_process, whereToGo, data);
sti();
monitor_write("Tasking starting\n");
tasking_switch();
}
-static struct thread *thread_next() { //NOT OPTIMAL : will allocate time slices to idle thread even if busy
- if (current_thread == 0) current_thread = threads;
+static struct thread *thread_next() {
+ if (current_thread == 0 || current_thread == idle_thread) current_thread = threads;
struct thread *ret = current_thread;
while (1) {
ret = ret->next;
@@ -44,12 +51,13 @@ static struct thread *thread_next() { //NOT OPTIMAL : will allocate time slices
if (thread_runnable(ret)) {
return ret;
}
+ if (ret == current_thread) return idle_thread;
}
}
void tasking_switch() {
- if (threads == 0) return; //no tasking yet
- cli();
+ if (threads == 0) PANIC("No more threads to run !");
+ asm volatile("cli");
uint32_t esp, ebp, eip;
@@ -89,9 +97,65 @@ void tasking_updateKernelPagetable(uint32_t idx, struct page_table *table, uint3
uint32_t tasking_handleException(struct registers *regs) {
if (threads == 0) return 0; //No tasking yet
+ monitor_write("\nUnhandled exception : ");
+ char *exception_messages[] = {"Division By Zero","Debug","Non Maskable Interrupt","Breakpoint",
+ "Into Detected Overflow","Out of Bounds","Invalid Opcode","No Coprocessor", "Double Fault",
+ "Coprocessor Segment Overrun","Bad TSS","Segment Not Present","Stack Fault","General Protection Fault",
+ "Page Fault","Unknown Interrupt","Coprocessor Fault","Alignment Check","Machine Check"};
+ monitor_write(exception_messages[regs->int_no]);
+ monitor_write("\nThread exiting.\n");
+ thread_exit_stackJmp(EX_TH_EXCEPTION);
return 0;
}
+void thread_sleep(uint32_t msecs) {
+ if (current_thread == 0) return;
+ current_thread->state = TS_SLEEPING;
+ current_thread->timeWait = timer_time() + msecs;
+ asm volatile("int $64" : : "a"(1));
+}
+
+void thread_exit2(uint32_t reason) { //See EX_TH_* defines in task.h
+ /*
+ * if reason == EX_TH_NORMAL, it is just one thread exiting because it has to
+ * 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;
+ struct process *pr = th->process;
+ if ((reason == EX_TH_NORMAL || reason == EX_TH_EXCEPTION) && pr->threads > 1) {
+ thread_delete(th);
+ } else {
+ process_delete(pr);
+ }
+ sti();
+ tasking_switch();
+}
+
+void thread_exit_stackJmp(uint32_t reason) {
+ uint32_t *stack;
+ cli();
+ stack = tasking_tmpStack + 0x4000;
+ stack--; *stack = reason;
+ stack--; *stack = 0;
+ asm volatile(" \
+ mov %0, %%esp; \
+ mov %1, %%ebp; \
+ mov %2, %%ecx; \
+ mov %3, %%cr3; \
+ jmp *%%ecx;" : :
+ "r"(stack), "r"(stack), "r"(thread_exit2), "r"(kernel_pagedir->physicalAddr));
+}
+
+void thread_exit() {
+ thread_exit_stackJmp(EX_TH_NORMAL);
+}
+
+void process_exit(uint32_t retval) {
+ if (retval == EX_TH_NORMAL || retval == EX_TH_EXCEPTION) retval = EX_PR_EXCEPTION;
+ thread_exit_stackJmp(retval);
+}
+
static uint32_t thread_runnable(struct thread *t) {
if (t->state == TS_RUNNING) return 1;
if (t->state == TS_SLEEPING && timer_time() >= t->timeWait) return 1;
@@ -102,7 +166,7 @@ static void thread_run(struct thread *thread, thread_entry entry_point, void *da
pagedir_switch(thread->process->pagedir); //TODO : take into account privilege level
asm volatile("sti");
entry_point(data);
- asm volatile("int $64");
+ thread_exit(0);
}
struct thread *thread_new(struct process *proc, thread_entry entry_point, void *data) {
@@ -147,3 +211,35 @@ struct process *process_new(struct process* parent, uint32_t uid, uint32_t privi
processes = p;
return p;
}
+
+static void thread_delete(struct thread *th) {
+ kfree(th->kernelStack_addr);
+ th->process->threads--;
+ if (threads == th) {
+ threads = th->next;
+ } else {
+ struct thread *it = threads;
+ while (it->next != th && it->next != 0) it = it->next;
+ if (it->next == th) it->next = th->next;
+ }
+ kfree(th);
+}
+
+static void process_delete(struct process *pr) {
+ struct thread *it;
+ while (threads->process == pr) thread_delete(threads);
+ it = threads;
+ while (it != 0) {
+ while (it->next->process == pr) thread_delete(it->next);
+ it = it->next;
+ }
+ pagedir_delete(pr->pagedir);
+ if (processes == pr) {
+ processes = pr->next;
+ } else {
+ struct process *it = processes;
+ while (it != 0 && it->next != pr) it = it->next;
+ if (it != 0 && it->next == pr) it->next = pr->next;
+ }
+ kfree(pr);
+}
diff --git a/src/stem/task/task.h b/src/stem/task/task.h
index f59bb2b..1d1d121 100644
--- a/src/stem/task/task.h
+++ b/src/stem/task/task.h
@@ -5,14 +5,6 @@
#include <mem/paging.h>
#include "idt.h"
-struct process {
- uint32_t pid, uid, privilege, threads;
- struct process *parent;
- struct page_directory *pagedir;
-
- struct process *next; //Forms a linked list
-};
-
#define TS_RUNNING 0
#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)
@@ -22,8 +14,20 @@ struct process {
#define PL_DRIVER 1
#define PL_KERNEL 0
+#define EX_TH_NORMAL 0x10000 //ERROR code : just one thread exits, because it has to
+#define EX_TH_EXCEPTION 0x10001 //ERROR code : just one thread exits, because of an unhandled exception
+#define EX_PR_EXCEPTION 0x10002 //ERROR code : all process finishes, because of an unhandled exception
+
typedef void (*thread_entry)(void*);
+struct process {
+ uint32_t pid, uid, privilege, threads;
+ struct process *parent;
+ struct page_directory *pagedir;
+
+ struct process *next; //Forms a linked list
+};
+
struct thread {
struct process *process;
uint32_t esp, ebp, eip;
@@ -42,6 +46,9 @@ 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_sleep(uint32_t msecs);
+void thread_exit();
+void process_exit(uint32_t retval);
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);