AxlMemPhys — physical-memory access
Held _map/_unmap mappings plus one-shot
_read{8,16,32,64} / _write{8,16,32,64} helpers and a
byte-pattern _search. UEFI is identity-mapped so map is
effectively a no-op; the abstraction is preserved for portability
to backends where physical access requires explicit mapping
(Linux mmap("/dev/mem"), AXL kernel POC explicit page-table
mapping).
API Reference
Physical-memory access — map / unmap and one-shot read / write.
UEFI runs with the physical memory map identity-mapped, so the map step is effectively a no-op there: the returned VA equals the physical address. The map / unmap shape exists for portability — a future Linux backend would mmap("/dev/mem") on the way in and munmap on the way out, and consumer code that holds a mapping over multiple accesses keeps working.
For the common case where a tool reads (or writes) a single address one time, the one-shot helpers do the map / access / unmap trio in one call. They keep the typical *(volatile uint32_t *)0xFEE00000 style readable without forcing every call site to manage a mapping.
// Held mapping over multiple accesses.
void *va;
if (axl_mem_phys_map(0xFED00000, 4096, &va) == 0) {
for (size_t i = 0; i < 4096; i += 4) {
uint32_t w = *(volatile uint32_t *)((uint8_t *)va + i);
// ...
}
axl_mem_phys_unmap(va, 4096);
}
// One-shot.
uint32_t signature;
axl_mem_phys_read32(0xE0000, &signature);
Functions
-
int axl_mem_phys_map(uintptr_t phys, size_t len, void **out_va)
Map
lenbytes of physical memory starting atphys.Returns a virtual address through
out_va. On UEFI this is the same asphys(identity-mapped); on a future Linux backend it is ammapreturn value. Either way the caller dereferences the VA directly withvolatile uint{N}_t *casts to read or write, and pairs every successful map with anaxl_mem_phys_unmapusing the samelen.- Parameters:
phys – physical address (alignment is consumer’s responsibility)
len – number of bytes to map
out_va – [out] receives the mapped VA
- Returns:
0 on success, -1 if the mapping cannot be established.
-
void axl_mem_phys_unmap(void *va, size_t len)
Release a mapping established by axl_mem_phys_map.
On UEFI this is a no-op; on a future Linux backend it is
munmap. NULLvais tolerated (no-op).- Parameters:
va – VA returned by axl_mem_phys_map
len – same length passed to map
-
int axl_mem_phys_read8(uintptr_t phys, uint8_t *out)
Read a byte from physical memory.
Maps the smallest aligned region covering
phys, dereferences, and unmaps. On UEFI all three steps are direct; on backends that actually need to map, this is one mmap + read + munmap per call, so the held-mapping API above is the better choice for hot loops.- Returns:
0 on success, -1 if the mapping cannot be established.
-
int axl_mem_phys_read16(uintptr_t phys, uint16_t *out)
16-bit variant.
physmust be 16-bit aligned on AArch64 (a misaligned access raises a synchronous Data Abort and terminates the image); x86 tolerates misaligned reads at a performance penalty.
-
int axl_mem_phys_read32(uintptr_t phys, uint32_t *out)
32-bit variant. Same alignment caveat as axl_mem_phys_read16 — required on AArch64, advisory on x86.
-
int axl_mem_phys_read64(uintptr_t phys, uint64_t *out)
64-bit variant. Same alignment caveat as axl_mem_phys_read16 — required on AArch64, advisory on x86.
-
int axl_mem_phys_write8(uintptr_t phys, uint8_t value)
One-shot byte write.
-
int axl_mem_phys_write16(uintptr_t phys, uint16_t value)
One-shot 16-bit write.
-
int axl_mem_phys_write32(uintptr_t phys, uint32_t value)
One-shot 32-bit write.
-
int axl_mem_phys_write64(uintptr_t phys, uint64_t value)
One-shot 64-bit write.
-
int axl_mem_phys_search(const void *va, size_t len, const void *needle, size_t needle_len, const void **out_match)
Find the first occurrence of
needlein a mapped region.Operates on a VA (typically returned by axl_mem_phys_map). Useful for scanning ROMs, firmware tables, or signature blocks. Linear byte-by-byte scan; use sparingly on multi-megabyte regions.
- Parameters:
va – mapped region base
len – region length in bytes
needle – pattern to find
needle_len – pattern length in bytes
out_match – [out] pointer inside
va
- Returns:
0 on hit (and
*out_matchis set to a pointer insideva), -1 ifneedleis not present.