The debug file system

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!

Comments

comments powered by Disqus
© 2012 Thomas Lovén - @thomasloven - GitHub