找回密码
 立即注册
查看: 11|回复: 0

[原创] 在 Android RK3566 上持久化安装 Entware

[复制链接]

2

主题

0

回帖

15

积分

初级渣柚V1

积分
15
QQ
hurdle 发表于 昨天 16:36 | 显示全部楼层 |阅读模式 IP:–福建–福州 联通
在 Android RK3566 上持久化安装 Entware
系列目录 | 下一篇:在 Entware 中部署 Home Assistant Core
RK356x Android 盒子通常具备足够的 CPU、内存和存储资源,但 Android 用户空间并不包含常规 Linux 包管理器。Entware 可以补充 BusyBox、Python、编译工具和 SysV 风格的服务脚本。
安装难点在 Android 与标准 Linux 环境的差异。根分区空间有限,/opt 不一定持久存在。系统缺少 wget,Entware 的 glibc 程序还需要可用的 /etc/resolv.conf。
本文建立以下目标状态:
  • Entware 实体数据保存在 /data/entware;
  • /opt 作为兼容入口指向持久化目录;
  • opkg、BusyBox 和 DNS 解析可用;
  • 普通重启后目录、链接和包管理能力仍然存在。
本文会修改 root 文件系统和 /etc/resolv.conf。任何写操作前都要核对目标设备。
1. 核对设备条件
在 Windows PowerShell 中设置网络 ADB 序列号:
$Serial = '192.168.110.247:65533'
adb connect $Serial
adb devices -l
设备状态必须为 device。如果显示 offline 或 unauthorized,不要继续执行写操作。
读取型号、Android 版本、CPU 架构、当前身份、内核和 /data 剩余空间:
adb -s $Serial shell getprop ro.product.model
adb -s $Serial shell getprop ro.build.version.release
adb -s $Serial shell getprop ro.product.cpu.abi
adb -s $Serial shell id
adb -s $Serial shell uname -a
adb -s $Serial shell df -h /data
本次设备的关键结果为:
  • CPU 架构为 aarch64;
  • 系统为 Android 11;
  • ADB shell 身份为 uid=0(root);
  • /data 仍有约 24 GB 可用空间;
  • 根分区空间接近耗尽。
这些条件决定了后续目录布局。Entware 数据不能直接堆放在根分区,也不能假设其他 Android 设备具备相同权限和 ABI。
2. 设计持久化目录
Entware 默认使用 /opt。为了兼容其目录约定,同时避免占用根分区,采用以下布局:
/data/entware     # Entware 实体数据,普通重启保留
/opt              # 指向 /data/entware 的符号链接
创建前检查两个路径是否已被其他软件占用:
adb -s $Serial shell 'ls -ld /opt /data/entware 2>/dev/null || true'
已有目录或链接时不要直接覆盖。应先确认其所有者、用途和真实指向。
确认无冲突后创建基础目录和符号链接:
adb -s $Serial shell 'mkdir -p /data/entware/bin /data/entware/etc /data/entware/lib/opkg /data/entware/tmp /data/entware/var/lock'
adb -s $Serial shell 'ln -s /data/entware /opt'
adb -s $Serial shell 'readlink -f /opt'
readlink 必须输出 /data/entware。如果根文件系统只读,应使用目标固件支持的 adb remount,并重新核对挂载状态。不同固件的 remount 机制可能不同。
3. 部署 opkg 引导文件
本次设备使用 Entware aarch64-k3.10 软件源。先在 Windows 下载官方引导文件,再通过 ADB 推送到设备:
$BaseUrl = 'https://bin.entware.net/aarch64-k3.10/installer'
$TempDir = Join-Path $env:TEMP 'entware-bootstrap'
New-Item -ItemType Directory -Force $TempDir | Out-Null

Invoke-WebRequest "$BaseUrl/opkg" -OutFile "$TempDir/opkg"
Invoke-WebRequest "$BaseUrl/opkg.conf" -OutFile "$TempDir/opkg.conf"

