summaryrefslogtreecommitdiff
path: root/ulib
diff options
context:
space:
mode:
authorFreya Murphy <freya@freyacat.org>2025-04-03 12:31:21 -0400
committerFreya Murphy <freya@freyacat.org>2025-04-03 12:31:21 -0400
commita524eb3846aac4d1b38f08cba49ff3503107042f (patch)
treedbe81fccf975f646a681e4fdcebd227cdfb98774 /ulib
parentnew libs (diff)
downloadcomus-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.S25
-rw-r--r--ulib/spawn.c32
-rw-r--r--ulib/syscall.S93
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