VOGONS


First post, by gsos

User metadata
Rank Newbie
Rank
Newbie

Years ago I started a personal project to learn how kernels work at their core. My initial goals and principles were
1) Try to use absolute minimum of ASM
2) Try to make the logic as clear as possible (educational)
3) Work from the philosophy that "programming languages are to CPU/MEM, what Kernel is to the machine/peripherals".

The last point is that a kernel should abstract the details of a machine into an API that allows usage of the machine as it interacts with humans in a portable form, just like programming languages do this for the machine as it computes. 
See my readme https://github.com/gerben-stavenga/RetroOS/bl … 8e505/README.md from 2023.

It became a working prototype kernel over my summer time off, but development stalled like it happens a lot with hobby os's. I had plans to have the kernel run 16,32 and 64 bit code and support old dos games.
Over the last months, I immersed myself in doing agentic coding projects to learn what is possible and I decided to pick up my kernel work. I had AI port it to rust which is what I have been coding in the last couple of years and which is well suited for OS dev. Using LLM allowed me to aggressively refactor and try out some new designs.
I pushed further on the design principles I started from and could really isolate the core of the kernel into a form where it became a rust trait/lib, that could either be implemented by the actual core-arch or by an interpreter. Using this I could build a kernel on top of it utilizing AI to implement syscall API's. I chose to do legacy DOS and Linux. Very quickly I could get some games working which made the project very fun. 

https://www.youtube.com/watch?v=Clh45xUpZNY

I ended up with a project that might be of some interest for the vogons community. It's basically a near fully compatible DOS OS. The kernel can be compiled against arch-metal and be installed on your computer to play natively (or run using qemu/bochs/86box), or it can be compiled against arch-interp (based on unicorn / qemu tcg) and it works like a dosbox app.

It tries to be as retro as possible, so on legacy bios machines with legacy soundblaster you can play the games natively utilizing vga/sound blaster directly. If you have a machine without a sound blaster it can emulate it over ac97 or hda. If you have a modern uefi without legacy bios it can emulate vga as well. Vga emulation and hda emulation is still work in progress and there are rough edges and some bugs, but it's in a state where one can start playing for real.

Previously I posted on vogons and it got removed because it violated rules around AI. I got a message on my youtube from a vogons visitor who expressed interest.,this incentivized me to try to post once more. Obviously I used AI to get my OS to a state where it presents some interesting capabilities. Filling in DOS int 21 syscalls or DPMI API in 30 min is just such a relief, allowing me to focus on design / architecture while seeing results. I know AI is a touchy subject, but I believe this project still to be of interest to this community.

Reply 1 of 35, by gsos

User metadata
Rank Newbie
Rank
Newbie

This hobby project has added quite a bit of features and I think the architecture will be interesting to the OS aficionados on this forum. See

https://www.youtube.com/watch?v=_DG_4CkjV9I

The most interesting thing perhaps is that I was able to isolate the x86 core stuff into arch-metal lib that implements arch-abi trait. The way it's setup is such, that I also implemented the trait by wrapping QEMU TCG engine (unicorn) and also a full kvm variant. The actual kernel (vfs, dos personality, linux personality, threading, ...) is written in almost entirely safe rust calling into a handful of arch functions through the arch-abi trait. This means that the same kernel can be build in three modes,

1) metal. It's a full OS with both legacy bios and modern uefi compatibility. So it can run on old machines with vga compatible graphics and sound blaster and it will expose this. But it can also run on uefi with hda, in which case vga and sound blaster is emulated, so you can still play your retro-games directly on the machine.

2) interpreted. This is basically dosbox mode, the QEMU TCG emulates the userspace programs, while the kernel is compiled as a regular app running native on the host machine. This can be played on any architecture.

3) kvm. This is basically dosemu2 mode. The userspace apps run natively on the cpu under kvm hypervisor, the kernel still runs as a regular app on the host machine. Most of the hosted specific code is shared with interpreted mode. The only differnce is that TCG is replaced with native execution using kvm

All the three modes above run the exact same kernel, with only a different implementation of the arch-abi injected. This actually is quite convenient as one can just run and debug the kernel like any normal app. No need to hook gdb through qemu or that kind of tricks.

