#include "pty.h"
#include "utils.h"
+extern uint32_t get_tick_count(void);
+
struct devfs_root {
fs_node_t vfs;
};
static struct devfs_root g_dev_root;
static fs_node_t g_dev_null;
+static fs_node_t g_dev_zero;
+static fs_node_t g_dev_random;
+static fs_node_t g_dev_urandom;
+static fs_node_t g_dev_console;
static fs_node_t g_dev_tty;
static fs_node_t g_dev_ptmx;
static fs_node_t g_dev_pts_dir;
static fs_node_t g_dev_pts0;
static uint32_t g_devfs_inited = 0;
+static uint32_t prng_state = 0x12345678;
+
static uint32_t dev_null_read(fs_node_t* node, uint32_t offset, uint32_t size, uint8_t* buffer) {
(void)node;
(void)offset;
return size;
}
+static uint32_t dev_zero_read(fs_node_t* node, uint32_t offset, uint32_t size, uint8_t* buffer) {
+ (void)node;
+ (void)offset;
+ if (buffer && size > 0)
+ memset(buffer, 0, size);
+ return size;
+}
+
+static uint32_t dev_zero_write(fs_node_t* node, uint32_t offset, uint32_t size, const uint8_t* buffer) {
+ (void)node;
+ (void)offset;
+ (void)buffer;
+ return size;
+}
+
+static uint32_t prng_next(void) {
+ uint32_t s = prng_state;
+ s ^= s << 13;
+ s ^= s >> 17;
+ s ^= s << 5;
+ prng_state = s;
+ return s;
+}
+
+static uint32_t dev_random_read(fs_node_t* node, uint32_t offset, uint32_t size, uint8_t* buffer) {
+ (void)node;
+ (void)offset;
+ if (!buffer || size == 0) return 0;
+ prng_state ^= get_tick_count();
+ for (uint32_t i = 0; i < size; i++) {
+ if ((i & 3) == 0) {
+ uint32_t r = prng_next();
+ buffer[i] = (uint8_t)(r & 0xFF);
+ } else {
+ buffer[i] = (uint8_t)((prng_next() >> ((i & 3) * 8)) & 0xFF);
+ }
+ }
+ return size;
+}
+
+static uint32_t dev_random_write(fs_node_t* node, uint32_t offset, uint32_t size, const uint8_t* buffer) {
+ (void)node;
+ (void)offset;
+ if (buffer && size >= 4) {
+ uint32_t seed = 0;
+ memcpy(&seed, buffer, 4);
+ prng_state ^= seed;
+ }
+ return size;
+}
+
+static uint32_t dev_console_read(fs_node_t* node, uint32_t offset, uint32_t size, uint8_t* buffer) {
+ (void)node;
+ (void)offset;
+ int rc = tty_read_kbuf(buffer, size);
+ if (rc < 0) return 0;
+ return (uint32_t)rc;
+}
+
+static uint32_t dev_console_write(fs_node_t* node, uint32_t offset, uint32_t size, const uint8_t* buffer) {
+ (void)node;
+ (void)offset;
+ int rc = tty_write_kbuf((const uint8_t*)buffer, size);
+ if (rc < 0) return 0;
+ return (uint32_t)rc;
+}
+
static uint32_t dev_tty_read(fs_node_t* node, uint32_t offset, uint32_t size, uint8_t* buffer) {
(void)node;
(void)offset;
if (!name || name[0] == 0) return 0;
if (strcmp(name, "null") == 0) return &g_dev_null;
+ if (strcmp(name, "zero") == 0) return &g_dev_zero;
+ if (strcmp(name, "random") == 0) return &g_dev_random;
+ if (strcmp(name, "urandom") == 0) return &g_dev_urandom;
+ if (strcmp(name, "console") == 0) return &g_dev_console;
if (strcmp(name, "tty") == 0) return &g_dev_tty;
if (strcmp(name, "ptmx") == 0) return &g_dev_ptmx;
if (strcmp(name, "pts") == 0) return &g_dev_pts_dir;
if (buf_len < sizeof(struct vfs_dirent)) return -1;
static const struct { const char* name; uint32_t ino; uint8_t type; } devs[] = {
- { "null", 2, FS_CHARDEVICE },
- { "tty", 3, FS_CHARDEVICE },
- { "ptmx", 4, FS_CHARDEVICE },
- { "pts", 5, FS_DIRECTORY },
+ { "null", 2, FS_CHARDEVICE },
+ { "zero", 7, FS_CHARDEVICE },
+ { "random", 8, FS_CHARDEVICE },
+ { "urandom", 9, FS_CHARDEVICE },
+ { "console", 10, FS_CHARDEVICE },
+ { "tty", 3, FS_CHARDEVICE },
+ { "ptmx", 4, FS_CHARDEVICE },
+ { "pts", 5, FS_DIRECTORY },
};
- enum { NDEVS = 4 };
+ enum { NDEVS = 8 };
uint32_t idx = *inout_index;
uint32_t cap = buf_len / (uint32_t)sizeof(struct vfs_dirent);
g_dev_null.close = 0;
g_dev_null.finddir = 0;
+ memset(&g_dev_zero, 0, sizeof(g_dev_zero));
+ strcpy(g_dev_zero.name, "zero");
+ g_dev_zero.flags = FS_CHARDEVICE;
+ g_dev_zero.inode = 7;
+ g_dev_zero.read = &dev_zero_read;
+ g_dev_zero.write = &dev_zero_write;
+
+ memset(&g_dev_random, 0, sizeof(g_dev_random));
+ strcpy(g_dev_random.name, "random");
+ g_dev_random.flags = FS_CHARDEVICE;
+ g_dev_random.inode = 8;
+ g_dev_random.read = &dev_random_read;
+ g_dev_random.write = &dev_random_write;
+
+ memset(&g_dev_urandom, 0, sizeof(g_dev_urandom));
+ strcpy(g_dev_urandom.name, "urandom");
+ g_dev_urandom.flags = FS_CHARDEVICE;
+ g_dev_urandom.inode = 9;
+ g_dev_urandom.read = &dev_random_read;
+ g_dev_urandom.write = &dev_random_write;
+
+ memset(&g_dev_console, 0, sizeof(g_dev_console));
+ strcpy(g_dev_console.name, "console");
+ g_dev_console.flags = FS_CHARDEVICE;
+ g_dev_console.inode = 10;
+ g_dev_console.read = &dev_console_read;
+ g_dev_console.write = &dev_console_write;
+
memset(&g_dev_tty, 0, sizeof(g_dev_tty));
strcpy(g_dev_tty.name, "tty");
g_dev_tty.flags = FS_CHARDEVICE;