#!/usr/bin/env bash set -euo pipefail echo "==== 1) 当前内核中的 SOF 固件 / 拓扑信息 ====" journalctl -k -b | grep -nE 'Firmware file:|Topology file:|Firmware info: version' || true echo # 确保用 root 运行 if [[ $EUID -ne 0 ]]; then echo "请用 sudo 运行本脚本:sudo bash $0" exit 1 fi echo "==== 2) 备份当前 SOF 固件和拓扑 ====" BACKUP_FW_DIR="/lib/firmware/intel/sof-backup-kaisa-20260416" BACKUP_TPLG_DIR="/lib/firmware/intel/sof-tplg-backup-kaisa-20260416" mkdir -p "$BACKUP_FW_DIR" mkdir -p "$BACKUP_TPLG_DIR" if [[ -f /lib/firmware/intel/sof/community/sof-cml.ri ]]; then cp -a /lib/firmware/intel/sof/community/sof-cml.ri "$BACKUP_FW_DIR"/ echo "已备份 sof-cml.ri 到 $BACKUP_FW_DIR/" else echo "警告:未找到 /lib/firmware/intel/sof/community/sof-cml.ri" fi if [[ -f /lib/firmware/intel/sof-tplg/sof-cml-rt5682.tplg ]]; then cp -a /lib/firmware/intel/sof-tplg/sof-cml-rt5682.tplg "$BACKUP_TPLG_DIR"/ echo "已备份 sof-cml-rt5682.tplg 到 $BACKUP_TPLG_DIR/" else echo "警告:未找到 /lib/firmware/intel/sof-tplg/sof-cml-rt5682.tplg" fi echo echo "==== 2.1) 校验备份是否落盘(sha256) ====" if [[ -f "$BACKUP_FW_DIR/sof-cml.ri" ]]; then sha256sum /lib/firmware/intel/sof/community/sof-cml.ri "$BACKUP_FW_DIR/sof-cml.ri" || true else echo "错误:未生成备份文件 $BACKUP_FW_DIR/sof-cml.ri(中止,避免覆盖后无法回滚)" exit 1 fi if [[ -f "$BACKUP_TPLG_DIR/sof-cml-rt5682.tplg" ]]; then sha256sum /lib/firmware/intel/sof-tplg/sof-cml-rt5682.tplg "$BACKUP_TPLG_DIR/sof-cml-rt5682.tplg" || true else echo "错误:未生成备份文件 $BACKUP_TPLG_DIR/sof-cml-rt5682.tplg(中止,避免覆盖后无法回滚)" exit 1 fi echo echo "==== 3) 下载并解压 sof-bin 2025.12.2 ====" WORKDIR="/var/tmp/sof-bin-upgrade" mkdir -p "$WORKDIR" cd "$WORKDIR" if [[ ! -f sof-bin-2025.12.2.tar.gz ]]; then echo "下载 sof-bin-2025.12.2.tar.gz ..." wget https://github.com/thesofproject/sof-bin/releases/download/v2025.12.2/sof-bin-2025.12.2.tar.gz else echo "已存在 sof-bin-2025.12.2.tar.gz,跳过下载。" fi echo "解析 tarball 顶层目录..." # 注意:脚本启用了 pipefail,直接用 `tar ... | head -n1` 会触发 tar 的 SIGPIPE (exit 141),导致脚本中止。 # 所以先将列表落盘,再读取第一行。 TAR_LIST_FILE="$WORKDIR/sof-bin-2025.12.2.tar.list" tar tf sof-bin-2025.12.2.tar.gz > "$TAR_LIST_FILE" TOPDIR="$(head -n 1 "$TAR_LIST_FILE" | cut -d/ -f1)" if [[ -z "${TOPDIR}" ]]; then echo "错误:无法解析 tarball 顶层目录(TOPDIR 为空)" exit 1 fi echo "tarball 顶层目录:$TOPDIR" if [[ ! -d "$TOPDIR" ]]; then echo "解压 sof-bin-2025.12.2.tar.gz 到 $WORKDIR/$TOPDIR ..." tar xf sof-bin-2025.12.2.tar.gz else echo "已存在目录 $TOPDIR,跳过解压。" fi cd "$TOPDIR" echo echo "==== 4) 查找 sof-cml.ri 和 sof-cml-rt5682*.tplg ====" # 重要:同一个 tarball 里可能同时存在: # - ./sof/sof-cml.ri(通常指向 intel-signed 版本或与旧版本相同) # - ./sof/community/sof-cml.ri(我们系统实际加载的路径也是 intel/sof/community/sof-cml.ri) # 为避免误选,优先选择 community 目录的固件。 FW_CML_PATH=$( find ./sof/community -maxdepth 1 \( -type f -o -type l \) -name 'sof-cml.ri' 2>/dev/null | head -n 1 || true ) if [[ -z "${FW_CML_PATH}" ]]; then FW_CML_PATH=$(find . \( -type f -o -type l \) -name 'sof-cml.ri' | head -n 1 || true) fi TPLG_RT5682_PATH=$( find ./sof-tplg -maxdepth 1 -type f -name 'sof-cml-rt5682.tplg' 2>/dev/null | head -n 1 || true ) if [[ -z "${TPLG_RT5682_PATH}" ]]; then TPLG_RT5682_PATH=$(find . -type f -name 'sof-cml-rt5682.tplg' | head -n 1 || true) fi echo "找到的 sof-cml.ri 路径: $FW_CML_PATH" echo "找到的 sof-cml-rt5682*.tplg 路径: $TPLG_RT5682_PATH" echo if [[ -z "$FW_CML_PATH" || -z "$TPLG_RT5682_PATH" ]]; then echo "错误:未能在 sof-bin 包内找到 sof-cml.ri 或 sof-cml-rt5682*.tplg" exit 1 fi echo "==== 5) 用新固件 / 拓扑 覆盖系统文件 ====" cp -L "$FW_CML_PATH" /lib/firmware/intel/sof/community/sof-cml.ri echo "已覆盖 /lib/firmware/intel/sof/community/sof-cml.ri" cp -L "$TPLG_RT5682_PATH" /lib/firmware/intel/sof-tplg/sof-cml-rt5682.tplg echo "已覆盖 /lib/firmware/intel/sof-tplg/sof-cml-rt5682.tplg" echo echo "==== 5.1) 覆盖后校验(sha256 / 文件大小) ====" sha256sum \ /lib/firmware/intel/sof/community/sof-cml.ri \ /lib/firmware/intel/sof-tplg/sof-cml-rt5682.tplg || true ls -la \ /lib/firmware/intel/sof/community/sof-cml.ri \ /lib/firmware/intel/sof-tplg/sof-cml-rt5682.tplg || true echo echo "提示:如果你想确认 tarball 里选中的文件 hash,可在工作目录下执行:" echo " sha256sum \"$FW_CML_PATH\" \"$TPLG_RT5682_PATH\"" echo echo "==== 6) 更新 initramfs(可能需要几秒) ====" update-initramfs -u echo echo "==== 7) 升级完成,当前系统中的固件信息 (下次重启后再确认一次) ====" journalctl -k -b | grep -nE 'Firmware file:|Topology file:|Firmware info: version' || true echo echo "步骤完成:" echo "1) 已备份旧版本到:" echo " - $BACKUP_FW_DIR/sof-cml.ri" echo " - $BACKUP_TPLG_DIR/sof-cml-rt5682.tplg" echo "2) 已将 sof-bin 2025.12.2 中的 sof-cml.ri / sof-cml-rt5682.tplg 覆盖到系统目录。" echo echo "下一步:请手动执行 reboot,然后重启回来后用以下命令确认新固件版本:" echo " journalctl -k -b | grep -nE 'Firmware file:|Topology file:|Firmware info: version'" echo echo "如需回滚,可将备份文件拷回原路径后再次执行 update-initramfs -u。"