aboutsummaryrefslogtreecommitdiff
path: root/sys/kern
diff options
context:
space:
mode:
authorIan Moffett <ian@osmora.org>2024-06-24 23:00:41 -0400
committerIan Moffett <ian@osmora.org>2024-06-24 23:00:41 -0400
commit963478ff0ad358fc3a44ff5dba0c64ddc889f296 (patch)
treea14c3ea6feb7d1b783364737fcefabce249473ff /sys/kern
parent236963e7563be3e3f8220dac7bb4af446928e194 (diff)
parent6f6a36d1e8b3dd50cb4d394fa1de4888663b4ea5 (diff)
Import hyra expt
Diffstat (limited to 'sys/kern')
-rw-r--r--sys/kern/init_main.c72
-rw-r--r--sys/kern/kern_fork.c78
-rw-r--r--sys/kern/kern_lock.c43
-rw-r--r--sys/kern/kern_panic.c58
-rw-r--r--sys/kern/kern_sched.c179
-rw-r--r--sys/kern/kern_syslog.c105
-rw-r--r--sys/kern/vfs_init.c70
-rw-r--r--sys/kern/vfs_lookup.c83
-rw-r--r--sys/kern/vfs_subr.c122
9 files changed, 810 insertions, 0 deletions
diff --git a/sys/kern/init_main.c b/sys/kern/init_main.c
new file mode 100644
index 0000000..df955ee
--- /dev/null
+++ b/sys/kern/init_main.c
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2023-2024 Ian Marco Moffett and the Osmora Team.
+ * 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 Hyra 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.
+ */
+
+#include <sys/reboot.h>
+#include <sys/syslog.h>
+#include <sys/sched.h>
+#include <sys/mount.h>
+#include <sys/proc.h>
+#include <dev/cons/cons.h>
+#include <dev/acpi/acpi.h>
+#include <machine/cpu.h>
+#include <vm/vm.h>
+
+static struct proc proc0;
+
+int
+main(void)
+{
+ /* Startup the console */
+ cons_init();
+ kprintf("Starting Hyra/%s v%s: %s\n", HYRA_ARCH, HYRA_VERSION,
+ HYRA_BUILDDATE);
+
+ /* Start the ACPI subsystem */
+ acpi_init();
+
+ /* Init the virtual memory subsystem */
+ vm_init();
+
+ /* Startup the BSP */
+ cpu_startup(&g_bsp_ci);
+
+ /* Init process 0 */
+ md_td_init(&proc0, NULL, 0);
+
+ /* Init the virtual file system */
+ vfs_init();
+
+ /* Start scheduler and bootstrap APs */
+ sched_init();
+ mp_bootstrap_aps(&g_bsp_ci);
+
+ /* Nothing left to do... halt */
+ cpu_reboot(REBOOT_HALT);
+ __builtin_unreachable();
+}
diff --git a/sys/kern/kern_fork.c b/sys/kern/kern_fork.c
new file mode 100644
index 0000000..64e0caf
--- /dev/null
+++ b/sys/kern/kern_fork.c
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2023-2024 Ian Marco Moffett and the Osmora Team.
+ * 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 Hyra 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.
+ */
+
+#include <sys/types.h>
+#include <sys/proc.h>
+#include <sys/errno.h>
+#include <sys/sched.h>
+#include <vm/dynalloc.h>
+#include <string.h>
+
+static size_t nthreads = 0;
+
+/*
+ * Fork1 - fork and direct a thread to 'ip'
+ *
+ * @cur: Current process.
+ * @flags: Flags to set.
+ * @ip: Location for new thread to start at.
+ * @newprocp: Will contain new thread if not NULL.
+ */
+int
+fork1(struct proc *cur, int flags, void(*ip)(void), struct proc **newprocp)
+{
+ struct proc *newproc;
+ int status = 0;
+
+ newproc = dynalloc(sizeof(*newproc));
+ if (newproc == NULL)
+ return -ENOMEM;
+
+ /*
+ * We want to zero the proc to ensure it is in known
+ * state. We then want to initialize machine dependent
+ * fields.
+ */
+ memset(newproc, 0, sizeof(*newproc));
+ status = md_td_init(newproc, cur, (uintptr_t)ip);
+ if (status != 0)
+ goto done;
+
+ /* Set proc output if we can */
+ if (newprocp != NULL)
+ *newprocp = newproc;
+
+ newproc->pid = nthreads++;
+ sched_enqueue_td(newproc);
+done:
+ if (status != 0)
+ dynfree(newproc);
+
+ return status;
+}
diff --git a/sys/kern/kern_lock.c b/sys/kern/kern_lock.c
new file mode 100644
index 0000000..9047a21
--- /dev/null
+++ b/sys/kern/kern_lock.c
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2023-2024 Ian Marco Moffett and the Osmora Team.
+ * 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 Hyra 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.
+ */
+
+#include <sys/spinlock.h>
+#include <sys/types.h>
+
+void
+spinlock_acquire(struct spinlock *lock)
+{
+ while (__atomic_test_and_set(&lock->lock, __ATOMIC_ACQUIRE));
+}
+
+void
+spinlock_release(struct spinlock *lock)
+{
+ __atomic_clear(&lock->lock, __ATOMIC_RELEASE);
+}
diff --git a/sys/kern/kern_panic.c b/sys/kern/kern_panic.c
new file mode 100644
index 0000000..0a17456
--- /dev/null
+++ b/sys/kern/kern_panic.c
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2023-2024 Ian Marco Moffett and the Osmora Team.
+ * 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 Hyra 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.
+ */
+
+#include <sys/panic.h>
+#include <sys/spinlock.h>
+#include <sys/syslog.h>
+#include <sys/reboot.h>
+
+/*
+ * Tells the user something terribly wrong happened then
+ * halting the system as soon as possible.
+ *
+ * XXX: There is no need to cleanup stuff here (e.g `va_list ap`)
+ * as we won't be returning from here anyways and the source
+ * of the panic could be *anywhere* so it's best not to mess with
+ * things.
+ */
+void
+panic(const char *fmt, ...)
+{
+ va_list ap;
+ static struct spinlock lock = {0};
+
+ spinlock_acquire(&lock); /* Never released */
+ va_start(ap, fmt);
+
+ kprintf(OMIT_TIMESTAMP "panic: ");
+ vkprintf(fmt, &ap);
+
+ cpu_reboot(REBOOT_HALT);
+ __builtin_unreachable();
+}
diff --git a/sys/kern/kern_sched.c b/sys/kern/kern_sched.c
new file mode 100644
index 0000000..c370311
--- /dev/null
+++ b/sys/kern/kern_sched.c
@@ -0,0 +1,179 @@
+/*
+ * Copyright (c) 2023-2024 Ian Marco Moffett and the Osmora Team.
+ * 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 Hyra 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.
+ */
+
+#include <sys/types.h>
+#include <sys/sched.h>
+#include <sys/schedvar.h>
+#include <sys/cdefs.h>
+#include <sys/syslog.h>
+#include <machine/frame.h>
+#include <machine/cpu.h>
+#include <vm/pmap.h>
+#include <dev/timer.h>
+#include <assert.h>
+#include <string.h>
+
+#define pr_trace(fmt, ...) kprintf("ksched: " fmt, ##__VA_ARGS__)
+
+void sched_switch(struct trapframe *tf);
+
+static sched_policy_t policy = SCHED_POLICY_RR;
+
+/*
+ * Thread ready queues - all threads ready to be
+ * scheduled should be added to the toplevel queue.
+ */
+static struct sched_queue qlist[SCHED_NQUEUE];
+
+/*
+ * Thread queue lock - all operations to `qlist'
+ * must be done with this lock acquired.
+ */
+__cacheline_aligned static struct spinlock tdq_lock = {0};
+
+/*
+ * Perform timer oneshot
+ */
+static inline void
+sched_oneshot(bool now)
+{
+ struct timer timer;
+ size_t usec = now ? SHORT_TIMESLICE_USEC : DEFAULT_TIMESLICE_USEC;
+ tmrr_status_t tmr_status;
+
+ tmr_status = req_timer(TIMER_SCHED, &timer);
+ __assert(tmr_status == TMRR_SUCCESS);
+
+ timer.oneshot_us(usec);
+}
+
+static struct proc *
+sched_dequeue_td(void)
+{
+ struct sched_queue *queue;
+ struct proc *td = NULL;
+
+ spinlock_acquire(&tdq_lock);
+
+ for (size_t i = 0; i < SCHED_NQUEUE; ++i) {
+ queue = &qlist[i];
+ if (!TAILQ_EMPTY(&queue->q)) {
+ td = TAILQ_FIRST(&queue->q);
+ TAILQ_REMOVE(&queue->q, td, link);
+ break;
+ }
+ }
+
+ spinlock_release(&tdq_lock);
+ return td;
+}
+
+/*
+ * Add a thread to the scheduler.
+ */
+void
+sched_enqueue_td(struct proc *td)
+{
+ struct sched_queue *queue;
+
+ spinlock_acquire(&tdq_lock);
+ queue = &qlist[td->priority];
+
+ TAILQ_INSERT_TAIL(&queue->q, td, link);
+ spinlock_release(&tdq_lock);
+}
+
+/*
+ * Return the currently running thread.
+ */
+struct proc *
+this_td(void)
+{
+ struct cpu_info *ci;
+
+ ci = this_cpu();
+ return ci->curtd;
+}
+
+/*
+ * Perform a context switch.
+ *
+ * TODO
+ */
+void
+sched_switch(struct trapframe *tf)
+{
+ struct cpu_info *ci;
+ struct pcb *pcbp;
+ struct proc *next_td, *td;
+
+ ci = this_cpu();
+ td = ci->curtd;
+
+ /* Do we have threads to switch to? */
+ if ((next_td = sched_dequeue_td()) == NULL) {
+ sched_oneshot(false);
+ return;
+ }
+
+ /* Re-enqueue the old thread */
+ if (td != NULL) {
+ memcpy(&td->tf, tf, sizeof(td->tf));
+ sched_enqueue_td(td);
+ }
+
+ memcpy(tf, &next_td->tf, sizeof(*tf));
+ ci->curtd = next_td;
+ pcbp = &next_td->pcb;
+
+ pmap_switch_vas(pcbp->addrsp);
+ sched_oneshot(false);
+}
+
+/*
+ * Main scheduler loop
+ */
+void
+sched_enter(void)
+{
+ sched_oneshot(false);
+ for (;;);
+}
+
+void
+sched_init(void)
+{
+ /* Setup the queues */
+ for (int i = 0; i < SCHED_NQUEUE; ++i) {
+ TAILQ_INIT(&qlist[i].q);
+ }
+
+ pr_trace("Prepared %d queues (policy=0x%x)\n",
+ SCHED_NQUEUE, policy);
+}
diff --git a/sys/kern/kern_syslog.c b/sys/kern/kern_syslog.c
new file mode 100644
index 0000000..6962a69
--- /dev/null
+++ b/sys/kern/kern_syslog.c
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2023-2024 Ian Marco Moffett and the Osmora Team.
+ * 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 Hyra 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.
+ */
+
+#include <sys/syslog.h>
+#include <sys/spinlock.h>
+#include <dev/cons/cons.h>
+#include <dev/timer.h>
+#include <stdarg.h>
+#include <string.h>
+
+/* Global logger lock */
+static struct spinlock lock = {0};
+
+static void
+syslog_write(const char *s, size_t len)
+{
+ const char *p = s;
+
+ while (len--) {
+ cons_putch(&g_root_scr, *p);
+ ++p;
+ }
+}
+
+/*
+ * XXX: Not serialized
+ */
+void
+vkprintf(const char *fmt, va_list *ap)
+{
+ char buffer[1024] = {0};
+
+ vsnprintf(buffer, sizeof(buffer), fmt, *ap);
+ syslog_write(buffer, strlen(buffer));
+}
+
+void
+kprintf(const char *fmt, ...)
+{
+ va_list ap;
+ char timestamp[64] = "[ 0.000000] ";
+ const char *fmt_p = fmt;
+ bool use_timestamp = true;
+ bool has_counter = true;
+ struct timer tmr;
+
+ /*
+ * If the first char is OMIT_TIMESTAMP, then we won't
+ * print out the timestamp.
+ */
+ if (*fmt == OMIT_TIMESTAMP[0]) {
+ ++fmt_p;
+ use_timestamp = false;
+ }
+
+ /* See if we have a timer */
+ if (req_timer(TIMER_GP, &tmr) != TMRR_SUCCESS) {
+ has_counter = false;
+ }
+
+ /* If we can use the counter, format the timestamp */
+ if (has_counter) {
+ if (tmr.get_time_sec != NULL && tmr.get_time_usec != NULL) {
+ snprintf(timestamp, sizeof(timestamp), "[ %d.%06d] ",
+ tmr.get_time_sec(), tmr.get_time_usec());
+ }
+ }
+
+ if (use_timestamp) {
+ syslog_write(timestamp, strlen(timestamp));
+ }
+
+ spinlock_acquire(&lock);
+ va_start(ap, fmt);
+
+ vkprintf(fmt_p, &ap);
+ va_end(ap);
+ spinlock_release(&lock);
+}
diff --git a/sys/kern/vfs_init.c b/sys/kern/vfs_init.c
new file mode 100644
index 0000000..aafbc00
--- /dev/null
+++ b/sys/kern/vfs_init.c
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2023-2024 Ian Marco Moffett and the Osmora Team.
+ * 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 Hyra 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.
+ */
+
+#include <sys/param.h>
+#include <sys/mount.h>
+#include <sys/vnode.h>
+#include <sys/panic.h>
+#include <string.h>
+
+struct vnode *g_root_vnode = NULL;
+static struct fs_info fs_list[] = {
+ {MOUNT_RAMFS, &g_initramfs_vfsops, 0, 0},
+};
+
+void
+vfs_init(void)
+{
+ struct fs_info *fs;
+ const struct vfsops *vfsops;
+
+ TAILQ_INIT(&g_mountlist);
+
+ for (size_t i= 0; i < NELEM(fs_list); ++i) {
+ fs = &fs_list[i];
+ vfsops = fs->vfsops;
+
+ /* Try to initialize the filesystem */
+ if (vfsops->init != NULL) {
+ vfsops->init(fs);
+ }
+ }
+}
+
+struct fs_info *
+vfs_byname(const char *name)
+{
+ for (int i = 0; i < NELEM(fs_list); ++i) {
+ if (strcmp(fs_list[i].name, name) == 0) {
+ return &fs_list[i];
+ }
+ }
+
+ return NULL;
+}
diff --git a/sys/kern/vfs_lookup.c b/sys/kern/vfs_lookup.c
new file mode 100644
index 0000000..83924c6
--- /dev/null
+++ b/sys/kern/vfs_lookup.c
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2023-2024 Ian Marco Moffett and the Osmora Team.
+ * 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 Hyra 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.
+ */
+
+#include <sys/namei.h>
+#include <sys/vnode.h>
+#include <sys/errno.h>
+#include <vm/dynalloc.h>
+#include <string.h>
+
+/*
+ * Convert a path to a vnode.
+ *
+ * @ndp: Nameidata containing the path and resulting
+ * vnode.
+ *
+ * TODO: Add support for lookups with individual
+ * path components
+ */
+int
+namei(struct nameidata *ndp)
+{
+ struct vnode *vp;
+ struct vop_lookup_args lookup_args;
+ const char *path = ndp->path;
+ int status;
+
+ if (path == NULL) {
+ return -EINVAL;
+ }
+
+ /* Path must start with "/" */
+ if (*path != '/') {
+ return -EINVAL;
+ }
+
+ /* Just return the root vnode if we can */
+ if (strcmp(path, "/") == 0) {
+ ndp->vp = g_root_vnode;
+ return 0;
+ }
+
+ /*
+ * Some filesystems (like initramfs) may only understand
+ * full paths, so try passing it through.
+ */
+ lookup_args.name = path;
+ lookup_args.dirvp = g_root_vnode;
+ lookup_args.vpp = &vp;
+ status = vfs_vop_lookup(lookup_args.dirvp, &lookup_args);
+
+ if (status != 0) {
+ return status;
+ }
+
+ ndp->vp = vp;
+ return 0;
+}
diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c
new file mode 100644
index 0000000..04d64e3
--- /dev/null
+++ b/sys/kern/vfs_subr.c
@@ -0,0 +1,122 @@
+/*
+ * Copyright (c) 2023-2024 Ian Marco Moffett and the Osmora Team.
+ * 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 Hyra 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.
+ */
+
+#include <sys/vnode.h>
+#include <sys/errno.h>
+#include <sys/mount.h>
+#include <vm/dynalloc.h>
+#include <string.h>
+
+mountlist_t g_mountlist;
+
+int
+vfs_alloc_vnode(struct vnode **res, int type)
+{
+ struct vnode *vp = dynalloc(sizeof(struct vnode));
+
+ if (vp == NULL) {
+ return -ENOMEM;
+ }
+
+ memset(vp, 0, sizeof(*vp));
+ vp->type = type;
+ *res = vp;
+ return 0;
+}
+
+/*
+ * Allocate a mount structure.
+ *
+ * @vp: Vnode this mount structure covers.
+ * @fip: File system information.
+ */
+struct mount *
+vfs_alloc_mount(struct vnode *vp, struct fs_info *fip)
+{
+ struct mount *mp;
+
+ mp = dynalloc(sizeof(*mp));
+
+ if (mp == NULL) {
+ return NULL;
+ }
+
+ memset(mp, 0, sizeof(*mp));
+ mp->vp = vp;
+ mp->mnt_ops = fip->vfsops;
+ return mp;
+}
+
+/*
+ * Release a vnode and its resources from
+ * memory.
+ */
+int
+vfs_release_vnode(struct vnode *vp)
+{
+ const struct vops *vops = vp->vops;
+ int status = 0;
+
+ if (vp == NULL) {
+ return -EINVAL;
+ }
+
+ if (vops->reclaim != NULL) {
+ status = vops->reclaim(vp);
+ }
+
+ dynfree(vp);
+ return status;
+}
+
+int
+vfs_vop_lookup(struct vnode *vp, struct vop_lookup_args *args)
+{
+ const struct vops *vops = vp->vops;
+
+ if (vops == NULL)
+ return -EIO;
+ if (vops->lookup == NULL)
+ return -EIO;
+
+ return vops->lookup(args);
+}
+
+int
+vfs_vop_read(struct vnode *vp, struct sio_txn *sio)
+{
+ const struct vops *vops = vp->vops;
+
+ if (vops == NULL)
+ return -EIO;
+ if (vops->read == NULL)
+ return -EIO;
+
+ return vops->read(vp, sio);
+}