2.7 KiB
layout: post title: "The debug file system" subtitle: "It's still in the kernel!" tags: [osdev, filesystems]
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.
:::c
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...
:::c
uint32_t debug_isatty(INODE node)
{
return 1;
}
The debug output is a terminal.
:::c
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":
:::c
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:
:::c
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
:::c
vfs_init();
vfs_mount("/", debug_dev_init());
in my kernel boot code. After that I can use the standard library functions:
:::c
FILE *dbg = fopen("/", "w");
fprintf(dbg, "Hello, world!\n");
or even:
:::c
fopen("/", "r");
fopen("/", "w");
printf("Hello, world!\n");
That's it for this time. Next time, we'll do some piping!