If you've watched some of my earlier videos or seen my posts here or on Discord, you might have seen that I've been working on my own QNX-like OS. Up until fairly recently, UX/RT only ran hardcoded tests built into the process server and had nothing to interact with, but now I have it running a minimal shell and a few other user programs. A demo VM image is now available on the dedicated site that I just set up for UX/RT, as well as in the Virtual OS Museum.
It's still quite preliminary though; rather than a regular shell like bash, the shell I've ported is sash, which is a minimalist shell with built-in implementations of common commands intended for system recovery purposes, which also makes it ideal for early bringup of a new OS. I've also ported a couple programs from the BSD games package. The first of these is banner, which displays an ASCII art banner of user-provided text. The second is the game Hunt the Wumpus, the Unix version of which dates back to Fourth Edition Research Unix from 1973, the first version to have a kernel written in C.
Still, a lot is unimplemented, and it's quite a ways away from the full-featured workstation and embedded OS I want to to be. There are no I/O device drivers except for the console serial port, and even that is a temporary hack built into the process server, since there isn't yet any support for the arbitrary user-level server processes characteristic of microkernel OSes. Everything is just running out of an in-memory filesystem built into the boot image that's basically the equivalent of Linux's initramfs. A lot of APIs are still unimplemented, and what is implemented is just enough to be able to run the stuff that's there. Performance also leaves a lot to be desired, for various reasons.
I've definitely learned a fair bit since I made my original video on UX/RT. seL4 turned out to be less than ideal for this kind of OS to say the least. By the way, if you want more information on how microkernel OSes work, there's a link in the description to an introductory video I made on them. Initially I'd planned to track upstream seL4 and use asynchronous message queues and per-thread buffers to support transferring arbitrary-sized messages between threads, but that would have ended up being overcomplicated and would have suffered from priority inversion in some situations, so I instead decided to fork the kernel and add support for QNX-style task-to-task copying of arbitrary-sized messages in the kernel itself. However, my implementation of that isn't very well optimized, and it still doesn't integrate asynchronous notifications with synchronous message passing the way QNX does with pulses. There's still also the issue of the convoluted seL4 memory model, which imposes a dependency cycle on memory allocation and requires making a separate system call to map each memory page, which isn't particularly good for performance on a general-purpose OS that allocates memory frequently. There's also seL4's use of a giant kernel lock meaning that only one thread can make a system call at a time, which also isn't good for performance either. Having the process server separate from the kernel rather than built into it as QNX does limits performance as well, and I can't see any really major disadvantages to colocating it in the kernel.
I could try to fix these issues in the existing seL4-derived kernel, but I'm probably better off trying to switch to another kernel. I'm thinking I'll base the new kernel on a fork of L4Ka, which was an older L4 kernel that had support for arbitrary-size message passing unlike seL4, meaning it should have a more optimized implementation than the rather hacky one in the current kernel. It also used fine-grained locking rather than a single giant kernel lock, so that's another thing I won't have to add. I will have to change it from using thread IDs to file descriptors as destinations for messages, which hopefully shouldn't be too difficult. I will also have to replace the memory management code based on recursive address spaces. Since I will be colocating the process server in the kernel, this hopefully shouldn't be too difficult either because the process server should just be able to manipulate page tables directly. I really wish I would have just done something like this from the beginning. I wasted lots of time fighting with seL4's memory and message passing models and would have probably spent less time converting some other kernel like L4Ka instead of trying to work around seL4's limitations. seL4 actually is pretty decent for the kinds of static embedded systems it's most commonly used in, but it's certainly less than ideal for a highly dynamic QNX-like OS such as UX/RT.
By the way, if anyone else is interested in contributing, I'm definitely open to that, and it should be easier now that I have user programs working and there are more possibilities for things to implement in parallel.
If you wish to support me monetarily, you can check out my Patreon and Ko-fi. Patrons get early access to my videos and a shoutout at the end of my videos and in the OS museum credits file. Anyway I think that's about everything. Thanks for watching.



