Add basic devfs

This commit is contained in:
Mark
2019-12-30 01:23:29 +02:00
parent 7c8e11a3ef
commit 822aa2c3f0
9 changed files with 131 additions and 8 deletions
+2 -1
View File
@@ -64,7 +64,8 @@ OBJS+=$(O)/sys/debug.o \
$(O)/sys/net/eth.o \
$(O)/sys/net/arp.o \
$(O)/sys/net/in.o \
$(O)/sys/net/netdev.o
$(O)/sys/net/netdev.o \
$(O)/sys/vfs/devfs.o
DIRS+=$(O)/sys/vfs/ext2 \
$(O)/sys/net \
$(O)/sys/blk
+3
View File
@@ -1,6 +1,9 @@
#pragma once
#include "sys/types.h"
// TODO: something like device name alias
// for example, /dev/root aliased to
// /dev/ramN or /dev/sdXN
enum dev_class {
DEV_CLASS_BLOCK,
DEV_CLASS_CHAR
+1
View File
@@ -0,0 +1 @@
#pragma once
+1 -1
View File
@@ -44,7 +44,7 @@ void *heap_alloc(heap_t *heap, size_t count) {
heap_block_t *begin = (heap_block_t *) MM_VIRTUALIZE(heap->phys_base);
// Some alignment fuck ups led me to this
count = (count + 31) & ~31;
count = (count + 15) & ~15;
for (heap_block_t *block = begin; block; block = block->next) {
if ((block->magic & HEAP_MAGIC) != HEAP_MAGIC) {
+5
View File
@@ -56,6 +56,11 @@ void init_func(void *arg) {
panic("mount rootfs: %s\n", kstrerror(res));
}
// Mount devfs
if ((res = vfs_mount(&ioctx, "/dev", NULL, "devfs", NULL)) != 0) {
panic("mount devfs: %s\n", kstrerror(res));
}
if ((res = vfs_stat(&ioctx, "/init", &st)) != 0) {
panic("/init: %s\n", kstrerror(res));
}
+84
View File
@@ -0,0 +1,84 @@
#include "sys/fs/devfs.h"
#include "sys/fs/vfs.h"
#include "sys/string.h"
#include "sys/fs/fs.h"
#include "sys/debug.h"
#include "sys/panic.h"
#include "sys/attr.h"
#include "sys/heap.h"
static int devfs_node_mapper(fs_t *devfs, struct vfs_node **root);
static struct fs_class _devfs = {
.name = "devfs",
.opt = FS_NODE_MAPPER,
.mapper = devfs_node_mapper
};
static struct vnode_operations _devfs_vnode_op = {
};
static vnode_t *devfs_create_vnode(fs_t *fs, struct vfs_node *node) {
vnode_t *res = (vnode_t *) kmalloc(sizeof(vnode_t));
res->tree_node = node;
res->fs = fs;
res->fs_data = NULL;
res->refcount = 0;
res->op = &_devfs_vnode_op;
res->type = VN_DIR;
return res;
}
// TODO: handle devices added post-mapper
static int devfs_node_mapper(fs_t *devfs, struct vfs_node **root) {
struct vfs_node *_root;
struct dev_entry *it;
// Make a root node
_root = (struct vfs_node *) kmalloc(sizeof(struct vfs_node));
_root->child = NULL;
_root->cdr = NULL;
_root->ismount = 0;
_root->parent = NULL;
_root->real_vnode = NULL;
_root->vnode = NULL;
// TODO: directory-categories (like "by-uuid" or something)
for (it = dev_iter(); it; it = it->cdr) {
struct vfs_node *ent_node = kmalloc(sizeof(struct vfs_node));
ent_node->child = NULL;
ent_node->ismount = 0;
ent_node->real_vnode = NULL;
strcpy(ent_node->name, it->dev_name);
// Create a vnode for device
vnode_t *ent_vnode = devfs_create_vnode(devfs, ent_node);
if (it->dev_class == DEV_CLASS_BLOCK) {
ent_vnode->type = VN_BLK;
} else if (it->dev_class == DEV_CLASS_CHAR) {
ent_vnode->type = VN_CHR;
} else {
panic("Unsupported device class\n");
}
ent_vnode->fs_data = it;
ent_vnode->dev = it->dev;
ent_node->vnode = ent_vnode;
ent_node->parent = _root;
ent_node->cdr = _root->child;
_root->child = ent_node;
}
vnode_t *vnode = devfs_create_vnode(devfs, _root);
_root->vnode = vnode;
*root = _root;
return 0;
}
static __init void devfs_init(void) {
fs_class_register(&_devfs);
}
+15 -5
View File
@@ -829,9 +829,6 @@ int vfs_open_node(struct vfs_ioctx *ctx, struct ofile *of, vnode_t *vn, int opt)
if (vn->type == VN_DIR) {
return -EISDIR;
}
if (vn->type != VN_REG) {
panic("Not implemented\n");
}
of->vnode = vn;
of->flags = opt;
@@ -938,6 +935,8 @@ ssize_t vfs_read(struct vfs_ioctx *ctx, struct ofile *fd, void *buf, size_t coun
vnode_t *vn = fd->vnode;
_assert(vn);
ssize_t nr;
switch (vn->type) {
case VN_REG:
_assert(vn->op);
@@ -956,7 +955,7 @@ ssize_t vfs_read(struct vfs_ioctx *ctx, struct ofile *fd, void *buf, size_t coun
return -EINVAL;
}
ssize_t nr = vn->op->read(fd, buf, count);
nr = vn->op->read(fd, buf, count);
if (nr > 0) {
fd->pos += nr;
@@ -967,7 +966,12 @@ ssize_t vfs_read(struct vfs_ioctx *ctx, struct ofile *fd, void *buf, size_t coun
// We don't need filesystem at all to read from devices
case VN_BLK:
_assert(vn->dev);
return blk_read((struct blkdev *) vn->dev, buf, fd->pos, count);
if ((nr = blk_read((struct blkdev *) vn->dev, buf, fd->pos, count)) > 0) {
fd->pos += nr;
}
return nr;
case VN_CHR:
_assert(vn->dev);
return chr_read((struct chrdev *) vn->dev, buf, fd->pos, count);
@@ -1227,6 +1231,12 @@ struct dirent *vfs_readdir(struct vfs_ioctx *ctx, struct ofile *fd) {
case VN_DIR:
ent_buf->d_type = DT_DIR;
break;
case VN_BLK:
ent_buf->d_type = DT_BLK;
break;
case VN_CHR:
ent_buf->d_type = DT_CHR;
break;
default:
kwarn("Unsupported vnode type: %d\n", item_node->vnode->type);
ent_buf->d_type = DT_UNKNOWN;
+1
View File
@@ -46,6 +46,7 @@ mkdirs:
mkdir -p $(DIRS)
mkstage-etc:
mkdir -p $(STAGE)/dev
cp -r etc $(STAGE)
# Application building
+19 -1
View File
@@ -86,7 +86,25 @@ static int cmd_exec(const char *cmd) {
}
while ((ent = readdir(dir))) {
printf("%c %s\n", ent->d_type == DT_DIR ? 'D' : '-', ent->d_name);
char type;
switch (ent->d_type) {
case DT_REG:
type = '-';
break;
case DT_DIR:
type = 'D';
break;
case DT_BLK:
type = 'b';
break;
case DT_CHR:
type = 'c';
break;
default:
type = '?';
break;
}
printf("%c %s\n", type, ent->d_name);
}
closedir(dir);