summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordzwdz2022-08-30 11:01:28 +0200
committerdzwdz2022-08-30 11:01:28 +0200
commit7cccc1fb9951f91d91fe72114b39585e5b428384 (patch)
treeb6d68254978c26ec341f047b3312a86935faebac /src
parent69d7da4945448f4a6901b085e746e977359f465c (diff)
set up the stack in user/bootstrap instead of the kernel
Diffstat (limited to 'src')
-rw-r--r--src/kernel/proc.c5
-rw-r--r--src/kernel/syscalls.c9
-rw-r--r--src/user/bootstrap/entry.S27
-rw-r--r--src/user/bootstrap/main.c6
4 files changed, 34 insertions, 13 deletions
diff --git a/src/kernel/proc.c b/src/kernel/proc.c
index 7b8e659..71d1f44 100644
--- a/src/kernel/proc.c
+++ b/src/kernel/proc.c
@@ -29,11 +29,6 @@ struct process *process_seed(void *data, size_t datalen) {
process_first->id = next_pid++;
process_first->_handles = kzalloc(sizeof(struct handle) * HANDLE_MAX);
- // map the stack to the last page in memory
- // TODO move to user bootstrap
- pagedir_map(process_first->pages, (userptr_t)~PAGE_MASK, page_zalloc(1), true, true);
- process_first->regs.rsp = (userptr_t) ~0xF;
-
// map .shared
extern char _shared_len;
for (size_t p = 0; p < (size_t)&_shared_len; p += PAGE_SIZE)
diff --git a/src/kernel/syscalls.c b/src/kernel/syscalls.c
index 9f77679..37a0ce3 100644
--- a/src/kernel/syscalls.c
+++ b/src/kernel/syscalls.c
@@ -317,17 +317,18 @@ void __user *_syscall_memflag(void __user *addr, size_t len, int flags) {
}
- for (userptr_t iter = addr; iter < addr + len; iter += PAGE_SIZE) {
- if (pagedir_iskern(pages, iter)) {
+ for (size_t off = 0; off < len; off += PAGE_SIZE) {
+ userptr_t page = addr + off;
+ if (pagedir_iskern(pages, page)) {
// TODO reflect failure in return value
continue;
}
- phys = pagedir_virt2phys(pages, iter, false, false);
+ phys = pagedir_virt2phys(pages, page, false, false);
if (!phys) {
// TODO test zeroing of user pages
phys = page_zalloc(1);
- pagedir_map(pages, iter, phys, true, true);
+ pagedir_map(pages, page, phys, true, true);
}
}
SYSCALL_RETURN((uintptr_t)addr);
diff --git a/src/user/bootstrap/entry.S b/src/user/bootstrap/entry.S
new file mode 100644
index 0000000..ecd60dd
--- /dev/null
+++ b/src/user/bootstrap/entry.S
@@ -0,0 +1,27 @@
+#define ASM_FILE 1
+#include <camellia/syscalls.h>
+#include <camellia/flags.h>
+
+.set STACK_TOP, 0xFFFFFFFFFFFFFFFF
+.set STACK_PAGES, 4
+
+.section .text.startup
+.global _start
+.type _start, @function
+_start:
+ mov $_SYSCALL_MEMFLAG, %rdi
+ mov $(STACK_TOP & ~0xFFF - (STACK_PAGES - 1) * 0x1000), %rsi
+ mov $(STACK_PAGES * 0x1000), %rdx
+ mov $MEMFLAG_PRESENT, %r10
+ syscall
+ mov $(STACK_TOP & ~0xF), %rsp
+
+ mov $_SYSCALL_MEMFLAG, %rdi
+ mov $_bss_start, %rsi
+ mov $_bss_end, %rdx
+ sub $_bss_start, %rdx
+ mov $MEMFLAG_PRESENT, %r10
+ mov %rsp, %r8
+ syscall
+
+ jmp main
diff --git a/src/user/bootstrap/main.c b/src/user/bootstrap/main.c
index ea92af6..a0885dd 100644
--- a/src/user/bootstrap/main.c
+++ b/src/user/bootstrap/main.c
@@ -11,10 +11,8 @@ extern char _bss_start;
extern char _bss_end;
extern char _initrd;
-__attribute__((section(".text.startup")))
-void _start(void) {
- _syscall_memflag(&_bss_start, &_bss_end - &_bss_start, MEMFLAG_PRESENT);
-
+__attribute__((section(".text")))
+_Noreturn void main(void) {
/* move everything provided by the kernel to /kdev */
MOUNT_AT("/kdev/") { fs_passthru(NULL); }
MOUNT_AT("/") {