driveAtlas: add ZimaBoard 832 layout for micro1 / monitor-02
Lint / Shell (shellcheck) (push) Successful in 13s
Lint / Shell (shellcheck) (push) Successful in 13s
Both micro hosts are ZimaBoard 832 (Celeron N3450, 8G LPDDR4, 32G eMMC). Add a dedicated "zimaboard" chassis type + generate_zimaboard_layout() and route micro1/monitor-02 to it, replacing the generic 2-bay "micro" render. Physical layout confirmed against the actual unit (not just vendor specs): FRONT face is two-tier - the 2x GbE sit directly ABOVE the 2x USB 3.0, with the Mini-DisplayPort left of that block and the DC 12V barrel right. The open-ended PCIe 2.0 x4 card edge exits the LEFT side. The REAR edge carries the 2x SATA data connectors with the single mini-4-pin SATA power header in the CENTRE between them, so two drives need a Y power cable. No drive bay (drives cable out and lie beside the board) and no M.2/mSATA. Map the two rear SATA ports via AHCI 00:12.0 (ata1/ata2) as sata-1/sata-2; the soldered eMMC has no by-path entry so it is probed directly at /dev/mmcblk0 and shown as the OS/boot slot. The render is a fanless finned-heatsink hero: an oblique brick whose lid is a corrugated block-element fin ramp lit from upper-left, with the front-left notch and the badge inset in the bevel, over three drive slots (solid+green when occupied, dashed ghost when empty). Drawn onto a fixed 66-column glyph/colour-key canvas and emitted with run-length colour, so every line is exactly the same display width in monochrome and colour; SAFE width-1 glyphs only (no ambiguous-width chars that smear under CJK locales). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+228
-13
@@ -904,20 +904,22 @@ declare -A SERVER_MAPPINGS=(
|
||||
pci-0000:26:00.0-nvme-1 m2-2
|
||||
"
|
||||
|
||||
# micro1
|
||||
# ZimaBoard 832 - Single board computer
|
||||
# 2 SATA ports on rear (currently unused)
|
||||
# Boot from onboard eMMC (mmcblk0)
|
||||
# SATA controller at 00:12.0
|
||||
# micro1 / monitor-02 - ZimaBoard 832 (Apollo Lake N3450), physical layout
|
||||
# confirmed on-unit 2026-07-20:
|
||||
# FRONT face : video-out (mDP) left, then 2x USB 3.0 (blue), then DC barrel;
|
||||
# the 2x GbE sit on an UPPER tier directly ABOVE the two USB ports.
|
||||
# LEFT side : open-ended PCIe 2.0 x4 slot (expansion path; no M.2/mSATA).
|
||||
# REAR edge : 2x SATA-III (ata1/ata2 via AHCI 00:12.0) with the single
|
||||
# mini-4-pin SATA power header in the CENTER between them
|
||||
# (2 drives need a Y power cable).
|
||||
# Onboard : 32G eMMC (mmcblk0) = OS/boot, soldered (no by-path).
|
||||
["micro1"]="
|
||||
pci-0000:00:12.0-ata-1 sata-1
|
||||
pci-0000:00:12.0-ata-2 sata-2
|
||||
"
|
||||
|
||||
# monitor-02
|
||||
# ZimaBoard 832 - Single board computer
|
||||
# 2 SATA ports on rear (currently unused)
|
||||
# Boot from onboard eMMC (mmcblk0)
|
||||
# SATA controller would be at a specific PCI address when drives connected
|
||||
["monitor-02"]="
|
||||
pci-0000:00:12.0-ata-1 sata-1
|
||||
pci-0000:00:12.0-ata-2 sata-2
|
||||
"
|
||||
|
||||
# pbs
|
||||
@@ -953,8 +955,8 @@ declare -A CHASSIS_TYPES=(
|
||||
["compute-storage-gpu-01"]="10bay"
|
||||
["storage-01"]="10bay"
|
||||
["large1"]="large1"
|
||||
["micro1"]="micro" # ZimaBoard 832
|
||||
["monitor-02"]="micro" # ZimaBoard 832
|
||||
["micro1"]="zimaboard" # ZimaBoard 832
|
||||
["monitor-02"]="zimaboard" # ZimaBoard 832
|
||||
["pbs"]="nuc" # Intel NUC5i5RYB (1 internal SATA + 2 rear USB-NVMe)
|
||||
)
|
||||
|
||||
@@ -1293,6 +1295,216 @@ if [[ "$RUN_DIAGNOSE" == true ]]; then
|
||||
run_diagnose
|
||||
fi
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# generate_zimaboard_layout
|
||||
#
|
||||
# ASCII art for a ZimaBoard 832 (micro1 / monitor-02): fanless x86 SBC (Celeron
|
||||
# N3450) whose entire lid is a finned aluminium heatsink. Physical layout
|
||||
# confirmed against the actual unit:
|
||||
# TOP : corrugated heatsink fins, rectangular notch at the FRONT-LEFT,
|
||||
# logo badge inset into the front bevel.
|
||||
# FRONT face : two tiers - 2x GbE sit directly ABOVE the 2x USB 3.0; the
|
||||
# Mini-DisplayPort is LEFT of that block, DC 12V barrel is RIGHT.
|
||||
# LEFT side : open-ended PCIe 2.0 x4 card edge protruding out the side.
|
||||
# REAR edge : 2x SATA data with the single SATA power header in the CENTRE
|
||||
# (SATA | PWR | SATA); no drive bay - drives cable out and lie
|
||||
# beside the board, and two drives need a Y power cable.
|
||||
# Onboard : 32G eMMC (mmcblk0) = OS/boot, soldered (never in DRIVE_MAP).
|
||||
# Bays: sata-1, sata-2 (+ a direct /dev/mmcblk0 probe for the eMMC).
|
||||
#
|
||||
# Renders onto a fixed 66-column glyph/colour-key canvas and emits with
|
||||
# run-length colour, so every line is exactly the same display width in both
|
||||
# monochrome and colour. Only SAFE width-1 glyphs (box-drawing + block elements).
|
||||
#
|
||||
# Args:
|
||||
# $1 - Hostname to display in the layout header
|
||||
#
|
||||
# Side effects: Calls build_drive_map() to populate DRIVE_MAP
|
||||
#------------------------------------------------------------------------------
|
||||
# shellcheck disable=SC2059
|
||||
generate_zimaboard_layout() {
|
||||
local host="${1:-$(hostname 2>/dev/null || echo host)}"
|
||||
|
||||
# Contract order: build the drive map first, then init colours.
|
||||
build_drive_map 2>/dev/null || true
|
||||
da_color_init
|
||||
|
||||
# --- storage discovery -------------------------------------------------
|
||||
# eMMC (OS/boot) is soldered and never in DRIVE_MAP -> probe it directly.
|
||||
local emmc_dev='' emmc_size='' emmc_on=0
|
||||
if [ -b /dev/mmcblk0 ]; then
|
||||
emmc_on=1; emmc_dev='mmcblk0'
|
||||
emmc_size="$(lsblk -dno SIZE /dev/mmcblk0 2>/dev/null | tr -d ' ')"
|
||||
[ -n "$emmc_size" ] || emmc_size='?'
|
||||
fi
|
||||
# Rear SATA ports come from DRIVE_MAP (guard set -u / never-built map).
|
||||
local sata1='EMPTY' sata2='EMPTY'
|
||||
if declare -p DRIVE_MAP >/dev/null 2>&1; then
|
||||
sata1="${DRIVE_MAP[sata-1]:-EMPTY}"
|
||||
sata2="${DRIVE_MAP[sata-2]:-EMPTY}"
|
||||
fi
|
||||
|
||||
# --- canvas + geometry -------------------------------------------------
|
||||
local WIDTH=66
|
||||
local S=5 Wi=44 FL=16 # oblique depth, front interior width, front-left col
|
||||
local BL=$((FL-S)) FR=$((FL+Wi+1))
|
||||
local BR=$((FR-S)) # NB: separate statement; FR is not visible in its own `local`
|
||||
local R0=2 HC=3 FE FB LEG HEIGHT
|
||||
FE=$((R0+S)); FB=$((FE+HC+1)); LEG=$((FB+3)); HEIGHT=$((LEG+6))
|
||||
|
||||
# dual grid: Gc = glyphs, Gk = per-cell colour key ('.' = default)
|
||||
local -a Gc Gk
|
||||
local r c t blank kblank
|
||||
printf -v blank '%*s' "$WIDTH" ''
|
||||
printf -v kblank '%*s' "$WIDTH" ''; kblank=${kblank// /.}
|
||||
for ((r=0;r<HEIGHT;r++)); do Gc[r]="$blank"; Gk[r]="$kblank"; done
|
||||
|
||||
# stamp glyph run at (row,col) carrying a single colour key
|
||||
_zp() {
|
||||
local rr=$1 cc=$2 s=$3 k=${4:-.} len=${#3} krun
|
||||
(( cc<0 )) && return
|
||||
Gc[rr]="${Gc[rr]:0:cc}${s}${Gc[rr]:cc+len}"
|
||||
printf -v krun '%*s' "$len" ''; krun=${krun// /$k}
|
||||
Gk[rr]="${Gk[rr]:0:cc}${krun}${Gk[rr]:cc+len}"
|
||||
}
|
||||
# reuse da_repeat when present, else fall back
|
||||
_zrep() {
|
||||
if declare -F da_repeat >/dev/null 2>&1; then da_repeat "$1" "$2"
|
||||
else local g=$1 n=$2 o=''; while ((n-->0)); do o+="$g"; done; printf '%s' "$o"; fi
|
||||
}
|
||||
# heatsink fin ramp: period-4 ridge, lit from upper-left
|
||||
_zfin() {
|
||||
case $(( (($1%4)+4)%4 )) in
|
||||
0) _zp "$2" "$3" '█' H ;;
|
||||
1) _zp "$2" "$3" '▓' H ;;
|
||||
2) _zp "$2" "$3" '▒' S ;;
|
||||
3) _zp "$2" "$3" '░' S ;;
|
||||
esac
|
||||
}
|
||||
|
||||
local dashW; dashW="$(_zrep '─' "$Wi")"
|
||||
|
||||
# --- header ------------------------------------------------------------
|
||||
_zp 0 0 'driveAtlas' H
|
||||
_zp 0 11 ":: ${host}" S
|
||||
_zp 0 $((WIDTH-13)) 'ZimaBoard 832' D
|
||||
|
||||
# --- left side face (shadow) + corrugated finned top -------------------
|
||||
for ((r=1;r<S;r++)); do
|
||||
local row=$((R0+r)) lc=$((BL+r)) rc=$((BR+r))
|
||||
for ((c=BL+1;c<lc;c++)); do _zp "$row" "$c" '▒' D; done
|
||||
for ((c=lc+1;c<rc;c++)); do _zfin $((c-row)) "$row" "$c"; done
|
||||
done
|
||||
_zp "$R0" "$BL" "┌${dashW}┐" H
|
||||
for ((r=1;r<S;r++)); do
|
||||
_zp $((R0+r)) $((BL+r)) '╲' H
|
||||
_zp $((R0+r)) $((BR+r)) '╲' H
|
||||
done
|
||||
|
||||
# --- front-top bevel carrying the logo badge ---------------------------
|
||||
_zp "$FE" "$BL" '│' D
|
||||
for ((c=BL+1;c<FL;c++)); do _zp "$FE" "$c" '▒' D; done
|
||||
local badge=' ZIMA BOARD 832 ' bl lead
|
||||
bl=${#badge}; lead=$(( (Wi-bl-2)/2 ))
|
||||
_zp "$FE" "$FL" "┌$(_zrep '─' "$lead")" H
|
||||
_zp "$FE" $((FL+1+lead)) '┤' G
|
||||
_zp "$FE" $((FL+2+lead)) "$badge" H
|
||||
_zp "$FE" $((FL+2+lead+bl)) '├' G
|
||||
_zp "$FE" $((FL+3+lead+bl)) "$(_zrep '─' $((Wi-lead-bl-2)))┐" H
|
||||
|
||||
# --- front face + left side fill, then close the side ------------------
|
||||
for ((r=FE+1;r<=FB;r++)); do
|
||||
for ((c=BL+1;c<FL;c++)); do _zp "$r" "$c" '▒' D; done
|
||||
_zp "$r" "$FL" '│' H
|
||||
_zp "$r" "$FR" '│' H
|
||||
done
|
||||
_zp "$FB" "$FL" "└${dashW}┘" H
|
||||
for ((r=R0+1;r<=FB-S;r++)); do _zp "$r" "$BL" '│' D; done
|
||||
for ((t=1;t<S;t++)); do
|
||||
for ((c=BL;c<BL+t;c++)); do _zp $((FB-S+t)) "$c" ' ' '.'; done
|
||||
_zp $((FB-S+t)) $((BL+t)) '╲' D
|
||||
done
|
||||
for ((c=BL;c<FL;c++)); do _zp "$FB" "$c" ' ' '.'; done
|
||||
|
||||
# --- rectangular notch cut into the FRONT-LEFT of the fin block --------
|
||||
_zp $((FE-2)) $((FL+2)) '┌─────┐' D
|
||||
_zp $((FE-1)) $((FL+2)) '└─────┘' D
|
||||
|
||||
# --- two-tier front I/O: mDP | [GbE over USB] | DC --------------------
|
||||
local cx=$((FL + Wi/2 - 1))
|
||||
_zp $((FE+1)) $((cx-2)) '▐▌' C ; _zp $((FE+1)) $((cx+1)) '▐▌' C # upper: 2x 1GbE
|
||||
_zp $((FE+2)) $((cx-2)) '▐▌' B ; _zp $((FE+2)) $((cx+1)) '▐▌' B # lower: 2x USB 3.0
|
||||
_zp $((FE+2)) $((FL+3)) '▐▌' S # mDP (left)
|
||||
_zp $((FE+2)) $((FR-5)) '▐▌' S # DC (right)
|
||||
_zp $((FE+3)) $((FL+3)) 'mDP' D
|
||||
_zp $((FE+3)) $((cx-3)) 'GbE/USB' D
|
||||
_zp $((FE+3)) $((FR-7)) 'DC 12V' D
|
||||
|
||||
# --- open-ended PCIe x4 card edge out the LEFT side --------------------
|
||||
_zp $((FE+1)) 0 'PCIe x4 ' D
|
||||
_zp $((FE+1)) 8 '▐▓▓▓▌' C
|
||||
|
||||
# --- rubber feet -------------------------------------------------------
|
||||
_zp $((FB+1)) $((FL+1)) '╹' D
|
||||
_zp $((FB+1)) $((FR-1)) '╹' D
|
||||
|
||||
# --- drive map: eMMC(OS) | rear SATA 1 | rear SATA 2 -------------------
|
||||
# occupied = solid box + green ; EMPTY = dashed ghost + dim
|
||||
local x0=2 x1=18 x2=34 bd gd
|
||||
bd="$(_zrep '─' 13)"; gd="$(_zrep '┄' 13)"
|
||||
_zp "$LEG" "$x0" 'eMMC (OS)' S
|
||||
_zp "$LEG" "$x1" 'rear SATA 1' S
|
||||
_zp "$LEG" "$x2" 'rear SATA 2' S
|
||||
|
||||
_zslot() { # $1=startcol $2=device-or-EMPTY $3=second-line text
|
||||
local x=$1 dev=$2 sub=$3 k br f1 f2 vb
|
||||
local r1=$((LEG+1)) r2=$((LEG+2)) r3=$((LEG+3)) r4=$((LEG+4))
|
||||
if [ "$dev" = EMPTY ]; then
|
||||
k=D; vb='┊'; br="$gd"
|
||||
printf -v f1 '%-11.11s' 'empty'
|
||||
printf -v f2 '%-11.11s' "$sub"
|
||||
else
|
||||
k=G; vb='│'; br="$bd"
|
||||
printf -v f1 '%-11.11s' "$dev"
|
||||
printf -v f2 '%-11.11s' "$sub"
|
||||
fi
|
||||
_zp "$r1" "$x" "┌${br}┐" "$k"
|
||||
_zp "$r4" "$x" "└${br}┘" "$k"
|
||||
_zp "$r2" "$x" "$vb" "$k"; _zp "$r2" $((x+1)) " $f1 " "$k"; _zp "$r2" $((x+14)) "$vb" "$k"
|
||||
_zp "$r3" "$x" "$vb" "$k"; _zp "$r3" $((x+1)) " $f2 " "$k"; _zp "$r3" $((x+14)) "$vb" "$k"
|
||||
}
|
||||
|
||||
if (( emmc_on )); then _zslot "$x0" "$emmc_dev" "${emmc_size} boot"
|
||||
else _zslot "$x0" 'EMPTY' 'no eMMC'; fi
|
||||
_zslot "$x1" "$sata1" 'cable-out'
|
||||
_zslot "$x2" "$sata2" 'cable-out'
|
||||
|
||||
_zp $((LEG+5)) "$x0" 'rear edge: SATA │ PWR │ SATA' D
|
||||
_zp $((LEG+5)) $((WIDTH-13)) 'Y-cable x2' D
|
||||
|
||||
# --- emit: run-length colour; identical display width mono & colour ----
|
||||
local i cur ch key out
|
||||
for ((r=0;r<HEIGHT;r++)); do
|
||||
out=''; cur='.'
|
||||
for ((i=0;i<WIDTH;i++)); do
|
||||
key="${Gk[r]:i:1}"; ch="${Gc[r]:i:1}"
|
||||
if [ "$key" != "$cur" ]; then
|
||||
case "$key" in
|
||||
H) out+="$DA_HL" ;; S) out+="$DA_ST" ;; D) out+="$DA_DIM" ;;
|
||||
G) out+="$DA_OK" ;; B) out+="$DA_BLU" ;; C) out+="$DA_CYN" ;;
|
||||
Y) out+="$DA_YEL" ;; *) out+="$DA_RST" ;;
|
||||
esac
|
||||
cur="$key"
|
||||
fi
|
||||
out+="$ch"
|
||||
done
|
||||
[ "$cur" != '.' ] && out+="$DA_RST"
|
||||
printf '%s\n' "$out"
|
||||
done
|
||||
|
||||
unset -f _zp _zrep _zfin _zslot 2>/dev/null || true
|
||||
}
|
||||
|
||||
HOSTNAME=$(hostname | tr -cd '[:alnum:]-_.')
|
||||
CHASSIS_TYPE=${CHASSIS_TYPES[$HOSTNAME]:-"unknown"}
|
||||
|
||||
@@ -1307,6 +1519,9 @@ case "$CHASSIS_TYPE" in
|
||||
"micro")
|
||||
generate_micro_layout "$HOSTNAME"
|
||||
;;
|
||||
"zimaboard")
|
||||
generate_zimaboard_layout "$HOSTNAME"
|
||||
;;
|
||||
"nuc")
|
||||
generate_nuc_layout "$HOSTNAME"
|
||||
;;
|
||||
|
||||
Reference in New Issue
Block a user