Files
Aaron e69b134bff
continuous-integration/drone/pr Build is failing
continuous-integration/drone/push Build is passing
Integrate x86_64 desktop boot and extend VirtualBox validation
2026-11-08 09:02:34 +00:00

34 KiB

x86-64 migration

Status

The x86-64 target boots into Pascal with exception handling, physical/virtual allocation, the shared heap, PIC/PIT interrupts and tested kernel-context preemption. Fatal faults report over COM1. The native desktop, terminal, storage, E1000 networking and WASM runtime now run. The existing x86 target remains the default.

Architecture boundaries and reuse

Follow the namespace convention in namespace.md: architecture units live under src/arch/<architecture>/ and use arch.<architecture>.* names. The compiler-required system.pas retains its special name.

  • src/arch/x86_64/boot/stub.asm: 32-bit Multiboot entry and long-mode transition.
  • src/arch/x86_64/arch.x86_64.boot.pas: bootstrap entry and serial self-checks.
  • src/arch/x86_64/system.pas: minimal compiler runtime definitions.
  • src/arch/x86_64/arch.x86_64.isr.pas: IDT/TSS setup, frame validation, and allocation-free exception reporting.
  • src/arch/x86_64/isr/entry.asm: generated entry stubs, register/FX save and restore, iretq, emergency stacks, and controlled fault probes.
  • src/debug/debug.early.pas: reusable architecture-independent diagnostic formatting, supplied with a character sink by arch.x86_64.debug.
  • src/arch/common/system.types.inc: shared scalar/compiler definitions extracted from the existing system unit; native widths follow the selected CPU target.
  • toolchain/target.sh: target selection shared by the existing build steps.
  • toolchain/x86_64/linker.script: bootstrap address layout.

Do not copy the i386 kernel, drivers, heap, scheduler policy, or runtime wholesale. As each subsystem is enabled, retain portable logic in its existing namespace and put architecture-specific operations behind the appropriate architecture interface. External lvgl/ and wasuro/ sources must remain unchanged.

Build and boot

Rebuild the builder image when first adding the native x86-64 FPC compiler:

docker-compose down --remove-orphans
docker-compose build builder

Build x86-64 using the normal build command with an explicit target:

$env:ASURO_ARCH = 'x86_64'
docker-compose run builder | Tee-Object -FilePath .\build.log
Remove-Item Env:ASURO_ARCH
Select-String -Path .\build.log -Pattern "Error|Fatal|Success|No errors|Failed" -CaseSensitive

Outputs are Asuro-x86_64.iso, bin/x86_64/kernel.bin, and lib/x86_64/. Without ASURO_ARCH, the existing x86 build still produces Asuro.iso, bin/kernel.bin, and lib/. Cleaning and linking only consider the selected target's objects. The x86 compiler search path excludes src/arch/x86_64.

Use VirtualBox for runtime validation. With the configured Asuro VM stopped, select Asuro-x86_64.iso as its optical medium, then start it through the normal VM workflow and read C:\Temp\asuro.log. Restore the original optical medium after testing. The normal image enumerates storage and mounts attached filesystems; boot checks read attached disks without writing them.

Expected serial output:

ASURO x86_64: IDT/TSS ready; DF/NMI/MC emergency stacks installed
ASURO x86_64: entered Pascal
PASS: long mode, Multiboot handoff, 64-bit Pascal types
PASS: INT3 frame, GPRs, RFLAGS, x87/SSE and IRETQ
PASS: page-fault error code, CR2 and IRETQ recovery
EXCEPTION_TESTS_PASSED=0000000000000002
EXCEPTION_TESTS_FAILED=0000000000000000
ASURO x86_64: desktop ready

An early single C means CPUID/long-mode support is unavailable; B means an invalid Multiboot magic value. The Pascal checks validate the handoff magic, a non-null info pointer, native/fixed type widths, wide arithmetic, and EFER.LMA.

