Skip to content

Latest commit

 

History

History
158 lines (146 loc) · 33.8 KB

File metadata and controls

158 lines (146 loc) · 33.8 KB

Backlog and capability roadmap

This backlog is source-inspected only unless a verification result, task-log item, or base-checkout artifact is explicitly labeled.

P0: build and documentation blockers

  1. Host build-tool baseline for this container is resolved.

    • Historical evidence: the initial documentation pass failed ../configure ARCH=i386 in build-docs-check with no acceptable C compiler found in $PATH.
    • Current reviewed status: task-log comments 2026-05-29T19:56:57Z and 2026-05-29T19:58:36Z record apt installation and review of the normal host baseline (build-essential, autoconf, automake, file, plus GCC/G++, Make, and binutils dependencies). ./configure --help passes.
    • Follow-up trigger: if this container is rebuilt or the host baseline disappears, reinstall/reverify those packages. Do not treat the old missing-host-compiler result as the current first blocker.
  2. Stable i686-unknown-elf target toolchain path is resolved for this task workspace.

    • Historical blocker: after host tools were installed, fresh /tmp ARCH=i386 configure probes passed host compiler checks and failed at i686-unknown-elf-gcc not found.
    • Provenance: task-log comments 2026-05-29T20:15:25Z, 2026-05-29T20:18:36Z, and 2026-05-29T20:20:57Z record that the README-recommended gcc_toolchain_build source at commit eecef0929616a96517a83dab988a8429ad8c62d8 produced i686-unknown-elf-{gcc,ld,ar,objcopy} under /tmp/the-nux-i386-target-toolchain-gcc_toolchain_build/install/bin. With that temporary path prepended to PATH, fresh i386 configure/build passed.
    • Current reviewed status: that reviewed install tree was copied into stable task path /home/glguida/mysrc/system/state/the_nux-d552afcb8e35/tasks/the-nux-docs-capabilities/toolchains/i686-unknown-elf; the documented TOOLBIN is /home/glguida/mysrc/system/state/the_nux-d552afcb8e35/tasks/the-nux-docs-capabilities/toolchains/i686-unknown-elf/bin. Stable TOOLBIN verification found GCC 14.2.0 and Binutils 2.43.1 ld/ar/objcopy.
    • Follow-up trigger: if the task-workspace toolchain is removed, corrupted, or needs to be recreated outside this instance, rebuild or recopy from the documented gcc_toolchain_build commit. Do not commit the toolchain into this repository.
  3. i386 QEMU runtime smoke blocker is resolved in this container.

    • Historical blocker: the reviewed target-toolchain slice said make qemu failed at qemu-system-i386: No such file or directory; qemu-system-x86_64 was also absent.
    • Current reviewed status: apt package qemu-system-x86 is installed with --no-install-recommends, providing /usr/bin/qemu-system-i386 and /usr/bin/qemu-system-x86_64 at QEMU 10.0.8 (Debian 1:10.0.8+ds-0+deb13u1+b2).
    • Verification: fresh /tmp/the-nux-i386-qemu-stable-path-build-i386 with stable TOOLBIN prepended to PATH passed ARCH=i386 configure, make -j"$(nproc)", and a bounded timeout --foreground 20s make qemu. The command returned rc 124 only after serial success markers appeared: APXH started., NUX library (nux), userspace hello, SYSC0/SYSC6 passed, and User exited with error code: 42. Later source fixes repeated the same flow and added regression markers: the uctxt_seta2() fix added UCTXT_SETA2 test passed. plus UCTXT_SETA2 user test passed., the uaddr_validrange() fix added UADDR_VALIDRANGE test passed., the KVA metadata-removal fix added KVA_ALLOC_FREE test passed., the user-access memset fix added UADDR_MEMSET test passed. plus UADDR_MEMSET user test passed., and the KMAP update guard fix added KMAP_UPDATE test passed.. The RISC-V UMAP bounds fix added UMAP_BOUNDS test passed. to prove the HAL leaf lookup rejects one-past-user addresses.
    • Current harness: tools/qemu-smoke-i386.sh now runs the reviewed out-of-tree i386 configure/build/QEMU flow with a configurable TOOLBIN, captures serial output, and treats timeout rc 124 as a pass only after the required APXH/NUX/userspace/regression markers appear.
    • Follow-up trigger: integrate the checked-in harness into CI or extend it for other architectures after their target-toolchain/QEMU paths are reviewed.
  4. Submodules are initialized and verified for the i386 smoke path in this task workspace.

    • Evidence: .gitmodules lists contrib/gnu-efi, contrib/binutils, and contrib/dtc; the uctxt_seta2() worktree initially showed them uninitialized with leading -.
    • Current i386 status: git submodule update --init --recursive in /home/glguida/mysrc/system/state/the_nux-d552afcb8e35/tasks/the-nux-docs-capabilities/worktree-uctxt-seta2 checked out the pinned submodule commits, after which the fresh i386 configure/build/QEMU smoke passed with the stable TOOLBIN.
    • Follow-up trigger: worktree-local submodule initialization succeeded for the amd64 follow-through task, and the amd64 override build is no longer blocked by submodule checkout or workspace capacity. Verify riscv64 submodule-dependent paths separately when its target tools and QEMU are available. The current build invokes contrib/binutils configure/make in the source submodule, so dedicated verification worktrees may need cleanup of generated files after builds; do not clean the dirty base checkout without authorization.
  5. APXH configure architecture selection is fixed.

    • Historical evidence: apxh/configure.ac was missing a separator between the amd64 and riscv64 AS_CASE branches; generated apxh/configure showed a malformed amd64 branch and had an invalid-architecture error message that omitted riscv64.
    • Current status: apxh/configure.ac and the tracked generated apxh/configure select multiboot for i386, multiboot efi for amd64, and sbi for riscv64; invalid architecture messages list i386, amd64, riscv64.
    • Follow-up trigger: default amd64 multiboot now has a reviewed README-built amd64-unknown-elf/i686-unknown-elf toolchain cache path; rebuild or restore that external cache if it disappears. The local smoke policy also preserves the reviewed x86_64-linux-gnu/i686-unknown-elf override and tools/qemu-smoke-amd64.sh captures it; wire either path into CI only after the runner provides the selected toolchain cache and QEMU. RISC-V EFI remains a separate platform-contract/toolchain decision and is guarded unsupported; keep it out of the default riscv64 APXH build until that decision is designed and verified.
  6. --disable-werror handling in configure inputs is fixed.

    • Historical evidence: top-level, APXH, and example configure.ac defined AC_ARG_ENABLE([werror]) but tested enable_relax rather than enable_werror.
    • Current status: top-level, APXH, and example configure inputs now test enable_werror; the generated configure scripts were regenerated and verified so default configure keeps -Werror while --disable-werror omits it from generated build flags.
    • Follow-up trigger: if new configure inputs are added, keep the AC_ARG_ENABLE([werror]) variable and generated scripts in sync.
  7. README boot-support claims are reconciled with configure behavior.

    • Historical evidence: README said APXH supported EFI on i386, amd64, and riscv64 even though the APXH configure selection is multiboot only for i386, multiboot efi for amd64, and sbi efi for riscv64.
    • Current status: README now describes configured APXH boot paths by architecture: i386 -> multiboot, amd64 -> multiboot efi, and riscv64 -> sbi. It also states that i386/multiboot and amd64/multiboot have full default-toolchain runtime-smoke coverage in this task environment when their README-built toolchain caches are on PATH, while the amd64 host-prefix override path passes bounded QEMU with the reviewed x86_64-linux-gnu/i686-unknown-elf override after the libec PIE fixes. RISC-V EFI is intentionally unsupported/guarded until a reviewed descriptor/toolchain contract exists.
    • Follow-up trigger: reopen only if configure behavior changes or target-toolchain/runtime verification proves a different support claim. amd64 EFI verification remains tracked in the architecture-specific follow-ups; RISC-V EFI should only be reopened for an explicit descriptor/toolchain design that can remove the unsupported guard.
  8. amd64 default/override smokes are standardized; riscv64 SBI/DTB smoke is verified.

    • Evidence: the 2026-05-30 follow-through integrated commit 51fc152c5d4cd92be9ee0ec9f7410e245bb16dd0 (libec: disable PIE for freestanding links) after review, followed by commit 8e1a5365dbdb2277fe9a2853f272765cbc6dd98e (libec: disable PIE for freestanding compiles). Prior reviewed logs show /usr/bin/qemu-system-x86_64 present but no qemu-system-riscv64; no default amd64-unknown-elf-* or riscv64-unknown-elf-* target tools were on PATH; the stable external i386 TOOLBIN remains under the the-nux-docs-capabilities task workspace.
    • amd64 status: the README gcc_toolchain_build path has now provisioned a real default-prefix cache. A local checkout at commit eecef0929616a96517a83dab988a8429ad8c62d8 produced amd64-unknown-elf-* and i686-unknown-elf-*; its install/ artifact was copied to /home/glguida/mysrc/system/state/the_nux-d552afcb8e35/tasks/the-nux-amd64-default-toolchain-policy/toolchains/gcc_toolchain_build. With that install/bin prepended to PATH, default ARCH=amd64 preflight, configure, make -j1, direct bounded make qemu, and tools/qemu-smoke-amd64.sh forced to TOOLCHAIN=amd64-unknown-elf TOOLCHAIN32=i686-unknown-elf pass.
    • Policy decision: use the README-built freestanding cache for default-prefix amd64 verification, keep compiler artifacts outside the repository, and rebuild/restore the external cache if default-path tools disappear. The reviewed ARCH=amd64 TOOLCHAIN=x86_64-linux-gnu TOOLCHAIN32=i686-unknown-elf override remains a supported local smoke path rather than a silent default alias. tools/qemu-smoke-amd64.sh defaults to that override path and accepts timeout rc 124 only after APXH/NUX, IPI!, userspace, SYSC0 through SYSC6, UCTXT_SETA2, UADDR_MEMSET, UMAP_BOUNDS, KMAP_UPDATE, exit, no unexpected kernel page fault, and repeated zero-valued pnux_entry_pagefault idle counter evidence.
    • i386 regression status: the prior follow-up verification reran tools/qemu-smoke-i386.sh with the stable external i386 TOOLBIN; it returned rc 0/PASS. Fresh re-verification in a runner without make/QEMU is blocked at missing host tools, not at the checked-in harness logic.
    • riscv64 status: default ARCH=riscv64 preflight/configure has a reviewed Debian package path with riscv64-unknown-elf-* tools and qemu-system-riscv64. The checked-in tools/qemu-smoke-riscv64.sh verifies the SBI/DTB runtime path. Default APXH configure selects sbi; RISC-V EFI is explicitly unsupported and unselected by default, with manual make -C apxh/efi guarded before the old misleading riscv64-unknown-elf-ld: -shared not supported link path.
    • Follow-up trigger: wire default-prefix amd64 into CI only on runners with the README-built amd64-unknown-elf/i686-unknown-elf cache, initialized submodules, make, and qemu-system-x86_64; wire the override harness only on runners with host-prefixed x86_64 tools and an approved i686 TOOLBIN. Revisit RISC-V EFI only with an explicit ACPI-vs-DTB platform contract and linker/toolchain plan that intentionally removes the current guard.
  9. amd64 EFI OVMF smoke is verified from a clean worktree; dirty gnu-efi sources are an environment blocker.

    • Build evidence: task the-nux-amd64-efi-runtime-smoke initialized submodules in a dedicated worktree and verified ARCH=amd64 ./tools/build-preflight.sh with the README-built amd64-unknown-elf/i686-unknown-elf cache. A fresh out-of-tree ARCH=amd64 configure followed by make -j1 -C apxh/efi all, make -j1 -C libhal_x86 all, make -j1 -C libplt_acpi all, make -j1 -C libnux all, make -j1 -C libnux_user all, make -j1 -C example/kern all, and make -j1 -C example/user all produced apxh/efi/apxh.efi, example/kern/example, and example/user/exuser. file(1) identified apxh.efi as a PE32+ x86-64 EFI application.
    • Firmware evidence: /usr/bin/qemu-system-x86_64 is present at QEMU 10.0.8 (Debian 1:10.0.8+ds-0+deb13u1+b2). The planner-approved apt gate installed only ovmf=2025.02-8+deb13u1 with sudo DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends ovmf=2025.02-8+deb13u1 after simulation showed one new package and 0 upgrades/removals; dpkg-query reports ovmf 2025.02-8+deb13u1 install ok installed with Installed-Size: 16443. Readable firmware includes /usr/share/qemu/OVMF.fd, /usr/share/OVMF/OVMF_CODE_4M.fd, and /usr/share/OVMF/OVMF_VARS_4M.fd. Local FAT-image helpers (mformat, mcopy, mkfs.vfat, mkfs.fat) are still not required by the checked-in harness because it uses QEMU's fat:rw: directory backend.
    • Current harness: after worktree submodule initialization, PATH="$AMD64_TOOLBIN:$PATH" ARCH=amd64 ./tools/build-preflight.sh passes. tools/qemu-smoke-amd64-efi.sh builds the EFI loader and payloads from an out-of-tree build, stages EFI/BOOT/BOOTX64.EFI, kernel.elf, and user.elf, auto-detects common OVMF paths or accepts OVMF_CODE/OVMF_VARS, and no longer fails on missing firmware in this container. With TOOLBIN="$AMD64_TOOLBIN" from a clean worktree, it reaches APXH/NUX, IPI!, userspace, SYSC0 through SYSC6, UCTXT_SETA2, UADDR_MEMSET, UMAP_BOUNDS, KMAP_UPDATE, User exited with error code: 42, and repeated zero-valued pnux_entry_pagefault idle counters before the expected timeout. The earlier libnux/alloc.h:192 ACPI/KVA assertion was fixed by commit d9ba5f5256cb76c4f6b9207aec775a65d22e0f1a.
    • Follow-up trigger: keep the amd64 EFI smoke on clean/disposable worktrees or CI checkouts. The EFI build uses build-local gnu-efi objects, but the harness intentionally stops before QEMU if contrib/gnu-efi has tracked local source modifications unless NUX_EFI_ALLOW_DIRTY_GNUEFI=1 is set for an intentional local experiment; inspect/clean/regenerate dirty base-checkout submodule artifacts only by explicit operator decision.

