Boot Memory and Lifecycle - Mainkill1/SpiritBoot GitHub Wiki
Boot memory, mappings, reset, and operation lifetime
This page supplements Runtime-Calls and Kernel-Calls with constraints that cross several calls. Source baseline: SpiritBoot main 27149596, using the ordered firmware patches.
Separate 64 and 128 MiB artifacts
Memory capacity is selected at build time, not discovered by treating both ROMs as interchangeable. Patch 0030 rejects values other than 64 or 128 and propagates the selection into kernel and loader builds. Match the ROM to xemu's memory configuration.
| Boot-layout quantity | 64 MiB build | 128 MiB build |
|---|---|---|
| Kernel PE virtual image base | 0x84000000 |
0x84000000 |
| Kernel physical image base | 0x03400000 |
0x04000000 |
| Loader physical base | 0x03800000 |
0x07d00000 |
| Loader physical limit | 0x03900000 |
0x07f00000 |
| Scratch physical base | 0x03900000 |
0x07000000 |
| Low page-table physical base | 0x03bc0000 |
0x07f00000 |
| Declared memory top | 0x03ffffff |
0x07ffffff |
These are loader layout constants, not freely allocatable title ranges. The fixed virtual image is mapped to the selected physical placement. Image and scratch capacity are checked against the actual PE file/header bounds; an oversized image must fail the build rather than overlap another region.
A physical address is not automatically a usable alias
0x80000000 | physical_address is a naming convention, not proof that a writable mapping exists. The boot and system-PTE layouts can constrain the alias window, especially with upper-memory frames. A direct memory operation must verify the live mapping and correct physical frame.
Patch 0009 adds guarded direct zeroing. Its fallback remains necessary when that mapping is absent or unsuitable. Patch 0004 addresses relocation copy mappings rather than assuming every physical frame has a permanent direct alias.
Do not bypass these checks merely because a common 64 MiB test passes. Test high frames, aliasing, read-only/non-direct mappings and build-specific reserved regions.
WB physical-address translation: conditional defect and draft robustness repair
The released NxMmGetPhysicalAddress() masks every address in the nominal 0x80000000–0x84000000 WB range. That shortcut returns an incorrect address if a live mapping in this range is nonidentity, and can invent an address for an absent mapping. NxkMmEnsureXboxWindows() caps the identity paint at MmSystemPteSpaceStart (rounded down to a 4 MiB boundary), so a loader that places System PTE space inside the nominal WB range can expose this defect.
The maintained nxldr layout does not establish that overlap. Its NXBL_PAGES_SPANNED = 0x4400 is passed as LoaderPagesSpanned by NxldrBuildLoaderBlock. ARM3 therefore computes MmSystemPteSpaceStart = 0x84400000, above the kernel image window; the Xbox painter establishes the full 64 MiB WB alias. The painter's old comment naming 0x82c00000 is stale for this loader. Released patch 0030 also checks the 0x4400 span. Issue #90 concerns the shortcut's behavior under nonidentity or absent mappings; this source evidence does not establish an actual WB remapping in the current release or a cause of a Forza failure.
Draft PR #91 adds patch 0042 at exact product head d0d497ca8b92fcf5a55862710bddc2ac7f9061f1. The candidate removes the WB mask shortcut and delegates to the existing maintained MmGetPhysicalAddress() walker. In the enabled NXK_MM_VM build, that is ntoskrnl/xb/mm/fault.c: it reads live PDE/PTE values, preserves offsets for 4 MiB and 4 KiB mappings, and returns zero for absent mappings. Translation adds no ownership reference or pin; callers still need the DMA and operation-lifetime guarantees described below.
The separate 0xf0000000–0xffc00000 WC/device API return contract is unchanged. The adapter returns the high input address. Device MMIO is identity mapped, while the WC aperture's actual PTE/PDE mapping aliases low RAM; these are distinct from what the exported API returns. The repair does not change allocation policy or introduce a translation cache.
The public candidate fixture extracts the production adapter and enabled walker bodies, supplies independent page tables, and covers eleven cases: identity and nonidentity large pages, remapped small pages and offsets, changed and removed mappings, absent mappings and invalid PDEs, relocated kernel image, system aperture and unchanged WC API behavior. The initial ten-case baseline comparison failed six cases before repair and passed all ten after; the added invalid-PDE case also passes. This is host source-path validation, not native title qualification. PR #91 remains draft and native validation is pending. Patch 0042 is not included in the released 27149596 baseline documented above.
Contiguous allocation and relocation
An allocator's capacity counter must refer to the same domain as the candidate window. Generic free pages and low pin-only pages are not interchangeable. Subtracting all free pages in a window from a generic-only free counter can underflow or admit an impossible relocation.
The capacity repair and generic-floor repair are separate from making scans faster. Mathematical fixtures establish accounting cases; native fragmented-memory/DMA workloads establish the integration behavior.
PR #93 independently merged patch 0043. After releasing NxContigLock for empty-bucket reclaim, the contiguous allocator now selects a fresh tracking slot before taking a retry run. Another allocation can occupy the old slot while the lock is released; reusing it would overwrite that allocation's ownership record. Failed slot acquisition returns NULL before taking a run. The production-body fixture has seven passing cases, including competing allocation, table growth and failed growth. This bookkeeping fix changes neither the physical allocation window nor the translation API, and does not establish a native title failure cause.
Pinning and DMA
A pin count represents outstanding ownership. Saturation cannot safely discard prior locks. A buffer with several virtual aliases to one PFN must account for their multiplicity before mutating pin state. Patch 0006 replaces unsafe scratch accounting with a bounded PFN-vector path while preserving conservative overflow behavior.
For DMA, preventing relocation after an MDL captured physical frames is too late: relocation between capture and pin invalidates the device's view. The cache paging path marks pool pages nonmovable before building its MDL and restores movability after transfer completion. Patch 0015 documents related bounce-buffer lifetime repair.
Physical pinning does not prevent content changes. A future host-native worker cannot safely retain arbitrary guest pointers merely because the underlying PFNs are pinned. Stable input snapshots and output publication ordering are additional requirements.
Request and completion lifetime
An asynchronous operation's request buffers, IOSB, event/APC context and file/object references must survive until its actual completion or qualified cancellation. Submission success and STATUS_PENDING are different states. A synchronous wrapper may wait, but it still must preserve final status and transferred-byte count.
Patch 0014 and patch 0023 repair specific ordering paths. They do not qualify every cancel-routine race or device teardown. Consult the individual Nt*, Io* and APC entries for supported semantics.
Reset and save-state boundaries
Fresh boot initializes a new kernel/session. Warm reset may preserve selected RAM/persistence state. Emulator snapshot restore can reintroduce a precise older device/memory state, including outstanding work. Ordinary game loading reads persistent title data and is another operation entirely.
A valid persistence checksum is an integrity check, not authentication or proof that every replayed cold-reset state is appropriate. Preserved memory may reconstruct maximal runs rather than the original allocation boundaries. These limits are recorded in the public clean-room review.
Always identify which boundary a failure crossed. A stale displayed framebuffer does not by itself prove missing guest memory clearing; a reset lockup does not prove an ordinary load would fail. Device/controller connection changes are emulator lifecycle events and require their own diagnosis.
Performance boundaries
The guest has one CPU execution stream. Adding guest threads does not automatically execute them on multiple host cores. Host-native bulk work, KVM, renderer ownership cooperation and asynchronous preparation are proposed architectural directions, not capabilities implied by these kernel exports.
An optimization should report removed mappings, scans, copies, invalidations or waits, then establish useful progress in matched uninstrumented runs. CPU savings, FPS gains, tail-latency improvement and compatibility fixes are distinct results. See Clean-Room-and-Validation.