Repeatable VirtualBox fault checks

The default build runs two returning self-tests. INT3 verifies the saved frame, all 15 general registers including high halves, CF/DF, x87 and XMM0/XMM15 state, and iretq. The handler intentionally destroys FX state before the return path restores it. A write to unmapped 0x100000000 verifies hardware error code 2, CR2, and recovery by changing RIP only for the exact expected probe.

Use the bounded test harness with the configured VM powered off:

.\toolchain\x86_64\test_boot.ps1 -Test none

For deliberately fatal tests, select ud, pf, or df when building, then use the matching harness option. For example:

$env:ASURO_ARCH = 'x86_64'
$env:ASURO_BOOT_TEST = 'df'
docker-compose run builder | Tee-Object -FilePath .\build.log
Remove-Item Env:ASURO_BOOT_TEST
Remove-Item Env:ASURO_ARCH
.\toolchain\x86_64\test_boot.ps1 -Test df

The harness uses localenv.json, temporarily attaches the ISO, starts the VM through virtualbox-wrapper.ps1 -command up -Headless -NoMonitor, validates serial output, captures registers, stops the VM, and restores the original optical medium in a finally block. The new wrapper switches are optional; the existing interactive workflow is unchanged. Storage disks are not changed.

Rebuild without ASURO_BOOT_TEST after testing to restore the normal image.

Bootstrap layout and limitations

  • GRUB loads the kernel at physical/virtual 1 MiB using explicit Multiboot v1 load-address fields; the payload is ELF64 with a 32-bit assembly entry.
  • Six reserved 4 KiB pages hold the PML4, PDPT, and four page directories. They identity-map the first 4 GiB with 2 MiB leaves.
  • A reserved 16 KiB stack is aligned for the SysV AMD64 calling convention. These bounded early allocations exist before any heap and must remain reserved when the physical allocator is introduced.
  • Paging, PAE, long mode, x87, and SSE2 support are enabled before calling Pascal.
  • A 256-entry IDT uses normalized 64-bit frames. TSS IST1 supplies a 16 KiB double-fault stack; IST2 and IST3 supply separate 8 KiB NMI and machine-check stacks. The 4 KiB IDT, 104-byte TSS, and emergency stacks are bounded early reservations before the allocator exists. Stack guard pages remain future work.
  • Entry preserves GPRs and captures CR2 before Pascal code. It clears DF, aligns the call stack, and saves/restores x87/SSE state using FXSAVE64/FXRSTOR64. AVX/OSXSAVE and lazy-FPU switching are not enabled. Future changes must extend this state policy before enabling those features.
  • IRQ0 is enabled during timer and context tests, then masked before the final halt. PIC acknowledgement and spurious IRQ7/15 handling are implemented. General driver hooks and APIC/SMP remain future work.
  • The low identity map is temporary. It is not a final process address-space design and does not enforce page-level W^X. New heap mappings use 4 KiB pages at 0xFFFF800000000000, spanning up to 16 GiB with NX when supported. Their backing frames can reside above 4 GiB.
  • Unsupported runtime operations intentionally fail to link rather than silently delegating to a hosted runtime or pretending to succeed.

Remaining migration work

Area Existing assumptions / next work
Runtime Keep compiler metadata shared; initialization dispatch is shared; implement further x86-64 helpers as consumers are ported.
Common kernel entry src/asuro.pas currently imports x86 units; separate common boot sequencing from architecture setup before sharing full initialization.
Exceptions IDT/TSS, IST stacks, normalized frames, diagnostics, and tested iretq paths are implemented. NMI/MC injection, user transitions, guard pages, and general IRQ dispatch remain.
ABI Bootstrap interrupt alignment and x87/SSE preservation are tested. Audit red-zone assumptions for each added compiler/library and extend preservation before enabling AVX or lazy-FPU switching.
Memory PMM, VMM and shared heap implemented. Final process layout, guards, MMIO and DMA APIs remain.
Scheduler/loader Shared scheduling, kernel preemption and process lifecycle tested. Process address spaces and executable loading remain.
Drivers/storage Audit uint32(pointer) conversions, MMIO and DMA translations, and hardware address limits. Keep disk/USB/controller structures fixed-width.
Graphics VESA calls into V86, which cannot operate in long mode. Initially use a bootloader framebuffer; rebuild LVGL and verify Pascal/C bindings later.
Validation Add deliberate exception tests, allocator checks, preemption checks, and storage tests as their implementations become available.