adb -s $Serial push "$TempDir/opkg" /opt/bin/opkg
adb -s $Serial push "$TempDir/opkg.conf" /opt/etc/opkg.conf
adb -s $Serial shell 'chmod 755 /opt/bin/opkg'
adb -s $Serial shell '/opt/bin/opkg --version'
能够输出版本号,说明 opkg 本体可以执行。此时尝试更新软件包索引:
adb -s $Serial shell 'PATH=/opt/binPATH /opt/bin/opkg update'
如果更新成功,可以跳过下一节的临时 wget 兼容处理。本次设备在这里失败,原因是 Android 只有 curl,而 Entware 引导流程调用了 wget。
4. 处理 Android 缺少 wget 的问题
先创建一个仅用于引导阶段的兼容脚本。它把 wget -q -O 目标 URL 转换为 Android curl 调用:
$WgetShim = Join-Path $TempDir 'wget'
@'
#!/system/bin/sh
exec /system/bin/curl -fsSL -o "$3" "$4"
'@ | Set-Content -Encoding ascii $WgetShim

adb -s $Serial push $WgetShim /opt/bin/wget
adb -s $Serial shell 'chmod 755 /opt/bin/wget'
adb -s $Serial shell 'PATH=/opt/binPATH /opt/bin/opkg update'
adb -s $Serial shell 'PATH=/opt/binPATH /opt/bin/opkg install busybox'
如果 BusyBox 安装成功,Entware 会提供正式的 wget。临时兼容脚本不再承担后续下载任务。
部分 Android 环境会在 BusyBox 预安装脚本阶段失败。此时不应反复运行 opkg。可以从仓库索引读取当前 BusyBox 包名,提取二进制文件,再交回 opkg 管理:
$PackagesGz = Join-Path $TempDir 'Packages.gz'
Invoke-WebRequest 'https://bin.entware.net/aarch64-k3.10/Packages.gz' -OutFile $PackagesGz

$InputStream = [System.IO.File]::OpenRead($PackagesGz)
$Gzip = [System.IO.Compression.GzipStream]::new(
    $InputStream,
    [System.IO.Compression.CompressionMode]:ecompress
)
$Reader = [System.IO.StreamReader]::new($Gzip)
$Packages = $Reader.ReadToEnd()
$Reader.Dispose()
$Gzip.Dispose()
$InputStream.Dispose()

$BusyBoxBlock = [regex]::Match(
    $Packages,
    '(?ms)^Package: busybox\r?\n.*?(?=\r?\n\r?\n)'
).Value
$BusyBoxFile = [regex]::Match(
    $BusyBoxBlock,
    '(?m)^Filename: (.+)$'
).Groups[1].Value.Trim()
if (-not $BusyBoxFile) { throw '未在仓库索引中找到 BusyBox 文件名' }

$BusyBoxIpk = Join-Path $TempDir $BusyBoxFile
Invoke-WebRequest "https://bin.entware.net/aarch64-k3.10/$BusyBoxFile" -OutFile $BusyBoxIpk

$BusyBoxStage = Join-Path $TempDir 'busybox-stage'
New-Item -ItemType Directory -Force $BusyBoxStage | Out-Null
tar -xf $BusyBoxIpk -C $BusyBoxStage ./data.tar.gz
tar -xzf "$BusyBoxStage/data.tar.gz" -C $BusyBoxStage ./opt/bin/busybox

adb -s $Serial push "$BusyBoxStage/opt/bin/busybox" /opt/bin/busybox
adb -s $Serial shell 'chmod 755 /opt/bin/busybox'
adb -s $Serial shell 'PATH=/opt/binPATH /opt/bin/opkg install busybox'
adb -s $Serial shell '/opt/bin/busybox ln -sf busybox /opt/bin/wget'
这段手动引导只用于解决首次安装的循环依赖:opkg 需要 wget,而正式 wget 又由尚未安装的 BusyBox 提供。
5. 修复 Entware DNS 解析
Android 本身能联网,不代表 Entware 程序一定能解析域名。Android 网络栈和 Entware glibc 程序使用的解析路径不同。本次设备出现了 Android curl 正常、Entware wget 报域名解析失败的现象。
运行下面的命令前,应确认 /etc/resolv.conf 没有被系统或其他服务管理。已有文件时不要直接覆盖。
将局域网 DNS 和备用 DNS 写入 Entware 持久化目录:
$Resolv = Join-Path $TempDir 'resolv.conf'
@'
nameserver 192.168.110.1
nameserver 1.1.1.1
'@ | Set-Content -Encoding ascii $Resolv

