Ghost Kernel

Kernel bugfixing & new monitoring application 2015/09/29, 22:00:00

Lately I had some issues where the PS2 driver process froze for unrecognizable reasons. And it didn't freeze all the time - only when you did a quick series of command inputs. This led to a nice and long debugging time: the process did not hang in userspace, so it was obviously a problem in the kernel. There weren't many changes in the kernel API before, except... well, the new variable messaging implementation.

When a variably sized message is sent, the kernel looks for inside a map that contains the message queue head for the target process where the message will be inserted. When a process dies, it had inserted NULL into that map. And well, the next time accessing the map, it accessed a null pointer and things went weird.

Whats the lesson? Use assert or add checks everywhere you feel sure that this pointer points to a valid value now. You definitely don't want this kind of bugs. But if you have them, you might like my solution.

Monitoring application

So how did I find the cause of this. Well, when a process blocks, there is an instance of a so-called "waiter" attached to its structure. This waiter tries to do a specific operation (in this case, sending a message) each time the process would be scheduled. There are no kernel threads in Ghost, so they are all compressed to operations as small as possible that happen between two timeslices. The bug was in the routine that handled the sending, so the waiter would wait forever to send the message.

To get a monitoring application to see what process does what (kind of task manager you know from Windows, but outside of the kernel). This application (written in plain Java) connects to the TCP socket that QEMU can expose and that is internally linked to the COM1 port of the virtual machine. Like this, I can simply read bytes that are written from the kernel to COM1, and read bytes that I send there via the socket. I then defined a small protocol, that allows the kernel to send events. These events for example happen when a task is put to sleep (a waiter is appended). The task status is then updated and you can see it in the task area of the monitoring tool.

The tool also shows what filesystem nodes are cached in the kernel, what process uses how much CPU, and some other nice things. When the tool is a little more advanced (and the code erfined), I might make it more generic, I think other developers could profit of it too.

A little rudimentary by now, but you should get the idea. :-) This view for example shows the list of running threads, their binary source and their CPU usage (id 0 is the idle thread):


Changelog 0.4.3 2015/08/29, 22:00:00

  • Idle task uses "HLT" to prevent 100% processor usage
  • fixed some problems in the standard I/O implementation, piping now works
  • Directory reading functionality is reworked
  • Spawner and others uses variable messages
  • Color in the terminal, and a fancy start screen
  • Minor bugfixes here and there
  • gatomicwait is now gatomiclock
  • g_spawn has slightly changed, its now possible to specify in and out descriptors of a process when spawning it


Open source - GitHub repository 2015/07/26, 22:00:00

Today I took the time to fix some remaining issues and clean the project up to make it publicly available. You can now obtain the sources on GitHub, the project is licensed as GPLv3.

If you are interested in building the project, there is an explanation on how to set up the toolchain within the repository.


Adding userspace IRQ handling support (... and signals) 2015/07/24, 22:00:00

A lot has happened since I kicked out Newlib. There were some minor bugs, but userspace & the window manager are running again.

To improve the performance of interrupt handling, there is now support for thread interruption. This will also be used for implementing signals. Like this, a driver can decide to register a routine as an IRQ handler, and each time the interrupt occurs, the driver's thread is interrupted and may do necessary work. This works fine for keyboard and mouse already. Next thing will be using this mechanism for signals.


Terminal is up again! 2015/07/01, 22:00:00

After implementing the basic parts of the custom libc that now replaces Newlib, the system services and applications are up and ready again! There are still some issues with libstdc++-v3 that I'm currently fixing. In a first test, the window manager also turned out to run without a hassle with the new custom C library. Newlib is gone.

I did some cleanup in the project structure and reworked the build process, too. The code base was cleaned up a little. When I've finally decided for a license and eliminated some minor atrocities I'll go for a the first public source release. Stay tuned!