Next milestone: port filesystem/console services and complete driver address/DMA audits. Kernel process lifecycle now uses the shared manager. Do not enable the desktop/storage stack before its dependencies are ported and tested.

Validation performed — 2026-11-07

  • x86-64 compile, link, GRUB header validation, and ISO generation passed.
  • The existing Asuro VirtualBox VM printed all three expected serial lines.
  • First-milestone VirtualBox registers showed CS=0x18, CR0=0x80000013, CR3=0x103000, CR4=0x620, and EFER=0x500 (LME and LMA set).
  • Disassembly confirmed 64-bit Pascal code, wide arithmetic, and aligned calls in the bootstrap. This does not establish interrupt safety for future code.
  • The full default x86 build passed, including compilation, linking, ISO, and documentation generation, with the x86-64 output directory still present.
  • The VM was stopped and its original optical medium restored after testing.
  • VirtualBox passed the normal boot tests and deliberate invalid-opcode, page-fault, and double-fault builds. The final write-fault test preserved error code 2 and CR2 0x100000000.
  • The exception milestone's normal boot captured TR=0x20, confirming the installed TSS selector, with long mode still active (EFER=0x500).
  • Double-fault injection set RSP to unmapped 0x100001000. Diagnostics reported vector 8, error 0, the original RSP, and a frame inside the IST1 stack.
  • Fatal exception reports include all 15 GPRs, RIP/CS/RFLAGS/RSP/SS, error code, CR2, and frame address. CR2 is the last page-fault address and may be stale for other exception types.

Runtime evidence is saved locally in the ignored bin/x86_64/boot.log and bin/x86_64/registers.log files for the first milestone, and boot-<test>.log / registers-<test>.log for the exception milestone. Unsupported-CPU boot checks and NMI/MC injection have not yet been performed.

The interrupt-frame and IST layout follows the AMD64 System Programming manual, chapter 8.

Memory, timer and shared scheduling progress

The PMM uses 4 KiB frames and dynamically placed bitmaps, with a 64 GiB management cap. Boot metadata, modules, kernel ranges, low bootstrap memory and allocator metadata stay reserved. VMM allocates high virtual arenas and rolls back both page tables and backing frames on failure. Page tables remain below 4 GiB; backing frames may reside above it.

memory.heap is shared between targets, with native-width pointer/size APIs, 16-byte alignment, overflow rejection and large-allocation rollback. memory.bitmap supplies the common bitmap operations. boot.multiboot owns fixed-width protocol records, with aliases retained in the x86 boot unit. arch.common.legacyirq shares PIC programming and PIT constants.

io.types separates data contracts from console initialization. proc.types uses native saved-stack addresses. The existing round-robin/quantum policy now lives in proc.scheduler, called by both the i386 process manager and x86-64 preemption tests. Process creation, messaging, return/exit, resource cleanup and reaping now use proc.mgr on x86-64. Descriptor tables are now active; console commands, executable loading and full filesystem/controller integration remain unavailable in the bootstrap.

VirtualBox validation has passed at 64 MiB, 2 GiB and 6 GiB. The 6 GiB run mapped, wrote, read and released RAM above 4 GiB. Tests cover PMM accounting and invalid frees, VMM rollback under injected allocation failures, heap alignment/zeroing/ large allocations, timer delivery, spurious IRQ7/15, IF preservation and CLI. Two heap-backed kernel contexts preserve distinct 64-bit registers, x87 and XMM state across timer preemption, then release their stacks after returning to the bootstrap context. Only the BSP is active; IRQ exclusion is not an SMP lock.

