In order to balance my previous blog, I decided to sum up some recent achievements on the HelenOS front. These things are well known to people who follow our mailing list, but I suspect that the majority of people out there are not even subscribed.
I scratched two of my long time kernel itches: the infamous "Sleep not implemented" panic and the kernel's inability to allocate memory from a low-memory region.
The "Sleep not implemented" panic occurred every time when the kernel invoked frame_alloc() in its blocking mode under very low memory conditions. That happened when the (virtual) machine had less memory than what the system required. After my modification, the offending thread would be simply put to sleep instead of panicing the kernel. When there is enough memory, the thread can complete the allocation request. The catch is that when all of the threads just allocate and none of them frees memory, all the threads will be put to sleep and none will run. You still have the possibility to break into kconsole and kill some of the tasks so that its allocated memory is freed and others can run. You are out of luck when the one which went to sleep is the kconsole thread itself (that could happen when running the kernel tests which allocate lots of memory). The situation can be further improved when we have support for paging pages out and back in. Btw, this improvement finally found good use for condition variables.
As mentioned above, the kernel can now theoretically allocate memory from the lowest 4G (contrary to allocating from all memory available). This is necessary, for example, for allocation of secondary processors' GDT on amd64. The fix works in the following way. When a memory zone is created, it is associated with flags that describe it. The frame allocator was slightly altered to only consider zones matching flags passed along with the request, if some were specified by the caller. What remains to be done is to change the way how memory zones are created in the architecture specific initialization code. In particular, it is necessary to avoid merging zones with incompatible flags.
My biggest achievement, however, is the read-only support for FAT16 as the root file system. Together with Tim Post's addition of a simple command line interface, Martin Decky's boot-from-ramdisk infrastructure and Jiri Svoboda's task loader, the system is now much more usable than before. The biggest differentiator is that you can now interactively walk the file system (either FAT or TMPFS) and spawn as many new tasks (located on the file system) as you want. Due to ramdisk size issues, the FAT filesystem is now usable only on ia32 and amd64, but this is likely to change soon.