From: Tulio A M Mendes Date: Tue, 10 Feb 2026 12:31:13 +0000 (-0300) Subject: feat: add /dev/zero, /dev/random, /dev/urandom, /dev/console device nodes X-Git-Url: https://projects.tadryanom.me/?a=commitdiff_plain;h=991ddb491bfa4b4a63a74aecd08f8672332933b2;p=AdrOS.git feat: add /dev/zero, /dev/random, /dev/urandom, /dev/console device nodes - /dev/zero: returns zeroes on read, discards writes - /dev/random: xorshift32 PRNG seeded from PIT tick counter - /dev/urandom: alias to /dev/random (same PRNG) - /dev/console: aliases to TTY read/write (like /dev/tty) - All registered in devfs finddir + readdir (8 devices total) - cppcheck clean, 19/19 smoke tests pass --- diff --git a/src/kernel/devfs.c b/src/kernel/devfs.c index 9bb782a..eec1583 100644 --- a/src/kernel/devfs.c +++ b/src/kernel/devfs.c @@ -5,18 +5,26 @@ #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; @@ -32,6 +40,73 @@ static uint32_t dev_null_write(fs_node_t* node, uint32_t offset, uint32_t size, 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; @@ -85,6 +160,10 @@ static struct fs_node* devfs_finddir_impl(struct fs_node* node, const char* name 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; @@ -104,12 +183,16 @@ static int devfs_readdir_impl(struct fs_node* node, uint32_t* inout_index, void* 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); @@ -203,6 +286,34 @@ static void devfs_init_once(void) { 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;