How to create an OS from scratch – tutorial
github.com
github.com
One thing I wish is that more of them would feature UEFI instead of BIOS, or at least come with a warning, as Intel plans to drop support for legacy BIOS in 2020.
Going through UEFI is actually easier anyway, IMHO. ... Maybe I should stop complaining and write that tutorial myself instead. Hmm.
Boot protocols are very uninspiring, arcane knowledge and understanding it does not bring any advantages (unless you want to write bootloaders). Especially dealing with legacy BIOS boot sequence, which is essentially a backwards compatibility emulation layer implemented in the firmware.
It's not like home computers of the 1980s where you'd look at the processor data sheet how the CPU actually boots (which address the program counter starts from, what's the initial machine state, etc).
By far the easiest way to get started in x86 bare metal programming is using the Multiboot header, which is supported by bootloaders (like Grub) and emulators (like QEMU). And you can use GDB for debugging.
Using UEFI is more involved to get started. The initial setup is more involved (you need UEFI headers and libs, etc), the build process is more complex (UEFI images are "Windows" PE executables) and attaching a debugger is not as easy as with a Multiboot-ELF image. UEFI "boot services" provide some nice things that may be helpful to get memory maps and CPU hierarchy so you don't need to go through the hassle of parsing EBDA and MP and ACPI tables.
The legacy BIOS boot protocol is "easy" to get started with (nasm -f bin mykernel.asm), but you have to deal with arcane stuff (like floppy drive BIOS routines, A20 lines), you don't get a debugger. This is by far the worst way to get started. It's not really "doing it from scratch", instead of using a proper bootloader you need to deal with a really bad bootloader implemented in your PC firmware.
The biggest advantage is that your kernel images are a bootable, debuggable ELF binary.
The emphasis being on "debuggable", you can easily plug in GDB to QEMU and use a proper debugger with your bare metal projects. Using GDB is much better than using the built-in debugging facilities of QEMU or Bochs. You can get the source view, set breakpoints and do everything you normally do in a debugger. In QEMU/Bochs built-in debuggers you have no source view and can only inspect memory and registers - not variables with symbolic names.
Here's some examples and documentation on building a debuggable ELF image for bare metal project, which I contributed to someone else's project:
https://github.com/Overv/MineAssemble/commit/56e317a28d069f4...
The more people keep using BIOS, the more likely it will stay around. IMHO UEFI is a bloated mess compared to BIOS, so I very much hope the latter will continue to live.
httpss://github.com/ReturnInfinity/Pure64
About every third minute I’ve changed my mind about this quote. I think that means it’s a good quote.
Anyway, feel free to leave your comments, I appreciate them a lot.
MIT 6.035 - Computer Language Engineering [3]: This course analyzes issues associated with the implementation of higher-level programming languages. Topics covered include: fundamental concepts, functions, and structures of compilers, the interaction of theory and practice, and using tools in building software. The course includes a multi-person project on compiler design and implementation.
[1] https://lagunita.stanford.edu/courses/Engineering/Compilers/...
[2] http://web.stanford.edu/class/cs143/
[3] https://ocw.mit.edu/courses/electrical-engineering-and-compu...
https://www.inf.ethz.ch/personal/wirth/
On the way you can also grab "Project Oberon" from there, both 1992 and 2013 editions, to see how to write an OS from scratch, including an FPGA board, in a GC enabled systems programming language.
There are also the tiger books, in C, Java and ML variants.
He explains every detail, goes through every routine, and you can see exactly what the compiler does. It's 'Small-C' so it doesn't have any fancy features, like floats or structs. But the basic machinery is there, and one can add features as desired. It does compile itself. The compiler outputs x86 assembly, which must be assembled and linked with standard programs.
The original Small-C was done by Ron Cain, and produced 8080 code. I like Mr. Hendrix' better because I have lots of x86 around (I specifically wanted it for my HP-200 LX palmtop, which I still have and works great!); and because the book is fantastic.
It's fully understandable in a small quantity of time. And, the back end is re-targetable, so you could, say, output to ARM or RISC-V or whatever.
I spoke with Mr. Hendrix some years ago, maybe 10 or so, and asked if he would consider putting the compiler into the public domain. He did.
In case anyone else is interested, there is a freely available ISO of the the book available from Dr Dobbs Journal. From the README in the ISO:
>"Welcome to Dr. Dobb's Small-C Resource CD-ROM, the definitive collection of Small-C related information and source code. This CD-ROM includes the full text to James Hendrix's book "A Small-C Compiler: Language, Usage, Theory, and Design," selected articles on Small-C from "Dr. Dobb's Journal" magazine, and Small-C implementations for a number of processor platforms, including the 8080, Z80, 6502, and others."
It's available here:
http://www.drdobbs.com/developer-network-small-c-compiler-bo...
[1] https://github.com/IUCompilerCourse/Essentials-of-Compilatio...
Thanks, I'll put in the pile of things to read.
MIT 6.828 - Operating System Engineering [2]: This course studies fundamental design and implementation ideas in the engineering of operating systems. Lectures are based on a study of UNIX and research papers. Topics include virtual memory, threads, context switches, kernels, interrupts, system calls, interprocess communication, coordination, and the interaction between software and hardware. Individual laboratory assignments involve implementation of a small operating system in C, with some x86 assembly
Please note that the MIT 6.828 is really tough but will turn you into a bad-ass C hacker.
It relies on MIT 6.004 - Computation Structures [1] (has edx mooc [2,3,4]) and MIT 6.033 - Computer Systems Engineering [5] as pre-requisites given that they teach you the fundamentals of computer architecture (digital abstraction, gates, circuits, processors, assembler, memory, cashes, pipelining, virtual memory, interrupts/io, buses, what have you) and system design (basically, managing complexity); they are not programming courses, but I recommend them if you have the time and interest, they are an awesome and principled way of learning the core concepts that you really need to have down before dabbling with OSs.
[1] https://ocw.mit.edu/courses/electrical-engineering-and-compu...
[2] https://courses.edx.org/courses/course-v1:MITx+6.004.1x_3+3T...
[3] https://courses.edx.org/courses/course-v1:MITx+6.004.2x+3T20...
[4] https://courses.edx.org/courses/course-v1:MITx+6.004.3x+2T20...
[5] https://ocw.mit.edu/courses/electrical-engineering-and-compu...
HN discussion here: https://news.ycombinator.com/item?id=10643757
I would be happy to refer to you at the end of mine: brainyv2.hak8or.com
I did this and wrote a bunch of scripts to automate the process. CLFS uses busybox and DropBear to keep things really small (~42MB binary for the entire OS, including the Raspberry Pi blobs) - but you'll learn enough to be able to swap out components of your choosing.
Edit: It actually doesn't seem that bad for some(?) rpi devices: https://elinux.org/RPi_Upstreaming
Not sure if that list includes all devices found on even the newer ones too.
1. The documentation is always in flux. You may get lucky and it's accurate, or you may not, and spend hours looking for tarballs that no longer exist online, or worse find them and they are no longer compatible with LFS - They don't host the required source archives along with the LFS book, and a lot of links to parts you need end up going nowhere.
2. As a step-by-step it does do what it says on the tin, but as a learning tool, there's a lot missing. When I was less knowledgeable about Linux I found myself following the LFS book with little to no idea about what I was actually doing and why. It would say things like 'chroot in the build folder' without actually explaining why, and what chroot actually did.
3. The whole thing can fail at any point, leaving you with a broken build, that more often than not, you'd have to wipe and start over. As most of the steps involve compiling, that's a lot of lost hours.
So then you're stuck with an old glibc for your kernel. Not all applications (especially newer ones) will successfully link against that, so then you're looking for replacements or older versions that do (if there are any). What about other libc implementations, like musl? There are differences between musl and glibc[1] that will drive you nuts trying to find things that will link in musl that were originally written to link against glibc.
0. https://mirrors.edge.kernel.org/pub/software/libs/glibc/hjl/...
1. https://wiki.musl-libc.org/functional-differences-from-glibc...