cndaqiang Web Linux DFT

海纳思刷机总结

2024-10-20
cndaqiang
RSS

刷机之后,第一次可以进入HiNAS的系统,但是系统变成了read-only, 无法设置。或者本来能用,但是重启/断电之后,系统变成read-only。 不知道是硬件的问题,还是软件的问题,遂对HiNAS的刷机包进行了分析和更改。 最后实际使用的系统为immortalwrt-21.02

写在前面

  • 感谢神雕大佬的开发:HiNas
  • 刷机有风险,别无脑复制下面的内容

设备

  • 咪咕盒子MG101
  • 芯片类型 hi3798mv100
  • 刷机包类型 mv100-mdmo1a-usb-flash.zip. 版本Hinas-20240201
  • openwrt刷机包immortalwrt-21.02.7@armvirt/32
  • 对我的设备来说,靠近电源的是优先的fastbot的U盘
    • 所以可以用一个小U盘插在电源上旁边的口作为引导
    • 但是开机后谁是sda/sdb并不一定。

官方的USB刷机流程

  • 短接/清空原始emmc的fastboot分区
  • 插入U盘,重插电源
  • 从U盘的fastboot.bin启动
  • 执行U盘中bootargs.bin的启动命令
    • 默认的bootargs.bin是执行刷机命令
    • 可以用cat或者记事本查看这个文件的内容,包含flash各个分区
    • 注: 我们可以替换这个bootargs.bin来实现启动到特定的系统分区
  • 默认的bootargs.bin会把U盘内mv100文件夹内的文件刷到各个分区
    • /dev/mmcblk0p1 mv100/fastboot.bin
    • /dev/mmcblk0p2 mv100/bootargs.bin
    • /dev/mmcblk0p3 mv100/baseparam.img
    • /dev/mmcblk0p4 mv100/pq_param.bin
    • /dev/mmcblk0p5 mv100/logo.img
    • /dev/mmcblk0p6 mv100/hi_kernel.bin
    • /dev/mmcblk0p7 mv100/recoverybox32.ext4, 这是一个精简的op系统
    • /dev/mmcblk0p8 mv100/www_ecoo_top.ext4, hinas的系统包,里面存放着backup-32/64.gz,如果使用HiNas的方式刷机,替换这个分区中的gz即可
  • 刷入完成后,重启,此时emmc中已经刷入了fastboot.bin,bootargs.bin,logo.img
  • 启动页面变为了mv100/logo.img,即启动图片变为正在刷入激动人心的系统...
  • 根据mmc0p2(mv100/bootargs.bin)中的参数启动
    • 默认启动到emmc0p7
    • 我们也可以替换U盘的mv100/bootargs.bin,实现刷机后启动到何分区。
  • 重启进入mmc0p7分区的系统后,会依次执行/etc/rc.local/etc/recovery.sh
  • /etc/recovery.sh中,会执行
    • 挂载8分区
    • mount -t ext4 /dev/mmcblk0p8 /backup
    • 把8分区存储的HiNAS系统刷入9分区
    • gunzip -c /backup/$backup_file | dd of=/dev/mmcblk0p9 bs=1024
    • 刷入启动到9分区的bootargs
    • dd of=/dev/mmcblk0p2 if=/etc/bootargs/bootargs9-${arch}.bin bs=1024 count=1024
    • 刷入新启动页面的logo
    • dd of=/dev/mmcblk0p5 if=/etc/bootargs/logo.img bs=1024 count=4096
    • 重启
  • 重启进入mmc0p9分区的系统后,刷机结束,开始HiNAS系统的初始化
    • 启动页面变为了mv100/logo.img,即启动图片变为HiNAS作者二维码

对于没有遇到异常的用户,上面的流程走完就结束了。

  • 但是我买的盒子emmc有问题
  • 刷完要么进系统是readonly,无法初始化
  • 要么连系统都进不去
  • 进入系统后,各种文件错误,突然变成只读
  • 对HiNAS的刷机包进行了一番研究后,有下面的总结

