From ProventusNova DeveloperWiki
No edit summary |
No edit summary |
||
| Line 23: | Line 23: | ||
| <code>---</code> || <span style="color:darkcyan">Cyan</span> || '''Free System RAM''': Available memory within that physical address range. |
| <code>---</code> || <span style="color:darkcyan">Cyan</span> || '''Free System RAM''': Available memory within that physical address range. |
||
|- |
|- |
||
| <code> |
| <code>|</code> || <span style="color:red">Red</span> || '''Occupancy Marker''': The specific boundary of current memory pressure. |
||
|- |
|- |
||
| <code>...</code> || <span style="color:red">Red</span> || '''Reserved/IO''': Non-system RAM (MMIO, GPU, Reserved by Firmware). |
| <code>...</code> || <span style="color:red">Red</span> || '''Reserved/IO''': Non-system RAM (MMIO, GPU, Reserved by Firmware). |
||
Revision as of 16:21, 20 February 2026
Overview
mempix is a lightweight bash utility designed to visualize physical memory allocation and real-time occupancy. It maps the data from /proc/iomem and correlates it with global memory statistics from /proc/meminfo to provide a per-block visual "pixel map."
It is specifically optimized for both embedded Yocto environments (like the MediaTek Genio 720) and standard Desktop Linux (Ubuntu/Debian).
Features
- Visual Occupancy: A 12-character progress bar showing used vs. free space within each RAM block.
- Threshold Marker: A red marker (|) indicating the exact transition point between used and free memory.
- Unit Intelligence: Automatically scales between KB, MB, and GB based on block size.
- Hardware Mapping: Identifies non-RAM regions (PCIe, GPU, Reserved) that are "locked" by hardware.
- Universal Compatibility: Uses POSIX-compliant math and standard escape codes for serial consoles.
Map Legend
| Symbol | Color | Meaning |
|---|---|---|
### |
Green | Used System RAM: Memory currently occupied by the kernel or processes. |
--- |
Cyan | Free System RAM: Available memory within that physical address range. |
| |
Red | Occupancy Marker: The specific boundary of current memory pressure. |
... |
Red | Reserved/IO: Non-system RAM (MMIO, GPU, Reserved by Firmware). |
Usage
Standard Run
On Yocto (root), run directly. On Ubuntu, use sudo:
sudo ./mempix.sh
Real-time Monitoring
To watch memory blocks change live as processes open/close:
watch -c sudo ./mempix.sh
Source Code
Save the following code as mempix.sh:
#!/bin/bash
IOMEM="/proc/iomem"
MEMINFO="/proc/meminfo"
# --- PERMISSION CHECK ---
# Try to actually read one line. If empty, the kernel is masking the data.
CHECK_READ=$(head -n 1 "$IOMEM" 2>/dev/null)
if [ -z "$CHECK_READ" ]; then
echo -e "\033[31mError: Cannot read physical addresses from $IOMEM.\033[0m"
echo "If on Ubuntu, you must run this script with sudo."
exit 1
fi
# 1. Get Global Stats
T_MEM_KB=$(grep MemTotal "$MEMINFO" | awk '{print $2}')
F_MEM_KB=$(grep MemFree "$MEMINFO" | awk '{print $2}')
OCC_RATIO=$(awk "BEGIN {print 1 - ($F_MEM_KB/$T_MEM_KB)}")
FREE_RATIO=$(awk "BEGIN {print $F_MEM_KB/$T_MEM_KB}")
format_matched() {
local val_mb="$1"
local target_unit="$2"
local is_small=$(awk "BEGIN {if ($val_mb < 0.1) print 1; else print 0}")
if [ "$is_small" -eq 1 ]; then
awk "BEGIN {printf \"%.1f KB\", $val_mb * 1024}"
elif [ "$target_unit" == "GB" ]; then
awk "BEGIN {printf \"%.2f GB\", $val_mb / 1024}"
else
awk "BEGIN {printf \"%.1f MB\", $val_mb}"
fi
}
# --- LEGEND ---
echo -e "\033[1mMAP LEGEND:\033[0m"
echo -e "\033[32m###\033[0m : Used System RAM \033[1;31m|\033[0m : Occupancy Marker"
echo -e "\033[36m---\033[0m : Free System RAM \033[31m...\033[0m : Reserved/Hardware/IO"
echo ""
echo -e "\033[1mPHYSICAL BLOCK ANALYSIS\033[0m"
printf "%-12s | %-12s | %-18s | %-12s | %s\n" "ADDRESS" "PIXEL MAP" "FREE (MATCHED)" "TOTAL SIZE" "LABEL"
echo "---------------------------------------------------------------------------------------------------"
# Clean input and iterate
grep -E "System RAM|Kernel|reserved|pcie|gpu" "$IOMEM" | sed 's/^[ ]*//' | while read -r line; do
ADDR=$(echo "$line" | cut -d' ' -f1)
LABEL=$(echo "$line" | cut -d':' -f2- | xargs)
S_HEX=$(echo "$ADDR" | cut -d'-' -f1)
E_HEX=$(echo "$ADDR" | cut -d'-' -f2)
# Validate Hex
if [[ ! $S_HEX =~ ^[0-9a-fA-F]+$ ]]; then continue; fi
S_DEC=$(printf "%d" "0x$S_HEX" 2>/dev/null)
E_DEC=$(printf "%d" "0x$E_HEX" 2>/dev/null)
SIZE_MB=$(awk "BEGIN {print ($E_DEC - $S_DEC + 1) / 1048576}")
UNIT="MB"; [ $(awk "BEGIN {if ($SIZE_MB >= 1024) print 1; else print 0}") -eq 1 ] && UNIT="GB"
if [[ "$LABEL" == "System RAM" ]]; then
FREE_MB=$(awk "BEGIN {print $SIZE_MB * $FREE_RATIO}")
P_FREE=$(awk "BEGIN {printf \"%.1f%%\", $FREE_RATIO * 100}")
U_CH=$(awk "BEGIN {val = 12 * $OCC_RATIO; printf \"%.0f\", (val<1 && val>0)?1:val}")
[ "$U_CH" -gt 12 ] && U_CH=12
F_CH=$((12 - U_CH))
if [ "$U_CH" -gt 0 ]; then
BAR_USED=$(printf "%$((U_CH-1))s" | tr ' ' '#')
MARKER="\033[1;31m|\033[0m"
BAR_FREE=$(printf "%${F_CH}s" | tr ' ' '-')
PIX="\033[32m${BAR_USED}${MARKER}\033[36m${BAR_FREE}\033[0m"
else
PIX="\033[36m------------\033[0m"
fi
STR_FREE=$(format_matched "$FREE_MB" "$UNIT")
STR_TOTAL=$(format_matched "$SIZE_MB" "$UNIT")
else
PIX="\033[31m............\033[0m"
P_FREE="0.0%"
STR_FREE=$(format_matched 0 "$UNIT")
STR_TOTAL=$(format_matched "$SIZE_MB" "$UNIT")
fi
printf "0x%08s | %b | %-18s | %-12s | %s\n" "$S_HEX" "$PIX" "$P_FREE ($STR_FREE)" "$STR_TOTAL" "$LABEL"
done
Troubleshooting
Error: Cannot read physical addresses
If you see this error, it means the Kernel is masking /proc/iomem for security.
- Desktop: Ensure you are using
sudo. - Embedded: Ensure you are logged in as a user with root privileges.
