U-Boot 如何从这种环境中引导 Linux?

逆向工程 嵌入式
2021-06-30 14:49:10

我正在尝试获得对我的中兴 F680 路由器的根访问权限。我已经有一个串行连接并且能够中断 U-Boot 自动启动。我遇到的问题是了解在以下环境中 U-Boot 是如何启动 Linux 的,而当我尝试在其 shell 中运行相同的命令时却失败了。环境:

CASset=max
EMAC=EMAC0
MACMODE=GMII
MALLOC_len=5
MPmode=SMP
amp_enable=no
autoload=no
baudrate=115200
boot_order=hd_scr hd_img pxe net_img net_scr
bootargs_dflt=$console $mtdparts $bootargs_root nfsroot=$serverip:$rootpath ip=$ipaddr:$serverip$bootargs_end $mvNetConfig video=dovefb:lcd0:$lcd0_params clcd.lcd0_enable=$lcd0_enable clcd.lcd_panel=$lcd_panel
bootargs_end=:10.4.50.254:255.255.255.0:AvantaLP:eth0:none
bootargs_root=root=/dev/nfs rw
bootcmd=setenv bootargs console=ttyS0,115200 root=/dev/ram0 rw load_ramdisk=1 rdinit=/sbin/init mv_switch_config=none memsize=$(memsize) mem=$(memsize); bootm 0x2000100;
bootdelay=3
bootfile=uboot.bin
bootsize=0x60000
cacheShare=no
console=console=ttyS0,115200
device_partition=0:1
disL2Cache=yes
disL2Prefetch=yes
disaMvPnp=no
eeeEnable=no
enaClockGating=no
enaCpuStream=no
enaDCPref=yes
enaFPU=yes
enaICPref=yes
enaMonExt=no
enaWrAllo=no
eth1addr=00:50:43:00:02:02
eth1mtu=1500
eth2addr=00:50:43:00:00:02
eth2mtu=1500
eth3addr=00:50:43:02:00:00
eth3mtu=1500
ethact=egiga0
ethaddr=00:50:43:00:02:02
ethmtu=1500
ethprime=egiga0
fdt_addr=2040000
flashsize=134217728
fullfile=upgrade.bin
ide_path=/
image_name=uImage
initrd_name=uInitrd
ipaddr=192.168.1.1
kernel_addr_r=2080000
kernelsize=0x16000000
lcd0_enable=0
lcd0_params=640x480-16@60
lcd_panel=0
linuzfile=vmlinuz.bin
loadaddr=0x02000000
loads_echo=0
memsize=253M
mtddevname=boot
mtddevnum=0
mtdids=nand0=mvebu-nand
mtdparts=mtdparts=mvebu-nand:1536k@0(boot),512k(env),20m(kernel0),20m(kernel1),6m(others),4m(parameter),8m(usercfg),4m(middleware),4m(wlan)
mvNetConfig=mv_switch_config=none
mv_pon_addr=00:50:43:02:00:00
nandEcc=1bit
nand_erasesize=20000
nand_oobsize=40
nand_writesize=800
netbsd_en=no
netdev=mii0
netmask=255.255.255.0
netretry=no
partition=nand0,0
pcieTune=no
pexMode=RC
pxe_files_load=:default.arm-armadaxp-db:default.arm-armadaxp:default.arm
pxefile_addr_r=3100000
ramdisk_addr_r=2880000
rcvr_image=rootfs.squashfs.rcvr.img
rootfile=rootfs.img
rootpath=/srv/nfs/
sata_delay_reset=0
sata_dma_mode=yes
script_addr_r=3000000
script_name=boot.scr
serverip=192.168.1.100
setL2CacheWT=no
silent=0
standalone=fsload 0x2000000 $image_name;setenv bootargs $console $mtdparts root=/dev/mtdblock0 rw ip=$ipaddr:$serverip$bootargs_end; bootm 0x2000000;
stderr=serial
stdin=serial
stdout=serial
versioninfo=U-Boot V2.0.10T5 0x1600000 0x1 0x82 0x87
vxworks_en=no
yuk_ethaddr=00:00:00:EE:51:81

