diff options
author | Ian Moffett <ian@osmora.org> | 2025-09-27 18:01:35 -0400 |
---|---|---|
committer | Ian Moffett <ian@osmora.org> | 2025-09-27 18:01:35 -0400 |
commit | 0487527441dff0c16d206bdf1747daa625b7597d (patch) | |
tree | 500efce2b3405636133fb6278fd07c7249972fd5 | |
parent | f933a2b93b8887e7104b15df85c6a8a3ed99df69 (diff) |
kern: fs: Add initial devfs implementation
Signed-off-by: Ian Moffett <ian@osmora.org>
-rw-r--r-- | src/sys/fs/devfs.c | 166 | ||||
-rw-r--r-- | src/sys/include/fs/devfs.h | 105 | ||||
-rw-r--r-- | src/sys/include/sys/mount.h | 2 | ||||
-rw-r--r-- | src/sys/os/Makefile | 1 | ||||
-rw-r--r-- | src/sys/os/vfs_init.c | 3 |
5 files changed, 276 insertions, 1 deletions
diff --git a/src/sys/fs/devfs.c b/src/sys/fs/devfs.c new file mode 100644 index 0000000..7553003 --- /dev/null +++ b/src/sys/fs/devfs.c @@ -0,0 +1,166 @@ +/* + * Copyright (c) 2025 Ian Marco Moffett and L5 engineers + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * Description: Device filesystem + * Author: Ian Marco Moffett + */ + +#include <sys/errno.h> +#include <sys/mount.h> +#include <sys/syslog.h> +#include <os/vnode.h> +#include <os/kalloc.h> +#include <fs/devfs.h> +#include <string.h> + +static struct vop devfs_vops; +static TAILQ_HEAD(, devfs_node) nodelist; + +/* + * Find a node within the device filesystem + */ +static int +devfs_lookup(struct vop_lookup_args *args) +{ + int error; + struct devfs_node *dnp = NULL; + struct vnode *vp; + + if (args == NULL) { + return -EINVAL; + } + + /* Need a pointer to write the result */ + if (args->vpp == NULL) { + return -EINVAL; + } + + TAILQ_FOREACH(dnp, &nodelist, link) { + if (dnp == NULL) { + continue; + } + + if (strcmp(dnp->name, args->name) != 0) { + continue; + } + + /* Found it! Create a vnode */ + error = vfs_valloc(&vp, VTYPE_FILE, 0); + if (error < 0) { + return error; + } + + vp->data = dnp; + *args->vpp = vp; + return 0; + } + + return -ENOENT; +} + +/* + * Register a new device to devfs + */ +int +devfs_register(const char *name, dev_type_t type, void *devsw, int flags) +{ + struct devfs_node *dnp; + size_t devname_len; + struct vop_lookup_args args; + struct vnode *vp; + + if (name == NULL || devsw == NULL) { + return -EINVAL; + } + + if (type >= __DEVFS_NTYPE) { + return -EINVAL; + } + + dnp = kalloc(sizeof(*dnp)); + if (dnp == NULL) { + return -ENOMEM; + } + + switch (type) { + case DEVFS_NONE: + case DEVFS_CDEV: + dnp->type = type; + break; + } + + devname_len = strlen(name); + memcpy(dnp->name, name, devname_len); + TAILQ_INSERT_TAIL(&nodelist, dnp, link); + return 0; +} + +/* + * Initialize the device filesystem + */ +static int +devfs_init(struct fs_info *fip) +{ + (void)fip; + TAILQ_INIT(&nodelist); + return 0; +} + +/* + * Mount the device filesystem + */ +static int +devfs_mount(struct fs_info *fip, struct mount_args *margs) +{ + int error; + struct vnode *vp; + + if (fip == NULL || margs == NULL) { + return -1; + } + + error = vfs_valloc(&margs->vp_res, VTYPE_DIR, 0); + if (error < 0) { + return error; + } + + vp = margs->vp_res; + vp->vops = &devfs_vops; + return 0; +} + +static struct vop devfs_vops = { + .lookup = devfs_lookup +}; + +struct vfsops g_devfs_vfops = { + .init = devfs_init, + .mount = devfs_mount +}; diff --git a/src/sys/include/fs/devfs.h b/src/sys/include/fs/devfs.h new file mode 100644 index 0000000..ea96cdd --- /dev/null +++ b/src/sys/include/fs/devfs.h @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2025 Ian Marco Moffett and L5 engineers + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _FS_DEVFS_H_ +#define _FS_DEVFS_H_ + +#include <sys/types.h> +#include <sys/queue.h> +#include <sys/limits.h> +#include <os/vnode.h> + +/* Forward declarations */ +struct devfs_node; + +/* + * Represents an I/O buffer for device files + * on the system + */ +struct dev_iobuf { + void *buf; + size_t count; +}; + +/* + * Character device descriptor and hooks + * + * @read: Read n bytes from the char device + * @write: Write n bytes from the char device + */ +struct cdevsw { + ssize_t(*read)(struct devfs_node *dnp, struct dev_iobuf *iob, int flags); + ssize_t(*write)(struct devfs_node *dnp, struct dev_iobuf *iob, int flags); +}; + +/* + * Describes the device node types + * + * @DEVFS_NONE: No type + * @DEVFS_CDEV: Char device + */ +typedef enum { + DEVFS_NONE, + DEVFS_CDEV, + __DEVFS_NTYPE +} dev_type_t; + +/* + * Represents a device filesystem node + * + * @name: Name of device node + * @type: Node type + * @cdev: Character device (if DEVFS_CDEV) + * @link: Queue link + */ +struct devfs_node { + char name[NAME_MAX]; + dev_type_t type; + union { + struct cdevsw *cdev; + void *dev; + }; + + TAILQ_ENTRY(devfs_node) link; +}; + +/* + * Register a character device + * + * @name: Name of character device + * @type: Device type to use + * @cdev: Character device operations to use + * @flags: Optional flags + * + * Returns zero on success, otherwise a less than zero + * value on failure. + */ +int devfs_register(const char *name, dev_type_t type, void *devsw, int flags); + +#endif /* !_FS_DEVFS_H_ */ diff --git a/src/sys/include/sys/mount.h b/src/sys/include/sys/mount.h index dbd8d53..4e39279 100644 --- a/src/sys/include/sys/mount.h +++ b/src/sys/include/sys/mount.h @@ -46,6 +46,7 @@ * Mount filesystem string names */ #define MOUNT_INITRD "initrd" /* Initial ramdisk */ +#define MOUNT_DEVFS "devfs" /* Device filesystem */ /* Forward declarations */ struct fs_info; @@ -54,6 +55,7 @@ struct mount; /* Filesystem vfsops */ extern struct vfsops g_omar_vfsops; +extern struct vfsops g_devfs_vfops; /* * Represents a mountpoint diff --git a/src/sys/os/Makefile b/src/sys/os/Makefile index de73afd..da481ec 100644 --- a/src/sys/os/Makefile +++ b/src/sys/os/Makefile @@ -12,6 +12,7 @@ CFILES += $(shell find ../lib -name "*.c") CFILES += $(shell find ../io -name "*.c") CFILES += $(shell find ../acpi -name "*.c") CFILES += $(shell find ../compat -name "*.c") +CFILES += $(shell find ../fs -name "*.c") DEPS = $(CFILES:.c=.d) OBJECTS = $(CFILES:%.c=%.o) diff --git a/src/sys/os/vfs_init.c b/src/sys/os/vfs_init.c index 92d7b94..80d8559 100644 --- a/src/sys/os/vfs_init.c +++ b/src/sys/os/vfs_init.c @@ -38,7 +38,8 @@ * The filesystem table */ static struct fs_info fstab[] = { - { MOUNT_INITRD, &g_omar_vfsops, 0 } + { MOUNT_INITRD, &g_omar_vfsops, 0 }, + { MOUNT_DEVFS, &g_devfs_vfops, 0 } }; /* |