.\toolchain\x86_64\test_boot.ps1 -Test none -MemoryMB 64
.\toolchain\x86_64\test_boot.ps1 -Test none -MemoryMB 6144

The harness restores original VM RAM and optical media. Logs use bin/x86_64/boot-<test>-<MemoryMB>.log and matching register filenames; zero means use the configured RAM. All subsystem *_TESTS_FAILED fields must be zero. PIC handling follows the Intel 8259A datasheet.

The final i386 regression build passed compilation, linking, ISO and documentation steps. VirtualBox reached Boot complete - halting into IDLE; reported boot test suites had zero failures. Evidence: bin/x86_64/i386-regression.log. Fatal UD, write-PF and broken-stack DF tests also passed after the context-return path was extended. Final normal images are built without fault injection.

Shared process lifecycle

proc.mgr now runs on both targets with native process-pointer slots, stable monotonic IDs, suspended creation, messaging, exit and resource ownership. Initial stack layout lives in the architecture context units. x86-64's scheduler adapter saves the current stack and calls the same scheduler/manager as i386. A shared reaper process handles destruction on both targets outside IRQ context. Timer selection and kill requests coalesce worker wakeups; cleanup runs after registry/resource detachment. The reaper sleeps while there is no pending work.

core.ds.dynamic contains the common dynamic-list implementation; existing core.ds.lists exports compatible aliases/wrappers. Native addresses, checked capacity arithmetic, overlap-safe insertion and empty-list regrowth replace 32-bit arithmetic. Deletion retains capacity; explicit DL_ShrinkToFit frees excess storage without allocating inside every scheduler deletion. memory.raw supplies allocation-free scalar fill/move operations.

Process tests cover suspended publication, high-address lookup, killed tasks never running, normal return, explicit exit, child notification waking an awaiting parent, callback reentry without double cleanup, command argument/ stream publication, sleep using the PIT divisor, and restored heap accounting. The full i386 build and VirtualBox boot passed after these shared changes; evidence is in bin/x86_64/i386-lifecycle-regression.log.

The dedicated reaper revision passed all 15 process/container checks at 64 MiB and 6 GiB, including the corrected check-before-await notification protocol. The final i386 build and VirtualBox boot also passed with the shared reaper. VM RAM and original optical media were restored and the VM was powered off.

Descriptor tables

The shared driver.storage.fdtable now uses native memory operations and balanced IRQ locking. Every x86-64 process, including system tasks, owns its normal FD table. Storage protocol types depend on shared record definitions rather than bringing in the linked-list implementation and its console dependencies.

Close reserves an entry until callbacks and owned-string cleanup finish, rejects active async references and reference-count overflow, and prevents callback reentry from freeing it twice. Table teardown atomically rejects new users before process removal. An exited process with active FD references remains alive; final completion only wakes the shared reaper, which performs cleanup in process context. Waiting does not repeatedly scan descriptors on every timer tick.

VirtualBox passes 15 descriptor checks plus 16 lifecycle/container checks, including an exited child held alive by an async FD reference until another task releases it. No disk I/O is performed by these bootstrap tests. This validates FD ownership, not full VFS operation or controller DMA support in long mode.

The descriptor-table revision also passes the complete i386 build and VirtualBox boot, including the existing storage/VFS suites and normal volume discovery. Evidence: bin/x86_64/i386-fd-regression.log. Original VM settings are restored.

Shared strings and console command infrastructure

core.util memory helpers accept native addresses and sizes, reusing scalar memory.raw operations while retaining i386's existing large-copy REP path. core.strings no longer imports the x86 utility or linked-list implementation; all string copy addresses are native. Its common tests cover signed 64-bit minimum formatting, overflowing substring/match bounds, and terminator size rejection. The x86-64 system unit supplies Double-to-int64 truncation using CVTTSD2SI without changing rounding control state.