So far it allows me to play my favorite games from my youth again on my razer laptop which is very satisfying. You can use it by just copying the kernel into your ext4 /boot directory, setup grub entry and /home/retroos becomes c: . You have access to your linux tools by starting shell.elf in c:\boot , but this is still work in progress (ls/cat/echo work but I'm not close to full linux environment). Of course I recommend qemu and installing it on your computer as in the video above is at your own risk. Anyway the project is complete enough that it might appeal to some retro hobbyist.

Of course I used AI as a "compiler" to compile DOS syscall spec to rust, compile the DPMI spec to rust, linux syscall API to rust. But the design and architecture is mine and you can see that that is still very similar to my code written back in 2023 in this repo. The design of the OS seems to occupy a somewhat new/original spot in the OS design space, sharing features and ideas with many other concepts in kernel design but in a unique way.

It is a monolithic kernel, one elf linked together, but it shares many ideas with microkernels. Arch is a microkernel , but uses just function calls instead of messages. The arch design is more like a hypervisor then the standard osdev tutorial/linux flow, which allows to abstract the core as a library. I haven't seen the trait factorization, ie. providing different ways of running the same kernel, done this way, but it of course strongly reminds one of UM-linux.

What I certainly havent seen before is using recursive paging in a way that unifies 32bit PAE paging and x64 paging, allowing the kernel to seamlessly toggle between 32bit and 64bit mode, which allows vm86 and 64-bit code to execute under one kernel (without the virtualization instruction set).

Specs:
It should run on 386/bios all the way up to x64/uefi without CSM. If you have an old computer with an actual sound blaster, games can use it natively. Otherwise sound blaster/adlib (experimental gus) is supported over hda/ac97 systems. Also when vga is not available, vga is emulated over the regular framebuffer. The video is RetroOS running on a razer (2025) with realtek hda. Old 486/sb I only tested through qemu/bochs/86box emulators.

Reply 2 of 35, by aVd

User metadata
Rank Member
Rank
Member

Hi, @gsos,
This is one very interesting project. Maybe I'm wrong, but at first glance it looks to me like a DOS (compatible) kernel without COMMAND.COM support.

I like the quieter planets, this one became pretty noisy 😀

Reply 3 of 35, by gsos

User metadata
Rank Newbie
Rank
Newbie
aVd wrote on 2026-07-12, 07:45:

Hi, @gsos,
This is one very interesting project. Maybe I'm wrong, but at first glance it looks to me like a DOS (compatible) kernel without COMMAND.COM support.

Yes it’s a dos compatible kernel (but also Linux compatible) it has a very basic command.com the forks address space to start programs. I use dos navigator as the tui to the os for the retro feel. It DN invokes “command.com /c program.exe” to start programs which forks internally. Look for command.c in the repo it is compiled by Borland c using retro os itself as part of the build to build command. Com . But command. Com is not a shell currently no

Reply 4 of 35, by Jo22

User metadata
Rank l33t++
Rank
l33t++

Hi there! I like DN, too - good choice! 🙂 DN is small and quick. A bit like NC 1.0 if run via NCSMALL.
This *nix/DOS crossover is interesting, I think. MS-DOS 2 used to have POSIX elements, I remember.

"Time, it seems, doesn't flow. For some it's fast, for some it's slow.
In what to one race is no time at all, another race can rise and fall..." - The Minstrel

//My video channel//

Reply 5 of 35, by gsos

User metadata
Rank Newbie
Rank
Newbie

Yeah I used NC as a child and still like orthodox file managers the best. NC is proprietary and DN is better and free to distribute, hence.

The origin of the project was more OS design focused, my goal was to decouple syscall api and other kernel specifics from managing resources. This worked out well, I'm planning to add OS/2, windows and freebsd personality in the near future. For now I'm mostly focused on getting the old hardware that effectively is part of the dos api (as programs would program those directly) emulated correctly . This is vga (some modes are not behaving properly see jazz jack rabbit), GUS music doesnt maintain exact tempo currently, roland emulation (still to do).

Also need drivers for modern hardware like the touchpad for mouse and ideally ethernet drivers + tcp stack.

Reply 6 of 35, by gsos

User metadata
Rank Newbie
Rank
Newbie

I addressed some sound issues, GUS starts sounding normal now, lag is now low enough to be unnoticeable to me and removing echos where the system couldn't keep up. This was an interesting exercise. The source of the problem is that intel really f'd up on the design in 32 bit mode with respect to interrupt flags, cli/sti trap however popf/iret just silently drop IF. The DPMI spec does say that users should use cli/sti or dpmi functions and not use popf to clear/set. Unfortuantely the typical dos-extenders were running code with iopl=3 which gave the dos-games full control over IF, something unacceptable for RetroOS, and doom/duke3d/raptor/etc... al rely on popf restoring interrupts. The solution I used was using the trap flag to single step when VIF=0 until a popf/iret restores VIF to prevent hangs. This was to brutal, doom DMX is mixing in VIF=0 and explosion of 100-1000x in instruction was causing starvation. I added a repair (where the kernel learns where to restore VIF after first single stepping) this makes most games run without single stepping and producing good sound.

Reply 7 of 35, by BinaryDemon

User metadata
Rank Oldbie
Rank
Oldbie

A super interesting project. I’m curious about the bare metal, the ram requirements are similar to MSDOS? Not sure I’ve ever seen a 386 with less than 2mb, but if the system only had 640kb ram would it still load and have enough memory to run stuff like Wolf3D / Prince / Keen?

Reply 8 of 35, by gsos

User metadata
Rank Newbie
Rank
Newbie

Thanks. Currently I haven't optimized the kernel for size too much, I'm sure there are a lot of things to make it smaller. The most egregious, currently kernel.elf contains command.com and dos navigator as a tarfs image in .rodata, so that it garanteed boots into DN without needing c: to be initialized in a specific way. This of course is nonsense and should go away. For now it needs some decent amount of memory available, but I haven't yet tested a workable minimum to be honest. But 640kb is not going to work, the boot process itself at the moment requires the kernel to be placed at 1mb. But I agree, it should support 2mb machines where the kernel lives >1mb and would have full 640kb available for dos programs with still something along ~500kb of memory free for ems/xms.

Future work definitely should include minimizing the kernel and perhaps add some paging/swap capability to allow it to run on minimal memory requirements is certainly a interesting project.

Reply 9 of 35, by tcaud

User metadata
Rank Newbie
Rank
Newbie

My first thought is we already have FreeDOS for this.

I'm really not enthused by the prospect of wrestling with 640k of memory to make a game (let alone the 256 color limitations that accompany it).

Creating a "DOS" (a rudimentary file system and program loader anchored on ISR calls and a command interpreter) is a 1 evening project. Most games from the 80s had them built "in house" to avoid having to pay Microsoft to package MS-DOS (a $100 product) with their game.

I look at the landscape and see a situation largely dominated by large firms. Microsoft's XP patents have been gone for some years and the Vista patents are starting to expire also. MS probably wouldn't lift a finger to stop API and feature emulation all the way to Windows 7 so why haven't people been giving their time to projects like ReactOS? MinuetOS offered 16-bit Windows compatibility more than 20 years ago...

I'm worried about the future as much as anyone but jumping back into DOS (the 8086 IBM PC, more like) isn't the way to go.

Reply 10 of 35, by gsos

User metadata
Rank Newbie
Rank
Newbie

@tcaud I'm not sure I understand what you want to say. I'm not advocating to go back to dos. This is just a hobby project where I wanted to learn kernel dev and some details about x86, with a side goal of executing my beloved very old games on my new systems natively. Anyway I thought maybe some people on this forum would have some interest.

Btw, my understanding was that freedos is not available on uefi non-csm systems, at least the website mention uefi-legacy as a system requirement.

Reply 11 of 35, by Jo22

User metadata
Rank l33t++
Rank
l33t++
tcaud wrote on 2026-07-15, 04:19:

My first thought is we already have FreeDOS for this.

Hey, let's don forget about PC-MOS/386 v5! It's Open Source, too!

tcaud wrote on 2026-07-15, 04:19:

I'm really not enthused by the prospect of wrestling with 640k of memory to make a game (let alone the 256 color limitations that accompany it).

You don't have to.
There are at least seven workarounds that come to my mind.
Besides using XMS or EMS/XMA.

a) use OS/2 Family API
b) use VCPI
c) use DPMI (16 and 32-Bit)
d) use Windows PE format for your EXE files (HX DOS Extender runs them on DOS)
e) use DPMS (Novell DOS 7)
f) use Helix' Cloaking technology (uses 1KB stubs in DOS memory, programs are located beyond 1MB

