Hacker News new | past | comments | ask | show | jobs | submit login

Author here. I am planning to do an in depth write up of how this works, but it seems Hacker News found it sooner :)

When DSL is first invoked at the command line it boots up the Linux kernel which takes over control of the computer from DOS.

Now here’s the trick: DSL makes use of a processor feature called VM8086 which allows for a 32 bit operating system to run legacy 16 bit code mostly natively. This feature is how early Windows, DOS extenders, etc worked. The Linux kernel also supports VM86, although it is largely undocumented and not really used these days. I think dosemu is the only major user of VM86 on Linux.

DSL then returns to DOS, which has essentially been flipped inside out and is now unknowingly running inside a VM8086 task. Helpfully Linux does not appear to clobber DOS’s memory during its own boot process.

DSL does just enough emulation of hardware like the keyboard to make things work, allowing DOS raw hardware access for everything else. This situation of running two operating systems at the same time on the same hardware is extremely fragile and unsafe of course, but it does seem to work surprisingly well anyway!

Wow you weren't kidding about "largely undocumented". https://man7.org/linux/man-pages/man2/vm86.2.html

Would be really cool if someone contributed a proper man page, I bet it would be a fascinating read.

> Helpfully Linux does not appear to clobber DOS’s memory during its own boot process.

Is that just a coincidence or intentional somehow?

I guess DOS can only access the first 1MB (err... plus 65520 HMA bytes?), so if Linux just avoids using that space then DOS can keep running happily... I was curious if there's actually a mechanism to tell Linux to avoid that space.

DOS memory management fascinates me in its absurdity.

With HIMEM.SYS + EMM386.EXE [0][1], you could include or exclude certain memory segments. But, DOS Subsystem for Linux uses non-standard little documented Unreal Mode [2][3] instead of traditional DOS Memory Management.

[0] http://www.mdgx.com/mem6.htm#6

[1] http://manmrk.net/tutorials/DOS/msdos7/emm386.htm

[2] https://en.m.wikipedia.org/wiki/Unreal_mode

[3] https://github.com/charliesome/doslinux/blob/master/doslinux...

After not finding much of a README (yet), I poked around the source code a few minutes ago. Thanks for my actually confirming my initial "...he can't be doing it that way, surely..." :)

This is nice. It reminds me of the IPL sequence of some mainframe OS I sadly can't remember right now (might be System/i?) where the bootloader that launched the kernel was a first-class OS process that went from running the entire system to being promoted to an OS task as the kernel started up. Except in this case you're promoting the entire OS to a kernel task, while the promoted OS continues to run :D

I wonder if you could extend this to turn Linux into a replacement for HIMEM.SYS, to "properly" support the fact that HIMEM has to be disabled. :D

(Immediately after reading that I thought "wait; the two OSes are running independently, of course that won't work..." but then I realized, no, HIMEM works by trapping interrupts... so this is not only possible, but vm86 of course works by handing you interrupts to deal with.)

The extremely-confusing-but-still-positive benefit of this would be to allow you to elevate DOS to have demand-paged virtual memory, complete with swapfile.

It might be interesting to identify the oldest kernel version(s) you're prepared to put up with, to realize the smallest _in-memory_ kernel size possible, and _possibly_ enable running multi-MB applications on real systems with only 640KB of RAM (with the proviso that using an SSD via a SATA-IDE adapter would give the best results - and the rationale that both of those items will soon be cheaper than old DIMMs). The issue suggesting 2.4 is maybe a bit of a stretch, but the early 2.6 trees might be interesting.

Implementing my own extended memory support in the supervisor is indeed an interesting idea, I might try it out :)

Another idea I had after reading the dosemu source is implementing a DPMI server to allow protected mode DOS apps to run. It might even be possible to run an early version of Windows this way too.

Have you tried the approach of booting Linux and then creating a normal fullscreen qemu/KVM-based VM initialized with the memory state of the DOS OS, with a configuration so that the transition works correctly?

That would make the whole system fully robust and safe, and also support running XMS/EMS managers, DOS extenders, Windows and other bootloaders from the DOS VM.

I'm not sure however whether you would need to modify qemu to make it work and how hard that would be (also I guess that would have less hacky fun factor).

Thanks for the explanations. Very interesting. Please add it to the README.md or the GitHub Wiki if you want to go into much more detail. Thanks!

Very cool! Can it use multiple processors under Linux or is it limited to 1 CPU because of some tricks for the DOS compatibility?

It would be cool to do the same using KVM. You can use a magic I/O port instead of an interrupt as the upcall mechanism, on the other hand trapping interrupts has to be done from the DOS side...

I look forward to your writeup, but in the meantime, thank you for your comment explaining how this works. Excellent hack!

That's hilarious. Nice hack!

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact