diff options
author | Freya Murphy <freya@freyacat.org> | 2025-04-03 12:31:21 -0400 |
---|---|---|
committer | Freya Murphy <freya@freyacat.org> | 2025-04-03 12:31:21 -0400 |
commit | a524eb3846aac4d1b38f08cba49ff3503107042f (patch) | |
tree | dbe81fccf975f646a681e4fdcebd227cdfb98774 /ulib | |
parent | new libs (diff) | |
download | comus-a524eb3846aac4d1b38f08cba49ff3503107042f.tar.gz comus-a524eb3846aac4d1b38f08cba49ff3503107042f.tar.bz2 comus-a524eb3846aac4d1b38f08cba49ff3503107042f.zip |
move old kernel code (for now) into kernel/old, trying to get long mode
Diffstat (limited to 'ulib')
-rw-r--r-- | ulib/entry.S | 25 | ||||
-rw-r--r-- | ulib/spawn.c | 32 | ||||
-rw-r--r-- | ulib/syscall.S | 93 |
3 files changed, 150 insertions, 0 deletions
diff --git a/ulib/entry.S b/ulib/entry.S new file mode 100644 index 0000000..87ad9c7 --- /dev/null +++ b/ulib/entry.S @@ -0,0 +1,25 @@ +// +// user-level startup routine +// + .text + .globl _start + .globl main + .globl exit + +// entry point - this is where the kernel starts us running +_start: + // we immediately call main() + call main + + // if we come back from that, it means the user + // program didn't call exit(), in which case the + // value returned from main() is the exit status + + // push that value onto the stack and call exit() + subl $12, %esp + pushl %eax + call exit + + // if we come back from that, something bad has + // happened, so we just lock up +1: jmp 1b diff --git a/ulib/spawn.c b/ulib/spawn.c new file mode 100644 index 0000000..78b1a53 --- /dev/null +++ b/ulib/spawn.c @@ -0,0 +1,32 @@ +#include <stdio.h> +#include <error.h> +#include <unistd.h> + +int wait(int32_t *status) +{ + return (waitpid(0, status)); +} + +int spawn(uint_t prog, char **args) +{ + int32_t pid; + + pid = fork(); + if (pid != 0) { + // failure, or we are the parent + return (pid); + } + + // we are the child + pid = getpid(); + + // child inherits parent's priority level + + exec(prog, args); + + // uh-oh.... + + fprintf(stderr, "Child %d exec() #%u failed\n", pid, prog); + + exit(EXIT_FAILURE); +} diff --git a/ulib/syscall.S b/ulib/syscall.S new file mode 100644 index 0000000..46fcb89 --- /dev/null +++ b/ulib/syscall.S @@ -0,0 +1,93 @@ +/** +** @file ulibs.S +** +** @author CSCI-452 class of 20245 +** +** @brief assembly-language user-level library functions +*/ + +#define ASM_SRC + +// get the system call codes + +#include <syscalls.h> + +/** +** System call stubs +** +** All have the same structure: +** +** move a code into EAX +** generate the interrupt +** return to the caller +** +** As these are simple "leaf" routines, we don't use +** the standard enter/leave method to set up a stack +** frame - that takes time, and we don't really need it. +** +** Could be modified to use the UNIX/Linux convention of +** having the syscall code set the 'C' flag to indicate that +** the value being returned in %EAX is an error code: +** +** ... +** int $VEC_SYSCALL +** jc set_errno +** ret +** ... +** +** .globl errno +** set_errno: +** movl %eax, errno +** movl $-1, %eax +** ret +*/ + +#define SYSCALL(name) \ + .globl name ; \ +name: ; \ + movl $SYS_##name, %eax ; \ + int $VEC_SYSCALL ; \ + ret + +/* +** "real" system calls +*/ + +SYSCALL(exit) +SYSCALL(waitpid) +SYSCALL(fork) +SYSCALL(exec) +SYSCALL(read) +SYSCALL(write) +SYSCALL(getpid) +SYSCALL(getppid) +SYSCALL(gettime) +SYSCALL(getprio) +SYSCALL(setprio) +SYSCALL(kill) +SYSCALL(sleep) + +/* +** This is a bogus system call; it's here so that we can test +** our handling of out-of-range syscall codes in the syscall ISR. +*/ +SYSCALL(bogus) + +/* +** Other library functions +*/ + +/** +** fake_exit() +** +** Dummy "startup" function +** +** calls exit(%eax) - serves as the "return to" code for +** main() functions, in case they don't call exit() themselves +*/ + + .globl fake_exit +fake_exit: + // alternate: could push a "fake exit" status + pushl %eax // termination status returned by main() + call exit // terminate this process |