tcaud wrote on 2026-07-15, 04:19:

Creating a "DOS" (a rudimentary file system and program loader anchored on ISR calls and a command interpreter) is a 1 evening project. Most games from the 80s had them built "in house" to avoid having to pay Microsoft to package MS-DOS (a $100 product) with their game.

There are many DOS compatibles OSes, really.
Quite a few are mentioned here: Memory ranking - 23 DOS KERNELS

In most simple cases, the int21h DOS API must be supported for DOS applications to run.
Secondly, an EXE loader and int15 (BIOS, memory) and int13h (BIOS, HDD) should be implemented.

(The PC-MODE application in DOS Plus 1.x did provide an DOS API emulation way back in 1986. It was on DOS 2.11 level.)

Some programs also do directly manipulate screen (also for text),
so an MDA or CGA compatible character generator should be emulated for increased compatibility.

The CALL5 interface for very early DOS applications would be a nice extra.
MS-DOS and PC-DOS unofficially carried it around until the end.

tcaud wrote on 2026-07-15, 04:19:

I'm worried about the future as much as anyone but jumping back into DOS (the 8086 IBM PC, more like) isn't the way to go.

Right, the PC/AT makes so much more sense!
It has more ressources, for example. Twice the IRQs and DMAs, for example.

I wonder if it would make sense to extend that a bit more?
Having another cascade of IRQ and DMA controller would be worth a consideration, maybe.
Because, all good things are three! 😃