P1: correctness and runtime capability gaps

  1. Audit HAL PTE naming/ownership before changing the API.
    • Evidence: task-log comment 2026-05-29T19:19:31Z records an untracked base-checkout /home/glguida/the_nux/TODO note about ROOTPTE/ROOTPTEP and LEAFPTE/LEAFPTEP; planner comment 2026-05-29T19:34:18Z required documenting it. This is historical task-log/base-checkout evidence, not a tracked-source mandate.
    • Current behavior: tracked include/nux/hal.h exposes leaf page-table pointer/entry APIs (hal_l1p_t, hal_l1e_t, hal_kmap_getl1p(), hal_umap_getl1p(), and hal_l1e_*()), and libnux/kmap.c/libnux/umap.c use those leaf entries for kernel and user data mappings. x86 and RISC-V walkers keep root/intermediate table details inside the HAL.
    • Audit status: docs/nux-pte-entry-contracts.md treats the old root/leaf wording as uncertain historical thinking. The current leaf-only contract is simple and adequate for current generic NUX callers; Murgia/MH is a downstream pressure test, not the only purpose of the API.
    • Follow-up trigger: no PTE code slice is authorized by the TODO alone. Reopen only for a demonstrated generic NUX problem, such as safe UMAP root-table ownership/share/detach semantics, partial page-table trimming that cannot be expressed with the current API, or a proven simplification that avoids parallel-name churn. Any proposal must keep amd64 especially important and riscv64 first-class with i386.
  2. Audit entry-hook return semantics before changing the ABI.
    • Evidence: task-log comment 2026-05-29T19:19:31Z records the base-checkout TODO note: “all entry function should not return a frame. Frame in input should be modified with return data.” Planner comment 2026-05-29T19:34:18Z tied this to the required docs fix. This is historical input, not an implementation mandate.
    • Current behavior: include/nux/nux.h declares entry_sysc(), entry_pf(), entry_ex(), entry_alarm(), entry_ipi(), and entry_irq() as returning uctxt_t *; libnux/entry.c assigns those return values and converts them with uctxt_frame(); libnux/uctxt.c handles UCTXT_IDLE, UCTXT_INVALID, frame-pointer conversion, and register mutation helpers.
    • Audit status: docs/nux-pte-entry-contracts.md records the current return-based hook contract as authoritative and adequate for current NUX examples. It already supports mutating return registers, resuming a different saved context, or idling the CPU.
    • Follow-up trigger: no mutate-input-frame/action ABI slice is authorized by the TODO alone. Reopen only if a source-backed generic NUX problem shows that an action/result model would make entry handling smaller, safer, or easier to verify while preserving syscall arity, UCTXT_SETA2, user-access page-fault recovery, EOI ordering, idle wake behavior, and i386/amd64/riscv64 coverage.
  3. uctxt_seta2() setter bug is fixed.
    • Historical evidence: libnux/uctxt.c called hal_frame_seta1(f, a2) inside uctxt_seta2().
    • Current status: uctxt_seta2() now calls hal_frame_seta2(). The example kernel/user smoke includes syscall 7, where the kernel uses uctxt_seta2() to write a known magic value into the resumed user frame's third argument register and userspace verifies it after the syscall returns.
    • Follow-up trigger: keep the UCTXT_SETA2 serial markers in the i386 QEMU smoke output and in tools/qemu-smoke-i386.sh unless the regression is replaced by a stronger checked-in test.
  4. User-address range validation is fixed.
    • Historical evidence: libnux/uaddr.c had unused malformed macros and uaddr_validrange() validated a + size rather than the last accessed byte; overflow/zero-length behavior was undocumented.
    • Current status: the stale macros are removed. uaddr_validrange(a, size) treats user ranges as half-open intervals [a, a + size) contained in [hal_virtmem_userbase(), hal_virtmem_userbase() + hal_virtmem_usersize()); for non-empty ranges it checks the last accessed byte without overflowing, so a range ending exactly at the user-region end is valid and a one-past-end non-empty range is invalid. Empty ranges are accepted for no-op user copies at any address from the user base through one-past-user-end inclusive. uaddr_valid(a) remains the single-address [base, end) check.
    • Verification: the example kernel i386 smoke now asserts first-byte validity, full [base, end) validity, one-past-end non-empty rejection, oversized/overflow rejection, and zero-length no-op acceptance, then prints UADDR_VALIDRANGE test passed..
    • Follow-up trigger: keep the UADDR_VALIDRANGE marker covered by tools/qemu-smoke-i386.sh unless the regression is replaced by a stronger checked-in test.
  5. HAL UMAP leaf bounds are enforced consistently.
    • Historical evidence: include/nux/hal.h requires hal_umap_getl1p() to reject non-user addresses by returning false and storing L1P_INVALID, and x86 used the correct lower-or-upper bound check; RISC-V used an impossible >= max && < min condition in libhal_riscv/pmap.c, so the first one-past-user address could enter sv48.c and assert on L4OFF(va) < UMAP_L4PTES.
    • Current status: RISC-V now matches the HAL contract and x86 behavior by rejecting addresses below the UMAP minimum or at/above the UMAP maximum with L1P_INVALID. The RISC-V hal_umap_next() wrapper also returns UADDR_INVALID for one-past-user addresses before calling the SV48 walker.
    • Verification: the example kernel bootstraps/uses a UMAP and prints UMAP_BOUNDS test passed. only after hal_umap_getl1p() rejects the first one-past-user address for both the bootstrapped UMAP and current CPU mappings with L1P_INVALID; i386, amd64, riscv64, and amd64 EFI smoke harnesses require the marker.
    • Follow-up trigger: keep the UMAP_BOUNDS marker covered by the checked-in smoke harnesses unless a stronger HAL UMAP contract regression replaces it.
  6. KVA allocator metadata removal is fixed.
    • Historical evidence: libnux/kva.c vmap_insert() allocates each struct vme metadata node with kmem_alloc(0, sizeof(struct vme)), but vmap_remove() removed the node from the red-black tree and then called kmem_alloc(0, sizeof(struct vme)) again instead of releasing the removed node.
    • Current status: vmap_remove() now frees the removed metadata with kmem_free(0, (vaddr_t) vme, sizeof(struct vme)) after unlinking it and decrementing vmap_size, preserving the existing KVA lock/tree/zone flow. The example i386 smoke repeatedly allocates and frees KVA ranges, checks that the high KMEM brk is unchanged across the balanced KVA churn, and prints KVA_ALLOC_FREE test passed..
    • Follow-up trigger: keep the KVA_ALLOC_FREE marker covered by tools/qemu-smoke-i386.sh unless the regression is replaced by a stronger checked-in test.
  7. KMAP update guard is fixed.
    • Historical evidence: libnux/cpu.c cpu_kmapupdate() returned when cpu_getinfo(cpu) succeeded and then dereferenced NULL for invalid/nonexistent CPUs, the opposite of the adjacent cpu_tlbflush() guard.
    • Current status: cpu_kmapupdate() now returns only when cpu_getinfo(cpu) is NULL; valid CPUs receive NMIOP_KMAPUPDATE before cpu_nmi(). The example kernel remaps one KVA page from one allocated PFN to another after CPU initialization, waits for the post-commit mapping to observe the new PFN through the same virtual address, verifies the write landed in the new page, and prints KMAP_UPDATE test passed..
    • Follow-up trigger: keep the KMAP_UPDATE marker covered by the i386/amd64/riscv64 smoke harnesses and retain a source-level guard check if the runtime remap is replaced by a different KMAP regression.
  8. Implement RISC-V SBI HSM/AP bootstrap beyond the current BSP-only contract.
    • Current status: libplt_sbi/sbi.c keeps all DTB-discovered harts internally for PLIC context mapping, but the public PCPU iterator deliberately exposes only BSP CPU0 once per full iteration and resets after PLT_PCPU_INVALID. If the DTB reports additional harts, the SBI/DTB path logs that secondary harts are discovered but not exposed/started until SBI HSM/AP bootstrap support exists.
    • Evidence: libhal_riscv/riscv.c still has TODO/no-op hal_pcpu_init() and hal_init_done() paths, hal_pcpu_startaddr() returns PADDR_INVALID, and libplt_sbi/sbi.c keeps plt_pcpu_start() as an explicit secondary-start no-op.
    • Next slice: design the APXH boot-hart handoff plus SBI HSM start/enter/trampoline/stack contract before exposing secondary harts through plt_pcpu_iterate().
  9. RISC-V external IRQ/PLIC baseline is implemented; device/SMP follow-through remains.
    • Current status: libplt_sbi/sbi.c now stores the DTB-discovered PLIC MMIO base/length, source count (riscv,ndev with a conservative fallback), and S-mode context mappings by DTB hart reg; maps the standard PLIC priority/enable/threshold/claim registers; initializes the current CPU's S-mode context; exposes valid PLIC source IDs through plt_irq_max(), plt_irq_type(), plt_irq_enable(), plt_irq_disable(), and plt_eoi_irq(); and dispatches supervisor external interrupt cause 9 through PLIC claim to hal_entry_irq() with completion through the normal EOI path.
    • Remaining gap: no device-specific trigger/polarity metadata is parsed yet, so valid PLIC sources default to active-high level semantics; the current smoke verifies discovery/initialization but does not inject an external device IRQ; secondary hart startup/context use remains blocked behind the explicit BSP-only SMP/HSM item above.
  10. RISC-V EFI platform contract is guarded unsupported; real support remains future work.
  • Current status: configured RISC-V NUX uses APXH SBI plus libplt_sbi/PLT_DTB. APXH EFI currently supports ACPI descriptors for x86 EFI, so the RISC-V EFI makefile and source path now fail early with an unsupported-contract guard instead of silently returning PLT_ACPI or reaching the old misleading EFI -shared link failure.
  • Next slice: only reopen RISC-V EFI for a reviewed design that chooses ACPI vs DTB handoff, specifies the APXH descriptor/toolchain/linker contract, and verifies the resulting path.
  1. x86 SMAP/SMEP supervisor hardening is implemented.
  • Current status: libhal_x86/x86.c detects CPUID leaf 7 SMEP and SMAP support, then enables CR4.SMEP and CR4.SMAP per CPU during HAL CPU entry only when the local CPU advertises each feature. hal_useraccess_start()/hal_useraccess_end() still bracket generic user-copy windows with stac/clac only when SMAP is enabled locally, and x86 user-origin entry paths clear AC when SMAP is active so userspace cannot carry an open user-access window into the kernel.
  • SMEP audit status: i386 and amd64 AP bootstrap reset-vector mappings are supervisor KVA mappings, and the temporary low trampoline leaf entries are deliberately installed as PTE_P | PTE_W without PTE_U even though the helper reaches them through UMAP page-table machinery. Forced-SMEP QEMU smoke is the regression trigger for accidental CPL0 execution from user mappings.
  • Follow-up trigger: reopen this item only if a future x86 feature intentionally executes supervisor code from a user (PTE_U) mapping, adds new trampoline mappings, or changes entry/return paths in a way that could bypass the guarded SMEP/SMAP setup.
  1. Framebuffer mask/bounds baseline is implemented; console/graphics refinements remain.
    • Current status: apxh/multiboot/mb.c builds RGB masks from Multiboot bit positions and sizes without shifting by 1 << pos; EFI and Multiboot RGB masks are consumed by libnux/framebuffer.c; framebuffer_color() packs channels through the active descriptor masks with a fallback for invalid/zero masks; and framebuffer_blt() clips glyph writes against descriptor width, height, pitch, bpp-derived pixel storage, and mapped framebuffer size. The amd64 EFI smoke requires the serial FRAMEBUFFER_MASK_BOUNDS test passed. marker from a clipped bottom-right framebuffer self-test.
    • Remaining limits: indexed/palette framebuffers are still not a real graphics path, normal multiboot -nographic smokes usually do not expose a framebuffer, and there is still no screenshot/visual comparison harness or broader graphics API.
    • Follow-up trigger: reopen only for a source-backed framebuffer console bug, visual regression harness, non-RGB/palette support decision, or a deliberate graphics API slice.
  2. Clarify i386 TLS support.
    • Evidence: libhal_x86/i386/sys_entry.c states hal_frame_settls() is ignored because i386 TLS needs LDT support.
    • Next slice: document as unsupported or add LDT/TLS support.
  3. ACPI/x86 MADT parser hardening is implemented; modern APIC expansion remains.
    • Current status: libplt_acpi/acpitbl.h models MADT Interrupt Source Override GSI as the ACPI-specified 32-bit field, so flags is read from the correct packed offset. libplt_acpi/acpi.c now guards absent root/MADT table loads and validates MADT record common headers, zero lengths, remaining payload length, and known record minimum sizes before dereferencing.
    • Remaining gap: LSAPIC, x2APIC, IOSAPIC, and LX2APICNMI entries are still ignored. Prioritize x2APIC if modern x86 hardware support is a near-term goal.
  4. Track the Murgia modern-hardware boundary without a NUX ACPI fact substrate.
    • Evidence: task-log comment 2026-05-29T21:51:15Z records the Murgia/MH design constraint that IOMMU support should stay transparent beneath the existing hwdev/sys_export/dexport device/export semantics. The corrected source-backed inventory in docs/murgia-substrate-roadmap.md records current NUX capabilities, gaps, and the approved APXH typed-platform-pointer/HAL boundary.
    • Current behavior: tracked x86 platform code scans ACPI RSDP/RSDT/XSDT internally for MADT and HPET, then initializes LAPIC, IOAPIC, and HPET support. Public NUX primitives already include PFN/KVA/KMAP/UMAP and kva_physmap() for CPU-side physical/MMIO mappings. A source/doc search found no current PCI bus enumeration, ACPI MCFG/PCIe ECAM discovery, MSI/MSI-X support, Intel DMAR or AMD IVRS parsing, IOMMU abstraction, DMA-remapping map/unmap API, AHCI/storage driver, filesystem, or real-disk-image QEMU harness.
    • Design constraint: APXH passes struct apxh_pltdesc (type, pltptr) to the selected HAL/PLT, and that code may consume the needed ACPI or DTB boot data internally. NUX must not export raw ACPI tables, ACPI table inventories, MCFG/ECAM records, DMAR/IVRS records, or public platform facts for Murgia. Murgia/kernel/userspace owns ACPI parsing, PCIe/MCFG interpretation, IOMMU/device policy, AHCI, and filesystem decisions above that boundary.
    • Priority order:
      1. Preserve and document the typed platform descriptor boundary; test only that selected platform libraries receive and use their expected descriptor internally.
      2. Keep x86 APIC/IOAPIC/HPET/x2APIC and RISC-V PLIC/timer work inside the platform/HAL abstraction instead of publishing hardware-description inventories.
      3. Route Murgia PCIe/MCFG/IOMMU/AHCI/filesystem policy to Murgia/kernel/userspace; do not make it depend on NUX ACPI export.
      4. Specify any future generic NUX memory, interrupt, or DMA helper as a separate reviewed API with concrete acceptance criteria and no raw ACPI table export.
      5. Preserve i386 QEMU harness coverage; add amd64/riscv64 and later disk-image harnesses only as bounded tasks after their boot paths and ownership boundaries are verified.
    • Next slice: no ACPI/platform-facts implementation slice is authorized. If future work is needed, start with an explicitly scoped internal HAL/platform test or a Murgia-owned device-policy task.