Environment size: 2586/131068 bytes

从我的选择来看,第2 阶段应该加载boot.scr脚本,然后执行bootcmd. 但是尝试在 shell 中执行此操作失败。尝试运行boot.scr声明此地址没有有效图像并加载它fsload失败:

### JFFS2 loading 'boot.scr' to 0x3000000
Scanning JFFS2 FS:  done.
find_inode failed for name=boot.scr
load: Failed to find inode

分区表确实存在:

=> mtdparts
mtdparts

device nand0 <mvebu-nand>, # parts = 9
 #: name        size        offset      mask_flags
 0: boot                0x000000180000      0x000000000000      0
 1: env                 0x000000080000      0x000000180000      0
 2: kernel0             0x000001400000      0x000000200000      0
 3: kernel1             0x000001400000      0x000001600000      0
 4: others              0x000000600000      0x000002a00000      0
 5: parameter           0x000000400000      0x000003000000      0
 6: usercfg             0x000000800000      0x000003400000      0
 7: middleware          0x000000400000      0x000003c00000      0
 8: wlan                0x000000400000      0x000004000000      0

但是列出其中任何一个都ls没有结果:

=> ls
Scanning JFFS2 FS:  done.

我想知道 U-Boot 是否是在没​​有某些命令(即fdt缺少命令)或某些硬编码启动序列的情况下编译的如果我不中断自动启动,它看起来像这样:

Hit any key to stop autoboot:  0
flash block_size is 0x20000
flash size(search addredd) is 0x8000000
search.c,372,do_search: search->result[index].entry = 0x200100
search.c,372,do_search: search->result[index].entry = 0x1600100
do_search ending
do_startup() start
select=0x1
search->result[select].entry=1600100
search->result[1].entry = 0x1600100
do_startup() ending
do_settings() start
do_setting versioninfo
btNumbers is V2.0.10T5
## Booting kernel from Legacy Image at 02000100 ...
   Image Name:   Linux Kernel Image
   Created:      2017-10-25   9:10:20 UTC
   Image Type:   ARM Linux Kernel Image (gzip compressed)
   Data Size:    15128571 Bytes = 14.4 MiB
   Load Address: 00008000
   Entry Point:  00008000
   Verifying Checksum ... OK
   Uncompressing Kernel Image ... OK
|-->setup versioninfo tag...versioninfo is U-Boot V2.0.10T5 0x1600000 0x1 0x82 0x87

Starting kernel ...
1个回答

差不多两年后,我不得不再次这样做,这次我记录了我的过程!看起来 U-Boot 有一个脚本(可能是为中兴通讯定制的),它扫描 NAND 内存以搜索图像,然后将其加载到内存中。这部分在此处的日志中可见:

search.c,372,do_search: search->result[index].entry = 0x200100
search.c,372,do_search: search->result[index].entry = 0x1600100
do_search ending
do_startup() start
select=0x1
search->result[select].entry=1600100
search->result[1].entry = 0x1600100
do_startup() ending

我不确定如何调用此脚本,但我设法手动加载了图像。首先我记下了地址:闪存中的图像:

search->result[select].entry=1600100

和它跳转到的内存:

## Booting kernel from Legacy Image at 02000100 ...

由于加载必须与页面对齐,我最终从0x1600000into加载0x2000000唯一缺少的部分是nand load命令的大小,但我认为整个分区就足够了,所以我只是从mtdparts命令中获取值并最终得到:

> nand read 0x2000000 0x1600000 0x1400000

现在加载图像后,我可以,run bootcmd但我想获得 root 访问权限,因此我bootargs通过添加single以在单用户模式下启动它来对它进行了小的调整

> setenv bootargs console=ttyS0,115200 root=/dev/ram0 rw load_ramdisk=1 rdinit=/sbin/init mv_switch_config=none memsize=$(memsize) mem=$(memsize) single
> bootm 0x2000100

我希望这个答案对支持这个问题的两个人和任何未来的访问者都有用