13 Dec 2013
This far in my vfs rewrite, I've made a vfs mount tree and written some file operation syscalls. Now it's time to actually use this, by writing a filesystem that can be mounted and then manipulated through the syscall interface.
The filesystem I want to start with is what I call the debug
file.
It is a single file, which mounts to /
for now (later /dev/debug
)
and cannot be read from. Writing to it will print the written text on
the screen.
Three functions are needed for newlib fprintf
to be able to write to
it: stat
, isatty
and write
. Those are all rather simple, since
they won't need to keep track of which file we're referencing.
uint32_t debug_stat(INODE node, struct stat *st) { memset(st, 0, sizeof(struct stat)); st->st_mode = S_IFCHR; return 0; }
I don't care much about the stat for the debug file. Maybe I'll add some creation time or so later...
uint32_t debug_isatty(INODE node) { return 1; }
The debug output is a terminal.
uint32_t debug_write(INODE node, void *buffer, uint32_t size, uint32_t offset) { char *buf = calloc(size + 1, 1); memcpy(buf, buffer, size); kdbg_puts(buf); free(buf); return size; }
kdbg_puts
is a function I wrote
a long time ago which prints a
string to the screen. The first two lines are just to make sure that the
data is null-terminated.
With this, I can define a driver for the "debug device":
vfs_driver_t debug_driver = { 0, // open 0, // close 0, // read debug_write, // write 0, // link 0, // unlink debug_stat, // stat debug_isatty, // isatty 0, // mkdir 0, // readdir 0 // finddir };
And then write a function to setup the device:
INODE debug_dev_init() { INODE node = calloc(1, sizeof(vfs_node_t)); strcpy(node->name, "debug"); node->d = &debug_driver; node->type = FS_CHARDEV; return node; }
Then, to activate it, all I need to do is add
vfs_init(); vfs_mount("/", debug_dev_init());
in my kernel boot code. After that I can use the standard library functions:
FILE *dbg = fopen("/", "w"); fprintf(dbg, "Hello, world!\n");
or even:
fopen("/", "r"); fopen("/", "w"); printf("Hello, world!\n");
That's it for this time. Next time, we'll do some piping!