io.stdio now builds on both targets: growable buffers, bounded command parsing, case-insensitive allocation-free lookup, registry growth, ANSI output, and ECHO/CLEAR/HELP share one implementation. Buffer appends reserve space in bulk and support self-append across relocation. Allocation failures retain the old buffer; parser failures release all partially built parameters. Completion detaches the halt owner before invoking callbacks, allowing safe reentry.

VFS working-directory delegation and VERSION/TIME/REBOOT registration remain gated until their platform dependencies are integrated. This is command infrastructure, not yet an interactive keyboard/display/serial shell. No VFS or storage-controller support is implied by compiling the console unit.

The 64-bit bootstrap runs 162 shared string tests and 17 stdio tests. The process suite also launches the registered ECHO through runCommand with real parsed arguments and a growable output buffer, bringing it to 17 lifecycle/container checks. The 6 GiB VirtualBox run verifies scheduled ECHO and physical RAM above 4 GiB. The complete i386 build and boot also pass, including 162 string tests, stdio tests, normal mounts, and the existing storage/VFS suites. Evidence: bin/x86_64/i386-console-regression.log and the normal x86-64 boot logs.

Build-selected platform adapters

Shared Pascal units no longer select CPUs with CPU64/CPU386 conditionals. ASURO_ARCH selects a single src/arch/<target>/platform directory in the compiler search path. Both targets implement the same arch.platform.cpu, arch.platform.memory, arch.platform.process, and arch.platform.diagnostics unit names. Their declarations are shared through src/arch/common/platform.*.inc; implementations delegate to the existing architecture units. Calls are resolved at compile/link time, with no runtime architecture selection or function-pointer dispatch.

The bitmap heap, allocation headers, process registry, scheduling policy, strings, console buffers/parser, and descriptor lifecycle remain single shared implementations. Native scalar widths live in each selected system unit. memory.raw builds its fill pattern from native word width without a CPU branch.

arch.x86.startup now registers heap/process/console startup with the boot manager. arch.x86.console owns VERSION/TIME/REBOOT commands and their driver dependencies. The x86-64 bootstrap retains its explicit startup sequence. Unused working-directory wrappers were removed; directory operations belong to VFS.

Existing DEBUG_LMM allocator guards and architecture-local fault-injection build flags remain; these are feature/test options, not architecture selection.

Validation: complete i386 build and VirtualBox boot, including 17 stdio checks, 162 string checks, storage/VFS suites and normal mounts. Evidence: bin/x86_64/i386-platform-regression.log. x86-64 boot validation covers heap, IRQs, contexts, descriptors, strings, console and scheduled command execution.

The final adapter build also passes the 6 GiB VirtualBox bootstrap, including physical memory above 4 GiB and all 162 string, 17 console, 15 descriptor, and 17 lifecycle/container checks. VM RAM and optical media were restored; the VM is powered off.

Source search paths are discovered recursively from shared roots and the selected architecture tree, with other architectures excluded. Both targets use the same compiler invocation; target.sh loads compiler options and entry points from toolchain/targets/<architecture>.sh. Directory arguments are NUL-delimited, sorted, and passed as an array so new subdirectories and spaces in names do not require compile-script edits. Full i386 and x86-64 builds pass using this discovery path.

All shared build steps now consume the selected profile: pipeline stages, assembler format and source roots, C/Pascal compiler options, linker format, entry points, output locations, optional compiler runtime, and image validation. target.sh loads the profile by filename instead of keeping an architecture switch. Assembly files, object files, and static libraries are discovered; the configured assembly entry is linked first to preserve the Multiboot header. Initialization-table, icon, LVGL, version, and checksum generation use target settings too. Full i386 and x86-64 builds and VirtualBox boot checks validate this pipeline; the i386 boot includes normal mounts and existing storage tests.

