July 2, 2011

File system, exceptions, and signals

Ok, so I didn't get my file system completed on my trip a few months ago. In fact, I didn't work on it at all during the trip. (I don't know why I thought I would)

I am now, however, working in earnest on getting the file system to work. This involves removing a lot of old code and rewriting some of the code. I'm basing my file system interfaces on Linux, which stores pointers to functions for open, close, read, write, lseek, and other system calls in the file and inode structures. This way each different type of file system (eg, FAT32, NTFS, or ext3) can supply its own set of methods for each system call. I'm simplifying the interfaces here and there, but it should be recognizable as being derived from Linux.

At first I am not going to write the Punix File System (which is stored on FlashROM), since that involves debugging PFS itself, the FlashROM block device driver, block buffer system, and the VFS interfaces. I am actually writing a memory-based file system, tmpfs, as the first file system. This removes device drivers and block buffers out of the equation. I only need to get VFS and tmpfs working correctly. Once tmpfs works, I'll start testing the flash driver and block buffer, and then writing PFS.

On an unrelated note, I made exceptions work correctly now. They used to panic regardless of the source (user or kernel). Now they panic only if they come from the kernel. Otherwise they send the appropriate signal to the offending process, which kills the process by default. I don't think signals are working completely yet, but they work well enough to cause a process to terminate.

While I was working on the link port driver, I uncovered a dormant bug in the "tests" applet in the shell which resulted in an Address Error exception:
When the applet timed out reading a packet, it attempted to longjmp() to an invalid context (without a matching setjmp()). I never saw this bug before because I always had "Listen for files" enabled in TiEmu, so TiEmu always replied immediately.

Regardless of what caused the address error, the kernel successfully caught and handled it. I ran the applet in a subshell, so only the subshell process died, and the parent shell took over and reported that the subshell terminated and how. The system just kept running as if nothing happened. TI-AMS would barf all over itself in this situation. :)

Of course... Punix will send a signal like this only when an exception occurs. It can do nothing about a process overwriting memory that belongs to the kernel or to another process. I mean "nothing" as in "no practical way to do it". There are ways to detect when it happens, but every way to do so would add significant overhead in time or memory. One example would be to dedicate all of RAM to a single process and use FlashROM as swap space. This would be a significant overhead in time and memory (though this method would have a few advantages).