终于不用不停地插拔SD卡更新程序了。。。Milk-v duo u-boot 支持 tftp 下载kernel

milk-v duo 原厂 SDK 的 u-boot 应该是直接作为正式生产环境使用的文件,默认没有支持网络相关命令和 tftp 和 nfs 功能。在开发阶段需要频繁更新 kernel,如果一直通过烧录 SD 卡方式更新未免效率太低了,通常做法是在开发阶段在 u-boot 下通过网络从主机上下载 kernel,然后测试运行。待测试完成后将 u-boot 相关配置关闭,正式打包作为生产文件发布。

今天尝试修改 u-boot 配置,开启 tftp 功能下载主机上的 kernel 文件至 SD 卡,并运行。

1、u-boot 运行

在系统启动后 u-boot 倒计时阶段,按回车即可进入 u-boot 命令行。

FSBL Jb28g9:g326b1882f-dirty:2024-01-31T16:56:56+08:00
st_on_reason=4090003
st_off_reason=0
P2S/0x1000/0x3bc0da00.
SD/0xca00/0x1000/0x1000/0.P2E.
DPS/0xda00/0x2000.
SD/0xda00/0x2000/0x2000/0.DPE.
DDR init.
ddr_param[0]=0x78075562.
pkg_type=3
D3_1_4
DDR2-512M-QFN68
Data rate=1333.
DDR BIST PASS
PLLS.
PLLE.
C2S/0xfa00/0x83f40000/0x3800.
SD/0xfa00/0x3800/0x3800/0.RSC.
C2E.
MS/0x13200/0x80000000/0x1b000.
SD/0x13200/0x1b000/0x1b000/0.ME.
L2/0x2e200.
SD/0x2e200/0x200/0x200/0.L2/0x414d3342/0xcafea8ef/0x80200000/0x22000/0x22000
COMP/1.
SD/0x2e200/0x22000/0x22000/0.DCP/0x80200020/0x1000000/0x81500020/0x22000/1.
DCP/0x47405/0.
Loader_2nd loaded.
Use internal 32k
Jump to monitor at 0x80000000.
OPENSBI: next_addr=0x80200020 arg1=0x80080000
OpenSBI v0.9
   ____                    _____ ____ _____
  / __ \                  / ____|  _ \_   _|
 | |  | |_ __   ___ _ __ | (___ | |_) || |
 | |  | | '_ \ / _ \ '_ \ \___ \|  _ < | |
 | |__| | |_) |  __/ | | |____) | |_) || |_
  \____/| .__/ \___|_| |_|_____/|____/_____|
        | |
        |_|

Platform Name             : Cvitek. CV180X ASIC. C906.
Platform Features         : mfdeleg
Platform HART Count       : 1
Platform IPI Device       : clint
Platform Timer Device     : clint
Platform Console Device   : uart8250
Platform HSM Device       : ---
Platform SysReset Device  : ---
Firmware Base             : 0x80000000
Firmware Size             : 132 KB
Runtime SBI Version       : 0.3

Domain0 Name              : root
Domain0 Boot HART         : 0
Domain0 HARTs             : 0*
Domain0 Region00          : 0x0000000074000000-0x000000007400ffff (I)
Domain0 Region01          : 0x0000000080000000-0x000000008003ffff ()
Domain0 Region02          : 0x0000000000000000-0xffffffffffffffff (R,W,X)
Domain0 Next Address      : 0x0000000080200020
Domain0 Next Arg1         : 0x0000000080080000
Domain0 Next Mode         : S-mode
Domain0 SysReset          : yes

Boot HART ID              : 0
Boot HART Domain          : root
Boot HART ISA             : rv64imafdcvsux
Boot HART Features        : scounteren,mcounteren,time
Boot HART PMP Count       : 16
Boot HART PMP Granularity : 4096
Boot HART PMP Address Bits: 38
Boot HART MHPM Count      : 8
Boot HART MHPM Count      : 8
Boot HART MIDELEG         : 0x0000000000000222
Boot HART MEDELEG         : 0x000000000000b109


U-Boot 2021.10 (Jan 31 2024 - 17:41:26 +0800)cvitek_cv180x

DRAM:  63.3 MiB
gd->relocaddr=0x8242d000. offset=0x222d000
MMC:   cv-sd@4310000: 0
Loading Environment from <NULL>... OK
In:    serial
Out:   serial
Err:   serial
Net:   
Warning: ethernet@4070000 (eth0) using random MAC address - 46:dc:c9:0e:cb:72
eth0: ethernet@4070000
Hit any key to stop autoboot:  0 
cv180x_c906# 

u-boot 环境变量打印

cv180x_c906# printenv
baudrate=115200
bootcmd=run sdboot
bootdelay=1
consoledev=ttyS0
fdtcontroladdr=81be6cf0
gatewayip=192.168.0.11
ipaddr=192.168.0.3
netdev=eth0
netmask=255.255.255.0
othbootargs=earlycon=sbi riscv.fwsz=0x80000  loglevel=9
root=root=/dev/mmcblk0p2 rootwait rw
sdboot=setenv bootargs ${reserved_mem} ${root} ${mtdparts} console=$consoledev,$baudrate $othbootargs;echo Boot from SD ...;mmc dev 0 && fatload mmc 0 ${uImage_addr} boot.sd; if test $? -eq 0; then bootm ${uImage_addr}#config-cv1800b_milkv_duo_sd;fi;
serverip=192.168.56.101
stderr=serial
stdin=serial
stdout=serial
uImage_addr=0x81400000
update_addr=0x82473000