If we had IRQs 1 to 22 and DMA channels 0 to 11 that would be cool!
Special software support could be avoided by re-mapping the IRQ/DMA chart a bit.
So that system components would use the new channels, if possible.
Most of the old ones then could be used by DOS applications.

Edit:

Anyway I thought maybe some people on this forum would have some interest.

That's for sure, I would say.

Personally, I would be looking forward serial support, if that's possible.
A lonely 8250 COM/AUX port would be nice for outside communication.
Things like playing games via null-modem cable, for example.

"Time, it seems, doesn't flow. For some it's fast, for some it's slow.
In what to one race is no time at all, another race can rise and fall..." - The Minstrel

//My video channel//

Reply 12 of 35, by aVd

User metadata
Rank Member
Rank
Member
tcaud wrote on 2026-07-15, 04:19:

My first thought is we already have FreeDOS for this.
...

And this explains all of your nonsense, that follows.

I like the quieter planets, this one became pretty noisy 😀

Reply 13 of 35, by Jo22

User metadata
Rank l33t++
Rank
l33t++
gsos wrote on 2026-07-14, 15:33:

Thanks. Currently I haven't optimized the kernel for size too much, I'm sure there are a lot of things to make it smaller. The most egregious, currently kernel.elf contains command.com and dos navigator as a tarfs image in .rodata, so that it garanteed boots into DN without needing c: to be initialized in a specific way. This of course is nonsense and should go away. For now it needs some decent amount of memory available, but I haven't yet tested a workable minimum to be honest. But 640kb is not going to work, the boot process itself at the moment requires the kernel to be placed at 1mb. But I agree, it should support 2mb machines where the kernel lives >1mb and would have full 640kb available for dos programs with still something along ~500kb of memory free for ems/xms.

Future work definitely should include minimizing the kernel and perhaps add some paging/swap capability to allow it to run on minimal memory requirements is certainly a interesting project.

Hi, another operating system with a DOS environment that comes to mind is "L3".
There's a release that's free and there's some source code available, I believe.

Anyway, the idea of that cloaking method is interesting, too.
The Logitech mouse driver uses it most popularily.
DPMS is another, related technology. Both are difficult to implement, however.
Neither FreeDOS nor latest DR-DOS have implemented it.

