Initial commit - Begun rewrite of website generator
This commit is contained in:
95
pages/2013-12-13-Debug-Filesystem.md
Normal file
95
pages/2013-12-13-Debug-Filesystem.md
Normal file
@@ -0,0 +1,95 @@
|
||||
layout: post
|
||||
title: "The debug file system"
|
||||
subtitle: "It's still in the kernel!"
|
||||
tags: [osdev]
|
||||
|
||||
This far in my vfs rewrite, I've made a [vfs mount tree](/blog/2013/12/Virtual-File-System2/) and written some [file operation syscalls](/blog/2013/12/VFS-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](/blog/2012/06/Kernel-Debug-Functions/) 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!
|
||||
|
||||
Reference in New Issue
Block a user