P2: usability, tests, and polish

  1. Preserve and analyze PORTING_0_EM as a binary artifact, not documentation.
    • Evidence: task-log comment 2026-05-29T19:19:31Z identifies /home/glguida/the_nux/PORTING_0_EM as a base-checkout binary/ELF artifact to preserve. A local magic-byte check in this fix job read 7f454c46 (ELF) and size 303904 bytes; file(1) was unavailable in the container.
    • Next slice: if analysis is authorized, inspect it with appropriate binary tools (readelf, objdump, or equivalent) and record metadata separately. Do not edit it, delete it, or treat it as Markdown/source documentation.
  2. Checked-in automated i386, amd64, and riscv64 smoke harnesses are implemented.
    • Evidence: tools/qemu-smoke-i386.sh runs from a source checkout/worktree, uses an out-of-tree build directory (defaulting under /tmp, overridable with BUILD or NUX_BUILD), prepends TOOLBIN when provided, runs configure ARCH=i386, make, and bounded make qemu, captures QEMU serial output, and verifies the reviewed APXH/NUX/userspace/regression markers before accepting timeout rc 124.
    • Evidence: tools/qemu-smoke-amd64.sh uses the same out-of-tree build/log conventions for ARCH=amd64 TOOLCHAIN=x86_64-linux-gnu TOOLCHAIN32=i686-unknown-elf, requires the host-prefixed x86_64 tools plus the stable i386 APXH compiler path, and verifies the reviewed amd64 APXH/NUX/IPI/userspace/syscall/UCTXT_SETA2/UADDR_MEMSET/UMAP_BOUNDS/KMAP_UPDATE/exit/idle markers before accepting timeout rc 124.
    • Evidence: tools/qemu-smoke-riscv64.sh repeats the verified SBI/DTB subset build from an out-of-tree directory, accepts RISC-V-only QEMU_EXTRA_ARGS for smoke evidence such as -smp 2, and verifies the OpenSBI/APXH/NUX/userspace/syscall/UCTXT/UADDR/UMAP/KVA/KMAP/exit/idle markers before accepting timeout rc 124.
    • Follow-up trigger: add CI wiring or GDB/debug variants for i386/amd64/riscv64 only on runners with the required toolchains, initialized submodules, make, and QEMU.
  3. QEMU/GDB debugging helper is implemented.
    • Current status: tools/qemu-debug.sh prepares the existing make qemu_dbg flow from an out-of-tree build for ARCH=i386, ARCH=amd64 multiboot, and ARCH=riscv64 SBI/DTB. It writes a build-local GDB command file that loads example/kern/example kernel symbols, includes commented optional APXH/user payload symbol lines, and connects to QEMU's default target remote :1234 stub.
    • Follow-up trigger: reopen only for a source-backed debugging workflow gap such as CI/operator integration, richer architecture-specific symbol helpers, or a real debugger frontend. Do not vendor GDB or make GDB a NUX build dependency.
  4. Document syscall ABI stability.
    • Evidence: libnux_user wraps syscalls, but syscall numbers are example-local (4096 putchar, 4097 exit in example/kern/main.c/example/user/main.c).
    • Next slice: either publish a minimal NUX syscall convention or explicitly state that kernels own their syscall ABI.
  5. Keep Murgia requirements traceable and triaged.
    • Evidence: docs/murgia-integration.md records task-log-backed MURGIA-MH-001, the 2026-05-29T19:53:34Z Murgia handoff rows for the entry_sysc arity contract, x86 PFN-0/MMIO-region behavior, and UIOMAP/IOUNMAP errno semantics, plus MURGIA-IOMMU-006 from the 2026-05-29T21:51:15Z IOMMU transparency constraint and the corrected MURGIA-SUBSTRATE-007 boundary note from docs/murgia-substrate-roadmap.md.
    • Next slice: for confirmed NUX contracts, add compile/build checks or source comments when useful; for Murgia-side dependency candidates, wait for concrete NUX acceptance criteria before changing APIs.
  6. Clean README and install docs.
    • Evidence: README has minor typos and a malformed closing fence in the build snippet; install.sh contains only a TODO comment.
    • Next slice: fix README after build commands are verified and either implement or remove/document install.sh.

Source TODO/FIXME scan summary

A tracked-file grep excluding contrib found TODO/XXX items in:

  • install.sh
  • apxh/efi/efi-main.c
  • libhal_riscv/riscv.c
  • libhal_x86/i386/i386.c
  • libnux/kmem.c
  • libnux/kva.c
  • libplt_acpi/lapic.c
  • libplt_sbi/sbi.c

Generated configure files and imported libec headers also contain generic FIXME/XXX/panic/assert strings; those are lower signal than the project-specific items above.