Shared unit initialization

Both system units now use arch/common/system.init.inc to dispatch the build-generated INITFINAL table. The x86-64 profile enables the existing initcalls stage, whose packed records use native procedure-pointer widths. An initialization guard prevents repeat or reentrant dispatch. This also removes the duplicated table walks from the i386 runtime.

Initializers may set globals or register boot work; they must not require heap, hardware setup, or dependency ordering. The existing generator enumerates symbols in object-file order, so actual subsystem startup remains explicitly sequenced on x86-64 and dependency-ordered by boot.mgr on i386. The full boot manager remains i386-only; the x86-64 composition now starts the shared storage services explicitly (see storage integration below).

Validation: x86-64 build and 64 MiB VirtualBox boot passed, including a real Pascal initialization section checked after two calls to system.init. The full i386 build and VirtualBox boot also passed, with 54 initialization entries, normal volume mounts, and zero failures in the reported regression suites.

Shared filesystem foundations

The shared FNV-1a hashes, hash map, managed/string lists, path syntax, and filesystem registry now compile and run in long mode. String-list slots hold native pointers; hash inputs and memory-copy addresses no longer truncate to 32 bits. Hash replacement preserves the entry count, rehashing links each item in constant time, and container allocation failures leave published state intact. Linked-list insertion supports the end position and string splitting shares one implementation with rollback on allocation failure.

driver.storage.path provides caller-owned absolute and normalized paths without volume or driver dependencies. VFS delegates to this implementation on i386. Normalization scans into one allocated output buffer, handling repeated slashes, dot segments, and parent traversal without climbing above root. It is lexical; symlink resolution remains VFS work.

The filesystem registry uses native record copies, handles empty registries, and traverses linked records directly for linear searches/probes. Its boot registration lives in arch.x86.startup; x86-64 initializes it explicitly. Registry tests invoke an identify callback using heap-backed volume/driver records and restore the existing registry after the test.

New shared checks: 9 FNV-1a, 47 hash-map, 8 list, 15 path, and 9 registry checks. These foundation checks preceded the storage integration described below.

The shared contiguous FIFO and I/O request pool also run on x86-64. Queue addresses and byte-size calculations use native widths, capacity growth checks for overflow/allocation failure, and zero-sized elements are rejected. Request pool initialization and free-list changes use arch.platform.cpu IRQ exclusion. Pool node recovery uses the actual request-field offset instead of assuming a pointer-sized prefix. The bounded, heap-backed pool retains its existing 512-request capacity and lifetime.

The 6 GiB VirtualBox run passes 22 CFIFO and 4 request-pool checks in addition to the filesystem-foundation suites. Tests cover queue compaction/growth, native pointer payloads, request-pool exhaustion/reuse, and callback/data copies. Hardware storage validation is covered by the subsequent integration below.

Final validation for this batch: both target builds pass. The x86-64 VirtualBox bootstrap passes at 64 MiB; the 6 GiB run also passes the above-4-GiB physical memory check. i386 reaches idle with all 114 shared foundation checks passing, all 130 VFS checks passing, normal ISO9660/FAT32/EXT2 mounts, and zero failures in the reported storage/controller suites. VM RAM and optical media are restored and the VM is powered off. Logs remain in bin/x86_64/ (ignored).

Shared storage integration

The x86-64 boot now starts PCI, AHCI, the shared storage request manager, volume manager, VFS, ISO9660, FAT32 and EXT2. Boot registration belongs to target startup units. Shared code uses build-selected CPU, memory, timer and interrupt adapters; there are no CPU conditionals or duplicated filesystem implementations.

AHCI command lists and FIS buffers use native virtual addresses and full physical addresses. Each command table fits within one physical page. PRDs translate every 4 KiB page, coalesce contiguous physical runs and retain upper address bits. Controllers lacking 64-bit DMA reject inaccessible structures and buffers rather than truncating addresses. Unsupported 32-bit-only controllers do not yet have bounce-buffer support. The descriptor count remains bounded at 32.

