diff options
| author | Jake Mannens <jake72360@gmail.com> | 2018-07-08 01:44:13 +1000 |
|---|---|---|
| committer | Jake Mannens <jake72360@gmail.com> | 2018-07-08 01:44:13 +1000 |
| commit | 70b141b3af85771f36119165e072c1c45d64de84 (patch) | |
| tree | 8c67026fc02c86ffc7328e13354adede5f0ea9ed /kernel | |
| parent | ec4f58e8e362e371718f656923c2d234f8ac215c (diff) | |
Added a printf() function to the library under stdio.c which uses the
vsprintf() function to render formatted strings and then the puts system
call to output them.
Moved the vsprintf() function from the kernel to the library.
Furthermore, the prototype for the function has been moved from the
kernel's headers, to the new header file stdio.h.
Renamed the kernel's internal printf() function to printk() in order to
avoid confusion with the library provided function.
Renamed the sys_print system call to the more appropriate name,
sys_puts.
Added a new system call sys_time, which returns the system's uptime in
seconds. This is mainly for testing the userspace binary and will not be
permanent.
Added the file time.c to the library which contains the caller for
sys_time and a helper routine sleep() which delays execution for the
specified number of seconds. The new header file time.h contains
prototypes for both these functions as well as the definition for the
type time_t.
Fixed a bug in which the value of EAX was not properly passed to the
system call handler, resulting in the wrong system call being executed.
This was caused by the code in the SAVE macro not properly preserving
the value.
Fixed a bug in which the value of EAX was not preserved during a return
from system call, but rather restored with the original EAX value prior
to the call. As a result, system call return codes were not properly
passed. This has been corrected by introducing a new macro RESTORE_SYS
which carries out the same restore operations, but maintains EAX prior
to the return.
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/con.c | 8 | ||||
| -rw-r--r-- | kernel/kmain.c | 4 | ||||
| -rw-r--r-- | kernel/sched.c | 14 | ||||
| -rw-r--r-- | kernel/sys.c | 12 | ||||
| -rw-r--r-- | kernel/traps.s | 17 | ||||
| -rw-r--r-- | kernel/vsprintf.c | 153 |
6 files changed, 38 insertions, 170 deletions
diff --git a/kernel/con.c b/kernel/con.c index 69c34e1..c8be80b 100644 --- a/kernel/con.c +++ b/kernel/con.c @@ -1,13 +1,13 @@ /* * con.c * - * Basic VGA text console. Implements printf() and puts(). + * Basic VGA text console. Implements printk() and puts(). */ #include <asm/io.h> -#include <kernel/vsprintf.h> #include <stdarg.h> #include <stdint.h> +#include <stdio.h> #define COLS 80 #define ROWS 25 @@ -64,7 +64,7 @@ void con_init(void) { } /* write a zero-terminated string to console */ -int puts(char *s) { +static int puts(char *s) { uint8_t *p = &vram[pos]; while(*s) { @@ -91,7 +91,7 @@ int puts(char *s) { return 0; } -int printf(char *fmt, ...) { +int printk(char *fmt, ...) { int ret; char buf[1024]; va_list ap; diff --git a/kernel/kmain.c b/kernel/kmain.c index 558df42..1828ad2 100644 --- a/kernel/kmain.c +++ b/kernel/kmain.c @@ -11,8 +11,8 @@ uint32_t ticks = 0; void kmain(void) { con_init(); - printf("Kernel booting...\n"); - printf("Kernel booted!\n\n"); + printk("Kernel booting...\n"); + printk("Kernel booted!\n\n"); userspace_init(); } diff --git a/kernel/sched.c b/kernel/sched.c index f0b79fc..3e25de0 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -57,19 +57,19 @@ void userspace_init(void) { * - stack table (1 page) */ p = alloc_physical_pages(totpages); - printf("Allocating %x pages for userspace process\n", totpages); + printk("Allocating %x pages for userspace process\n", totpages); if(p == NULL) { - printf("Failed to allocate memory for userspace!\n"); + printk("Failed to allocate memory for userspace!\n"); return; } getpage(pdir, p); getpage(stackt, p); getpage(stackp, p); - printf(" Page directory: 0x%08x\n", (uint32_t) pdir); - printf(" Stack table: 0x%08x\n", (uint32_t) stackt); - printf(" Stack page: 0x%08x\n", (uint32_t) stackp); - printf(" Page tables:\n"); + printk(" Page directory: 0x%08x\n", (uint32_t) pdir); + printk(" Stack table: 0x%08x\n", (uint32_t) stackt); + printk(" Stack page: 0x%08x\n", (uint32_t) stackp); + printk(" Page tables:\n"); /* populate the page directory */ c = npages; @@ -78,7 +78,7 @@ void userspace_init(void) { for(i = 0; i < ntables; i++) { /* add the table entry to the directory */ getpage(tab, p); - printf(" 0x%08x\n", (uint32_t) tab); + printk(" 0x%08x\n", (uint32_t) tab); map = map_page(pdir); ((uint32_t*) map)[i + (PGENT / 4)] = (uint32_t) tab | 0x007; diff --git a/kernel/sys.c b/kernel/sys.c index b648dd1..3748e2b 100644 --- a/kernel/sys.c +++ b/kernel/sys.c @@ -1,8 +1,16 @@ #include <errno.h> #include <kernel/con.h> +#include <stdint.h> +#include <time.h> -int sys_print(char *s) { - printf(s); +extern uint32_t ticks; + +int sys_puts(char *s) { + return printk(s); +} + +time_t sys_time(void) { + return ticks / 100; } int sys_dummy(void) { diff --git a/kernel/traps.s b/kernel/traps.s index 0381ee8..15e2640 100644 --- a/kernel/traps.s +++ b/kernel/traps.s @@ -23,7 +23,7 @@ extern register_isr mov fs, ax mov gs, ax ; restore EAX (needed for syscalls) - mov eax, [esp+44] + mov eax, [esp+30] %endmacro %macro SAVE_ERR 0 @@ -64,6 +64,19 @@ extern register_isr iret %endmacro +%macro RESTORE_SYS 0 + ; preserve our modified EAX (return value for syscalls) + mov [esp+30], eax + ; restore the data segment selectors + pop ax + mov ds, ax + mov es, ax + mov fs, ax + mov gs, ax + popa + iret +%endmacro + traps: dd exc_div dd exc_debug @@ -230,7 +243,7 @@ syscall_handler: call [eax] add esp, 12 - RESTORE + RESTORE_SYS syscall_init: diff --git a/kernel/vsprintf.c b/kernel/vsprintf.c deleted file mode 100644 index a566b83..0000000 --- a/kernel/vsprintf.c +++ /dev/null @@ -1,153 +0,0 @@ -#include <stdarg.h> -#include <stdbool.h> -#include <stdint.h> - -enum TYPE { - TYPE_INT = 1, - TYPE_UINT = 2, - TYPE_HEX = 3, - TYPE_STRING = 4, - TYPE_PERCENT = 5 -}; - -enum FLAGS { - FL_ZERO = 1, /* zero padded */ - FL_ALT = 2, /* alternate form (effect is type dependent) */ - FL_UPPER = 4 /* uppercase */ -}; - -static void hex(char **str, char flags, int fwidth, int size, int x) { - bool seen; - int i, y, len; - char c; - char *prefl = "0x"; - char *prefu = "0X"; - - /* print the prefix, if the alt flag is set */ - if(flags & FL_ALT) { - if(flags & FL_UPPER) { - while(*prefu) - *(*str)++ = *prefu++; - } else { - while(*prefl) - *(*str)++ = *prefl++; - } - } - - /* calculate the number of digits */ - len = 0; - y = x; - seen = false; - for(i = 0; i < sizeof(y) << 1; i++) { - c = ((unsigned int) y >> 28); - if(c) - seen = true; - if(c || seen) - len++; - y = y << 4; - } - - /* print the padding characters (if any) */ - c = ' '; - if(flags & FL_ZERO) - c = '0'; - for(i = 0; i < fwidth - len; i++) - *(*str)++ = c; - - /* actually print the digits */ - seen = false; - for(i = 0; i < sizeof(x) << 1; i++) { - c = ((unsigned int) x >> 28) + '0'; - if(c > '9') { - c += 0x27; - if(flags & FL_UPPER) - c -= 0x20; - } - - if(c != '0') - seen = true; - if(c != '0' || seen) - *(*str)++ = c; - - x = x << 4; - } -} - -int vsprintf(char *str, char *fmt, va_list ap) { - int x, fwidth; - char flags; - char *s; - char *start = str; - uint8_t type; - - while(*fmt) { - if(*fmt != '%') { - *str++ = *fmt++; - continue; - } - - type = 0; - flags = 0; - fwidth = 0; - - fmt++; - while(1) { - switch(*fmt) { - case '#': - flags |= FL_ALT; - break; - case '%': - type = TYPE_PERCENT; - goto done; - case 's': - type = TYPE_STRING; - goto done; - case 'x': - type = TYPE_HEX; - goto done; - case 'X': - type = TYPE_HEX; - flags |= FL_UPPER; - goto done; - default: - /* the first zero enables zero-padding */ - if(*fmt == '0' && !fwidth) { - flags |= FL_ZERO; - goto next; - } - - /* subsequent numbers indicate field width */ - if(*fmt >= '0' && *fmt <= '9') { - fwidth = (fwidth * 10) + (*fmt - '0'); - goto next; - } - - goto done; - } -next: - fmt++; - } - -done: - fmt++; - - switch(type) { - case TYPE_STRING: - s = va_arg(ap, char*); - while(*s) - *str++ = *s++; - break; - case TYPE_HEX: - x = va_arg(ap, int); - hex(&str, flags, fwidth, 4, x); - break; - case TYPE_PERCENT: - *str++ = '%'; - break; - } - } - - *str = 0; - - return (str - start); -} |
