Search Knowledge

© 2026 LIBREUNI PROJECT

Operating Systems Internals / Laboratory: OS Development

From Source to Screen: Building and Emulating

From Source to Screen: Building and Emulating

Having written the code (boot.s and kernel.c), we now need to transform it into a single binary file that a computer can execute. This requires a specialized tool: a Linker Script.

1. The Linker Script (linker.ld)

Standard programs are placed in memory wherever the OS feels like. For a kernel, we must be much more precise. Most bootloaders expect the kernel to be loaded at 1 Megabyte (0x100000).

/* The entry point defined in boot.s */
ENTRY(_start)

SECTIONS {
    /* Most kernels start at 1MB */
    . = 1M;

    /* First, the Multiboot header and the code */
    .text BLOCK(4K) : ALIGN(4K) {
        *(.multiboot)
        *(.text)
    }

    /* Read-only data */
    .rodata BLOCK(4K) : ALIGN(4K) {
        *(.rodata)
    }

    /* Read-write data (initialized) */
    .data BLOCK(4K) : ALIGN(4K) {
        *(.data)
    }

    /* Read-write data (uninitialized) and stack */
    .bss BLOCK(4K) : ALIGN(4K) {
        *(COMMON)
        *(.bss)
    }
}

2. The Build Process

To compile these, you need a “bare-metal” cross-compiler. If you are on Linux, you can use the standard gcc and nasm.

Step 1: Assemble the Boot Code

nasm -f elf32 boot.s -o boot.o

Step 2: Compile the C Kernel

We use special flags to tell GCC not to use any standard C libraries or OS-dependent features. gcc -m32 -c kernel.c -o kernel.o -ffreestanding -O2 -Wall -Wextra

This combines the object files using our linker script. ld -m elf_i386 -T linker.ld boot.o kernel.o -o myos.bin

3. Running in QEMU

Developing an OS on real hardware is slow (and can be dangerous). Instead, we use an Emulator like QEMU. It simulates an x86 PC in software.

To run your new kernel, simply execute:

qemu-system-i386 -kernel myos.bin

If everything worked, a new window will appear with a black screen and the text “Hello, OS World!” in the top-left corner. You have successfully booted your own code!

Summary of Tools

ToolPurposeOutput
NASMAssemblerObject File (.o)
GCCC Compiler (with -ffreestanding)Object File (.o)
LDLinker (with -T linker.ld)Executable Binary (.bin)
QEMUEmulatorSimulated PC Execution

Exercise: The Entry Point

Which line in the linker script tells the computer where to start executing the code when the kernel is loaded?

Interactive Lab

Defining the Entry

()

Congratulations! You have moved from understanding how kernels manage processes to actually writing a “heart” that beats on its own. This is the first step on a long journey that leads to building schedulers, file systems, and eventually, a fully functional operating system.