Environment size: 620/131068 bytes

其中:
bootcmd 为 run sdboot
bootargs:为 ${reserved_mem} ${root} ${mtdparts} console=$consoledev,$baudrate $othbootargs;echo Boot from SD ...;mmc dev 0 && fatload mmc 0 ${uImage_addr} boot.sd; if test $? -eq 0; then bootm ${uImage_addr}#config-cv1800b_milkv_duo_sd;fi;

手动引导 Linux

可通过 run sdboot 命令手工启动 Linux 内核。
然后分解 bootargs 可以得到以下命令:

setenv bootargs root=/dev/mmcblk0p2 rootwait rw console=ttyS0,115200,earlycon=sbi riscv.fwsz=0x80000 loglevel=9
mmc dev 0
fatload mmc 0 81400000 boot.sd
bootm 81400000#config-cv1800b_milkv_duo_sd

依次执行以上命令,也同样启动了 Linux 内核。

2、编译 u-boot

在 build/boards/cv180x/cv1800b_milkv_duo_sd/u-boot/cvitek_cv1800b_milkv_duo_sd_defconfig 文件中加入以下配置:

CONFIG_CMD_NET=y
CONFIG_CMD_TFTPBOOT=y
CONFIG_NET_TFTP_VARS=y
CONFIG_CMD_NFS=y
CONFIG_CMD_PING=y

然后运行 ./build.sh milkv-duo 一键编译。

由于一键编译时间较久,也可以采用分布编译,在 bash 下依次输入如下命令:

$ source device/milkv-duo/boardconfig.sh
$ source build/milkvsetup.sh
$ defconfig cv1800b_milkv_duo_sd
$ build_fsbl

注:如果使用 zsh 分步编译有可能失败,须切换至 bash。

编译完成后文件在 fsbl/build/cv1800b_milkv_duo_sd/fip.bin,覆盖原 SD 卡中的 fip.bin 文件即可。

3、tftp-server 设置

我是在 Windows 下使用 tftpd64 搭建tftp server,

tftp-server

  1. 点击 Browse 按钮至 milkv-duo 内核文件 boot.sd 在的文件夹。

  2. 可点击 Show Dir 查看当前文件夹下文件。

4、u-boot运行

网络设置

  1. 依照步骤一,进入 u-boot 命令行,依次设置网络相关的环境变量:
cv180x_c906# setenv ipaddr 192.168.31.180
cv180x_c906# setenv serverip 192.168.31.35
cv180x_c906# setenv netmask 255.255.255.0
cv180x_c906# setenv gatewayip 192.168.31.1

注:IP 地址请根据实际情况修改。

  1. 完成配置后,可使用 ping 命令测试当前网络连接情况:
cv180x_c906# ping 192.168.31.35
Speed: 100, full duplex
Using ethernet@4070000 device
host 192.168.31.35 is alive

显示网络正常。

Kernel 下载

在 u-boot 命令行下输入:

cv180x_c906# tftpboot 81400000 boot.sd
Speed: 100, full duplex
Using ethernet@4070000 device
TFTP from server 192.168.31.35; our IP address is 192.168.31.180
Filename 'boot.sd'.
Load address: 0x81400000
Loading: #################################################################
         #################################################################
         #################################################################
         ##
         482.4 KiB/s
done
Bytes transferred = 2891672 (2c1f98 hex)

通过 tftp 将 boot.sd 下载到内存 0x81400000 地址处,0x81400000 为 Linux Kernel 地址。

如不想存储当前 boot.sd 文件至 SD 卡,运行以下命令直接在内存中运行:

cv180x_c906# bootm 81400000#config-cv1800b_milkv_duo_sd

Kernel 存储

将下载完成的 kernel 文件保存至 SD 卡。

cv180x_c906# fatwrite mmc 0 81400000 boot.sd 2c1f98

通过 fatwrite 命令将 0x81400000 地址处大小为 0x2c1f98 大小的文件保存为 boot.sd 文件。

注:u-boot 相关文件可查阅其他文件。

[Todo]:目前还未解决 u-boot 下 saveenv 命令,无法保存当前配置的环境变量。

2 Likes

可以挂载 tf卡启动分区替换升级 内核 参考

fdisk -l

Device         Boot  Start      End  Sectors  Size Id Type
/dev/mmcblk0p1 *         1   262144   262144  128M  c W95 FAT32 (LBA)
/dev/mmcblk0p2      262145 61445215 61183071 29.2G 83 Linux

mkdir -p boot
mount /dev/mmcblk0p1 boot

7z  x  ~/duo256_WireGuard.zip
1 Like

修改uboot源代码,把uboot参数埋到源代码里面。

cv181x_c906# bootm 81400000

Loading kernel from FIT Image at 81400000 …

Could not find configuration node
ERROR: can’t get kernel image!

bootm 0x81800000#config-cv1812cp_milkv_duo256m_sd 即可