Входит в набор rPi Seal
#!/bin/bash export LANG=en_US.UTF-8 export LC_ALL=en_US.UTF-8 # ==DIS/AUTOEXEC== # === 🧪 Pi Compatibility === # 10_pi_compatibility.sh — Проверка совместимости с Raspberry Pi 3/4/5 # set -euo pipefail # Все функции do_check() { local root_dev="$1" local boot_dir="$2" local live="$3" echo echo "📁 Анализ загрузочного каталога: $boot_dir" echo "──────────────────────────────────────────────" declare -A MODELS MODELS["Pi3"]="start.elf fixup.dat kernel7.img" MODELS["Pi4"]="start4.elf fixup4.dat kernel8.img" MODELS["Pi5"]="start4.elf fixup4.dat kernel8.img" declare -A MISSING for MODEL in "${!MODELS[@]}"; do echo "🧩 Проверка файлов для $MODEL:" MISSING[$MODEL]="" for file in ${MODELS[$MODEL]}; do if [[ -f "$boot_dir/$file" ]]; then echo " ✅ $file найден" else if [[ "$MODEL" == "Pi3" || "$file" != "kernel7.img" ]]; then echo " ❌ $file отсутствует" MISSING[$MODEL]+="$file " fi fi done done echo "──────────────────────────────────────────────" if [[ "$live" == true && -f /proc/device-tree/model ]]; then MODEL_RAW=$(tr -d '\0' < /proc/device-tree/model) else MODEL_RAW="(в .img определить нельзя)" fi echo "🖥️ Модель устройства: $MODEL_RAW" ARCH=$(uname -m) echo "🧠 Архитектура: $ARCH" [[ "$ARCH" == "aarch64" ]] && echo " ✅ 64-битная система" || echo " ⚠️ Рекомендуется 64-битная система для Pi 5" KERNEL=$(uname -r) echo echo "🧬 Ядро: $KERNEL" if dpkg --compare-versions "$KERNEL" ge "6.1"; then echo " ✅ Ядро >= 6.1 (подходит для Pi 5)" else echo " ⚠️ Ядро < 6.1 — возможны проблемы на Pi 5" fi echo echo "📦 Прошивка GPU:" if [[ "$live" == true && $(command -v vcgencmd) ]]; then vcgencmd version | sed 's/^/ /' else FW_FILE="$boot_dir/start4.elf" [[ -f "$FW_FILE" ]] || FW_FILE="$boot_dir/start.elf" FW_DATE=$(strings "$FW_FILE" 2>/dev/null | grep -i "version" | head -n 1) echo " ${FW_DATE:-Не удалось определить версию}" fi if [[ "$live" == true && $(command -v rpi-eeprom-update) ]]; then echo echo "🧰 EEPROM bootloader:" sudo rpi-eeprom-update | sed 's/^/ /' fi echo echo "🧾 config.txt:" CONFIG="$boot_dir/config.txt" if [[ -f "$CONFIG" ]]; then grep -E 'dtoverlay|device_tree|kernel=' "$CONFIG" | while read -r line; do echo " 🔍 $line" [[ "$line" == *"pi3-disable"* ]] && echo " ⚠️ Может не подойти для Pi 3" [[ "$line" == *"vc4-kms-v3d"* ]] && echo " ⚠️ Требует Pi 4/5, проблемы на Pi 3" done else echo " ❌ config.txt не найден" fi echo echo "📋 Совместимость:" for MODEL in Pi3 Pi4 Pi5; do if [[ -z "${MISSING[$MODEL]}" ]]; then echo "✅ $MODEL: потенциально совместим" else echo -e "❌ $MODEL: отсутствуют файлы → ${MISSING[$MODEL]}" fi done } check_img() { local img_path="$1" if [[ ! -f "$img_path" ]]; then echo "❌ Файл не найден: $img_path" exit 1 fi LOOPDEV=$(sudo losetup --show -Pf "$img_path") BOOT_PART="${LOOPDEV}p1" TMPDIR=$(mktemp -d) sudo mount "$BOOT_PART" "$TMPDIR" echo echo "🔍 Проверка образа: $img_path" do_check "$LOOPDEV" "$TMPDIR" false sudo umount "$TMPDIR" sudo losetup -d "$LOOPDEV" rmdir "$TMPDIR" } select_img_and_check() { NAS_PATH="/mnt/backup_nas" if mountpoint -q "$NAS_PATH"; then mapfile -t DEVICES < <(lsblk -nrpo NAME,SIZE,MOUNTPOINT | grep -E "/dev/sd|/dev/nvme" | awk '{print $1":"$2":"$3}') DEVICES+=("$NAS_PATH::NAS") else mapfile -t DEVICES < <(lsblk -nrpo NAME,SIZE,MOUNTPOINT | grep -E "/dev/sd|/dev/nvme" | awk '{print $1":"$2":"$3}') fi if [[ ${#DEVICES[@]} -eq 0 ]]; then echo "❌ Нет доступных устройств." exit 1 fi echo "💾 Выберите диск с .img-файлами:" i=1 for dev in "${DEVICES[@]}"; do IFS=":" read -r name size mnt <<< "$dev" label="" [[ "$mnt" == "NAS" ]] && label="🖧 сетевой диск" [[ -z "$mnt" && -z "$label" ]] && label="🔌 не примонтировано" echo "$i - $name $size $mnt $label" ((i++)) done echo "0 - Отмена" read -rp "👉 Ваш выбор: " choice [[ "$choice" == "0" || -z "$choice" ]] && echo "❎ Отменено." && exit 0 (( choice < 1 || choice > ${#DEVICES[@]} )) && echo "❌ Неверный выбор." && exit 1 SEL_DEV="${DEVICES[$((choice-1))]}" IFS=":" read -r DEV_NAME DEV_SIZE DEV_MNT <<< "$SEL_DEV" TEMP_MOUNTED=false if [[ "$DEV_NAME" == "$NAS_PATH" ]]; then TARGET_DIR="$NAS_PATH" echo "📁 Используем NAS каталог: $TARGET_DIR" else MOUNTED_PATH=$(lsblk -nrpo NAME,MOUNTPOINT "$DEV_NAME" | awk '$2!="" {print $2; exit}') if [[ -n "$MOUNTED_PATH" ]]; then echo "✅ Используем: $MOUNTED_PATH" TARGET_DIR="$MOUNTED_PATH" else i=0 while true; do MNT_PATH="/mnt/rpi_target$i" if ! mountpoint -q "$MNT_PATH"; then break fi ((i++)) done sudo mkdir -p "$MNT_PATH" if sudo mount "$DEV_NAME" "$MNT_PATH"; then echo "✅ Устройство примонтировано: $MNT_PATH" TARGET_DIR="$MNT_PATH" TEMP_MOUNTED=true else echo "❌ Не удалось примонтировать." exit 1 fi fi fi mapfile -t IMG_LIST < <(find "$TARGET_DIR" -maxdepth 1 -type f -name "*.img") if [[ ${#IMG_LIST[@]} -eq 0 ]]; then echo "❌ Не найдено .img файлов в $TARGET_DIR" $TEMP_MOUNTED && sudo umount "$TARGET_DIR" exit 1 fi echo "🗂️ Найденные образы:" i=1 for img in "${IMG_LIST[@]}"; do echo "$i - $img" ((i++)) done echo "0 - Отмена" read -rp "👉 Выберите образ для проверки: " img_choice [[ "$img_choice" == "0" || -z "$img_choice" ]] && echo "❎ Отменено." && $TEMP_MOUNTED && sudo umount "$TARGET_DIR" && exit 0 (( img_choice < 1 || img_choice > ${#IMG_LIST[@]} )) && echo "❌ Неверный выбор." && exit 1 IMGFILE="${IMG_LIST[$((img_choice-1))]}" echo "📦 Выбран образ: $IMGFILE" check_img "$IMGFILE" $TEMP_MOUNTED && sudo umount "$TARGET_DIR" } check_live_system() { echo echo "🔍 Проверка текущей системы..." BOOT_DIR="/boot/firmware" [[ -d "/boot" && ! -d "$BOOT_DIR" ]] && BOOT_DIR="/boot" do_check "/" "$BOOT_DIR" true } print_menu() { echo "🧪 Проверка совместимости Raspberry Pi" echo "───────────────────────────────────────" echo " 1 - 🐧 Проверить текущую систему" echo " 2 - 🔍 Проверить .img-файл (выбрать с USB/NAS)" echo " 0 - ❌ Выход" read -rp "👉 Ваш выбор: " choice case "$choice" in 1) check_live_system ;; 2) select_img_and_check ;; 0) echo "🚪 Выход."; exit 0 ;; *) echo "❌ Неверный выбор."; exit 1 ;; esac } print_menu