adb -s $Serial push $Resolv /opt/etc/resolv.conf
adb -s $Serial shell 'ln -s /opt/etc/resolv.conf /etc/resolv.conf'
adb -s $Serial shell 'PATH=/opt/binPATH /opt/bin/opkg update'
192.168.110.1 是本次环境的路由器地址。部署到其他网络时必须替换。若固件自行管理 /etc/resolv.conf,应采用该固件提供的持久化 DNS 机制。
6. 安装 Entware 基础套件
安装 entware-opt,补齐账号文件,并设置共享临时目录权限:
adb -s $Serial shell 'PATH=/opt/binPATH /opt/bin/opkg install entware-opt'
adb -s $Serial shell 'cp /opt/etc/passwd.1 /opt/etc/passwd'
adb -s $Serial shell 'cp /opt/etc/group.1 /opt/etc/group'
adb -s $Serial shell 'cp /opt/etc/shells.1 /opt/etc/shells'
adb -s $Serial shell 'chmod 1777 /opt/tmp'
1777 允许多个服务写入 /opt/tmp,同时通过 sticky bit 防止普通用户删除其他用户的文件。
进入设备交互式 shell 后,可为当前会话临时补充 Entware 命令路径:
adb -s $Serial shell
export PATH=/opt/bin:/opt/sbinPATH
该设置只对当前 shell 有效,不会修改 Android 的全局环境。
7. 验证安装与重启持久性
在当前启动周期内检查软件源、基础包、符号链接和 DNS 下载:
adb -s $Serial shell 'PATH=/opt/bin:/opt/sbinPATH opkg update'
adb -s $Serial shell '/opt/bin/opkg status entware-opt busybox opkg | /opt/bin/grep -E "^(Package|Status|Version):"'
adb -s $Serial shell 'readlink -f /opt'
adb -s $Serial shell '/opt/bin/wget -qO- http://bin.entware.net/aarch64-k3.10/installer/opkg.conf | /opt/bin/grep "^arch aarch64"'
静态检查通过后,记录当前 Boot ID 并执行真实重启:
$BootIdBefore = (adb -s $Serial shell 'cat /proc/sys/kernel/random/boot_id').Trim()
adb -s $Serial reboot
设备重新上线后复查:
adb connect $Serial
adb -s $Serial shell getprop sys.boot_completed
$BootIdAfter = (adb -s $Serial shell 'cat /proc/sys/kernel/random/boot_id').Trim()
"Boot ID changed: $($BootIdBefore -ne $BootIdAfter)"

adb -s $Serial shell 'readlink -f /opt'
adb -s $Serial shell 'PATH=/opt/bin:/opt/sbinPATH opkg update'
验收标准如下:
  • sys.boot_completed 返回 1;
  • Boot ID changed 返回 True;
  • /opt 仍解析为 /data/entware;
  • opkg update 能完成索引更新。
Boot ID 用于区分真实重启与短暂 ADB 断线。只看到设备重新连接,不能证明系统已经完成重启。
8. 维护与回滚边界
  • 恢复出厂会清空 /data,Entware 数据也会被删除。
  • OTA、刷机或 root overlay 重建可能删除 /opt、/etc/resolv.conf 和 init 配置。
  • 不要直接执行 rm -rf /opt。删除前必须用 readlink -f /opt 确认真实目标。
  • 临时停用 Entware 时,应先停止 /opt/etc/init.d/S* 服务,再移除系统入口。
  • 保留 /data/entware 可以降低恢复成本,也便于定位问题。
下一篇将在这个 Entware 环境中部署独立的 Python 运行环境和 Home Assistant Core。
参考资料
  • Entware 官方仓库
  • Entware aarch64-k3.10 软件源


您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|小黑屋|矿渣社区 ( 黔ICP备2024020525号-1 )

GMT+8, 2026-8-6 05:34 , Processed in 0.065731 second(s), 23 queries .

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表