From 0d1c8a1bdb47b2782ed8df003deaaef9ae7cebf3 Mon Sep 17 00:00:00 2001 From: Mark Date: Fri, 25 Oct 2019 11:46:56 +0300 Subject: [PATCH] Add tarfs/initrd support --- include/sys/dev.h | 3 ++- sys/amd64/kernel.c | 7 +++++++ sys/amd64/sys/sched.c | 18 ++++++++++++++++++ sys/blk/ram.c | 15 +++++++++++++++ sys/dev.c | 8 ++++++++ sys/vfs/vfs.c | 1 - 6 files changed, 50 insertions(+), 2 deletions(-) diff --git a/include/sys/dev.h b/include/sys/dev.h index 6d04919..b209ab1 100644 --- a/include/sys/dev.h +++ b/include/sys/dev.h @@ -8,7 +8,8 @@ enum dev_class { #define DEV_BLOCK_SDx 1 #define DEV_BLOCK_HDx 2 -#define DEV_BLOCK_PART 3 +#define DEV_BLOCK_RAM 3 +#define DEV_BLOCK_PART 127 struct dev_entry { char dev_name[64]; diff --git a/sys/amd64/kernel.c b/sys/amd64/kernel.c index 7590a7b..dbaa216 100644 --- a/sys/amd64/kernel.c +++ b/sys/amd64/kernel.c @@ -14,6 +14,8 @@ #include "sys/panic.h" #include "sys/assert.h" #include "sys/fs/vfs.h" +#include "sys/blk/ram.h" +#include "sys/fs/tar.h" static multiboot_info_t *multiboot_info; @@ -39,6 +41,11 @@ void kernel_main(struct amd64_loader_data *data) { pci_init(); vfs_init(); + if (data->initrd_ptr) { + // Create ram0 block device + ramblk_init(MM_VIRTUALIZE(data->initrd_ptr), data->initrd_len); + tarfs_init(); + } #if defined(AMD64_SMP) amd64_smp_init(); diff --git a/sys/amd64/sys/sched.c b/sys/amd64/sys/sched.c index 62a041f..ca76477 100644 --- a/sys/amd64/sys/sched.c +++ b/sys/amd64/sys/sched.c @@ -4,6 +4,11 @@ #include "sys/debug.h" #include "sys/heap.h" #include "sys/spin.h" +#include "sys/fs/vfs.h" +#include "sys/fs/fcntl.h" +#include "sys/errno.h" +#include "sys/blk.h" +#include "sys/panic.h" static struct thread *sched_queue_heads[AMD64_MAX_SMP] = { 0 }; static struct thread *sched_queue_tails[AMD64_MAX_SMP] = { 0 }; @@ -28,6 +33,19 @@ void idle_func(uintptr_t id) { void init_func(void *arg) { kdebug("Entering [init]\n"); + + // Mount rootfs if available + struct blkdev *root_blk = blk_by_name("ram0"); + struct vfs_ioctx ioctx = {0}; + struct ofile fd; + int res; + + if (root_blk) { + if ((res = vfs_mount(&ioctx, "/", root_blk, "ustar", NULL)) != 0) { + panic("mount rootfs: %s\n", kstrerror(res)); + } + } + while (1) { asm volatile ("sti; hlt"); } diff --git a/sys/blk/ram.c b/sys/blk/ram.c index a801a7c..ff11315 100644 --- a/sys/blk/ram.c +++ b/sys/blk/ram.c @@ -1,5 +1,8 @@ #include "sys/blk/ram.h" #include "sys/string.h" +#include "sys/assert.h" +#include "sys/heap.h" +#include "sys/dev.h" #define MIN(x, y) ((x) < (y) ? (x) : (y)) @@ -28,4 +31,16 @@ struct blkdev *ramblk0 = &_ramblk0; void ramblk_init(uintptr_t at, size_t len) { ram_priv.begin = at; ram_priv.lim = len; + + struct dev_entry *ent = (struct dev_entry *) kmalloc(sizeof(struct dev_entry)); + _assert(ent); + + ent->dev = ramblk0; + ent->dev_class = DEV_CLASS_BLOCK; + ent->dev_subclass = DEV_BLOCK_RAM; + if (dev_alloc_name(ent->dev_class, ent->dev_subclass, ent->dev_name) != 0) { + panic("Failed to allocate a name for ram device\n"); + } + + dev_entry_add(ent); } diff --git a/sys/dev.c b/sys/dev.c index bb13c9a..e4bde30 100644 --- a/sys/dev.c +++ b/sys/dev.c @@ -3,14 +3,22 @@ #include "sys/assert.h" #include "sys/panic.h" #include "sys/debug.h" +#include "sys/string.h" static struct dev_entry *dev_begin = NULL; static struct dev_entry *dev_end = NULL; static uint64_t dev_scsi_bitmap = 0; static uint64_t dev_ide_bitmap = 0; +static int dev_ram_count = 0; static int dev_alloc_block_name(uint16_t subclass, char *name) { + if (subclass == DEV_BLOCK_RAM) { + strcpy(name, "ram"); + name[3] = dev_ram_count++ + '0'; + name[4] = 0; + return 0; + } if (subclass == DEV_BLOCK_SDx || subclass == DEV_BLOCK_HDx) { uint64_t *bmp = subclass == DEV_BLOCK_SDx ? &dev_scsi_bitmap : &dev_ide_bitmap; name[1] = 'd'; diff --git a/sys/vfs/vfs.c b/sys/vfs/vfs.c index f7bdcdb..581eb1d 100644 --- a/sys/vfs/vfs.c +++ b/sys/vfs/vfs.c @@ -424,7 +424,6 @@ static int vfs_mount_internal(struct vfs_node *at, void *blkdev, const char *fs_ panic("Trying to mount a filesystem at a destination which already is a mount\n"); } - if (fs->cls->opt & FS_NODE_MAPPER) { _assert(fs_class->mapper); // Request the driver to map VFS tree for us