一些有用的说明

  • mv100中的ext4文件、dd备份的分区以及img、iso等文件,可以直接用7zip打开的
  • 安装系统不用非得dd,可以格式化一个ext4的分区,把系统文件解压复制进去。这样系统空间不受dd的大小限制
  • mv100中的ext4是Android sparse image格式,无法直接dd
    • 如果要用dd的命令刷入HiNas作者提供的刷机包,需要提前将dd的img格式转为Android sparse image格式

分区表

[写在最前面]调试阶段建议把emmc的fastboot给删除

  • 手动刷系统时,务必把emmc的fastboot给删除,免得刷了系统没法开机还得刷机
  • dd if=/dev/zero of=/dev/mmcblk0p1 bs=1024 count=1024
  • 此时复制mv100-mdmo1a-usb-flash.zip中的fastboot.bin和自己生成的bootargs.bin到U盘
  • 通过复制不同的bootargs.bin到U盘中,决定开机后启动到哪个分区

修改HiNas的恢复分区

  • 在第一次能进入到9分区的HiNAS系统后
  • HiNAS的作者在7分区放置了一个精简的OP用于安装系统
  • 我们可以修改7分区的recovery系统为自己所用,方便我们手动不断尝试将新的系统flash到9分区上面去

配置7分区的网络为DHCP

  • cd /tmp
    mkdir 7
    mount /dev/mmcblk0p7 7
    #配置dhcp启动
    vi /tmp/7/etc/config/network
    #设置lan口为dhcp,屏蔽下面的内容
    option proto 'dhcp'
    #option gateway 
    #option ipaddr '
    #option dns
    

Hinas作者设置的密码不知道,替换为我们自己的密码

  • cp /etc/shadow /tmp/7/etc/shadow

去除7分区的自动装系统命令

  • 注释掉/tmp/7/etc/rc.local中的命令

删除掉mmc分区的fastboot

  • dd if=/dev/zero of=/dev/mmcblk0p1 bs=1024 count=1024

在U盘中放上fastboot.bin和启动到7分区的bootargs.bin

  • mkdir -p /tmp/mymount/a
    mount /dev/sda1 /tmp/mymount/
    cd /tmp/mymount/a
    mv bootargs.bin bootargs.flash.bin
    cp mv100/bootargs.bin .
    

插上U盘开机得到一个纯净的op环境

  • 进入路由器查看ip后,就可以http://ip/cgi-bin/luci
  • 也可以ssh到这个op上, 安装系统

在其他系统下可以备份一下7分区

  • 7分区目前的默认大小是16384=1024*64M
  • dd if=/dev/mmcblk0p7 of=op.base.64.bin bs=1024 count=16384 conv=fsync

在7分区的系统下向9分区刷HiNas系统

dd的方式刷入

mount /dev/mmcblk0p8 /tmp/8
gunzip -c /tmp/8/backup-32.gz  | dd of=/dev/mmcblk0p9 bs=1024

cp的方式刷入

