Linux UIO Mapping Offsets: Select the Region Before Adding the Device Byte Offset

A UIO mapping has two different offsets: one selects a memory region in the mmap() call, and another locates the device’s usable start inside the returned mapping. Confusing them can select the wrong region or address the padding before the device, even when the call itself succeeds.

This guide uses Linux v6.12’s standard UIO mapping convention. The example is a hypothetical passive status region on an embedded Linux device. It does not rebind a driver, open real hardware or prescribe register accesses. A UIO driver with a custom mapping callback requires its own checked contract.

Inventory the selected region

The UIO guide exposes each available mapping under a maps/mapN directory. Its attributes include a name, address, size and byte offset. Match the intended device and region using the product’s documented identity and mapping layout before doing pointer arithmetic.

Do not assume that the device is always uio0 or that a region number means the same function across driver revisions. An optional mapping name can assist selection, but an empty name is permitted. Preserve the driver identity and the observed region description with any mapping diagnosis.

The address attribute describes the exposed memory address. It is not a replacement for the region-selection offset passed to a normal UIO mmap() call. Copying it into that argument confuses an address description with the UIO selector.

Select the region with the runtime page size

For standard UIO mapping, the documented file offset is N * page_size, with region numbering beginning at zero. Obtain the actual base page size through the supported userspace interface, validate it, and check multiplication and type conversion before making the call.

Take an illustrative system with a 4096-byte base page and a selected region numbered two. Its selector is 2 * 4096 = 8192 bytes, or 0x2000. This value selects map2; it does not mean “start eight kilobytes into map zero.”

Now suppose the selected region’s sysfs offset is 0x120. After a successful mapping returns base address B, the usable device start is B + 0x120. That addition happens to the returned byte pointer. It is not added to the region selector supplied to mmap().

Three steps separate a UIO region selector of 8192 bytes from a device-start adjustment of 0x120 and a field displacement of 0x20.
Original hypothetical UIO offset worksheet. The mmap file offset selects map2; the device byte offset adjusts the returned pointer.

Original address worksheet. Page size, region number and byte offset are hypothetical inputs, not inspected target values.

Add a register-relative displacement last

Suppose a documented passive status field begins 0x20 bytes from that usable device start. Its illustrative location is B + 0x120 + 0x20 = B + 0x140. Keep all three quantities named in the application: region selector, device-start offset and field-relative displacement.

This does not authorize reading the field with an arbitrary C type. The device contract must separately specify access width, alignment, byte order and any read side effects. Correct address arithmetic alone is insufficient evidence for a valid MMIO operation.

Before forming or dereferencing the final pointer, verify that the complete requested range lies within both the permitted device region and the mapping established by the call. Check additions for overflow. Page-rounded virtual coverage does not grant permission to read neighboring padding or unrelated registers.

Keep mapping ownership separate from the interior pointer

Store the original mapping base and length for cleanup. A convenient pointer adjusted to the device start is a view into that mapping, not a new mapping identity. Retain both explicitly so later code does not try to release an interior pointer as though it were the original base.

Handle a failed mapping before any pointer addition. Also keep the descriptor and mapping lifetime rules under one owner, especially if acquisition can stop while another task still holds a region view. This worksheet is not a concurrency protocol for a hot-unplugged device.

The guide permits drivers to supply a custom mmap callback instead of the built-in implementation. Inspect the actual driver before extending the standard selector model to a vendor-specific interface. Do not assume that a familiar sysfs directory proves every mapping detail is identical.

Review wrong-offset cases without touching hardware

A proposed arithmetic fixture can compare four inputs: region zero with no adjustment, region two with 0x120 adjustment, the same region under another hypothetical page size, and an overflowing selector. Assert that only the selector changes with page size while the independent device-byte adjustment retains its meaning.

Include two deliberate mistakes: passing 0x120 as the UIO file offset, and adding the region selector to the returned pointer. The review should identify the wrong role of each value before any device operation occurs.

On an approved development target, reconcile that worksheet with the exact driver and published region bounds. Keep mapping success, correct field addressing and valid hardware access as separate evidence. The result should be an explicit address derivation, without claims about DMA coherency, interrupt handling or memory-ordering guarantees.

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *