diff --git a/etc/make/conf.mk b/etc/make/conf.mk index 7b2dc59..1c81cfb 100644 --- a/etc/make/conf.mk +++ b/etc/make/conf.mk @@ -56,6 +56,8 @@ OBJS+=$(O)/sys/debug.o \ $(O)/sys/time.o \ $(O)/sys/sys_file.o \ $(O)/sys/sys_sys.o \ + $(O)/sys/snprintf.o \ + $(O)/sys/random.o \ $(O)/sys/init.o OBJS+=$(O)/sys/driver/pci/pci.o \ diff --git a/include/sys/random.h b/include/sys/random.h new file mode 100644 index 0000000..5c0cd4d --- /dev/null +++ b/include/sys/random.h @@ -0,0 +1,5 @@ +#pragma once +#include "sys/types.h" + +void random_init(uint64_t seed); +uint64_t random_single(void); diff --git a/include/sys/snprintf.h b/include/sys/snprintf.h new file mode 100644 index 0000000..cc1d66e --- /dev/null +++ b/include/sys/snprintf.h @@ -0,0 +1,6 @@ +#pragma once +#include +#include "sys/types.h" + +int snprintf(char *buf, size_t lim, const char *fmt, ...); +int vsnprintf(char *buf, size_t lim, const char *fmt, va_list args); diff --git a/sys/amd64/kernel.c b/sys/amd64/kernel.c index 4f5b1ab..9aca6e8 100644 --- a/sys/amd64/kernel.c +++ b/sys/amd64/kernel.c @@ -12,10 +12,12 @@ #include "sys/amd64/cpuid.h" #include "sys/amd64/mm/mm.h" #include "sys/block/ram.h" +#include "sys/fs/sysfs.h" #include "sys/char/tty.h" #include "sys/config.h" #include "sys/fs/tar.h" #include "sys/fs/vfs.h" +#include "sys/random.h" #include "sys/sched.h" #include "sys/debug.h" #include "sys/panic.h" @@ -24,6 +26,10 @@ static multiboot_info_t *multiboot_info; +static void amd64_make_random_seed(void) { + random_init(15267 + system_time); +} + void kernel_main(struct amd64_loader_data *data) { cpuid_init(); data = (struct amd64_loader_data *) MM_VIRTUALIZE(data); @@ -76,9 +82,12 @@ void kernel_main(struct amd64_loader_data *data) { tarfs_init(); } + amd64_make_random_seed(); + syscall_init(); sched_init(); + sysfs_populate(); user_init_start(); sched_enter(); diff --git a/sys/fs/sysfs.c b/sys/fs/sysfs.c index ac59d61..65019c1 100644 --- a/sys/fs/sysfs.c +++ b/sys/fs/sysfs.c @@ -2,6 +2,7 @@ #include "sys/user/errno.h" #include "sys/amd64/cpu.h" #include "sys/fs/sysfs.h" +#include "sys/snprintf.h" #include "sys/fs/ofile.h" #include "sys/fs/node.h" #include "sys/assert.h" @@ -150,52 +151,52 @@ int sysfs_add_config_endpoint(const char *name, size_t bufsz, void *ctx, cfg_rea return 0; } -//// TODO: move this to an appropriate place -//#define PROC_PROP_PID 1 -//#define PROC_PROP_NAME 2 -// -//static int proc_property_getter(void *ctx, char *buf, size_t lim) { -// uint64_t prop = (uint64_t) ctx; -// struct thread *thr = get_cpu()->thread; -// _assert(thr); -// -// switch (prop) { -// case PROC_PROP_PID: -// sysfs_buf_printf(buf, lim, "%d\n", (int) thr->pid); -// break; -// case PROC_PROP_NAME: -// sysfs_buf_puts(buf, lim, thr->name); -// sysfs_buf_puts(buf, lim, "\n"); -// break; -// } -// -// return 0; -//} -// -//static int system_uptime_getter(void *ctx, char *buf, size_t lim) { -// char *p = buf; -// uint64_t t = system_time / 1000000000ULL; -// int days = (t / 86400), -// hours = (t / 3600) % 24, -// minutes = (t / 60) % 60, -// seconds = t % 60; -// -// sysfs_buf_printf(buf, lim, "%u day", days); -// if (days != 1) { -// sysfs_buf_puts(buf, lim, "s"); -// } -// sysfs_buf_printf(buf, lim, ", %02u:%02u:%02u\n", hours, minutes, seconds); -// -// return 0; -//} +// TODO: move this to an appropriate place +#define PROC_PROP_PID 1 +#define PROC_PROP_NAME 2 + +static int proc_property_getter(void *ctx, char *buf, size_t lim) { + uint64_t prop = (uint64_t) ctx; + struct thread *thr = get_cpu()->thread; + _assert(thr); + + switch (prop) { + case PROC_PROP_PID: + sysfs_buf_printf(buf, lim, "%d\n", (int) thr->pid); + break; + case PROC_PROP_NAME: + sysfs_buf_puts(buf, lim, "TODO"); + sysfs_buf_puts(buf, lim, "\n"); + break; + } + + return 0; +} + +static int system_uptime_getter(void *ctx, char *buf, size_t lim) { + char *p = buf; + uint64_t t = system_time / 1000000000ULL; + int days = (t / 86400), + hours = (t / 3600) % 24, + minutes = (t / 60) % 60, + seconds = t % 60; + + sysfs_buf_printf(buf, lim, "%u day", days); + if (days != 1) { + sysfs_buf_puts(buf, lim, "s"); + } + sysfs_buf_printf(buf, lim, ", %02u:%02u:%02u\n", hours, minutes, seconds); + + return 0; +} void sysfs_populate(void) { -// sysfs_add_config_endpoint("version", sizeof(KERNEL_VERSION_STR) + 1, KERNEL_VERSION_STR, sysfs_config_getter, NULL); -// -// sysfs_add_config_endpoint("uptime", 32, NULL, system_uptime_getter, NULL); -// -// sysfs_add_config_endpoint("self.pid", 16, (void *) PROC_PROP_PID, proc_property_getter, NULL); -// sysfs_add_config_endpoint("self.name", 128, (void *) PROC_PROP_NAME, proc_property_getter, NULL); + sysfs_add_config_endpoint("version", sizeof(KERNEL_VERSION_STR) + 1, KERNEL_VERSION_STR, sysfs_config_getter, NULL); + + sysfs_add_config_endpoint("uptime", 32, NULL, system_uptime_getter, NULL); + + sysfs_add_config_endpoint("self.pid", 16, (void *) PROC_PROP_PID, proc_property_getter, NULL); + sysfs_add_config_endpoint("self.name", 128, (void *) PROC_PROP_NAME, proc_property_getter, NULL); } static void __init sysfs_class_init(void) { diff --git a/sys/random.c b/sys/random.c new file mode 100644 index 0000000..43a7abe --- /dev/null +++ b/sys/random.c @@ -0,0 +1,25 @@ +#include "sys/random.h" +#include "sys/panic.h" +#include "sys/debug.h" + +static int random_ready = 0; +static uint64_t xs64_state; + +void random_init(uint64_t s) { + if (random_ready) { + kinfo("Random is ready already\n"); + } + random_ready = 1; + xs64_state = s; +} + +uint64_t random_single(void) { + if (!random_ready) { + panic("Random was not ready\n"); + } + uint64_t x = xs64_state; + x ^= x << 13; + x ^= x >> 7; + x ^= x << 17; + return xs64_state = x; +} diff --git a/sys/snprintf.c b/sys/snprintf.c new file mode 100644 index 0000000..a0d458e --- /dev/null +++ b/sys/snprintf.c @@ -0,0 +1,261 @@ +// TODO: merge snprintf and debug.c +#include "sys/snprintf.h" +#include "sys/string.h" + +union printfv { + int value_int; + unsigned int value_uint; + long value_long; + uint32_t value_uint32; + uint64_t value_uint64; + uintptr_t value_ptr; + const char *value_str; +}; + +static const char *s_print_xs_set0 = "0123456789abcdef"; +static const char *s_print_xs_set1 = "0123456789ABCDEF"; + +static int vsnprintf_ds(int64_t x, char *res, int s, int sz) { + if (!x) { + res[0] = '0'; + res[1] = 0; + return 1; + } + + int c; + uint64_t v; + + if (sz) { + if (s && x < 0) { + v = (uint64_t) -x; + } else { + s = 0; + v = (uint64_t) x; + } + } else { + if (s && ((int32_t) x) < 0) { + v = (uint64_t) -((int32_t) x); + } else { + s = 0; + v = (uint64_t) x; + } + } + + c = 0; + + while (v) { + res[c++] = '0' + v % 10; + v /= 10; + } + + if (s) { + res[c++] = '-'; + } + + res[c] = 0; + + for (int i = 0, j = c - 1; i < j; ++i, --j) { + res[i] ^= res[j]; + res[j] ^= res[i]; + res[i] ^= res[j]; + } + + return c; +} + +static int vsnprintf_xs(uint64_t v, char *res, const char *set) { + if (!v) { + res[0] = '0'; + res[1] = 0; + return 1; + } + + int c = 0; + + while (v) { + res[c++] = set[v & 0xF]; + v >>= 4; + } + + res[c] = 0; + + for (int i = 0, j = c - 1; i < j; ++i, --j) { + res[i] ^= res[j]; + res[j] ^= res[i]; + res[i] ^= res[j]; + } + + return c; +} + +int snprintf(char *buf, size_t len, const char *fmt, ...) { + va_list args; + va_start(args, fmt); + int res = vsnprintf(buf, len, fmt, args); + va_end(args); + return res; +} + +int vsnprintf(char *buf, size_t len, const char *fmt, va_list args) { + union printfv val; + char cbuf[64]; + size_t p = 0; + // padn > 0: + // --------vvvvv + // padn < 0: + // vvvv---------- + int padn; + char padc; + int pads; + int clen; + char c; + +#define __putc(ch) \ + if (p == len - 1) { \ + goto __end; \ + } else { \ + buf[p++] = ch; \ + } + +#define __puts(s, l) \ + if (padn >= 0) { \ + if ((int) l < padn) { \ + size_t padd = padn - l; \ + if (p + padd < len + 1) { \ + memset(buf + p, padc, padd); \ + p += padd; \ + } else { \ + memset(buf + p, padc, len - 1 - p); \ + p = len - 1; \ + goto __end; \ + } \ + } \ + if (p + l < len + 1) { \ + strncpy(buf + p, s, l); \ + p += l; \ + } else { \ + strncpy(buf + p, s, len - 1 - p); \ + p = len - 1; \ + goto __end; \ + } \ + } else { \ + padn = -padn; \ + if (p + l < len + 1) { \ + strncpy(buf + p, s, l); \ + p += l; \ + } else { \ + strncpy(buf + p, s, len - 1 - p); \ + p = len - 1; \ + goto __end; \ + } \ + if ((int) l < padn) { \ + size_t padd = padn - l; \ + if (p + padd < len + 1) { \ + memset(buf + p, padc, padd); \ + p += padd; \ + } else { \ + memset(buf + p, padc, len - 1 - p); \ + p = len - 1; \ + goto __end; \ + } \ + } \ + } + + while ((c = *fmt)) { + switch (c) { + case '%': + c = *++fmt; + padn = 0; + padc = ' '; + pads = 1; + + if (c == '0') { + padc = c; + c = *++fmt; + } + if (c == '-') { + pads = -1; + c = *++fmt; + } + + while (c >= '0' && c <= '9') { + padn *= 10; + padn += c - '0'; + c = *++fmt; + } + + padn *= pads; + + switch (c) { + case 'l': + // Not supported + return -1; + + case 's': + if ((val.value_str = va_arg(args, const char *))) { + __puts(val.value_str, strlen(val.value_str)); + } else { + __puts("(null)", 6); + } + break; + + case 'p': + val.value_ptr = va_arg(args, uintptr_t); + __putc('0'); + __putc('x'); + padn = sizeof(uintptr_t) * 2; + padc = '0'; + clen = vsnprintf_xs(val.value_ptr, cbuf, s_print_xs_set0); + __puts(cbuf, clen); + break; + + case 'i': + case 'd': + val.value_int = va_arg(args, int); + clen = vsnprintf_ds(val.value_int, cbuf, 1, 1); + __puts(cbuf, clen); + break; + case 'u': + val.value_uint = va_arg(args, unsigned int); + clen = vsnprintf_ds(val.value_uint, cbuf, 0, 1); + __puts(cbuf, clen); + break; + + case 'x': + val.value_uint32 = va_arg(args, uint32_t); + clen = vsnprintf_xs(val.value_uint32, cbuf, s_print_xs_set0); + __puts(cbuf, clen); + break; + case 'X': + val.value_uint32 = va_arg(args, uint32_t); + clen = vsnprintf_xs(val.value_uint32, cbuf, s_print_xs_set1); + __puts(cbuf, clen); + break; + + case 'c': + val.value_int = va_arg(args, int); + __putc(val.value_int); + break; + + default: + __putc('%'); + __putc(c); + break; + } + + break; + default: + __putc(c); + break; + } + + ++fmt; + } + +#undef __puts +#undef __putc + +__end: + buf[p] = 0; + return p; +} diff --git a/sys/thread.c b/sys/thread.c index bbed6a6..42071c1 100644 --- a/sys/thread.c +++ b/sys/thread.c @@ -515,6 +515,9 @@ int sys_waitpid(pid_t pid, int *status) { if (status) { *status = chld->exit_status; } + + // TODO: Cleanup the child here + return 0; }