4 The Plan
This page will explain the scope of our OS, the ordering of component implementations, and a schedule organized into milestones.
4.1 The Scope
Our goal is to build an OS that can run on bare metal, with a working shell.
The OS itself will be implemented as a monokernel.
Our OS will not be POSIX-compliant. However, the OS will be Unix-like, meaning that implementing POSIX will not require major modification.
4.2 Component Ordering
The components are to be implemented in the following order...
4.3 Milestones
Each milestone is expected to take roughly a week.
4.4 Milestone 1
4.4.1 Freestanding Binary
4.4.1.1 Binaries
A binary is a file that does not contain human-readable text. IE: Interpreting the file contents as ASCII or UTF-8 yields un-printable characters.
v=5�'�p������?Te|��Ľo��yMMޭ��Xo��f����k�OX�|�|z�ڽ�H�
Programmers typically use the term binary to refer to the files produced as a result of program compilation—an executable is a common example.
4.4.1.2 C Program to Binary
"foo.c" contains a basic C program.
// foo.c
int main() {
int x = 42;
x += 1;
return 0;
}
The -mno-red-zone flag disables the red zone optimization in gcc.
We can compile the program to assembly code: gcc foo.c -mno-red-zone -S.
gcc compiled "foo.c" into assembly specifically for a platform. In this case, x86-64 Linux.
# foo.s
main:
pushq %rbp
movq %rsp, %rbp
subq $16, %rsp
movl $42, -4(%rbp)
addl $1, -4(%rbp)
movl $0, %eax
leave
ret
Finally, we can assemble (and link) "foo.s": gcc foo.s -o foo into a binary. At this point, we have an executable—something we can run on our machine.
We use the objdump program on Linux to try to understand the contents of the binary.
objdump -d foo will dissassemble the "foo" binary.
0000000000400450 <_start>:
...
400463: 49 c7 c0 c0 05 40 00 mov $0x4005c0,%r8
40046a: 48 c7 c1 50 05 40 00 mov $0x400550,%rcx
400471: 48 c7 c7 36 05 40 00 mov $0x400536,%rdi
400478: ff 15 6a 0b 20 00 callq *0x200b6a(%rip) # <__libc_start_main@GLIBC_2.2.5>
...
0000000000400536 <main>:
400536: 55 push %rbp
400537: 48 89 e5 mov %rsp,%rbp
40053a: 48 83 ec 10 sub $0x10,%rsp
40053e: c7 45 fc 2a 00 00 00 movl $0x2a,-0x4(%rbp)
400545: 83 45 fc 01 addl $0x1,-0x4(%rbp)
400549: b8 00 00 00 00 mov $0x0,%eax
40054e: c9 leaveq
40054f: c3 retq
Notice that main is not the only function! We also see the _start function, that calls the __lib_c_start_main function, with the address of main as its first argument (%rdi).
The _start function represents the C runtime. Typically, a runtime is an environment where code is executed, can provide features such as garbage collection. For C, the runtime is minimal (and optional) and only performs simple initialization—passing command-line arguments into the main function is one example.
4.4.1.3 Bare Metal Rust
Bare metal refers to execution of programs directly on computer hardware.
Our OS should also not make system calls, since that would mean our OS runs on an OS, and not on the hardware directly.
Since, our OS doesn’t link with the Rust standard library, we can’t use the Rust runtime. Instead, we simply implement our own _start function.
4.4.1.4 Aside: The Java Virtual Machine
Many programmers say that C doesn’t really have a runtime, since the runtime is a few minimal initialization steps. A common saying is that C’s runtime is the OS itself. However, note that C can run without a runtime, and it often does! Most operating systems are written in C (bare metal).
A more classic example of a serious runtime system is the Java Virtual Machine (JVM). Java code can only run on the JVM. The JVM provides automatic memory management in the form of garbage collection.
Runtime System <- Java runs here.
Operating System <- "Standard C" runs here.
Hardware <- "Freestanding C" runs here.
We want our OS to run directly on the hardware, without any dependencies on a runtime system or an OS.
4.4.2 Hello World Bootable Disk Image
We have a freestanding binary. Now what? We want to be able to put the binary on a USB, and then boot the OS.
What makes something bootable?
What is the BIOS?
What is the bootloader dependency?
What is the bootimage thingy?
4.4.3 Testing
4.4.3.1 Booting
qemu
4.4.3.2 Unit Tests
We write unit tests by...
4.5 Milestone 2
TODO
4.6 Milestone 3
TODO