第8章 zynq uboot更新系统镜像并引导启动和个人心得


文章目录


前言

由于本人较懒,记录主要是过程,由于zynq的比stm32做的人少很多,资料也少很多,我会简要介绍原理,操作流程主要由图片加少量文字组成,每一章都是在之前的章节基础上做的


上一章成功启动了linux系统,这一章在uboot下更新sd卡镜像并启动

一、精简和修改uboot环境变量

默认uboot的启动命令为run $modeboot || run distro_bootcmd,而modebootboard/xilinx/zynq/board.c中的board_late_init会根据启动模式来选择,distro_bootcmd则是在前者启动失败后进行一系列的启动测试,而我们使用的启动模式并非标准,因此将其修改为

之所以选择从sd卡启动而不用nand,是因为nand坏块管理起来比较麻烦,而且sd卡速度更快。修改include/configs/zynq-common.h内的环境变量,添加IP地址和升级命令,删除大部分用不到的环境变量

c 复制代码
#define CONFIG_EXTRA_ENV_SETTINGS	\
	"ethaddr=00:0a:35:00:01:22\0"	\
	"ipaddr=192.168.0.10\0" \
	"serverip=192.168.0.11\0" \
	"kernel_image=uImage\0"	\
	"kernel_load_address=0x2080000\0" \
	"ramdisk_image=rootfs.cpio.uboot\0"	\
	"ramdisk_load_address=0x4000000\0"	\
	"devicetree_image=system-top.dtb\0"	\
	"devicetree_load_address=0x2000000\0"	\
	"bitstream_image=design_1_wrapper.bit\0"	\
	"loadbit_addr=0x100000\0"	\
	"boot_image=BOOT.bin\0"	\
	"bootenv=uEnv.txt\0" \
	"mmc_loadbit=echo Loading bitstream from SD/MMC/eMMC to RAM.. && " \
		"mmcinfo && " \
		"load mmc 0 ${loadbit_addr} ${bitstream_image} && " \
		"fpga loadb 0 ${loadbit_addr} ${filesize}\0" \
	"sdboot=if test -e mmc 0 /design_1_wrapper.bit; then run mmc_loadbit;fi;" \
		"echo Copying Linux from SD to RAM... && " \
		"load mmc 0 ${kernel_load_address} ${kernel_image} && " \
		"load mmc 0 ${devicetree_load_address} ${devicetree_image} && " \
		"load mmc 0 ${ramdisk_load_address} ${ramdisk_image} && " \
		"bootm ${kernel_load_address} ${ramdisk_load_address} ${devicetree_load_address}\0 " \
	"jtagboot=echo TFTPing Linux to RAM... && " \
		"tftpboot ${kernel_load_address} ${kernel_image} && " \
		"tftpboot ${devicetree_load_address} ${devicetree_image} && " \
		"tftpboot ${ramdisk_load_address} ${ramdisk_image} && " \
		"bootm ${kernel_load_address} ${ramdisk_load_address} ${devicetree_load_address}\0" \
	"up_bin=tftpboot 80000 ${boot_image} &&  nand erase 0 ${filesize} && nand write 80000 0 ${filesize} \0" \
	"up_kernel=tftpboot ${kernel_load_address} ${kernel_image} && " \
		"fatwrite mmc 0:1 ${kernel_load_address} ${kernel_image} ${filesize} \0" \
	"up_tree=tftpboot ${devicetree_load_address} ${devicetree_image} && " \
		"fatwrite mmc 0:1 ${devicetree_load_address} ${devicetree_image} ${filesize}  \0" \
	"up_rootfs=tftpboot ${ramdisk_load_address} ${ramdisk_image} && " \
		"fatwrite mmc 0:1 ${ramdisk_load_address} ${ramdisk_image} ${filesize} \0" \
	"up_fpga=tftpboot ${loadbit_addr} ${bitstream_image} && " \
		"fatwrite mmc 0:1 ${loadbit_addr} ${bitstream_image} ${filesize} \0" \
	"up_all_boot=run up_kernel && run up_tree && run up_rootfs && " \
		"run sdboot \0"

修改完重新生成uboot和BOOT.bin,烧录重启后发现环境变量没有变化,这是因为之前执行了saveenv保存了旧的环境变量,每次启动都会默认加载,此时输入env default -a便会使用uboot内的环境变量,再执行saveenv保存

删除后的环境变量仅2153bytes

二、更新系统镜像

输入run up_all_boot即可更新系统镜像,烧录完会从sd上启动

之后每次重启都会自动从sd卡加载系统镜像启动,需要更新系统镜像时只需执行对应的run up_*即可

三、关于uboot的简单个人心得

芯片启动开始时,芯片会根据内部ROM代码,对时钟和存储器初始化,根据启动引脚选择启动方式从相应的器件启动,大部分由于内部内存小无法正常运行uboot,在uboot之前还有一级启动程序(像spl或fsbl)来对DDR初始化和管理,等到了uboot时几乎可以操作所有的硬件来完成简单的程序,类似于裸机开发

很多硬件如果只需要做一次初始化就可以在uboot下通过指令脚本来实现。像I2C、SPI等这些外设的读写测试都很适合在uboot下完成,很多裸机程序修改为uboot程序较linux简单许多

在uboot引导系统时也有很多操作可以秀,像多系统、系统冗余,除了Linux,也可以引导其他系统像vx,或者直接运行裸机程序

四、常见的启动失败的原因分析

1、开机没有任何反应

在硬件没有问题时,首先要考虑ddr和串口配置有问题,建议先运行裸机测试程序测试,再打开调试信息查看,分析卡在哪一步

2、uboot卡在某一行

通过复制打印信息在源码里查找,一步一步很容易查到卡在哪,因为uboot的流程较短,熟悉后很容易查到问题处,这也是我喜欢用uboot而不是uefi的原因,解决问题很有成就感,然而对项目来说好像这并不重要。这也是软件开发很悲哀的一个点,大量的重复性没有成就感的项目很容易消磨一个人的好奇心导致技术停滞不前,然后陷入担忧中年危机的死循环之中。还是要钻研的深一点才好打动技术面试人的心


总结

主要介绍了zynq uboot更新系统镜像并引导启动和个人心得

参考

相关推荐
szxinmai主板定制专家5 小时前
基于ARM+FPGA的无人机数据采集卡,6通道24bit采集
arm开发·嵌入式硬件·fpga开发·无人机·能源
贝塔实验室6 小时前
QPSK信号载波同步技术---四相Costas 环法
数学建模·fpga开发·硬件工程·动态规划·信息与通信·信号处理·傅立叶分析
bnsarocket12 小时前
Verilog和FPGA的自学笔记2——点亮LED
笔记·fpga开发·verilog·自学
易享电子18 小时前
基于单片机智能台灯(调光,时钟)系统Proteus仿真(含全部资料)
单片机·嵌入式硬件·fpga开发·51单片机·proteus
电子凉冰19 小时前
FPGA强化-串口RS485
fpga开发
ShiMetaPi20 小时前
操作【GM3568JHF】FPGA+ARM异构开发板 使用指南:音频接口
arm开发·嵌入式硬件·fpga开发·rk3568
码不停蹄Zzz21 小时前
xdma IP使用教程1-xdma ip核配置
网络协议·tcp/ip·fpga开发
易享电子1 天前
基于单片机电器断路器保护器系统Proteus仿真(含全部资料)
单片机·嵌入式硬件·fpga开发·51单片机·proteus