4 fixes for VirtualBox compatibility + 1 cosmetic:
1. UART hardware detection (fixes boot freeze with serial disabled)
- hal_uart_init() now probes the scratch register before configuring
- All UART operations (putc, drain_rx, poll_rx, try_getc) guarded
behind uart_present flag — prevents infinite loop on floating bus
- console_init() auto-enables VGA when no UART detected so boot
messages are visible
- Added hal_uart_is_present() API + stubs for ARM/MIPS/RISC-V
2. alarm/SIGALRM test: replace 20M-iteration busy-loop with nanosleep
polling (50ms × 40 = 2s max wait). Fast VirtualBox CPUs completed
the busy-loop before the 1-second alarm fired.
3. x86_enter_usermode: load DS/ES/FS/GS=0x23 before iret to ring 3.
Without this, iret nulls segment registers (kernel DPL=0 < new CPL=3
per Intel SDM §6.12.1). On QEMU this was masked by early context
switches that fixed DS via x86_enter_usermode_regs, but VirtualBox
with Hyper-V acceleration may expose the race window.
4. User-mode exception handling: deliver SIGSEGV for any ring-3
exception (#GP, #UD, etc.) instead of kernel panic. Previously only
#PF (14) had this handling. A user-mode #GP now kills the process
cleanly instead of halting the entire system.
5. LAPIC timer ticks printed in decimal instead of hex.