// bare metal · x86 · c + asm

An operating system,
built from the bootloader up.

Eiciel OS boots real hardware through GRUB multiboot, sets up its own GDT and IDT, drives the framebuffer directly over VBE/VESA, and draws a graphical desktop — dock, draggable windows, wallpaper — with zero external OS underneath it.

qemu-system-i386 · serial0
[0.000000] grub: multiboot header found, kludge fields zeroed
[0.000012] kernel_main(magic, mb_info) — cdecl push order corrected
[0.000031] init_gdt() — null · code@0x08 · data@0x10
[0.000044] reload cs via far jump ... ok
[0.000058] init_idt() ... ok (no triple fault)
[0.000102] vbe: mode 640x400, probing colour mask fields
[0.000119] vbe: reported mask unreliable, falling back to probe
[0.000140] fb: hardcoded XRGB8888 — r:16 g:8 b:0 ... ok
[0.000201] wm: init dock, window manager, wallpaper ... ok
[0.000210] eiciel: desktop ready
0x0100three bugs, layered

What it took to see a pixel

QEMU's -kernel loader always falls back to mode 13h. Getting a real linear framebuffer up under GRUB meant fighting the boot process one layer at a time.

0x00 — multiboot
fixed

GRUB misreads the video-mode request

The multiboot header was missing five zeroed a.out-kludge placeholder fields, and kernel_main(magic, mb_info) had its cdecl push order reversed.

Fix — zero the kludge fields, correct the argument push order.

0x01 — gdt/idt
fixed

Triple fault on real boot

init_idt() hardcoded selector 0x08, assuming QEMU's bootloader GDT layout — a layout GRUB doesn't provide.

Fix — init_gdt() loads a known minimal GDT (null, code@0x08, data@0x10) before interrupts are set up, then reloads CS with a far jump.

0x02 — vbe colour
fixed

The BIOS lies about its own colour mask

QEMU's VBE BIOS reports incorrect colour-mask fields for 640×400. Byte-writing directly to the framebuffer confirmed the real layout.

Fix — hardcode XRGB8888: r_pos=16 g_pos=8 b_pos=0, 8 bits each, rather than trust the reported metadata.

0x0200userland, such as it is

A desktop, drawn pixel by pixel

The window manager owns everything above the framebuffer: a dock, draggable windows, and a wallpaper — no toolkit, no compositor library, just writes to 0x….

representative render, not a screenshot — wm.c drives the real thing
0x0300what's under it
language
C + x86 assembly
bootloader
GRUB, multiboot spec
graphics
VBE/VESA linear framebuffer
runs on
QEMU (i386)
interrupts
custom GDT + IDT
shell
dock · windows · wallpaper
0x0400get it

Boot it yourself

Source, launch thread, and the full write-up of getting from a black screen to a desktop.