gunzip -c /tmp/mymount/8/backup-32.gz > /tmp/mymount/a/Ubuntu-20.04.5-armhf-20240201-0d93d.img
mkdir ubuntu
mount -o loop  /tmp/mymount/a/Ubuntu-20.04.5-armhf-20240201-0d93d.img /tmp/mymount/ubuntu
mkfs.ext4 /dev/mmcblk0p9 
mkdir 9
mount /dev/mmcblk0p9 9
cp -a /tmp/mymount/ubuntu/*  /tmp/mymount/9/

此时显示的/dev/root更真实,而不是之前dd显示的3.6G

root@localhost:~# df -h
Filesystem      Size  Used Avail Use% Mounted on
/dev/root       3.0G  1.1G  1.8G  39% /
devtmpfs        337M     0  337M   0% /dev
tmpfs           338M     0  338M   0% /dev/shm
tmpfs            68M  808K   67M   2% /run
tmpfs           5.0M     0  5.0M   0% /run/lock
tmpfs           338M     0  338M   0% /sys/fs/cgroup
tmpfs           338M     0  338M   0% /tmp

刷op系统

hi-op的刷法

  • 使用神雕大佬的包hi-op
  • 不要使用dd,空间会很小,而是直接复制文件到大分区
  • 本次安装op到8分区,将9分区留着
  • 备份op系统,就把整个系统tar个包就行
gunzip -c /tmp/mymount/b/backup/openwrt-armvirt-32-root.ext4.gz > /tmp/mymount/b/backup/openwrt-armvirt-32-root.bin
mkdir /tmp/mymount/op
mount -o loop  /tmp/mymount/b/backup/openwrt-armvirt-32-root.bin /tmp/mymount/op
mkfs.ext4 /dev/mmcblk0p8 
mkdir /tmp/mymount/8
mount /dev/mmcblk0p8 /tmp/mymount/8
cp -a /tmp/mymount/op/* /tmp/mymount/8/

如果短期不刷机了,可以让系统默认从8分区启动

dd if=fastboot.bin of=/dev/mmcblk0p1 bs=1024 count=1024
dd if=bootargs8.bin of=/dev/mmcblk0p2 bs=1024 count=1024

op开机后的配置

  • 关闭lan的桥接,就直接用eth0就行
    mkfs.ext4 /dev/mmcblk0p9
    opkg install openssh-sftp-server htop
    #下载mihomo. https://github.com/MetaCubeX/mihomo/releases/download/v1.18.9/mihomo-linux-armv7-v1.18.9.gz
    gunzip mihomo-linux-armv7-v1.18.9.gz
    mv mihomo-linux-armv7-v1.18.9 mihomo
    #
    mkdir -p /etc/cndaqiang/openclash/
    mv mihomo /etc/cndaqiang/openclash/
    /etc/cndaqiang/openclash/mihomo -d /etc/cndaqiang/openclash/
    #添加开机启动
    (sleep 60; /etc/cndaqiang/openclash/mihomo -d /etc/cndaqiang/openclash/ &)
    #下载yacd解压到www,https://github.com/haishanh/yacd
    

openwrt/immortalwrt

  • 因为hi-op更新软件不方便
  • 自己重新编译了hi-op,发现op版本19.07太老了,很多软件不支持
  • 通过查找openwrt/immortalwrt的仓库中target为armvirt/32的设备,找到两个
    • 刷法同上面https://downloads.openwrt.org/releases/22.03.7//targets/armvirt/32/openwrt-22.03.7-armvirt-32-rootfs-ext4.img.gz
    • 刷法同上面https://downloads.immortalwrt.org/releases/21.02.7/targets/armvirt/32/immortalwrt-21.02.7-armvirt-32-rootfs-ext4.img.gz

再记录一遍刷immortalwrt的过程

cd /tmp
mkdir a
mount /dev/sda1 a
cd a/
#这次使用tar.gz的包
wget "http://mirrors.jlu.edu.cn/immortalwrt/releases/21.02.7/targets/armvirt/32/immortalwrt-21.02.7-armvirt-32-default-rootfs.tar.gz"
mkfs.ext4 /dev/mmcblk0p8 
mkdir 8
mount /dev/mmcblk0p8 8
tar -xzvf immortalwrt-21.02.7-armvirt-32-default-rootfs.tar.gz -C 8
sync

开机进入8的系统, 等系统初始化之后,(此时盒子是主路由模式)

  • 要么连交换机配置盒子
  • 要么重启进其他系统,修改/tmp/a/8/etc/config/network
    config interface 'lan'
          option device 'br-lan'
          option proto 'dhcp'
          #option proto 'static'
          #option ipaddr '192.168.1.1'
          #option netmask '255.255.255.0'
          #option ip6assign '60'
    
  • 再重启就能用了
  • 额外可选,取消lan口的桥接,而是采用eth0
  • 以后备份系统就整个系统tar个包
  • 此外务必设置双op救援,方法见下面的参考材料
  • 后续使用同OpenWRT编译配置:以CMCC RAX3000M为例
    src/gz immortalwrt_core https://mirrors.cernet.edu.cn/immortalwrt/releases/21.02.7/targets/armvirt/32/packages
    src/gz immortalwrt_base https://mirrors.cernet.edu.cn/immortalwrt/releases/21.02.7/packages/arm_cortex-a15_neon-vfpv4/base
    src/gz immortalwrt_luci https://mirrors.cernet.edu.cn/immortalwrt/releases/21.02.7/packages/arm_cortex-a15_neon-vfpv4/luci
    src/gz immortalwrt_packages https://mirrors.cernet.edu.cn/immortalwrt/releases/21.02.7/packages/arm_cortex-a15_neon-vfpv4/packages
    src/gz immortalwrt_routing https://mirrors.cernet.edu.cn/immortalwrt/releases/21.02.7/packages/arm_cortex-a15_neon-vfpv4/routing
    src/gz immortalwrt_telephony https://mirrors.cernet.edu.cn/immortalwrt/releases/21.02.7/packages/arm_cortex-a15_neon-vfpv4/telephony
    #
    opkg update
    opkg install luci-app-samba4 luci-app-qbittorrent luci-app-zerotier luci-theme-argon  openssh-sftp-server htop
    #https://github.com/vernesong/OpenClash/releases
    # opkg install luci-app-openclash_0.46.033-beta_all.ipk 
    

支持材料: 工具、方法、文件

ext4刷机文件simg与dd的文件img之间的格式转换

mv100/xxx.ext4的文件是稀疏镜像(sparse image)

cnche@HP MINGW64 /d/GreenSoft/HiNAS/mv100-mdmo1a-usb-flash/mv100
$ file.exe recoverybox32.ext4
recoverybox32.ext4: Android sparse image, version: 1.0, Total of 16384 4096-byte output blocks in 959 input chunks.

cnche@HP MINGW64 /d/GreenSoft/HiNAS/mv100-mdmo1a-usb-flash/mv100
$ file.exe www_ecoo_top.ext4
www_ecoo_top.ext4: Android sparse image, version: 1.0, Total of 131072 4096-byte output blocks in 25 input chunks.

dd能直接输入输出的是这样的文件系统

$ file.exe backup-32
backup-32: Linux rev 1.0 ext4 filesystem data, UUID=9ff69023-ba06-40dc-8be1-fa511ade1973 (extents) (64bit) (large files) (huge files)

两种文件格式之间的互相转换

(base) cndaqiang@vmnode:~/work/img2img$  sudo apt install android-sdk-libsparse-utils
(base) cndaqiang@vmnode:~/work/img2img$ file recoverybox32.ext4 
recoverybox32.ext4: Android sparse image, version: 1.0, Total of 16384 4096-byte output blocks in 959 input chunks.
(base) cndaqiang@vmnode:~/work/img2img$ simg2img recoverybox32.ext4 recoverybox32.ext4.img 
(base) cndaqiang@vmnode:~/work/img2img$ file recoverybox32.ext4.img 
recoverybox32.ext4.img: Linux rev 1.0 ext4 filesystem data, UUID=57f8f4bc-abf4-655f-bf67-946fc0f9f25b (extents) (large files)

转换之后就可以挂载了

root@hi3798m:/tmp/mymount/a/backup# dd if=www_ecoo_top.ext4.img of=/dev/mmcblk0p8 
root@hi3798m:/tmp# mount /dev/mmcblk0p8 8
root@hi3798m:/tmp# ls 8
backup-32.gz  lost+found

制作bootargs分区

  • 根据/etc/bootargs_input.txt修改root=/dev/mmcblk0p8,然后使用mkbootargs生成
  • 参考更改MAC网卡地址
echo "baudrate=115200
ethaddr=00:11:22:33:44:55
ipaddr=192.168.1.10
netmask=255.255.255.0
gatewayip=192.168.1.1
serverip=192.168.1.1
bootcmd=mmc read 0 0x1FFFFC0 0x7000 0xA000;bootm 0x1FFFFC0
bootargs_512M=mem=512M mmz=ddr,0,0,48M vmalloc=500M
bootargs_1G=mem=1G mmz=ddr,0,0,48M vmalloc=500M
bootargs_2G=mem=2G mmz=ddr,0,0,48M vmalloc=500M
bootargs_768M=mem=768M mmz=ddr,0,0,48M vmalloc=500M
bootargs_1536M=mem=1536M mmz=ddr,0,0,48M vmalloc=500M
bootargs_3840M=mem=3840M mmz=ddr,0,0,48M vmalloc=500M
bootargs=console=ttyAMA0,115200 root=/dev/mmcblk0p8 rootfstype=ext4 rootwait blkdevparts=mmcblk0:1M(boot),1M(bootargs),4M(baseparam),4M(pqparam),4M(logo),20M(kernel),64M(busybox),512M(backup),-(ubuntu)
bootdelay=0
stdin=serial
stdout=serial
stderr=serial" > /tmp/bootargs_input.txt

制作

mkbootargs -s 64 -r /tmp/bootargs_input.txt -o bootargs.bin
#dd if=bootargs.bin of=/dev/mmcblk0p2 bs=1024 count=1024

read-only的解决方案

  • 其实是硬件问题,mmc是坏的,换了U盘启动就没有这些问题了。
  • 下面是之前尝试的记录

触发read-only的事件

  • 重启
  • 开机之前插入了某个U盘,开机供电不足导致短暂io错误也有概率触发
  • 执行一个命令后,突然系统就变成read-only

开机变成readonly的一种解决办法:双op救援

  • 救援之后luci-提示rpc错误,则/etc/init.d/rpcd restart
  • 虽然下面的可以启动了,但是时不时还有各种异常,比如luci等软件打不开了,系统使用过程中突然就read-only了,文件无法删除创建
  • 在8分区的op出问题后利用7分区的op进行救援

7系统的/etc/rc.local

/usr/sbin/fsck.ext4 -y /dev/mmcblk0p8
/usr/sbin/fsck.ext4 -y /dev/mmcblk0p9
#其他分区无法启动时,会创建这个文件
if [ -f /reboot ]
then
dd if=/etc/bootargs/bootargs8.bin of=/dev/mmcblk0p2  bs=1024 count=1024;sync
rm -rf /reboot
touch /tmp/rebootTommc0p8
reboot 
fi
exit 0

8系统的/etc/rc.local

touch /test.read.only.pass
if [ $? -ne 0 ];then
echo 只读系统
mkdir /tmp/7
mount /dev/mmcblk0p7 /tmp/7
dd if=/tmp/7/etc/bootargs/bootargs7.bin of=/dev/mmcblk0p2  bs=1024 count=1024;sync
touch /tmp/7/reboot
sync
umount /tmp/7
touch /tmp/read.only
reboot
fi
rm -rf /test.read.only.pass
#有时候需要执行
/etc/init.d/rpcd restart

8系统增加一个提示,/etc/profile

if [ -f /tmp/read.only ]
then
echo read-only, you need reboot.
fi

上面形成了自动修复循环.可以使用mmc启动

dd if=/etc/bootargs/fastboot.bin of=/dev/mmcblk0p1 bs=1024 count=1024
dd if=/etc/bootargs/bootargs7.bin of=/dev/mmcblk0p2 bs=1024 count=1024

op中查看UUID

root@mv100:~# block info
/dev/mmcblk0p7: UUID="57f8f4bc-abf4-655f-bf67-946fc0f9f25b" VERSION="1.0" TYPE="ext4"
/dev/mmcblk0p8: UUID="1dfa27bf-e971-43bf-ac3a-92f4fbee7e93" VERSION="1.0" MOUNT="/" TYPE="ext4"
/dev/mmcblk0p9: UUID="3d258aa0-f51a-4f6a-ae0c-fe385ad0f653" VERSION="1.0" TYPE="ext4"
/dev/sda1: UUID="0000-0000" LABEL="SANDISK" VERSION="FAT32" TYPE="vfat"
/dev/sdb1: UUID="4E21-0000" LABEL="ToolBox" TYPE="exfat"
/dev/sdb2: UUID="223C-F3F8" LABEL="VTOYEFI" VERSION="FAT16" TYPE="vfat"

本文首发于我的博客@cndaqiang.
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!


类似文章

目录

访客数据