#!/bin/sh # ShiMeta-AI-Stack 板卡端通用安装脚本(仅 wget 方式,从 ShimetaPi 软件源下载) # # 用法: # sh install.sh # 默认镜像站 + 最新版本 # sh install.sh # 指定服务器 # sh install.sh # 指定服务器 + 版本 # sh install.sh -v # 指定版本 # # 仅支持 wget 从 https://mirrors.shimetapi.cn 下载,无多协议 set -e SERVER="${1:-https://mirrors.shimetapi.cn/repos/GK7206/shimeta-ai}" # 版本号: 从服务器 LATEST 获取最新,或 -v 指定 VERSION="" case "$1" in -v) VERSION="$2"; shift 2; SERVER="${1:-https://mirrors.shimetapi.cn/repos/GK7206/shimeta-ai}"; esac case "$2" in -v) VERSION="$3"; shift 2; esac case "$2" in [0-9]*.*) VERSION="$2" ;; esac # 优先 SD 卡(嵌入式板卡通常 rootfs 很小),其次 /usr INSTALL_PREFIX="${INSTALL_PREFIX:-/mnt}" ARCH="arm_cortex-a7" # ---- 检测 NPU 硬件 ---- # 返回设备代号: gk7206 | rk3588 | j5 | ascend310b | unknown detect_npu() { # 方法 1: 设备节点扫描 if [ -c /dev/npu.0 ] || [ -c /dev/npu0 ]; then echo "gk7206"; return 0 fi if [ -c /dev/rknn0 ]; then echo "rk3588"; return 0 fi if [ -c /dev/bpu0 ] || [ -c /dev/bpu.0 ]; then echo "j5"; return 0 fi if [ -c /dev/davinci0 ]; then echo "ascend310b"; return 0 fi # 方法 2: sysfs 探测 if [ -d /sys/class/npu ]; then echo "gk7206"; return 0 fi if [ -d /sys/class/rknpu ]; then echo "rk3588"; return 0 fi # 方法 3: /proc/cpuinfo 关键字 if grep -qi "gk7206\|sigmastar" /proc/cpuinfo 2>/dev/null; then echo "gk7206"; return 0 fi if grep -qi "rk3588\|rockchip" /proc/cpuinfo 2>/dev/null; then echo "rk3588"; return 0 fi # 兜底 echo "unknown" } # ---- 自动检测 SD 卡 ---- auto_detect_sd() { # 如果 INSTALL_PREFIX 可用空间 < 20MB,尝试挂载 SD 卡 local avail=$(df -k "${INSTALL_PREFIX}" 2>/dev/null | tail -1 | awk '{print $4}') if [ -n "$avail" ] && [ "$avail" -lt 20480 ]; then echo "[bare] ${INSTALL_PREFIX} 空间不足 (${avail}KB),搜索 SD 卡..." for dev in /dev/mmcblk1p1 /dev/mmcblk0p1 /dev/sda1; do if [ -b "$dev" ]; then mount "$dev" "${INSTALL_PREFIX}" 2>/dev/null && \ echo "[bare] 已挂载 $dev → ${INSTALL_PREFIX}" && break fi done fi } # ---- bare 安装(wget 下载对应 tarball) ---- install_bare() { echo "[bare] 无包管理器..." # 清理 /tmp(嵌入式 rootfs 极小,shell 需要临时空间) find /tmp -name 'shimeta*' -delete 2>/dev/null || true # 自动检测 SD 卡 auto_detect_sd local avail=$(df -k "${INSTALL_PREFIX}" 2>/dev/null | tail -1 | awk '{print $4}') echo "[bare] 安装目录: ${INSTALL_PREFIX} (可用: ${avail}KB)" mkdir -p ${INSTALL_PREFIX} local npu_type=$(detect_npu) echo "[bare] NPU 类型: ${npu_type}" # 升级时清理旧二进制,保留用户数据 local old_ver=$(cat "${INSTALL_PREFIX}/.shimeta_version" 2>/dev/null || echo "") if [ -n "$old_ver" ] && [ "$old_ver" != "${VERSION}" ]; then echo "[bare] 检测到旧版本 v${old_ver} → v${VERSION}" echo "[bare] 清理旧运行时..." rm -rf "${INSTALL_PREFIX}/bin" "${INSTALL_PREFIX}/lib" "${INSTALL_PREFIX}/plugins" "${INSTALL_PREFIX}/setup.sh" 2>/dev/null || true echo "[bare] 用户数据(模型/图片)已保留" fi if ! command -v wget >/dev/null 2>&1; then echo "[bare] [ERROR] 未找到 wget,无法下载" return 1 fi # 未指定版本时从服务器获取最新 if [ -z "${VERSION}" ]; then echo "[bare] 获取最新版本号..." VERSION=$(wget -qO- "${SERVER}/bare/LATEST" 2>/dev/null || echo "") if [ -z "${VERSION}" ]; then VERSION="1.0.0" echo "[bare] 无法获取最新版本,回退到 v${VERSION}" else echo "[bare] 最新版本: ${VERSION}" fi fi local tarball="bare/shimeta-${npu_type}_${VERSION}_arm.tar.gz" local local_file="${INSTALL_PREFIX}/shimeta-${npu_type}.tar.gz" echo " [wget] ${SERVER}/${tarball} -> ${local_file}" wget "${SERVER}/${tarball}" -O "${local_file}" || { echo "[bare] ${npu_type} 包下载失败"; return 1; } cd ${INSTALL_PREFIX} tar xzf "${local_file}" rm -f "${local_file}" # VFAT 兼容:cp 替代软链 [ -f lib/libshimeta_rt.so ] && [ ! -f lib/libshimeta_rt.so.0 ] && \ cp lib/libshimeta_rt.so lib/libshimeta_rt.so.0 2>/dev/null || true mkdir -p plugins [ -f lib/libshimeta_plugin_*.so ] && \ cp lib/libshimeta_plugin_*.so plugins/ 2>/dev/null || true # 自动设置环境变量 (/etc/profile 持久化) local prof="/etc/profile" [ -w /etc/profile ] || prof="${INSTALL_PREFIX}/.profile" grep -q "shimeta" "$prof" 2>/dev/null || { echo "" >> "$prof" echo "# ShiMeta-AI-Stack auto-setup" >> "$prof" echo "mount /dev/mmcblk1p1 /mnt 2>/dev/null" >> "$prof" echo ". ${INSTALL_PREFIX}/setup.sh 2>/dev/null" >> "$prof" echo "export PATH=${INSTALL_PREFIX}/bin:\$PATH" >> "$prof" } # 加载 SDK 内核模块 if [ -x /opt/ko/load ]; then cd /opt/ko && ./load xm7206v12a -i 2>/dev/null; cd - >/dev/null; fi . "${INSTALL_PREFIX}/setup.sh" 2>/dev/null echo "[bare] 安装完成 (${npu_type} v${VERSION})" echo "[bare]" echo "[bare] 当前终端请执行:" echo "[bare] . ${INSTALL_PREFIX}/setup.sh" echo "[bare] shimeta_infer ${INSTALL_PREFIX}/yolov8n_demo.zip ${INSTALL_PREFIX}/people.jpg" echo "[bare]" echo "[bare] 重启后自动生效(已写入 /etc/profile)" } # ---- 主流程 ---- main() { echo "============================================" echo " ShiMeta-AI-Stack v${VERSION} 安装程序" echo " 服务器: ${SERVER}" echo "============================================" echo "" echo "检测到 NPU 硬件: $(detect_npu)" echo "" install_bare echo "" echo "============================================" echo " 安装完毕!" if [ -x ${INSTALL_PREFIX}/bin/shimeta_infer ]; then echo "" echo " 当前终端请执行:" echo " . ${INSTALL_PREFIX}/setup.sh" echo " shimeta_infer ${INSTALL_PREFIX}/yolov8n_demo.zip ${INSTALL_PREFIX}/people.jpg" echo "" echo " 重启后自动生效,无需再次 source" else echo " 未找到 shimeta_infer(包需先构建: ./packaging/release.sh)" fi echo "============================================" } main "$@"