683 lines
28 KiB
HTML
683 lines
28 KiB
HTML
|
|
<!DOCTYPE html>
|
|||
|
|
<html lang="en">
|
|||
|
|
<head>
|
|||
|
|
<meta charset="UTF-8">
|
|||
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|||
|
|
<title>KingDezigns — NAS08 Kernel Recovery Summary</title>
|
|||
|
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|||
|
|
<link href="https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;500&family=IBM+Plex+Sans:wght@400;500&display=swap" rel="stylesheet">
|
|||
|
|
<style>
|
|||
|
|
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
|
|||
|
|
|
|||
|
|
:root {
|
|||
|
|
--bg: #f7f6f2;
|
|||
|
|
--surface: #ffffff;
|
|||
|
|
--surface-alt: #f1f0eb;
|
|||
|
|
--border: #e2e0d8;
|
|||
|
|
--border-strong: #c8c5ba;
|
|||
|
|
--text-primary: #1a1917;
|
|||
|
|
--text-secondary: #6b6960;
|
|||
|
|
--text-muted: #9b9890;
|
|||
|
|
--green-bg: #eaf3de;
|
|||
|
|
--green-border: #97c459;
|
|||
|
|
--green-text: #2d5a0e;
|
|||
|
|
--red-bg: #fcebeb;
|
|||
|
|
--red-border: #f09595;
|
|||
|
|
--red-text: #7a1f1f;
|
|||
|
|
--amber-bg: #faeeda;
|
|||
|
|
--amber-border: #fac775;
|
|||
|
|
--amber-text: #633806;
|
|||
|
|
--coral-bg: #faece7;
|
|||
|
|
--coral-border: #f0997b;
|
|||
|
|
--coral-text: #4a1b0c;
|
|||
|
|
--mono: 'IBM Plex Mono', monospace;
|
|||
|
|
--sans: 'IBM Plex Sans', sans-serif;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
body {
|
|||
|
|
font-family: var(--sans);
|
|||
|
|
font-size: 14px;
|
|||
|
|
background: var(--bg);
|
|||
|
|
color: var(--text-primary);
|
|||
|
|
line-height: 1.7;
|
|||
|
|
padding: 2.5rem 1.5rem;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.page { max-width: 860px; margin: 0 auto; }
|
|||
|
|
|
|||
|
|
header {
|
|||
|
|
border-bottom: 1px solid var(--border-strong);
|
|||
|
|
padding-bottom: 1.25rem;
|
|||
|
|
margin-bottom: 2rem;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
header h1 {
|
|||
|
|
font-family: var(--mono);
|
|||
|
|
font-size: 18px;
|
|||
|
|
font-weight: 500;
|
|||
|
|
letter-spacing: -0.02em;
|
|||
|
|
margin-bottom: 6px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.meta {
|
|||
|
|
font-size: 12px;
|
|||
|
|
color: var(--text-muted);
|
|||
|
|
font-family: var(--mono);
|
|||
|
|
display: flex;
|
|||
|
|
gap: 16px;
|
|||
|
|
flex-wrap: wrap;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.section { margin-bottom: 2.25rem; }
|
|||
|
|
|
|||
|
|
.section-title {
|
|||
|
|
font-family: var(--mono);
|
|||
|
|
font-size: 11px;
|
|||
|
|
font-weight: 500;
|
|||
|
|
text-transform: uppercase;
|
|||
|
|
letter-spacing: 0.08em;
|
|||
|
|
color: var(--text-muted);
|
|||
|
|
margin-bottom: 1rem;
|
|||
|
|
display: flex;
|
|||
|
|
align-items: center;
|
|||
|
|
gap: 10px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.section-title::before {
|
|||
|
|
content: attr(data-num);
|
|||
|
|
background: var(--text-primary);
|
|||
|
|
color: var(--bg);
|
|||
|
|
font-size: 10px;
|
|||
|
|
width: 18px;
|
|||
|
|
height: 18px;
|
|||
|
|
border-radius: 50%;
|
|||
|
|
display: inline-flex;
|
|||
|
|
align-items: center;
|
|||
|
|
justify-content: center;
|
|||
|
|
flex-shrink: 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.section-title::after {
|
|||
|
|
content: '';
|
|||
|
|
flex: 1;
|
|||
|
|
height: 1px;
|
|||
|
|
background: var(--border);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
p { margin-bottom: 0.75rem; color: var(--text-primary); }
|
|||
|
|
p:last-child { margin-bottom: 0; }
|
|||
|
|
|
|||
|
|
.badge-row { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 1rem; }
|
|||
|
|
|
|||
|
|
.badge {
|
|||
|
|
font-family: var(--mono);
|
|||
|
|
font-size: 11px;
|
|||
|
|
padding: 3px 10px;
|
|||
|
|
border-radius: 3px;
|
|||
|
|
border: 1px solid var(--border);
|
|||
|
|
background: var(--surface);
|
|||
|
|
color: var(--text-secondary);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.badge.red { background: var(--red-bg); color: var(--red-text); border-color: var(--red-border); }
|
|||
|
|
.badge.green { background: var(--green-bg); color: var(--green-text); border-color: var(--green-border); }
|
|||
|
|
.badge.amber { background: var(--amber-bg); color: var(--amber-text); border-color: var(--amber-border); }
|
|||
|
|
|
|||
|
|
.step {
|
|||
|
|
background: var(--surface);
|
|||
|
|
border: 1px solid var(--border);
|
|||
|
|
border-radius: 6px;
|
|||
|
|
padding: 1rem 1.25rem;
|
|||
|
|
margin-bottom: 0.6rem;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.step-header {
|
|||
|
|
font-family: var(--mono);
|
|||
|
|
font-size: 12px;
|
|||
|
|
font-weight: 500;
|
|||
|
|
color: var(--text-secondary);
|
|||
|
|
margin-bottom: 0.6rem;
|
|||
|
|
display: flex;
|
|||
|
|
align-items: center;
|
|||
|
|
gap: 8px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.step-num {
|
|||
|
|
background: var(--surface-alt);
|
|||
|
|
border: 1px solid var(--border);
|
|||
|
|
border-radius: 50%;
|
|||
|
|
width: 20px;
|
|||
|
|
height: 20px;
|
|||
|
|
display: inline-flex;
|
|||
|
|
align-items: center;
|
|||
|
|
justify-content: center;
|
|||
|
|
font-size: 10px;
|
|||
|
|
flex-shrink: 0;
|
|||
|
|
color: var(--text-muted);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
pre {
|
|||
|
|
background: var(--surface-alt);
|
|||
|
|
border: 1px solid var(--border);
|
|||
|
|
border-radius: 4px;
|
|||
|
|
padding: 10px 12px;
|
|||
|
|
font-family: var(--mono);
|
|||
|
|
font-size: 12px;
|
|||
|
|
overflow-x: auto;
|
|||
|
|
margin: 0.5rem 0;
|
|||
|
|
white-space: pre;
|
|||
|
|
line-height: 1.6;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
code {
|
|||
|
|
font-family: var(--mono);
|
|||
|
|
font-size: 12px;
|
|||
|
|
background: var(--surface-alt);
|
|||
|
|
padding: 1px 5px;
|
|||
|
|
border-radius: 3px;
|
|||
|
|
border: 1px solid var(--border);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.why {
|
|||
|
|
font-size: 12px;
|
|||
|
|
color: var(--text-muted);
|
|||
|
|
margin-top: 0.4rem;
|
|||
|
|
padding-left: 2px;
|
|||
|
|
}
|
|||
|
|
.why::before { content: '↳ why: '; font-family: var(--mono); }
|
|||
|
|
|
|||
|
|
.result { font-size: 12px; margin-top: 0.35rem; padding-left: 2px; }
|
|||
|
|
.result.pass { color: var(--green-text); }
|
|||
|
|
.result.pass::before { content: '✓ '; font-family: var(--mono); }
|
|||
|
|
.result.fail { color: var(--red-text); }
|
|||
|
|
.result.fail::before { content: '✗ '; font-family: var(--mono); }
|
|||
|
|
.result.neutral { color: var(--text-secondary); }
|
|||
|
|
.result.neutral::before { content: '→ '; font-family: var(--mono); }
|
|||
|
|
|
|||
|
|
.callout { border-radius: 6px; padding: 1rem 1.25rem; margin-bottom: 0.75rem; }
|
|||
|
|
.callout.coral { background: var(--coral-bg); border: 1px solid var(--coral-border); }
|
|||
|
|
.callout.coral p { color: var(--coral-text); }
|
|||
|
|
.callout.coral pre { background: #fdf0eb; border-color: var(--coral-border); }
|
|||
|
|
.callout.amber { background: var(--amber-bg); border: 1px solid var(--amber-border); }
|
|||
|
|
.callout.amber p { color: var(--amber-text); }
|
|||
|
|
.callout.amber pre { background: #fdf5e6; border-color: var(--amber-border); }
|
|||
|
|
.callout.amber code { background: #fdf5e6; border-color: var(--amber-border); color: var(--amber-text); }
|
|||
|
|
.callout.green { background: var(--green-bg); border: 1px solid var(--green-border); }
|
|||
|
|
.callout.green p { color: var(--green-text); }
|
|||
|
|
.callout.green pre { background: #d8efc0; border-color: var(--green-border); }
|
|||
|
|
|
|||
|
|
.clue-label {
|
|||
|
|
font-family: var(--mono);
|
|||
|
|
font-size: 10px;
|
|||
|
|
font-weight: 500;
|
|||
|
|
text-transform: uppercase;
|
|||
|
|
letter-spacing: 0.07em;
|
|||
|
|
color: var(--amber-text);
|
|||
|
|
margin-bottom: 8px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.script-box { background: var(--surface); border: 1px solid var(--border); border-radius: 6px; overflow: hidden; }
|
|||
|
|
.script-row { padding: 0.75rem 1.25rem; border-bottom: 1px solid var(--border); }
|
|||
|
|
.script-row:last-child { border-bottom: none; }
|
|||
|
|
.script-label { font-family: var(--mono); font-size: 10px; text-transform: uppercase; letter-spacing: 0.07em; color: var(--text-muted); margin-bottom: 6px; }
|
|||
|
|
.script-row pre { margin: 0; }
|
|||
|
|
|
|||
|
|
table { width: 100%; border-collapse: collapse; font-size: 13px; background: var(--surface); border: 1px solid var(--border); border-radius: 6px; overflow: hidden; }
|
|||
|
|
th { text-align: left; padding: 8px 14px; font-family: var(--mono); font-size: 10px; text-transform: uppercase; letter-spacing: 0.06em; color: var(--text-muted); background: var(--surface-alt); border-bottom: 1px solid var(--border); font-weight: 500; }
|
|||
|
|
td { padding: 9px 14px; border-bottom: 1px solid var(--border); vertical-align: top; line-height: 1.5; }
|
|||
|
|
tr:last-child td { border-bottom: none; }
|
|||
|
|
|
|||
|
|
.footer {
|
|||
|
|
font-family: var(--mono);
|
|||
|
|
font-size: 11px;
|
|||
|
|
color: var(--text-muted);
|
|||
|
|
margin-top: 2.5rem;
|
|||
|
|
padding-top: 1rem;
|
|||
|
|
border-top: 1px solid var(--border);
|
|||
|
|
display: flex;
|
|||
|
|
justify-content: space-between;
|
|||
|
|
flex-wrap: wrap;
|
|||
|
|
gap: 8px;
|
|||
|
|
}
|
|||
|
|
</style>
|
|||
|
|
</head>
|
|||
|
|
<body>
|
|||
|
|
<div class="page">
|
|||
|
|
|
|||
|
|
<header>
|
|||
|
|
<h1>KingDezigns — NAS08 Kernel Recovery Summary</h1>
|
|||
|
|
<div class="meta">
|
|||
|
|
<span>📅 May 15–16, 2026</span>
|
|||
|
|
<span>🖥 NAS08 — Raspberry Pi 5 Model B Rev 1.1</span>
|
|||
|
|
<span>⚙️ OpenMediaVault 8.2.13 / Debian Trixie</span>
|
|||
|
|
<span>🔌 Radxa Penta SATA HAT (JMB585)</span>
|
|||
|
|
<span>🐧 Kernel 6.12.75 → 6.18.29 → rolled back → 6.18.29 (fixed)</span>
|
|||
|
|
</div>
|
|||
|
|
</header>
|
|||
|
|
|
|||
|
|
|
|||
|
|
<!-- SECTION 1 — THE PROBLEM -->
|
|||
|
|
<div class="section">
|
|||
|
|
<div class="section-title" data-num="1">The problem</div>
|
|||
|
|
|
|||
|
|
<p>After a routine apt upgrade that included a kernel jump from 6.12 to 6.18 and a new <code>raspi-firmware</code> package, NAS08 lost all four SATA data drives connected via the Radxa Penta SATA HAT. ZFS reported no pools available and OMV could not see the drives.</p>
|
|||
|
|
|
|||
|
|
<div class="badge-row">
|
|||
|
|
<span class="badge red">zpool status: no pools available</span>
|
|||
|
|
<span class="badge red">ahci: failed to start port 0 (errno=-12)</span>
|
|||
|
|
<span class="badge red">lsblk: sdb/sdc/sdd/sde missing</span>
|
|||
|
|
<span class="badge red">BAR 0 [io size 0x0080]: can't assign; no space</span>
|
|||
|
|
<span class="badge amber">DMA32: empty</span>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<p>The upgrade included <code>linux-image-6.18.29+rpt-rpi-2712</code>, <code>raspi-firmware 1:1.20260513-1</code>, and <code>openmediavault 8.2.13-1</code> among 20+ packages. The Radxa Penta SATA HAT uses a JMicron JMB585 PCIe SATA controller. An upstream kernel commit (ee95f3c) affecting the JMB585 chipset means kernel 6.18 now requires the <code>pcie-32bit-dma-pi5</code> device tree overlay for the controller to allocate DMA memory successfully. This overlay was present in <code>config.txt</code> but placed under the <code>[cm5]</code> conditional section, which is ignored on a Raspberry Pi 5 Model B. As a result, the overlay never loaded and the JMB585 had no DMA32 address space.</p>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
|
|||
|
|
<!-- SECTION 2 — DIAGNOSTIC COMMANDS -->
|
|||
|
|
<div class="section">
|
|||
|
|
<div class="section-title" data-num="2">Diagnostic commands run & why</div>
|
|||
|
|
|
|||
|
|
<div class="step">
|
|||
|
|
<div class="step-header"><span class="step-num">1</span> Confirm ZFS module is loaded</div>
|
|||
|
|
<pre>lsmod | grep zfs</pre>
|
|||
|
|
<p class="why">Rule out ZFS module as the cause — if it's not loaded, drives won't be visible to any pool.</p>
|
|||
|
|
<p class="result pass">ZFS module loaded correctly — zfs and spl both present. Not the cause.</p>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div class="step">
|
|||
|
|
<div class="step-header"><span class="step-num">2</span> Check running kernel vs installed kernels</div>
|
|||
|
|
<pre>uname -r
|
|||
|
|
dpkg -l | grep linux-image</pre>
|
|||
|
|
<p class="why">Confirm which kernel booted and whether a version mismatch caused the issue.</p>
|
|||
|
|
<p class="result neutral">Booted into 6.18.29 — confirmed the kernel jump from 6.12 happened. Both versions still installed.</p>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div class="step">
|
|||
|
|
<div class="step-header"><span class="step-num">3</span> Check if OS sees the drives at all</div>
|
|||
|
|
<pre>lsblk
|
|||
|
|
ls /dev/disk/by-id/</pre>
|
|||
|
|
<p class="why">Determine if the problem is at the ZFS layer or the OS/hardware layer.</p>
|
|||
|
|
<p class="result fail">Only boot SSD visible. Data drives completely absent — hardware/driver level problem confirmed.</p>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div class="step">
|
|||
|
|
<div class="step-header"><span class="step-num">4</span> Check dmesg for USB/SATA/PCIe errors</div>
|
|||
|
|
<pre>dmesg | grep -iE "usb|sd|storage|attach|disconnect|reset" | grep -v "loop\|zram\|firmware" | tail -60</pre>
|
|||
|
|
<p class="why">Identify whether drives were seen at boot and then lost, or never detected at all.</p>
|
|||
|
|
<p class="result fail">Only one USB device detected at boot (boot SSD). No SATA drives enumerated. Pointed to PCIe HAT issue.</p>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div class="step">
|
|||
|
|
<div class="step-header"><span class="step-num">5</span> Check PCIe controller visibility</div>
|
|||
|
|
<pre>lspci</pre>
|
|||
|
|
<p class="why">Confirm whether the JMicron JMB585 SATA controller on the Radxa HAT is being detected by the PCIe bus.</p>
|
|||
|
|
<p class="result neutral">JMicron JMB585 visible at 0001:01:00.0 — controller detected but not functional.</p>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div class="step">
|
|||
|
|
<div class="step-header"><span class="step-num">6</span> Check PCIe BAR assignment errors</div>
|
|||
|
|
<pre>dmesg | grep -iE "pcie|pci|ahci|sata|asm|jmb|asmedia" | head -40</pre>
|
|||
|
|
<p class="why">Identify why the detected controller isn't working — look for resource allocation failures.</p>
|
|||
|
|
<p class="result fail">BAR 0–4 all failed to assign I/O space. PCI bridge showed zero-length address range. AHCI errno=-12 (ENOMEM).</p>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div class="step">
|
|||
|
|
<div class="step-header"><span class="step-num">7</span> Check DMA memory layout</div>
|
|||
|
|
<pre>cat /proc/meminfo | grep -i cma
|
|||
|
|
dmesg | grep -iE "cma|dma|coherent" | head -20</pre>
|
|||
|
|
<p class="why">Determine why AHCI port start was failing with ENOMEM — check DMA zone availability.</p>
|
|||
|
|
<p class="result fail">DMA32 zone empty. CmaFree: 0 kB. JMB585 forced into 32-bit DMA mode with no available DMA32 address space.</p>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div class="step">
|
|||
|
|
<div class="step-header"><span class="step-num">8</span> Check hardware identity</div>
|
|||
|
|
<pre>cat /proc/device-tree/model</pre>
|
|||
|
|
<p class="why">Confirm exact hardware model — critical for applying the correct config.txt overlay section.</p>
|
|||
|
|
<p class="result neutral">Raspberry Pi 5 Model B Rev 1.1 — confirmed Pi 5, not CM5. This meant the [cm5] section in config.txt was being ignored.</p>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div class="step">
|
|||
|
|
<div class="step-header"><span class="step-num">9</span> Check config.txt overlay placement</div>
|
|||
|
|
<pre>cat /boot/firmware/config.txt</pre>
|
|||
|
|
<p class="why">Identify whether the pcie-32bit-dma-pi5 overlay was present and in the correct conditional section.</p>
|
|||
|
|
<p class="result fail">Overlay was present but under [cm5] section — ignored on Pi 5. Moving it to [all] section was the fix.</p>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div class="step">
|
|||
|
|
<div class="step-header"><span class="step-num">10</span> Check EEPROM version and config</div>
|
|||
|
|
<pre>sudo rpi-eeprom-update
|
|||
|
|
sudo rpi-eeprom-config</pre>
|
|||
|
|
<p class="why">Determine if pci=pcie_bus_safe was coming from the EEPROM bootloader config.</p>
|
|||
|
|
<p class="result neutral">EEPROM was 5 months out of date. Updated during recovery session.</p>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
|
|||
|
|
<!-- SECTION 3 — ROOT CAUSE -->
|
|||
|
|
<div class="section">
|
|||
|
|
<div class="section-title" data-num="3">Root cause</div>
|
|||
|
|
|
|||
|
|
<div class="callout coral">
|
|||
|
|
<p>An upstream Linux kernel commit (ee95f3c) changed how the JMB585 PCIe SATA controller allocates DMA memory on kernel 6.18. The JMB585 now requires the <code>pcie-32bit-dma-pi5</code> device tree overlay to function correctly. This overlay was present in <code>/boot/firmware/config.txt</code> but placed under the <code>[cm5]</code> conditional section, which is silently ignored on a Raspberry Pi 5 Model B. As a result the overlay never loaded, the JMB585 had no DMA32 address space, and AHCI failed with ENOMEM on every port start attempt.</p>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div class="callout amber">
|
|||
|
|
<div class="clue-label">⚠ Key clue</div>
|
|||
|
|
<p style="margin-bottom:6px;">The config.txt overlay section mismatch was the root cause. The overlay fix was correct — it was simply applied to the wrong conditional block during the initial recovery attempt.</p>
|
|||
|
|
<pre># Wrong — ignored on Pi 5 Model B:
|
|||
|
|
[cm5]
|
|||
|
|
dtoverlay=pcie-32bit-dma-pi5
|
|||
|
|
|
|||
|
|
# Correct — applies to all Pi hardware:
|
|||
|
|
[all]
|
|||
|
|
dtoverlay=pcie-32bit-dma-pi5</pre>
|
|||
|
|
<p style="margin-top:8px;">The kernel 6.18 requirement for <code>pcie-32bit-dma-pi5</code> on JMB585 hardware is documented upstream. Any Pi 5 running kernel 6.18 with this HAT requires this overlay in the <code>[all]</code> or <code>[pi5]</code> section of config.txt.</p>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div class="callout green" style="margin-top:0.75rem;">
|
|||
|
|
<p><strong>Resolution:</strong> Moved <code>dtoverlay=pcie-32bit-dma-pi5</code> from the <code>[cm5]</code> section to the <code>[all]</code> section in <code>/boot/firmware/config.txt</code>, then copied the 6.18.29 kernel binary back to <code>/boot/firmware/kernel_2712.img</code> and rebooted. All four SATA drives appeared immediately on kernel 6.18.</p>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
|
|||
|
|
<!-- SECTION 4 — RECOVERY PROCEDURE -->
|
|||
|
|
<div class="section">
|
|||
|
|
<div class="section-title" data-num="4">Recovery procedure applied</div>
|
|||
|
|
|
|||
|
|
<div class="step">
|
|||
|
|
<div class="step-header"><span class="step-num">1</span> Roll back to kernel 6.12 (initial emergency recovery)</div>
|
|||
|
|
<pre>sudo apt-mark hold raspi-firmware linux-image-rpi-2712 linux-image-rpi-v8 linux-image-6.18.29+rpt-rpi-2712 linux-image-6.18.29+rpt-rpi-v8
|
|||
|
|
sudo cp /boot/vmlinuz-6.12.75+rpt-rpi-2712 /boot/firmware/kernel_2712.img
|
|||
|
|
sudo cp /boot/vmlinuz-6.12.75+rpt-rpi-v8 /boot/firmware/kernel8.img
|
|||
|
|
sudo reboot</pre>
|
|||
|
|
<p class="why">Immediately restored drive visibility on 6.12 while the root cause was investigated. Holds prevented the firmware hook from re-upgrading kernel_2712.img on reboot.</p>
|
|||
|
|
<p class="result pass">All four drives (sdb/sdc/sdd/sde) returned on 6.12.</p>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div class="step">
|
|||
|
|
<div class="step-header"><span class="step-num">2</span> Fix the overlay placement in config.txt</div>
|
|||
|
|
<pre>sudo nano /boot/firmware/config.txt
|
|||
|
|
|
|||
|
|
# Remove dtoverlay=pcie-32bit-dma-pi5 from the [cm5] section
|
|||
|
|
# Add it to the [all] section instead:
|
|||
|
|
|
|||
|
|
[cm5]
|
|||
|
|
dtoverlay=dwc2,dr_mode=host
|
|||
|
|
|
|||
|
|
[all]
|
|||
|
|
dtoverlay=pcie-32bit-dma-pi5</pre>
|
|||
|
|
<p class="why">The overlay was present but in the wrong conditional section. Moving it to [all] ensures it applies to the Pi 5 Model B hardware.</p>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div class="step">
|
|||
|
|
<div class="step-header"><span class="step-num">3</span> Unhold packages and copy 6.18 kernel back</div>
|
|||
|
|
<pre>sudo apt-mark unhold raspi-firmware linux-image-rpi-2712 linux-image-rpi-v8 linux-image-6.18.29+rpt-rpi-2712 linux-image-6.18.29+rpt-rpi-v8
|
|||
|
|
sudo cp /boot/vmlinuz-6.18.29+rpt-rpi-2712 /boot/firmware/kernel_2712.img
|
|||
|
|
sudo cp /boot/vmlinuz-6.18.29+rpt-rpi-v8 /boot/firmware/kernel8.img
|
|||
|
|
sudo reboot</pre>
|
|||
|
|
<p class="why">6.18 was already installed — only the kernel_2712.img binary needed updating. The overlay fix was now in place before boot.</p>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div class="step">
|
|||
|
|
<div class="step-header"><span class="step-num">4</span> Verify and re-apply holds</div>
|
|||
|
|
<pre>uname -r # should show 6.18.29+rpt-rpi-2712
|
|||
|
|
lsblk # should show sdb sdc sdd sde
|
|||
|
|
sudo zpool status
|
|||
|
|
|
|||
|
|
sudo apt-mark hold raspi-firmware linux-image-rpi-2712 linux-image-rpi-v8 linux-image-6.18.29+rpt-rpi-2712 linux-image-6.18.29+rpt-rpi-v8
|
|||
|
|
sudo apt-mark showhold</pre>
|
|||
|
|
<p class="result pass">All four drives present on 6.18.29. ZFS pool ONLINE. Holds re-applied to prevent uncontrolled kernel upgrades.</p>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
|
|||
|
|
<!-- SECTION 5 — EMERGENCY ROLLBACK -->
|
|||
|
|
<div class="section">
|
|||
|
|
<div class="section-title" data-num="5">Emergency rollback — if a future upgrade breaks drives again</div>
|
|||
|
|
|
|||
|
|
<p>If a future upgrade causes drives to disappear again, this is the fast rollback procedure. Takes less than 5 minutes.</p>
|
|||
|
|
|
|||
|
|
<div class="step">
|
|||
|
|
<div class="step-header"><span class="step-num">1</span> Hold packages immediately</div>
|
|||
|
|
<pre>sudo apt-mark hold raspi-firmware linux-image-rpi-2712 linux-image-rpi-v8 linux-image-6.18.29+rpt-rpi-2712 linux-image-6.18.29+rpt-rpi-v8</pre>
|
|||
|
|
<p class="why">The z50-raspi-firmware hook overwrites kernel_2712.img on every apt operation. Hold first to stop this.</p>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div class="step">
|
|||
|
|
<div class="step-header"><span class="step-num">2</span> Copy 6.12 kernel directly over the firmware kernel image</div>
|
|||
|
|
<pre>sudo cp /boot/vmlinuz-6.12.75+rpt-rpi-2712 /boot/firmware/kernel_2712.img
|
|||
|
|
sudo cp /boot/vmlinuz-6.12.75+rpt-rpi-v8 /boot/firmware/kernel8.img
|
|||
|
|
|
|||
|
|
# Verify sizes — should be 9698043 and 9695883
|
|||
|
|
ls -la /boot/firmware/kernel_2712.img /boot/firmware/kernel8.img</pre>
|
|||
|
|
<p class="why">raspi-firmware boots whichever kernel is in kernel_2712.img directly. Replacing it with 6.12 forces the rollback.</p>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div class="step">
|
|||
|
|
<div class="step-header"><span class="step-num">3</span> Reboot and confirm</div>
|
|||
|
|
<pre>sudo reboot
|
|||
|
|
|
|||
|
|
# After reboot:
|
|||
|
|
uname -r # should show 6.12.75+rpt-rpi-2712
|
|||
|
|
lsblk # should show sdb sdc sdd sde
|
|||
|
|
sudo zpool status</pre>
|
|||
|
|
<p class="result pass">Drives and ZFS pools return immediately on 6.12.</p>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
|
|||
|
|
<!-- SECTION 6 — SCRIPTS CREATED -->
|
|||
|
|
<div class="section">
|
|||
|
|
<div class="section-title" data-num="6">Scripts created this session</div>
|
|||
|
|
<div class="script-box">
|
|||
|
|
<div class="script-row">
|
|||
|
|
<div class="script-label">NAS08 ZFS Health Report</div>
|
|||
|
|
<pre>zfs_report_nas08.sh</pre>
|
|||
|
|
</div>
|
|||
|
|
<div class="script-row">
|
|||
|
|
<div class="script-label">NAS16 ZFS Health Report</div>
|
|||
|
|
<pre>zfs_report_nas16.sh</pre>
|
|||
|
|
</div>
|
|||
|
|
<div class="script-row">
|
|||
|
|
<div class="script-label">Commands executed per run</div>
|
|||
|
|
<pre>zpool status -v <pool>
|
|||
|
|
zpool list -H -o name,size,alloc,free,frag,cap,health <pool>
|
|||
|
|
zfs list -r -H -o name,used,avail,refer,mountpoint <pool></pre>
|
|||
|
|
</div>
|
|||
|
|
<div class="script-row">
|
|||
|
|
<div class="script-label">Deploy & schedule (cron)</div>
|
|||
|
|
<pre>chmod +x zfs_report_nas08.sh
|
|||
|
|
sudo mv zfs_report_nas08.sh /opt/scripts/
|
|||
|
|
# Add to crontab — runs daily at 7:00 AM:
|
|||
|
|
0 7 * * * /opt/scripts/zfs_report_nas08.sh >> /var/log/zfs_report.log 2>&1</pre>
|
|||
|
|
</div>
|
|||
|
|
<div class="script-row">
|
|||
|
|
<div class="script-label">Email recipient</div>
|
|||
|
|
<pre>rufus.king@kingdezigns.com</pre>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
|
|||
|
|
<!-- SECTION 7 — NAS16 PROTECTION -->
|
|||
|
|
<div class="section">
|
|||
|
|
<div class="section-title" data-num="7">NAS16 — apply same fix</div>
|
|||
|
|
|
|||
|
|
<p>NAS16 runs the identical Radxa Penta SATA HAT on a Raspberry Pi 5. It will hit the exact same kernel 6.18 / JMB585 DMA issue if updated without the overlay fix in place. SSH into NAS16 and follow these steps.</p>
|
|||
|
|
|
|||
|
|
<div class="step">
|
|||
|
|
<div class="step-header"><span class="step-num">1</span> Hold kernel and firmware packages on NAS16</div>
|
|||
|
|
<pre>sudo apt-mark hold raspi-firmware linux-image-rpi-2712 linux-image-rpi-v8
|
|||
|
|
sudo apt-mark showhold</pre>
|
|||
|
|
<p class="why">Prevents kernel 6.18 and new raspi-firmware from installing automatically while the config.txt fix is applied.</p>
|
|||
|
|
<p class="result pass">Expected: all packages listed as held.</p>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div class="step">
|
|||
|
|
<div class="step-header"><span class="step-num">2</span> Confirm hardware identity</div>
|
|||
|
|
<pre>cat /proc/device-tree/model</pre>
|
|||
|
|
<p class="why">Verify NAS16 is also a Pi 5 Model B so the [all] section placement is correct.</p>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div class="step">
|
|||
|
|
<div class="step-header"><span class="step-num">3</span> Fix the overlay placement in config.txt</div>
|
|||
|
|
<pre>sudo nano /boot/firmware/config.txt
|
|||
|
|
|
|||
|
|
# Ensure pcie-32bit-dma-pi5 is in the [all] section:
|
|||
|
|
[all]
|
|||
|
|
dtoverlay=pcie-32bit-dma-pi5</pre>
|
|||
|
|
<p class="why">Same fix as NAS08 — overlay must be in [all], not [cm5], to apply on Pi 5 hardware.</p>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div class="step">
|
|||
|
|
<div class="step-header"><span class="step-num">4</span> Unhold, upgrade, and reboot</div>
|
|||
|
|
<pre>sudo apt-mark unhold raspi-firmware linux-image-rpi-2712 linux-image-rpi-v8
|
|||
|
|
sudo apt upgrade
|
|||
|
|
sudo cp /boot/vmlinuz-6.18.29+rpt-rpi-2712 /boot/firmware/kernel_2712.img
|
|||
|
|
sudo cp /boot/vmlinuz-6.18.29+rpt-rpi-v8 /boot/firmware/kernel8.img
|
|||
|
|
sudo reboot</pre>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div class="step">
|
|||
|
|
<div class="step-header"><span class="step-num">5</span> Verify and re-hold</div>
|
|||
|
|
<pre>uname -r
|
|||
|
|
lsblk
|
|||
|
|
sudo zpool status
|
|||
|
|
sudo apt-mark hold raspi-firmware linux-image-rpi-2712 linux-image-rpi-v8 linux-image-6.18.29+rpt-rpi-2712 linux-image-6.18.29+rpt-rpi-v8</pre>
|
|||
|
|
<p class="result pass">Expected: sdb sdc sdd sde all present, uname shows 6.18.x, ZFS ONLINE.</p>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
|
|||
|
|
<!-- SECTION 8 — LESSONS LEARNED -->
|
|||
|
|
<div class="section">
|
|||
|
|
<div class="section-title" data-num="8">Lessons learned</div>
|
|||
|
|
<table>
|
|||
|
|
<thead>
|
|||
|
|
<tr><th>Lesson</th><th>Detail</th></tr>
|
|||
|
|
</thead>
|
|||
|
|
<tbody>
|
|||
|
|
<tr>
|
|||
|
|
<td>Always identify exact hardware before troubleshooting</td>
|
|||
|
|
<td>Run <code>cat /proc/device-tree/model</code> at the start of every session. The initial recovery misidentified NAS08 as a CM5, which placed the overlay fix under [cm5] where it was silently ignored on the Pi 5 Model B.</td>
|
|||
|
|
</tr>
|
|||
|
|
<tr>
|
|||
|
|
<td>Never update both NAS systems at the same time</td>
|
|||
|
|
<td>Update NAS08 first, confirm stable for 48hrs, then update NAS16. This approach would have prevented both systems from failing simultaneously.</td>
|
|||
|
|
</tr>
|
|||
|
|
<tr>
|
|||
|
|
<td>config.txt conditional sections are silently ignored</td>
|
|||
|
|
<td>Overlays placed under [cm4] or [cm5] are completely ignored on Pi 5 Model B hardware. There is no warning or error. Always verify placement with <code>cat /proc/device-tree/model</code> first.</td>
|
|||
|
|
</tr>
|
|||
|
|
<tr>
|
|||
|
|
<td>Kernel 6.18 requires pcie-32bit-dma-pi5 for JMB585</td>
|
|||
|
|
<td>Upstream commit ee95f3c changed DMA behaviour for the JMB585 chipset. Any Pi 5 running kernel 6.18 with the Radxa Penta SATA HAT must have <code>dtoverlay=pcie-32bit-dma-pi5</code> in the <code>[all]</code> section of config.txt or drives will not appear.</td>
|
|||
|
|
</tr>
|
|||
|
|
<tr>
|
|||
|
|
<td>Hold kernel packages on all Pi-based NAS systems</td>
|
|||
|
|
<td>Kernel updates can silently break HAT compatibility. Always hold and update deliberately, never via unattended-upgrades.</td>
|
|||
|
|
</tr>
|
|||
|
|
<tr>
|
|||
|
|
<td>raspi-firmware manages kernel_2712.img directly</td>
|
|||
|
|
<td>The post-install hook z50-raspi-firmware copies the kernel directly to /boot/firmware/kernel_2712.img. Copying an older kernel binary over this file is the correct rollback mechanism. Hold raspi-firmware before doing so or it will be overwritten on next boot.</td>
|
|||
|
|
</tr>
|
|||
|
|
<tr>
|
|||
|
|
<td>Always simulate before upgrading</td>
|
|||
|
|
<td>Run <code>sudo apt upgrade --simulate 2>&1 | grep -E "raspi-firmware|linux-image|linux-headers|Inst|Remv"</code> before every upgrade. If any kernel or firmware packages appear as Inst lines, investigate before proceeding.</td>
|
|||
|
|
</tr>
|
|||
|
|
</tbody>
|
|||
|
|
</table>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
|
|||
|
|
<!-- SECTION 9 — CONFIG FILE REFERENCE -->
|
|||
|
|
<div class="section">
|
|||
|
|
<div class="section-title" data-num="9">Current working config — NAS08</div>
|
|||
|
|
|
|||
|
|
<p>This is the known-good configuration for NAS08 on kernel 6.18.29 with all four SATA drives visible and ZFS healthy.</p>
|
|||
|
|
|
|||
|
|
<div class="script-box">
|
|||
|
|
<div class="script-row">
|
|||
|
|
<div class="script-label">/boot/firmware/config.txt — bottom section</div>
|
|||
|
|
<pre># Enable PCIe
|
|||
|
|
dtparam=pciex1
|
|||
|
|
dtparam=pciex1_gen=3
|
|||
|
|
|
|||
|
|
[cm4]
|
|||
|
|
otg_mode=1
|
|||
|
|
|
|||
|
|
[cm5]
|
|||
|
|
dtoverlay=dwc2,dr_mode=host
|
|||
|
|
|
|||
|
|
[all]
|
|||
|
|
dtoverlay=pcie-32bit-dma-pi5</pre>
|
|||
|
|
</div>
|
|||
|
|
<div class="script-row">
|
|||
|
|
<div class="script-label">/boot/firmware/cmdline.txt</div>
|
|||
|
|
<pre>console=serial0,115200 console=tty1 root=PARTUUID=57cb028e-02 rootfstype=ext4 fsck.repair=yes rootwait cfg80211.ieee80211_regdom=US</pre>
|
|||
|
|
</div>
|
|||
|
|
<div class="script-row">
|
|||
|
|
<div class="script-label">Active kernel</div>
|
|||
|
|
<pre>6.18.29+rpt-rpi-2712</pre>
|
|||
|
|
</div>
|
|||
|
|
<div class="script-row">
|
|||
|
|
<div class="script-label">Held packages</div>
|
|||
|
|
<pre>raspi-firmware
|
|||
|
|
linux-image-rpi-2712
|
|||
|
|
linux-image-rpi-v8
|
|||
|
|
linux-image-6.18.29+rpt-rpi-2712
|
|||
|
|
linux-image-6.18.29+rpt-rpi-v8</pre>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
|
|||
|
|
<!-- SECTION 10 — NETWORK MAP -->
|
|||
|
|
<div class="section">
|
|||
|
|
<div class="section-title" data-num="10">Network map — items to update</div>
|
|||
|
|
<table>
|
|||
|
|
<thead>
|
|||
|
|
<tr><th>Item</th><th>Old value</th><th>New value</th></tr>
|
|||
|
|
</thead>
|
|||
|
|
<tbody>
|
|||
|
|
<tr>
|
|||
|
|
<td>NAS08 kernel version</td>
|
|||
|
|
<td><code>6.12.75+rpt-rpi-2712</code></td>
|
|||
|
|
<td><code>6.18.29+rpt-rpi-2712 (held)</code></td>
|
|||
|
|
</tr>
|
|||
|
|
<tr>
|
|||
|
|
<td>NAS08 config.txt overlay</td>
|
|||
|
|
<td><code>pcie-32bit-dma-pi5 under [cm5] — ignored</code></td>
|
|||
|
|
<td><code>pcie-32bit-dma-pi5 under [all] — active</code></td>
|
|||
|
|
</tr>
|
|||
|
|
<tr>
|
|||
|
|
<td>NAS08 raspi-firmware</td>
|
|||
|
|
<td><code>auto-update enabled</code></td>
|
|||
|
|
<td><code>held at 1:1.20260513-1</code></td>
|
|||
|
|
</tr>
|
|||
|
|
<tr>
|
|||
|
|
<td>NAS16 kernel + overlay fix</td>
|
|||
|
|
<td><code>6.12.75 — pending upgrade</code></td>
|
|||
|
|
<td><code>apply config.txt fix first, then upgrade to 6.18.29</code></td>
|
|||
|
|
</tr>
|
|||
|
|
<tr>
|
|||
|
|
<td>ZFS report scripts</td>
|
|||
|
|
<td><code>not deployed</code></td>
|
|||
|
|
<td><code>zfs_report_nas08.sh + zfs_report_nas16.sh — deploy to /opt/scripts/</code></td>
|
|||
|
|
</tr>
|
|||
|
|
</tbody>
|
|||
|
|
</table>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
|
|||
|
|
<div class="footer">
|
|||
|
|
<span>KingDezigns Home Network</span>
|
|||
|
|
<span>Updated May 16, 2026</span>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
</div>
|
|||
|
|
</body>
|
|||
|
|
</html>
|