rootfs为jffs2格式,挂载为只读。看了启动脚本,没有找到可以利用的地方来调用其他可写分区的脚本,于是尝试修改分区后再写回闪存。

挂载jffs2镜像的方法可以参考这里:https://elinux.org/Mount_jffs2,修改开机自启动脚本/etc/rcS.d/S99modules,在最后加上

sleep 10
/userconfig/start.sh &
sleep 20
/mnt/usb1_1/start.sh &

目的就是开机后自动调用可写分区/userconfig和优盘根目录下的start.sh脚本,这样就方便我们以后随时在start.sh加入自定义的内容,即使恢复出厂telnet被关闭也可以插上优盘自动运行任意命令。修改完后umount,把/dev/mtd0 dd成rootfs_mod.bin,放到opentftpserver目录下,准备下载到光猫闪存内

rootfs分区在闪存中的位置为0x1920000-0x3e00000,size: 0x024e0000,被包含在kernel1分区内,kernel2和kernel1内容完全相同。

tftp 0x88000000 rootfs_mod.bin
nand erase 0x1920000 0x024e0000
nand write 0x88000000 0x1920000 0x024e0000
reset

报错如下

vmlinuz crc error 0x9932f447
Failture: boot kernel

说明kernel分区有crc校验,修改内容后就通不过校验,搜索到一篇文章有提到:http://www.chinadsl.net/forum.php?mod=viewthread&tid=168275

把修改后的rootfs_mod分区替换到kernel1分区内的对应位置,找到kernel1分区中的crc校验位应该在0x150-0x153,替换成前述启动错误日志中给出的值0x9932f447,写回光猫,启动,报错如下:

zboot info init done!
header crc error,add=0x01600000
header crc error,add=0x03e00000
none fully-formed version
Erro: do_search  failed
Failture: boot kernel

中兴不仅校验kernel分区的内容,还要校验用来校验分区的header部分,双层套娃验证,和上述帖子中的情况不同,F7607P的uboot并没有给出计算出来的正确crc校验值。猜测存储此校验值的位置在0x1e0-0x1e3,后面跟着编译日期。遗憾的是并不知道校验方式和范围,只能作罢。尝试修改不同位置的值再写回光猫启动,发现校验范围至少包括0x0-0x1df,但是校验方式不清楚。再尝试修改了一位校验范围外的值写回光猫,这次不报header crc error了,又来个这个

verify vmlinuz success!!
RSA Verify error!
Failture: boot kernel

我服了你中兴,还有RSA签名,三层套娃验证,原来分区头部的那一串怪怪的东西是RSA签名。

至此彻底放弃了这条路,想看看能不能绕过所有验证直接启动kernel,printenv看到bootcmd为

bootcmd=setenv bootargs console=$(console) swiotlb=128 root=/dev/mtdblock12 ro rootfstype=jffs2 pcie_pme=nomsi  vid=15 mem=$(memsize);bootm 0x88000240;

正常启动过程日下:

Hit any key to stop autoboot:  0
rx data disable
zboot info init done!
select=0x0
<nand_read_skip_bad_,1199>!mtdpart=0x6,offset=0x0,mtdpartoffset=0x200000,mtdPartsize=0x200000,length=0x1000
tmp=0x00000001, value=1
select=0x1
search=0x2
search->result[1].entry=3e00240,offset=240
<nand_read_skip_bad_,1199>!mtdpart=0x3,offset=0x0,mtdpartoffset=0x3e00000,mtdPartsize=0x2800000,length=0x1d60000
verify vmlinuz success!!
RSA Verify OK
start 3e00000-6600000
no jffs2 found!
<nand_read_skip_bad_,1199>!mtdpart=0x0,offset=0x0,mtdpartoffset=0x0,mtdPartsize=0x180000,length=0xc0000
lseek=0x8c088430
cmdline=U-Boot V2.0.5P1N1 20211203105956
Saving Environment to NAND...
Erasing 0x180000 - 0x1a0000:<nand_erase_skip_bad_,1397>!mtdpart=0x1,start=0x0,mtdpartoffset=0x180000,mtdPartsize=0x80000,length=0x20000
                [Done]
Writing to Nand:<nand_write_skip_bad_,1292>!mtdpart=0x1,offset=0x0,mtdpartoffset=0x180000,mtdPartsize=0x80000,length=0x20000
                [Done]
kernel start step1..images->state:70f
    ==BOOTM_STATE_START:1
    ==BOOTM_STATE_FINDOS:2
## Loading kernel from FIT Image at 88000240 ...
   Using 'conf@132SG' configuration
   Trying 'kernel@A53' kernel subimage
     Description:  Unify(TODO) Linux kernel for project-131G
     Type:         Kernel Image
     Compression:  lzma compressed
     Data Start:   0x88000348
     Data Size:    3198889 Bytes = 3.1 MiB
     Architecture: AArch64
     OS:           Linux
     Load Address: 0x80080000
     Entry Point:  0x80080000
   Verifying Hash Integrity ... OK
    ==BOOTM_STATE_FINDOTHER:4
## Loading fdt from FIT Image at 88000240 ...
   Using 'conf@132SG' configuration
   Trying 'fdt@132SG' fdt subimage
     Description:  Flattened Device Tree blob for project-132SG
     Type:         Flat Device Tree
     Compression:  uncompressed
     Data Start:   0x8830d3e0
     Data Size:    35163 Bytes = 34.3 KiB
     Architecture: AArch64
   Verifying Hash Integrity ... OK
   Booting using the fdt blob at 0x8830d3e0
    ==BOOTM_STATE_LOADOS:8
   Uncompressing Kernel Image ... OK
kernel start step6..
   Loading Device Tree to 0000000083ff4000, end 0000000083fff95a ... OK

Starting kernel ...

first spin
first spin
first spin
first spin
CPUID:0 cpunoline 1 nucpus 4 try wake up secondary cpu from rom.
CPUID:1  wake up from rom.
CPUID:2  wake up from rom.
CPUID:3  wake up from rom.
init psci ok!!
cpu 1 power on
cpu 1 has been powered on
cpu 2 power on
cpu 2 has been powered on
cpu 3 power on
cpu 3 has been powered on

可以看到启动的初始位置在kernel分区的0x240处,直接把分区读入内存然后跳到这个位置启动呢?

nand read 0x88000000 0x1600000 0x2800000
bootm 0x88000240

它真的绕过了所有验证,直接启动了内核,直到这里

cpu 1 power on
cpu 1 has been powered on
cpu 2 power on
cpu 2 has been powered on
cpu 3 power on
cpu 3 has been powered on

启动日志都和正常启动一模一样,然后没有任何预兆到这里又自动重启了,连个查找问题的线索都没有

至此彻底放弃,写回原始的分区镜像,装上外壳插上光纤继续使用。