Read and Check the I/O Port Map in /proc/ioports
A driver claiming ports another device already owns is the classic reason to open /proc/ioports in the first place. This guide gives you a repeatable way to inspect the kernel's current I/O port regions, identify the names attached to them, and save a timestamped snapshot for troubleshooting. It uses the proc_ioports(5) entry from Linux man-pages 6.7, installed here as package version 6.7-2. The host currently runs Linux kernel 6.8.0-139-generic, so the exact entries and ranges on your machine may differ.
The route
Jump straight to the step you need, or tick off Done means at the end.
Allow about ten minutes. You need a shell and a mounted /proc filesystem. The commands below only read data. No elevated privilege is normally required, and nothing here changes a device, reserves a port, unloads a driver or edits kernel configuration.
1. Read the live map
Start by displaying the file exactly as the kernel exposes it:
$ cat /proc/ioports
0000-0000 : PCI Bus 0000:00
0000-0000 : dma1
0000-0000 : pic1
...
The file lists currently registered Input-Output port regions that are in use. Each line gives a range followed by a label, and indentation shows a relationship in the displayed listing, so keep it intact when copying output into a report. The labels are useful clues, but they are not a stable inventory you can safely compare byte-for-byte across boots or between different hardware.
Checkpoint
Confirm the file can be opened and that it contains text. An empty result is still worth recording, not a reason to invent a device entry.
if test -r /proc/ioports; then
wc -l /proc/ioports
else
printf '%s\n' 'Cannot read /proc/ioports' >&2
exit 1
fi
2. Read the ranges without losing the labels
For a quick view of the top-level lines, drop only lines that begin with whitespace. That keeps the range and name together, without claiming every formatted line represents an independent allocation:
sed -n '/^[^[:space:]]/p' /proc/ioports
For a narrow search, match the label you are actually investigating, quoting the pattern if it contains shell characters or spaces:
$ grep -i 'ahci' /proc/ioports
0000-0000 : ahci
0000-0000 : ahci
0000-0000 : ahci
Your output might show a different driver name, several matches, or none at all. A missing label is not proof the hardware is absent; it only says the current text does not contain that label.
Do not parse the range with a blind field split and then throw away the rest of the line. Names can contain spaces, and indentation carries information for a human reader. If a script needs to report entries, preserve each complete line unless you have already tested the parser against every output format you support.
3. Capture a diagnostic snapshot
When investigating a driver or hardware problem, capture the map alongside the kernel identity and UTC time. Swap in a directory you control for /tmp/ioports-check if the snapshot needs to survive a reboot or get attached to a ticket:
snapshot_dir=/tmp/ioports-check
mkdir -p "$snapshot_dir"
{
date -u
uname -a
printf '%s\n' '--- /proc/ioports ---'
cat /proc/ioports
} > "$snapshot_dir/ioports.txt"
sed -n '1,12p' "$snapshot_dir/ioports.txt"
This creates or replaces a file named ioports.txt inside that explicitly named temporary directory. The redirection is the only state-changing part of the example, and it never touches /proc/ioports itself. Before reusing the command, double-check the value of snapshot_dir: a mistyped redirection target can overwrite an ordinary file.
Recovery is simple. If this example created data you no longer need, remove only the file you created:
$ rm -- /tmp/ioports-check/ioports.txt
That deletion is irreversible unless another copy exists somewhere. Do not use a broad recursive removal command for a diagnostic snapshot.
4. Check common failure modes
If cat reports that /proc/ioports does not exist, first check whether /proc is mounted and whether the path is even present:
$ test -d /proc && printf '%s\n' '/proc exists'
$ test -e /proc/ioports && printf '%s\n' '/proc/ioports exists'
A container or restricted environment may expose a reduced view of host hardware. That is an environment boundary, not evidence the host has no I/O port registrations. Ask the host administrator for a host-side snapshot when the question actually concerns physical hardware.
If access is denied, do not immediately reach for a privileged operation. Confirm the path and environment first. If your local policy allows it, an administrator can run the same read-only command with sudo:
$ sudo cat /proc/ioports
Elevated access does not make the listing any more current and does not reserve a port. Avoid writing to any path below /proc for this task: the manpage describes this file as a list to read, not a configuration interface.
5. Use the result correctly
Treat the listing as a point-in-time diagnostic view. Read it again after a device, driver or virtual machine configuration changes:
$ diff -u /tmp/ioports-before.txt /proc/ioports
This comparison only works when /tmp/ioports-before.txt is a snapshot you made earlier, for example with cat /proc/ioports > /tmp/ioports-before.txt. Differences can reflect legitimate changes in registered resources or in presentation, so investigate them against the relevant kernel log, driver documentation and device-specific tools. Do not infer a conflict from matching text alone.
For a report, include the unmodified file, the capture time, the kernel release, and whether the command ran inside a container. That context stops a reader from mistaking a filtered or later view for the state you actually observed.
Done means
- Read
/proc/ioportswithout changing system state. - Preserved ranges, labels and indentation in your copy.
- Treated searches as clues, not complete hardware detection.
- Captured a diagnostic snapshot recording time, kernel identity and the live listing.
- Knew when a container boundary or access restriction requires a host-side check instead.