PCI driver callbacks receive persistent device records rather than stack locals. Multifunction probing visits functions 1 through 7. IRQ/timer callbacks use the existing i386 interrupt infrastructure or the x86-64 PIC dispatch implementation. MMIO currently uses the low 4 GiB mapping; this is not general high-BAR support.

VFS, filesystem buffers, volume slots and controller references preserve native pointer widths. EXT2's worker starts before blocking filesystem operations, with scheduler interrupts enabled. Filesystem registration follows the i386 probe order so stale FAT signatures do not take precedence over EXT2 identification. FAT32 now falls back to the space required by a write when optional preallocation cannot fit, instead of incorrectly returning disk-full.

VirtualBox validation at 64 MiB and 6 GiB passes:

  • 130 shared VFS checks and 34 AHCI checks.
  • 123 storage metadata/filesystem checks, including heap-backed FAT32 and EXT2 format, file creation, cross-block write, close/reopen, unaligned read-back, persisted size and volume cleanup. No attached disk is written by these tests.
  • Actual ISO9660, FAT32 and EXT2 mounts through the AHCI controller.
  • A 4096-byte VFS read of the ISO's ELF64 kernel with header validation.
  • At 6 GiB, sector reads into physical RAM above 4 GiB compared byte-for-byte against ordinary-buffer reads from every attached storage device.

The boot harness requires the new failure counters and content-read marker; a high-memory run must also complete the high-DMA comparison. Evidence is saved in bin/x86_64/boot-none-64.log and bin/x86_64/boot-none-6144.log.

This completes the tested AHCI/filesystem path, not the entire OS port. The x86-64 image now continues into the desktop and shared application startup. Remaining USB controllers still require porting and validation. Disk LBAs and file sizes retain the existing storage API's 32-bit limits.

Final i386 regression also passes: the complete image reaches idle with 123 metadata/filesystem checks, 130 VFS checks, 34 AHCI checks and the existing USB, controller, storage and core suites reporting zero failures. Early-boot tests use private filesystem descriptors with synchronous transfer hooks; scheduled x86-64 tests keep the normal async hooks and exercise the EXT2 worker. The final 6 GiB x86-64 image passes the same 123 checks and the high-DMA comparison. VirtualBox is powered off with its original 2048 MiB RAM and Asuro.iso restored.

USB core and OHCI bring-up

The shared USB types, descriptor parsing, controller/device registry and hub logic now use native pointers and platform adapters. Aligned allocations store a native-width allocation header and reject invalid alignment and size overflow. Device-list slots retain full pointers, empty-list loops are bounded, and failed controller registration rolls back its allocation. Tests isolate registry state under IRQ exclusion and verify that their allocations are returned.

OHCI runs in the x86-64 VirtualBox image. Its hardware ED/TD prefix stays 16 bytes; software links and cleanup pointers use native widths. Controller MMIO and IRQ routing use the existing platform adapters. DMA buffers and descriptor pages must fit below 4 GiB; inaccessible buffers fail submission without truncation. There is no OHCI high-memory bounce-buffer support yet. Schedule allocation must succeed before the controller enters the operational state.

A 6 GiB VirtualBox boot starts OHCI, resets its port and enumerates the configured USB device (VID 80EE, PID 0030). At that stage, USB class-driver input/storage, UHCI, EHCI and xHCI were not part of the long-mode boot. That established real control transfers, not full USB feature parity. The boot harness requires successful enumeration as well as the USB type/core/hub/OHCI test failure counters.

Validation after the OHCI changes: both target builds and VirtualBox boots pass. The x86-64 runs at 64 MiB and 6 GiB report 55 USB type checks, 55 core checks, 44 hub checks and 91 OHCI checks with zero failures, plus real device enumeration. The i386 boot reaches idle with the existing storage, USB/HID and core suites passing. Original VM RAM and optical media are restored and the VM is off.