"Time, it seems, doesn't flow. For some it's fast, for some it's slow.
In what to one race is no time at all, another race can rise and fall..." - The Minstrel

//My video channel//

Reply 14 of 35, by aVd

User metadata
Rank Member
Rank
Member
Jo22 wrote on 2026-07-15, 09:10:
Anyway, the idea of that cloaking method is interesting, too. The Logitech mouse driver uses it most popularily. DPMS is another […]
Show full quote

Anyway, the idea of that cloaking method is interesting, too.
The Logitech mouse driver uses it most popularily.
DPMS is another, related technology. Both are difficult to implement, however.
Neither FreeDOS nor latest DR-DOS have implemented it.

Hi, Jo22,
This Helix's cloaking for DOS drivers is interesting. Somehow this reminds me of DOS extenders, but in a variant for TSRs. And thanks for the forgotten OSes info you're giving!

I like the quieter planets, this one became pretty noisy 😀

Reply 15 of 35, by gsos

User metadata
Rank Newbie
Rank
Newbie

I'm unfamiliar with cloaking, in retroos the mouse driver is for instance implemented kernel side and takes 0 bytes of conventional mem. The whole conventional mem footprint of retroos is 512 bytes of code. I use a 256 element array of "CD 31", located right after IVT at 0x500 as stubs for various services. I chose int 31h as the universal syscall for DOS, that is the DPMI int, that I extent with extra capability. I didn't choose int 21h as code should be able to hook that one (if it's a PM exit interrupt the IVT is ignored).

So int 31h handler when executed from real mode. looks at CS:IP and branches to various special implementations of int 10h/15h/20h/21h/2fh etc... when cs:ip = 0:500-700 . The same array is also aliased with another non-zero cs range, for non-interrupt services like xms and dpmi switch far calls. Same in protected mode. That array it the totality of retroos code in conventional mem. The only other mem reserved is a real-mode stack for DPMI, which is also used for IRQ interrupts. Net effect is that basically its 640kb - 4 kb of free mem.

Reply 16 of 35, by jmarsh

User metadata
Rank Oldbie
Rank
Oldbie
gsos wrote on 2026-07-14, 06:55:

The solution I used was using the trap flag to single step when VIF=0 until a popf/iret restores VIF to prevent hangs. This was to brutal, doom DMX is mixing in VIF=0 and explosion of 100-1000x in instruction was causing starvation. I added a repair (where the kernel learns where to restore VIF after first single stepping) this makes most games run without single stepping and producing good sound.

Do what windows does; trap pushf and set trap in the pushed flags (based on VIF), so that single-stepping kicks in immediately after popf executes (and restore VIF there).

Reply 17 of 35, by gsos

User metadata
Rank Newbie
Rank
Newbie
jmarsh wrote on 2026-07-15, 15:57:
gsos wrote on 2026-07-14, 06:55:

The solution I used was using the trap flag to single step when VIF=0 until a popf/iret restores VIF to prevent hangs. This was to brutal, doom DMX is mixing in VIF=0 and explosion of 100-1000x in instruction was causing starvation. I added a repair (where the kernel learns where to restore VIF after first single stepping) this makes most games run without single stepping and producing good sound.

Do what windows does; trap pushf and set trap in the pushed flags (based on VIF), so that single-stepping kicks in immediately after popf executes (and restore VIF there).

Very interesting. How does windows trap pushf? I trap cli/sti as those properly trap, the pushf has already executed and difficult to recover on the stack. I'm thinking the natural seqence
pushf
...
cli
...
popf

Reply 18 of 35, by gsos

User metadata
Rank Newbie
Rank
Newbie

What I can see, working in practice. Is learning the stack pointer delta between esp at cli trap (using single time single stepping until encountering restoring popf). Then subsequent cli traps => or TF at [esp + delta]. These tricks can never be made to work against truly adversarial code, but in practice this might work.

Reply 19 of 35, by gsos

User metadata
Rank Newbie
Rank
Newbie

Thanks for the tip, I’m now having the kernel learn the pushf stack offset or which register holds the flags, watcom seems to generate pushf popf eax cli and then later push eax popf, I’m detecting these patterns. This is certainly simpler then learning the critical section exists.