Backport sysfs and random
This commit is contained in:
parent
4269177c1a
commit
14805828b5
@ -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 \
|
||||
|
5
include/sys/random.h
Normal file
5
include/sys/random.h
Normal file
@ -0,0 +1,5 @@
|
||||
#pragma once
|
||||
#include "sys/types.h"
|
||||
|
||||
void random_init(uint64_t seed);
|
||||
uint64_t random_single(void);
|
6
include/sys/snprintf.h
Normal file
6
include/sys/snprintf.h
Normal file
@ -0,0 +1,6 @@
|
||||
#pragma once
|
||||
#include <stdarg.h>
|
||||
#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);
|
@ -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();
|
||||
|
||||
|
@ -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) {
|
||||
|
25
sys/random.c
Normal file
25
sys/random.c
Normal file
@ -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;
|
||||
}
|
261
sys/snprintf.c
Normal file
261
sys/snprintf.c
Normal file
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user