summaryrefslogtreecommitdiff
path: root/user/lib
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--user/lib/alloc.c15
-rw-r--r--user/lib/entry.S26
-rw-r--r--user/lib/fread.c65
-rw-r--r--user/lib/fwrite.c57
-rw-r--r--user/lib/printf.c40
-rw-r--r--user/lib/spawn.c32
-rw-r--r--user/lib/syscall.S111
-rw-r--r--user/lib/timetostr.c143
8 files changed, 166 insertions, 323 deletions
diff --git a/user/lib/alloc.c b/user/lib/alloc.c
index 49c762b..3d987d4 100644
--- a/user/lib/alloc.c
+++ b/user/lib/alloc.c
@@ -21,6 +21,19 @@ static const size_t header_len = sizeof(struct page_header);
static struct page_header *start_header = NULL;
static struct page_header *end_header = NULL;
+static void *alloc_pages(size_t pages)
+{
+ (void)pages;
+ // TODO: impl
+ return NULL;
+}
+
+static void free_pages(struct page_header *header)
+{
+ (void)header;
+ // TODO: impl
+}
+
static struct page_header *get_header(void *ptr)
{
struct page_header *header =
@@ -39,7 +52,6 @@ static void *alloc_new(size_t size)
{
size_t pages = ((size + header_len) / PAGE_SIZE) + 1;
- // FIXME: use brk/sbrk
void *addr = alloc_pages(pages);
void *mem = (char *)addr + header_len;
@@ -209,7 +221,6 @@ void free(void *ptr)
header->next->prev = header->prev;
if (header->prev)
header->prev->next = header->next;
- // FIXME: use brk/sbrk
free_pages(header);
}
}
diff --git a/user/lib/entry.S b/user/lib/entry.S
index 87ad9c7..34390a0 100644
--- a/user/lib/entry.S
+++ b/user/lib/entry.S
@@ -1,25 +1,15 @@
-//
-// user-level startup routine
-//
- .text
.globl _start
- .globl main
- .globl exit
+ .extern main
+ .extern exit
-// entry point - this is where the kernel starts us running
+ .section .text
+ .code64
_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
+ subq $16, %rsp # ???
+ pushq %rax
call exit
- // if we come back from that, something bad has
- // happened, so we just lock up
-1: jmp 1b
+halt:
+ jmp halt
diff --git a/user/lib/fread.c b/user/lib/fread.c
new file mode 100644
index 0000000..f8d0ad8
--- /dev/null
+++ b/user/lib/fread.c
@@ -0,0 +1,65 @@
+#include <stdio.h>
+#include <unistd.h>
+
+FILE *stdin = (void *)0;
+
+int getchar(void)
+{
+ return fgetc(stdin);
+}
+
+int getc(FILE *stream)
+{
+ return fgetc(stream);
+}
+
+int fgetc(FILE *stream)
+{
+ int c;
+ if (fread(&c, 1, 1, stream) < 1)
+ return EOF;
+ return c;
+}
+
+char *gets(char *str)
+{
+ char *s = str;
+ while (1) {
+ char c = fgetc(stdin);
+ if (c == '\n' || c == EOF || c == '\0')
+ break;
+ *(str++) = c;
+ }
+ *str = '\0';
+ return s;
+}
+
+char *fgets(char *restrict str, int size, FILE *stream)
+{
+ if (size < 1)
+ return NULL;
+
+ char *s = str;
+ while (size > 1) {
+ char c = fgetc(stream);
+ if (c == '\n' || c == EOF || c == '\0')
+ break;
+ *(str++) = c;
+ size--;
+ }
+
+ *str = '\0';
+ return s;
+}
+
+size_t fread(void *restrict ptr, size_t size, size_t n, FILE *restrict stream)
+{
+ int fd = (uintptr_t)stream;
+ char *restrict buf = ptr;
+
+ for (size_t i = 0; i < n; i++)
+ if (read(fd, buf + i * size, size) < 1)
+ return i;
+
+ return n;
+}
diff --git a/user/lib/fwrite.c b/user/lib/fwrite.c
new file mode 100644
index 0000000..aa828e0
--- /dev/null
+++ b/user/lib/fwrite.c
@@ -0,0 +1,57 @@
+#include <stdio.h>
+#include <unistd.h>
+
+FILE *stdout = (void *)1;
+
+int putchar(int c)
+{
+ return putc(c, stdout);
+}
+
+int putc(int c, FILE *stream)
+{
+ return fputc(c, stream);
+}
+
+int fputc(int c, FILE *stream)
+{
+ if (fwrite(&c, 1, 1, stream) < 1)
+ return EOF;
+ return c;
+}
+
+int puts(const char *str)
+{
+ int res;
+ res = fputs(str, stdout);
+ if (res == EOF)
+ return res;
+ res = fputc('\n', stdout);
+ if (res == EOF)
+ return res;
+ return 0;
+}
+
+int fputs(const char *str, FILE *stream)
+{
+ int res;
+ while (*str) {
+ res = fputc(*str++, stream);
+ if (res == EOF)
+ return res;
+ }
+ return 0;
+}
+
+size_t fwrite(const void *restrict ptr, size_t size, size_t n,
+ FILE *restrict stream)
+{
+ int fd = (uintptr_t)stream;
+ const char *restrict buf = ptr;
+
+ for (size_t i = 0; i < n; i++)
+ if (write(fd, buf + i * size, size) < 1)
+ return i;
+
+ return n;
+}
diff --git a/user/lib/printf.c b/user/lib/printf.c
index 65d7f0f..e6abd09 100644
--- a/user/lib/printf.c
+++ b/user/lib/printf.c
@@ -7,6 +7,7 @@
#include <stdarg.h>
#define PRINTF_NUMERIC_BUF_LEN 50
+#define PRINTF_BUFFER_LEN 256
typedef union {
unsigned long long int u;
@@ -620,42 +621,3 @@ int vfprintf(FILE *stream, const char *format, va_list args)
do_printf(&ctx, args);
return ctx.written_len;
}
-
-int putchar(int c)
-{
- return putc(c, stdout);
-}
-
-int putc(int c, FILE *stream)
-{
- return fputc(c, stream);
-}
-
-int fputc(int c, FILE *stream)
-{
- // TODO: a
- return c;
-}
-
-int puts(const char *str)
-{
- int res;
- res = fputs(str, stdout);
- if (res == EOF)
- return res;
- res = fputc('\n', stdout);
- if (res == EOF)
- return res;
- return 0;
-}
-
-int fputs(const char *str, FILE *stream)
-{
- int res;
- while (*str) {
- res = fputc(*str++, stream);
- if (res == EOF)
- return res;
- }
- return 0;
-}
diff --git a/user/lib/spawn.c b/user/lib/spawn.c
deleted file mode 100644
index 78b1a53..0000000
--- a/user/lib/spawn.c
+++ /dev/null
@@ -1,32 +0,0 @@
-#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/user/lib/syscall.S b/user/lib/syscall.S
index 46fcb89..fc1ab93 100644
--- a/user/lib/syscall.S
+++ b/user/lib/syscall.S
@@ -1,93 +1,26 @@
-/**
-** @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 ; \
+.macro SYSCALL name num
+ .align 8
+ .globl \name
+\name:
+ movq $\num, %rax
+ int $VEC_SYSCALL
ret
+.endm
-/*
-** "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
+SYSCALL exit SYS_exit
+SYSCALL waitpid SYS_waitpid
+SYSCALL fork SYS_fork
+SYSCALL exec SYS_exec
+SYSCALL read SYS_read
+SYSCALL write SYS_write
+SYSCALL getpid SYS_getpid
+SYSCALL getppid SYS_getppid
+SYSCALL gettime SYS_gettime
+SYSCALL getprio SYS_getprio
+SYSCALL setprio SYS_setprio
+SYSCALL kill SYS_kill
+SYSCALL sleep SYS_sleep
+SYSCALL brk SYS_brk
+SYSCALL sbrk SYS_sbrk
diff --git a/user/lib/timetostr.c b/user/lib/timetostr.c
deleted file mode 100644
index fa77362..0000000
--- a/user/lib/timetostr.c
+++ /dev/null
@@ -1,143 +0,0 @@
-#include <lib.h>
-#include <time.h>
-
-static char *ABB_WEEKDAY[7] = {
- "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
-};
-
-static char *FULL_WEEKDAY[7] = { "Sunday", "Monday", "Tuesday", "Wednesday",
- "Thursday", "Friday", "Saturady" };
-
-static char *ABB_MONTH[12] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
- "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
-
-static char *FULL_MONTH[12] = {
- "January", "Feburary", "March", "April", "May", "June",
- "July", "August", "September", "October", "November", "December"
-};
-
-static char *write_num(unsigned int num, unsigned int pad, char *buf, size_t n)
-{
- size_t digits = 1;
- unsigned int x = num;
-
- while (x /= 10, x > 0)
- digits++;
- if (pad == 0)
- pad = digits;
-
- for (size_t i = 0; i < pad; i++) {
- size_t digit;
- if (i >= digits) {
- digit = 0;
- } else {
- digit = num % 10;
- num /= 10;
- }
-
- if (pad - i - 1 >= n)
- continue;
- buf[pad - i - 1] = '0' + digit;
- }
-
- if (pad > n)
- pad = n;
-
- return buf + pad;
-}
-
-void timetostr(time_t *time, char *format, char *buf, size_t n)
-{
- char *index = buf;
- char c;
- int space;
-
- while (c = *format++, space = (buf + n) - index, c != '\0' && space > 0) {
- if (c != '%') {
- *index++ = c;
- continue;
- } else {
- c = *format++;
- }
-
- switch (c) {
- case '%':
- *index++ = '%';
- break;
- case 'a':
- index = strncpy(index, ABB_WEEKDAY[time->wday], space);
- break;
- case 'A':
- index = strncpy(index, FULL_WEEKDAY[time->wday], space);
- break;
- case 'b':
- case 'h':
- index = strncpy(index, ABB_MONTH[time->mon], space);
- break;
- case 'B':
- index = strncpy(index, FULL_MONTH[time->mon], space);
- break;
- case 'C':
- index = write_num(time->cen, 0, index, space);
- break;
- case 'd':
- index = write_num(time->mday, 2, index, space);
- break;
- case 'H':
- index = write_num(time->hour, 2, index, space);
- break;
- case 'I':
- index = write_num((time->hour + 12) % 12 + 1, 2, index, space);
- break;
- case 'j':
- index = write_num(time->yday, 3, index, space);
- break;
- case 'm':
- index = write_num(time->mon + 1, 2, index, space);
- break;
- case 'M':
- index = write_num(time->min, 2, index, space);
- break;
- case 'n':
- *index++ = '\n';
- break;
- case 'p':
- index = strncpy(index, time->hour > 11 ? "PM" : "AM", space);
- break;
- case 'P':
- index = strncpy(index, time->hour > 11 ? "pm" : "am", space);
- break;
- case 'q':
- index = write_num((time->mon + 3) / 3, 0, index, space);
- break;
- case 'S':
- index = write_num(time->sec, 2, index, space);
- break;
- case 't':
- *index++ = '\t';
- break;
- case 'u':
- index = write_num(((time->wday + 1) % 7) + 1, 0, index, space);
- break;
- case 'w':
- index = write_num(time->wday, 0, index, space);
- break;
- case 'y':
- index = write_num(time->yn, 2, index, space);
- break;
- case 'Y':
- index = write_num(time->year + 1900, 0, index, space);
- break;
- default: {
- char b[3] = { '%', c, '\0' };
- index = strncpy(index, b, space);
- break;
- }
- }
- }
-
- if (space < 1)
- buf[n - 1] = '\0';
- else
- *index = '\0';
-}