Add read/write syscalls again
This commit is contained in:
+3
-3
@@ -8,7 +8,8 @@ CFLAGS+=-Wall \
|
||||
-Wno-unused-variable \
|
||||
-Wno-language-extension-token \
|
||||
-Wno-gnu-zero-variadic-macro-arguments \
|
||||
-O0
|
||||
-O0 \
|
||||
-ggdb
|
||||
|
||||
ifdef KERNEL_TEST_MODE
|
||||
CFLAGS+=-DKERNEL_TEST_MODE
|
||||
@@ -40,7 +41,6 @@ CFLAGS+=-D__KERNEL__
|
||||
# $(O)/sys/vfs/tar.o \
|
||||
# $(O)/sys/binfmt_elf.o \
|
||||
# $(O)/sys/errno.o \
|
||||
# $(O)/sys/tty.o \
|
||||
# $(O)/sys/chr.o
|
||||
|
||||
OBJS+=$(O)/sys/debug.o \
|
||||
@@ -64,12 +64,12 @@ OBJS+=$(O)/sys/debug.o \
|
||||
$(O)/sys/vfs/ext2/ext2blk.o \
|
||||
$(O)/sys/vfs/tar.o \
|
||||
$(O)/sys/blk/ram.o \
|
||||
$(O)/sys/tty.o \
|
||||
$(O)/sys/reboot.o \
|
||||
$(O)/sys/random.o \
|
||||
$(O)/sys/init.o
|
||||
|
||||
# \
|
||||
$(O)/sys/tty.o \
|
||||
$(O)/sys/vfs/pty.o \
|
||||
$(O)/sys/vfs/ext2/ext2alloc.o \
|
||||
$(O)/sys/vfs/ext2/ext2dir.o \
|
||||
|
||||
@@ -2,6 +2,10 @@
|
||||
#include "node.h"
|
||||
#include <sys/types.h>
|
||||
|
||||
#define OF_WRITABLE (1 << 0)
|
||||
#define OF_READABLE (1 << 1)
|
||||
#define OF_DIRECTORY (1 << 2)
|
||||
|
||||
struct ofile {
|
||||
int flags;
|
||||
struct vnode *vnode;
|
||||
|
||||
@@ -28,9 +28,11 @@ int vfs_link_resolve(struct vfs_ioctx *ctx, struct vnode *lnk, struct vnode **re
|
||||
int vfs_find(struct vfs_ioctx *ctx, struct vnode *rel, const char *path, struct vnode **node);
|
||||
int vfs_mount(struct vfs_ioctx *ctx, const char *at, void *blk, const char *fs, const char *opt);
|
||||
|
||||
int vfs_open_vnode(struct vfs_ioctx *ctx, struct ofile *fd, struct vnode *node, int opt);
|
||||
int vfs_open(struct vfs_ioctx *ctx, struct ofile *fd, const char *path, int flags, int mode);
|
||||
void vfs_close(struct vfs_ioctx *ctx, struct ofile *fd);
|
||||
|
||||
int vfs_stat(struct vfs_ioctx *ctx, const char *path, struct stat *st);
|
||||
|
||||
ssize_t vfs_write(struct vfs_ioctx *ctx, struct ofile *fd, const void *buf, size_t count);
|
||||
ssize_t vfs_read(struct vfs_ioctx *ctx, struct ofile *fd, void *buf, size_t count);
|
||||
|
||||
@@ -16,8 +16,6 @@
|
||||
#define THREAD_STOPPED (1 << 2)
|
||||
|
||||
// Thread init flags:
|
||||
// Initialize I/O context and open stdio
|
||||
#define THREAD_INIT_IOCTX (1 << 1)
|
||||
// Initialize platform context
|
||||
#define THREAD_INIT_CTX (1 << 0)
|
||||
|
||||
@@ -26,6 +24,8 @@ typedef uint64_t *mm_space_t;
|
||||
#include "sys/amd64/sys/thread.h"
|
||||
#endif
|
||||
|
||||
#define THREAD_MAX_FDS 16
|
||||
|
||||
struct image_info {
|
||||
uintptr_t image_end;
|
||||
uintptr_t brk;
|
||||
@@ -47,7 +47,7 @@ struct thread {
|
||||
int exit_code;
|
||||
|
||||
struct vfs_ioctx ioctx;
|
||||
struct ofile fds[4];
|
||||
struct ofile *fds[THREAD_MAX_FDS];
|
||||
|
||||
// Signals
|
||||
uint32_t sigq;
|
||||
|
||||
+1
-1
@@ -33,7 +33,7 @@ uint32_t ps2_irq_keyboard(void *ctx) {
|
||||
char key_char = ps2_key_table_0[key];
|
||||
|
||||
if (key_char != 0) {
|
||||
//tty_buffer_write(0, key_char);
|
||||
tty_buffer_write(0, key_char);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@ static uint32_t rs232_irq(void *ctx) {
|
||||
c = '\n';
|
||||
}
|
||||
|
||||
//tty_buffer_write(0, c);
|
||||
tty_buffer_write(0, c);
|
||||
}
|
||||
|
||||
return has_data ? IRQ_HANDLED : IRQ_UNHANDLED;
|
||||
|
||||
+1
-1
@@ -64,7 +64,7 @@ void kernel_main(struct amd64_loader_data *data) {
|
||||
pci_init();
|
||||
|
||||
vfs_init();
|
||||
//tty_init();
|
||||
tty_init();
|
||||
if (data->initrd_ptr) {
|
||||
// Create ram0 block device
|
||||
ramblk_init(MM_VIRTUALIZE(data->initrd_ptr), data->initrd_len);
|
||||
|
||||
+1
-14
@@ -102,14 +102,6 @@ int thread_platctx_init(struct thread *t, uintptr_t entry, void *arg) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int thread_ioctx_init(struct thread *t, uint32_t init_flags) {
|
||||
_assert(t);
|
||||
|
||||
// Setup default I/O context
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int thread_init(
|
||||
struct thread *t,
|
||||
mm_space_t space,
|
||||
@@ -191,11 +183,6 @@ int thread_init(
|
||||
thread_platctx_init(t, entry, arg);
|
||||
}
|
||||
|
||||
// 4. Setup I/O context if requested
|
||||
if (init_flags & THREAD_INIT_IOCTX) {
|
||||
thread_ioctx_init(t, init_flags);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -204,7 +191,7 @@ void thread_cleanup(struct thread *t) {
|
||||
|
||||
// Release files
|
||||
for (size_t i = 0; i < 4; ++i) {
|
||||
if (t->fds[i].vnode) {
|
||||
if (t->fds[i]) {
|
||||
//vfs_close(&t->ioctx, &t->fds[i]);
|
||||
}
|
||||
}
|
||||
|
||||
+21
-12
@@ -10,24 +10,33 @@
|
||||
#include "sys/debug.h"
|
||||
|
||||
ssize_t sys_read(int fd, void *buf, size_t lim) {
|
||||
return -EINVAL;
|
||||
//if (fd >= 4 || fd < 0) {
|
||||
// return -EBADF;
|
||||
//}
|
||||
//struct thread *thr = get_cpu()->thread;
|
||||
//_assert(thr);
|
||||
struct thread *thr = get_cpu()->thread;
|
||||
_assert(thr);
|
||||
|
||||
//struct ofile *of = &thr->fds[fd];
|
||||
if (fd < 0 || fd >= THREAD_MAX_FDS) {
|
||||
return -EBADF;
|
||||
}
|
||||
|
||||
//if (!of->vnode) {
|
||||
// return -EBADF;
|
||||
//}
|
||||
if (thr->fds[fd] == NULL) {
|
||||
return -EBADF;
|
||||
}
|
||||
|
||||
//return vfs_read(&thr->ioctx, of, buf, lim);
|
||||
return vfs_read(&thr->ioctx, thr->fds[fd], buf, lim);
|
||||
}
|
||||
|
||||
ssize_t sys_write(int fd, const void *buf, size_t lim) {
|
||||
return -EINVAL;
|
||||
struct thread *thr = get_cpu()->thread;
|
||||
_assert(thr);
|
||||
|
||||
if (fd < 0 || fd >= THREAD_MAX_FDS) {
|
||||
return -EBADF;
|
||||
}
|
||||
|
||||
if (thr->fds[fd] == NULL) {
|
||||
return -EBADF;
|
||||
}
|
||||
|
||||
return vfs_write(&thr->ioctx, thr->fds[fd], buf, lim);
|
||||
}
|
||||
|
||||
ssize_t sys_readdir(int fd, struct dirent *ent) {
|
||||
|
||||
+27
@@ -72,6 +72,33 @@ static void user_init_start(void) {
|
||||
|
||||
kfree(file_buffer);
|
||||
|
||||
// Setup I/O context for init task
|
||||
struct ofile *stdin, *stdout, *stderr;
|
||||
file_buffer = kmalloc(sizeof(struct ofile) * 2);
|
||||
_assert(file_buffer);
|
||||
|
||||
stdin = (struct ofile *) file_buffer;
|
||||
stdout = (struct ofile *) (file_buffer + sizeof(struct ofile));
|
||||
stderr = stdout;
|
||||
|
||||
// TODO: use dev_find and open its node instead
|
||||
struct vnode *stdout_device;
|
||||
if ((res = dev_find(DEV_CLASS_CHAR, "tty0", &stdout_device)) != 0) {
|
||||
panic("%s: %s\n", "tty0", kstrerror(res));
|
||||
}
|
||||
|
||||
if ((res = vfs_open_vnode(&user_init->ioctx, stdin, stdout_device, O_RDONLY)) != 0) {
|
||||
panic("Failed to open stdin for init task: %s\n", kstrerror(res));
|
||||
}
|
||||
if ((res = vfs_open_vnode(&user_init->ioctx, stdout, stdout_device, O_WRONLY)) != 0) {
|
||||
panic("Failed to open stdout/stderr for init task: %s\n", kstrerror(res));
|
||||
}
|
||||
|
||||
// TODO: use STDIN_/STDOUT_/STDERR_FILENO macros
|
||||
user_init->fds[0] = stdin;
|
||||
user_init->fds[1] = stdout;
|
||||
user_init->fds[2] = stderr;
|
||||
|
||||
sched_add(user_init);
|
||||
}
|
||||
|
||||
|
||||
@@ -22,12 +22,6 @@ static struct chrdev _dev_tty0 = {
|
||||
.write = tty_write,
|
||||
.read = tty_read
|
||||
};
|
||||
static struct dev_entry _ent_tty0 = {
|
||||
.dev = &_dev_tty0,
|
||||
.dev_class = DEV_CLASS_CHAR,
|
||||
.dev_subclass = DEV_CHAR_TTY,
|
||||
.dev_name = "tty0"
|
||||
};
|
||||
|
||||
static struct ring tty_ring = {0};
|
||||
|
||||
@@ -38,7 +32,8 @@ void tty_buffer_write(int tty_no, char c) {
|
||||
|
||||
void tty_init(void) {
|
||||
ring_init(&tty_ring, 16);
|
||||
dev_entry_add(&_ent_tty0);
|
||||
|
||||
dev_add(DEV_CLASS_CHAR, DEV_CHAR_TTY, &_dev_tty0, "tty0");
|
||||
}
|
||||
|
||||
// TODO: multiple ttys
|
||||
|
||||
+81
-17
@@ -6,6 +6,7 @@
|
||||
#include "sys/debug.h"
|
||||
#include "sys/errno.h"
|
||||
#include "sys/fcntl.h"
|
||||
#include "sys/chr.h"
|
||||
|
||||
static int vfs_find_internal(struct vfs_ioctx *ctx, struct vnode *at, const char *path, struct vnode **child);
|
||||
|
||||
@@ -348,6 +349,45 @@ int vfs_find(struct vfs_ioctx *ctx, struct vnode *rel, const char *path, struct
|
||||
|
||||
///////////
|
||||
|
||||
int vfs_open_vnode(struct vfs_ioctx *ctx, struct ofile *fd, struct vnode *node, int opt) {
|
||||
int res;
|
||||
|
||||
_assert(ctx);
|
||||
_assert(fd);
|
||||
_assert(node);
|
||||
|
||||
if (opt & O_DIRECTORY) {
|
||||
panic("NYI: O_DIRECTORY\n");
|
||||
}
|
||||
|
||||
// 1. If file operations struct specifies some non-trivial open()
|
||||
// function for the node - use it
|
||||
if (node->op && node->op->open) {
|
||||
if ((res = node->op->open(node, opt)) != 0) {
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
// 2. Setup ofile
|
||||
fd->pos = 0;
|
||||
fd->vnode = node;
|
||||
fd->flags = 0;
|
||||
|
||||
switch (opt & O_ACCMODE) {
|
||||
case O_RDONLY:
|
||||
fd->flags |= OF_READABLE;
|
||||
break;
|
||||
case O_WRONLY:
|
||||
fd->flags |= OF_WRITABLE;
|
||||
break;
|
||||
case O_RDWR:
|
||||
fd->flags |= OF_READABLE | OF_WRITABLE;
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int vfs_open(struct vfs_ioctx *ctx, struct ofile *fd, const char *path, int opt, int mode) {
|
||||
struct vnode *node;
|
||||
int res;
|
||||
@@ -358,27 +398,14 @@ int vfs_open(struct vfs_ioctx *ctx, struct ofile *fd, const char *path, int opt,
|
||||
|
||||
// 1. Try to find the file
|
||||
if ((res = vfs_find(ctx, ctx->cwd_vnode, path, &node)) != 0) {
|
||||
panic("NYI: O_CREAT\n");
|
||||
}
|
||||
|
||||
if (opt & O_DIRECTORY) {
|
||||
panic("NYI: O_DIRECTORY\n");
|
||||
}
|
||||
|
||||
// 2. If file operations struct specifies some non-trivial open()
|
||||
// function for the node - use it
|
||||
if (node->op && node->op->open) {
|
||||
if ((res = node->op->open(node, opt)) != 0) {
|
||||
if (opt & O_CREAT) {
|
||||
panic("NYI: O_CREAT\n");
|
||||
} else {
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
// 3. Setup ofile
|
||||
fd->pos = 0;
|
||||
fd->vnode = node;
|
||||
fd->flags = opt;
|
||||
|
||||
return 0;
|
||||
return vfs_open_vnode(ctx, fd, node, opt);
|
||||
}
|
||||
|
||||
void vfs_close(struct vfs_ioctx *ctx, struct ofile *fd) {
|
||||
@@ -405,9 +432,43 @@ int vfs_stat(struct vfs_ioctx *ctx, const char *path, struct stat *st) {
|
||||
return node->op->stat(node, st);
|
||||
}
|
||||
|
||||
ssize_t vfs_write(struct vfs_ioctx *ctx, struct ofile *fd, const void *buf, size_t count) {
|
||||
struct vnode *node;
|
||||
|
||||
_assert(fd);
|
||||
|
||||
if (!(fd->flags & OF_WRITABLE) || (fd->flags & OF_DIRECTORY)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
node = fd->vnode;
|
||||
|
||||
_assert(ctx);
|
||||
_assert(buf);
|
||||
_assert(node);
|
||||
|
||||
switch (node->type) {
|
||||
case VN_REG:
|
||||
_assert(node->op && node->op->write);
|
||||
return node->op->write(fd, buf, count);
|
||||
case VN_CHR:
|
||||
_assert(node->dev && ((struct chrdev *) node->dev)->write);
|
||||
return chr_write(node->dev, buf, fd->pos, count);
|
||||
|
||||
case VN_DIR:
|
||||
default:
|
||||
// Cannot do such things
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
ssize_t vfs_read(struct vfs_ioctx *ctx, struct ofile *fd, void *buf, size_t count) {
|
||||
struct vnode *node;
|
||||
|
||||
if (!(fd->flags & OF_READABLE)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
_assert(fd);
|
||||
|
||||
node = fd->vnode;
|
||||
@@ -420,6 +481,9 @@ ssize_t vfs_read(struct vfs_ioctx *ctx, struct ofile *fd, void *buf, size_t coun
|
||||
case VN_REG:
|
||||
_assert(node->op && node->op->read);
|
||||
return node->op->read(fd, buf, count);
|
||||
case VN_CHR:
|
||||
_assert(node->dev && ((struct chrdev *) node->dev)->read);
|
||||
return chr_read(node->dev, buf, fd->pos, count);
|
||||
|
||||
case VN_DIR:
|
||||
default:
|
||||
|
||||
Reference in New Issue
Block a user