Learn to write a simple OS kernel with keyboard/screen support (2014)
github.com
github.com
The problem was that there was just too much to do: Booting, memory management, interrupt/exception handling, video output, keyboard, disc access, file systems, scheduling... most of those things are potentially interesting, but not all at once, and yet they are all pretty much necessary to get your OS to the "critical mass" where working on individual aspects starts being fun.
Until I had the idea to not just boot using plain old 16bit DOS, but too also keep DOS running in my OS, as a task. The thing about DOS is that it is barely an "operating system" in the modern sense. Instead, it is more a crude collection of 16bit x86 routines that do most of the aforementioned things: Console input/output, file system access, crude memory management, a whole shell actually (COMMAND.COM)... and you can even load drivers for networking, sound, and almost everything else, provided for form of it already existed about 15 years ago.
My current toy OS is a modern message passing microkernel, but for everything that I did not feel like implementing yet, I call into the DOS task. The task runs as a vm86 task, essentially within a hypervisor (called the "vm86 monitor"), but specifically for 16 bit real mode code. (64bit x86 got rid of the now obsolete vm86 mode, so there you would have to actually implement something much closer to a modern hypervisor.) This is done using using a shim layer that receives messages using the message passing system of my OS and translates them into the (usually) soft-interrupt driven DOS/BIOS function calls.
This is possible with DOS, unlike modern OSes, because it's such a crude and conceptually simple OS, centered around direct hardware access and with essentially no own memory protection/address space separation, that it just does not get in the way of implementing my own OS.
But I found that I was able to play with individual elements before having a system that's even remotely useful. I recommend the Xinu book. After only a few weeks' work (which was mostly research and reading, not programming) I had a system that could do a context switch. This was always the most magical part of an OS for me. After that I started to implement memory management, but it just got too hard to be fun (ARM64).
When you do Common Lisp, Smalltalk, Java, .NET, Go, D, ... the underlying OS kind of loses its meaning.
The standard library can bind to OS primitives, or you can implement your hardware abstraction layer that allows for the language runtime to run bare metal.
If you squint a bit, UNIX is C's runtime, and gets everywhere via POSIX.
So, the OS does not lose more of its meaning if you move to rich language runtime environments. Those language environments are mostly about garbage collection. Most other things that make the OS "lose its meaning" are just libraries (that you can write in any language).
Developing on Windows, and deploying across several UNIX flavours, mainframes and embedded targets has been pretty much OS independent for me during the last two decades, regardless how much OS specific code those runtime libraries might have inside of them.
Even if the CI/CD pipeline had to do OS specific builds.
I don't know what's your point here, or why you keep repeating this on HN hundreds of times. I didn't ever hear anyone claiming it was the "first systems language". Nor do I care.
(We all want a better language. I haven't tried many, but any other systems language I've seen I've found awkward, starting with Pascal with its mess of 1-based vs 0-based indexing, case insensitivity, weird mix of ref-counted / manually managed, weird syntax choices, mess of basic string types, requirement to create tons of typealiases... going to older languages that have upper-case only identifiers, for example).
As to rest - it's just a matter of libraries. Not runtimes.
EDIT: it seems some definitions of runtime include standard libraries. So, whatever.
The way I understand it, the following code is based one of the assumptions you can't make without x86 BIOS, can you?
/* video memory begins at address 0xb8000 */
char *vidptr = (char*)0xb8000;I quote-unquote frame buffer because it's text mode, one byte for the ASCII code (extended to 256 characters in configurable and often confusing and incompatible ways, MS had "codepages" and ISO has the equivalent Latin-1 through Latin-14 or so), and one byte for the attribute.
Many modern cards used to keep the basic VGA compatibility upon boot, until you switch them into more sophisticated modes. I'm not sure if they still do these days. QEMU, which is the actual target for the minimal demo kernel above, pretty sure supports it.
BIOS used INT 10h for video operations, from mode setting to printing characters, code that calls INT 10h is actually relying on BIOS. IIRC next to nobody used it except for mode setting, you could much more easily and flexibly write the right bytes yourself (with a little bit more work for compatibility). Plus you could use DOS INT 21h to actually print output strings with a bit more of a concept of a terminal.
[1] MezzanoOS, an OS written in Common Lisp (https://github.com/froggey/Mezzano)
[2] SerenityOS, a Unix-like OS (https://github.com/SerenityOS/serenity/). The primary author has a youtube channel (https://www.youtube.com/c/AndreasKling/)
[3] RedoxOS, a microkernel OS written in Rust (https://www.redox-os.org/)
[4] Nebulet, a microkernel based on webassembly (https://github.com/nebulet/nebulet)
[5] It was never released by Microsoft, but Midori OS had some fascinating ideas like software isolated processes, asynchronous message passing and object capabilities. Nice write-up about the project by Joe Duffy here http://joeduffyblog.com/2015/11/03/blogging-about-midori/
> While never reaching commercial release, at one time Midori powered all of Microsoft’s natural language search service for the West Coast and Asia.
https://www.microsoft.com/en-us/research/project/singularity...
And although not quite the same, at least Singularity's code is available.
The WinRT .NET 8.x compiler was based on Singularity's way of compiling[1][2] and UWP .NET Native kind of had some learnings from Midori [3].
[1] - https://channel9.msdn.com/Shows/Going+Deep/Mani-Ramaswamy-an...
[2] - https://channel9.msdn.com/Events/Build/2012/3-005
[3] - https://channel9.msdn.com/Shows/Going+Deep/Inside-NET-Native
Oberon System - http://www.projectoberon.com/
COSMOS - https://www.gocosmos.org/
JNode - https://www.jnode.org/
TamaGo - https://github.com/f-secure-foundry/tamago-go
A2/Bluebottle - http://cas.inf.ethz.ch/projects/a2