2026-05-19
The asker is building a 16-bit real-mode kernel in C using Open Watcom. Local variables work fine — they can print to VGA memory at 0xB8000 — but as soon as they promote those variables to file-scope globals, the kernel misbehaves. This is one of the most classic OSdev rites of passage, and the answer almost always lives at the seam between the compiler, the linker script, and the boot loader.
Why it's interesting: a hosted C program gets BSS zeroing and DATA initialization for free from the C runtime startup (crt0). A freestanding kernel has no such luxury. When you transition from locals to globals, you suddenly depend on three invariants that nobody set up for you:
.data section's initialized contents must actually be loaded from disk into RAM at the address the linker assigned..bss section must be zeroed before main runs.DS (and often SS) must point at the segment where those sections live — otherwise the CPU happily reads/writes garbage at the wrong physical address.Direction toward a solution:
wlink ... option map) and inspect where .data and .bss were placed. Compare those addresses to what your boot loader is actually loading. If the boot loader only reads the .text bytes from disk, globals with initializers will be uninitialized in RAM.DS setup. A common bug: setting CS via a far jump but leaving DS=0, so accesses to a global at linear address 0x10000 get resolved relative to segment 0._bss_start to _bss_end writing zeros.-ms (small), -mc (compact), -ml (large) change how the compiler emits pointer references to globals. A model mismatch between the kernel and its boot stub leads to exactly this "locals work, globals don't" symptom.Gotchas: VGA_MEM 0xB8000000UL in the snippet looks like a far pointer encoding (segment 0xB800, offset 0x0000) — fine if Watcom's far qualifier is honored, but if a global pointer is dereferenced via the default DS, the whole computation collapses. Also: if the boot loader loads the kernel above the 64 KB boundary, any 16-bit near pointer to a global silently truncates.