USB class drivers and stable storage registration

The shared mass-storage, boot keyboard and boot mouse drivers now compile for both targets through the platform adapters. The mouse receives bounds from the video subsystem; i386 startup supplies the optional PS/2 keyboard-disable hook. USB class registration stays in architecture startup composition.

Boot work after scheduler initialization runs in a normal process. Running it on the idle context starved initialization once the persistent USB worker started. Storage device records now have stable heap addresses behind native pointer slots: registering a fifth disk previously moved the by-value registry and left mounted volumes pointing at freed records. Registry publication and lookup exclude interrupts. ISO9660 now stops on failed sector reads instead of parsing empty data.

VirtualBox checks pass at 64 MiB and 6 GiB: 40 mass-storage protocol tests, 62 keyboard tests and 33 mouse tests, plus the existing USB/core/OHCI and storage suites. The existing USB disk serves a read-only sector-zero request through OHCI, and the AHCI kernel-file read passes before and after USB registration. The 6 GiB run also compares high-physical-memory reads against normal buffers. No USB writes are used. The full i386 image builds and reaches idle with its suites passing.

Temporarily enabling VirtualBox USB keyboard and mouse binds both class drivers alongside the disk. This validates attachment, not injected input: boot-protocol requests returned failure and the existing drivers continued. Report delivery, hot unplug, USB writes and UHCI/EHCI/xHCI remain unvalidated in long mode. The image now continues into the graphical desktop.

Native desktop, networking and applications

The normal image runs the shared LVGL desktop and application manager. Both architectures use the same application registrations; architecture startup retains CPU/BIOS-specific commands. PS/2 mouse and keyboard drive the terminal, including paced and burst input. Live BGA switching to 1280x800 and subsequent terminal input pass in VirtualBox. The LVGL lock hands ownership to queued waiters, and framebuffer flush stays inside that lock so mode changes cannot release a buffer during use.

E1000 uses native MMIO mappings, platform IRQ routing and owned DMA buffers. VirtualBox NAT tests obtained a DHCP lease and received ping replies at 6 GiB; DHCP also passed at 64 MiB. This does not establish complete TCP protocol coverage.

The WASM bridge resolves its context from the current process, initializes a suspended process before publishing it, and releases partially loaded contexts on failure. Native WASI proc_exit tests pass, and /disk/ram/hello prints Hello, World! in the terminal. The external runtime's fixed VM stacks exceed the available RAM in the 64 MiB configuration; launch is rejected before allocating those stacks. MEMINFO uses platform physical-byte counters and reports RAM above 4 GiB.

Both target builds pass. The i386 image reaches idle with its suites reporting zero failures. Native boots at 64 MiB and 6 GiB reach the interactive desktop; the high-memory run also passes AHCI DMA comparisons above 4 GiB. MD5SUM of abc matches 900150983CD24FB0D6963F7D28E17F72. VM test settings are restored afterward.

Full feature parity is still outstanding: UHCI/EHCI/xHCI, USB report delivery and hot unplug, broader network workloads, and full interactive application coverage. OHCI still rejects DMA addresses above its 32-bit hardware limit rather than providing bounce buffers. These limits must not be described as a finished port.

Follow-up interactive checks pass with VirtualBox USB keyboard and mouse: the mouse opens Terminal and paced/burst keyboard commands produce the expected output. SET_PROTOCOL warnings remain, but report delivery is now demonstrated. Files, Notepad and Disk Utility also open successfully; Files lists root entries, and Disk Utility lists AHCI and USB devices. This checks startup and display, not destructive disk operations or every editor/file-management workflow.

The application check exposed a duplicate core.strings.helpers unit shadowing the native implementation. Removing the stale copy fixes the Files sorting fault without changing compiler search rules. Low-memory WASM launch now displays the handler's memory error, and a subsequent terminal command succeeds.