6 ms·
Start your small operating system in Assembly
- RandomCode 12y agoUse INT 13, 42 for read. LBA48 and >130Gig. Why the FUCK are you doing CHS?
- ekr 12y agoThis is in no way an operating system. An operating system (by most definitions) is supposed to abstract the hardware, to provide things such as processes, a scheduler, a file system, a framework for device drivers.
- nawitus 12y agoThe article describes how to start an operating system, not how to write it. The article even states this at the end: "Now, your job would be to develop your little kernel in the system.asm file.
- exDM69 12y agoNice little article, but the common wisdom in "hobby" OS development is: if you want to write an operating system, do not write a bootloader. The arcane details of initializing a x86 PC are not a good use of brain space or programming time (things like A20 line). The OP says he spent weeks writing this small snippet. There is some appeal in doing it "from the ground up" in Assembly but that's very slow and tiresome. And there's still the PC BIOS code blob running before your OS loads, so it's not like you're in control of the CPU right from the first instruction it executes. It takes roughly the same amount of trouble as this article (or slightly less) to build a bootable ELF file using the Multiboot protocol, which you can boot to using qemu or bochs directly (e.g. qemu -kernel mykernel.elf) or on real hardware using GRUB. There are lots of advantages to this: the bootloader will initialize the CPU for you and you'll enter directly into 32 bit protected mode, the state of the CPU will be in a well defined state. Additionally you can use the bootloader to set up a graphics mode and provide a physical memory address to the VRAM (this would require falling back to 16 bit mode for some BIOS interrupts and then back to 32 bit mode). You'll also get a proper ELF binary file with all the section information (useful for setting up your page tables), and debugging symbols so you can debug your kernel in GDB which is a lot more productive than using the built-in monitor facilities of QEMU or Bochs. And you can actually use a linker so you don't have to put all your code in one file (you will need a linker script). It also makes sense to boot to C code as soon as possible (Rust is another option, C++ too but it's a bit more trouble). I actually did write a small OS prototype in "raw" assembly (with interrupt handling and simple threading), but it wasn't very productive and I quickly reverted to writing C code instead and got a lot more done in less time. You shouldn't need a lot of assembly code, only the early boot code (a few hundred lines), the interrupt handler entry point and trampoline code for booting the other cores of your CPU. In addition, there will be some inline assembly oneliners for accessing privileged instructions (like lgdt, etc). Here's the beginnings of my hobby OS project from years ago. I made the mistake of using 64 bit long mode, which is a lot more work to get booted and not a very good use of time. Stick to 32 bit mode if you want to get things done. https://github.com/rikusalminen/danjeros https://github.com/rikusalminen/danjeros
- JoshTriplett 12y agoAs another alternative, bootstrap your OS using EFI. You get to boot directly in 32-bit or 64-bit mode, as with multiboot, and you get a handful of OS-like facilities to bootstrap yourself with, such as files, input, output, graphics, and even networking. (You'll want to replace those with your own facilities eventually, but until then you can focus on more interesting problems.)
- exDM69 12y agoExcellent point, back when I was writing my project, EFI wasn't a viable alternative. Do you know how is the tooling with EFI these days? Can you boot EFI-bootable images using QEMU or Bochs? How about debugging, etc?
- JoshTriplett 12y agoKVM/QEMU with the OVMF BIOS image provides a full emulation environment for testing and debugging. You can build EFI binaries using entirely Open Source tools. Also try BITS (biosbits.org) for experimentation with either BIOS, ACPI, and EFI; it's a port of Python to run in GRUB2. (I'm one of the upstream authors.)
- voltagex_ 12y agoHave you got any good references for OS dev under (U)EFI? The specs from the Tianocore project are fairly verbose.
- JoshTriplett 12y agoI don't know of any tutorial-style material, but for references, I use both the official specs from uefi.org and the wiki on the Phoenix site (for instance, http://wiki.phoenix.com/wiki/index.php/EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL http://wiki.phoenix.com/wiki/index.php/EFI_SIMPLE_TEXT_INPUT... ).
- pgeorgi 12y agobut you don't get to decide whether to use 32bit or 64bit mode, your firmware does for you.
- danbaz 12y agoWriting the bootloader contrary to what exDM69 has said in my opinion is not a waste of time. A few years back I set about writing the smallest possible kernel I could for the x86 architecture and eventually got it down to 512 bytes - meaning the bootloader is the kernel. https://bitbucket.org/danielbarry/saxoperatingsystem/src https://bitbucket.org/danielbarry/saxoperatingsystem/src Obviously in such a small amount of space, you only get an extremely simple file system, use of one core, heavy reliance on interrupts, 16 BIT, no concept of threads, ~16Kb of RAM and a lot of headaches. But the fact is that it works and programs do get offered a variety of functions that they can go onto use in order to save space. It's relatively complete, with a text editor, game and simple script language. Without using interrupts, the speed is just incredible. Unlike your normal kernel, there aren't a million pointers to follow through or any safety checks eating up your precious processing time or other processes to share your precious registers and cache. You may only use one core, but you really do use that to your advantage. In doing so, I learnt a lot about programming space efficiencies and OS design in general. I would highly recommend it as a journey worth taking. It recently all came in handy at work where I needed to run some very tight image processing loops for 120FPS at HD (don't ask!) and knowing how the underlying system worked meant I could bypass the heavy kernel operations in favour of my own much leaner, purpose built ones. UEFI has of course put a bit of a spanner in the works, where some modern computers unless put into 'compatibility mode' in the 'BIOS', have completely blocked out the world of hobby OS's for time being. I would highly suggest that you all check out the MikeOS project and if you're interested ask questions on the mailing list. It's a bit quiet at the moment but he's a great guy and knows his stuff as well as the others on there. What's more, if you consider yourself more hardcore and need more power, I think the InfinityOS project was inspired by MikeOS and runs on 64 bit computers and allows for distributed tasks over a network. It's very impressive to say the least. A down side to writing your own 32/64 Kernel is you take a look at the support and what you're competing against and you start woundering whether you should just use the embedded Linux kernel for example or of you're hell bent on ASM then Kolibri OS is pretty complete! Another point for 16 Bit kernels is the fact you get to whip your old machines out of storage and boot those noisy beasts up. Load an old OS onto a kernel and listen to it churn away.
- 101914 12y ago