环境
- hdf设计:vivado 2017.4套件
- 交叉编译环境: arm-linux-gnueabihf-
- 虚拟机Linux系统版本:ubuntu 16.04
- 开发板:ALINX AX7Z100 开发板(ZYNQ7100)
Zynq Linux系统启动流程
Linux移植流程和思路
不使用petalinux工具,尽管它提升了开发效率,能直接生成BOOT.BIN
和image.ub
但是这种方法既不利于学习移植过程,又不灵活,一旦有什么新的需要就得重新编译
嵌入式Linux系统移植主要由四大部分组成:
- 搭建交叉编译开发环境
- bootloader的选择和移植
- kernel的配置、编译、和移植
- 根文件系统的制作
整体的思路如图,即将比特流文件system.bit
从BOOT.BIN
文件中分离出来,同时将fbsl
镜像和u-boot
镜像合成BOOT.bin
文件
将内核镜像文件zImage
、内核设备树system.dtb
文件以及根文件系统rootfs
从image.ub
中分离出来
将SD卡格式化并划分为FAT32
和EXT4
两个区,分别启动镜像和根文件系统
本文主要来移植 bootloader,最常用的是U-BOOT
,下面就让我们开始吧
目标:编译出 u-boot
镜像文件
SDK由hdf文件得到设备树文件
下载设备树源码
下载地址为:https://github.com/Xilinx/device-tree-xlnx/tags,我这里下载的是2017.4版本的
准备hdf文件
vivado里面设计,编译导出生成hdf文件
生成设备树文件
- 解压设备树源码,拷贝到SDK安装目录下
2.windows下打开SDK,工具栏 Xilinx–>Preferences 配置Repositories, New一个,添加刚才的设备树源码路径
3.新建BSP (File–>new–>Board Support Package),选择hdf文件,finish
4.生成device tree,finish,弹出一个BSP settings窗口,默认选项,然后OK
5.在device_tree_bsp_0目录下查看生成的设备树文件,红框内的文件后续还有用
U-BOOT的移植
下载u-boot源码
下载地址为:https://github.com/Xilinx/u-boot-xlnx/releases,我这里下载的是2017.4版本的
添加自己的板子
1.解压源码 tar -zxvf u-boot-xlnx-xilinx-v2017.4.tar.gz
2.拷贝上一节 device_tree_bsp_0 目录下查看生成的设备树文件到 /arch/arm/dts
目录下,并重命名 system-top.dts
为 zynq-ax7z100.dts
3.修改设备树文件 zynq-ax7z100.dts
,根据板子和自己的需求配置
4.进入/include/configs目录下,拷贝一份zynq-common.h cp zynq-common.h ax7z100-common.h
, 然后修改ax7z100-common.h
找到 Default environment
字样开始修改,这一步最为关键,也能更好地理解u-boot是如何启动内核过程的
理解CONFIG_EXTRA_ENV_SETTINGS宏
Default environment
下是CONFIG_EXTRA_ENV_SETTINGS宏,设置了u-boot是如何加载内核镜像,如何从SD卡、QSPI、USB启动的
由于我们是准备从SD卡启动u-boot,所以我们需要理解并修改sdboot
找到sdboot关键词,修改成如下内容
"sdboot=if mmcinfo; then " \
"run uenvboot; " \
"echo Copying Linux from SD to RAM... && " \
"load mmc 0 ${bitstream_load_address} ${bitstream_image} && " \
"fpga loadb 0 ${bitstream_load_address} ${bitstream_size} && " \
"load mmc 0 ${kernel_load_address} ${kernel_image} && " \
"load mmc 0 ${devicetree_load_address} ${devicetree_image} && " \
"bootz ${kernel_load_address} - ${devicetree_load_address}; " \
"fi\0" \
第三行命令是打印字符串,可自行修改
第四行命令是从SD卡拷贝bitstream文件到内存
第五行命令是从内存中加载bitstream数据到FPGA
第六行命令是从SD卡拷贝内核镜像到内存
第七行命令是从SD卡拷贝设备树到内存
第八行命令是bootz启动内核
接下来我们需要设置这几个变量 ${}
,有一些是自动生成的,没有的话须要自行设置
网络环境也需要宏定义一下,否则会报错
5.进入/include/configs目录下,拷贝一份zynq_zc70x.h cp zynq_zc70x.h zynq_ax7z100.h
然后修改 zynq_ax7z100.h 中 #include <configs/zynq-common.h>
为 #include <configs/ax7z100-common.h>
6.进入/arch/arm/dts ,修改Makefile,找到 dtb-$(CONFIG_ARCH_ZYNQ)
配置,增加 zynq-ax7z100.dtb
,如图
7.进入configs目录下,拷贝一份配置文件cp zynq_zc702_defconfig zynq_ax7z100_defconfig
设计参考Xilinx官方的zc702开发板,ax7z100是我的开发板名字
修改zynq_ax7z100_defconfig,主要修改项及说明如下
# 1. head file in "include/configs/zynq_ax7z100.h"
CONFIG_SYS_CONFIG_NAME="zynq_ax7z100"
# 2. u-boot start delay for 5s
CONFIG_BOOTDELAY=5
# 3. device tree file in arch/arm/dts/zynq-ax7z100.dts
CONFIG_DEFAULT_DEVICE_TREE="zynq-ax7z100"
# 4. u-boot start banner
CONFIG_IDENT_STRING="ALINX AX7Z100 by HAMMER"
# 5. boot command
CONFIG_BOOTCOMMAND="run default_bootcmd"
# 6. UART BASE ADDRESS
CONFIG_DEBUG_UART_BASE=0xe0000000
8.uboot支持图形界面配置,修改 /arch/arm/mach-zynq/Kconfig
文件 ,找到 config SYS_CONFIG_NAME
,修改如下
编译u-boot
新建一个脚本 zynq_uboot_gen.sh
,写入内容
#!/bin/bash
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- distclean
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- zynq_ax7z100_defconfig
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -j8
chmod +x zynq_uboot_gen.sh
./zynq_uboot_gen.sh
编译成功之后,会在u-boot源码根目录生成以下文件,其中 文件 u-boot
是我们所需要关注的
测试U-BOOT
准备hw文件夹
来自于Vivado工程SDK文件夹下的 xxx_wrapper_hw_platform_0
文件夹,将该文件夹复制到 u-boot 根目录下
准备tcl文件调试linux内核
u-boot 根目录下新建一个linux.tcl
文件,,用来下载 fgpa 的 bitstream 文件和 uboot 的 elf 文件以启动linux内核
内容如下
connect
source zynq7100_wrapper_hw_platform/ps7_init.tcl
targets -set -filter {name =~"APU*" && jtag_cable_name =~ "Digilent*"} -index 0
rst -system
after 3000
targets -set -filter {jtag_cable_name =~ "Digilent*" && level==0} -index 1
fpga -file zynq7100_wrapper_hw_platform/design_1_wrapper.bit
targets -set -filter {name =~"APU*" && jtag_cable_name =~ "Digilent*"} -index 0
loadhw -hw zynq7100_wrapper_hw_platform/system.hdf -mem-ranges [list {0x40000000 0xbfffffff}]
configparams force-mem-access 1
targets -set -filter {name =~"APU*" && jtag_cable_name =~ "Digilent*"} -index 0
ps7_init
ps7_post_config
targets -set -nocase -filter {name =~ "ARM*#0"}
dow u-boot
configparams force-mem-access 0
targets -set -nocase -filter {name =~ "ARM*#0"}
con
准备tcl文件调试u-boot
新建一个名为uboot.tcl
的文件。当我们只是调试uboot,不启动内核的时候或没有使用 fpga 部分时启动内核的时候,可使用该文件,内容如下
connect
source zynq7100_wrapper_hw_platform/ps7_init.tcl
targets -set -filter {name =~"APU"}
loadhw zynq7100_wrapper_hw_platform/system.hdf
stop
ps7_init
targets -set -nocase -filter {name =~ "ARM*#0"}
rst -processor
dow u-boot
con
下载u-boot测试
- 设置开发板启动模式为
JTAG
,连接串口并打开串口软件 - 上电,ubuntu连接 JTAG 的 USB 接口
- 配置petalinux环境变量,输入命令
xsct uboot.tcl
下载u-boot文件调试
运行过程及结果
成功下载u-boot到开发板 Successfully downloaded /home/hammer/work/u-boot/u-boot-xlnx-xilinx-v2017.4/u-boot
串口输出,没有内核所以就只有u-boot信息
第一行输出是zynq_ax7z100_defconfig
文件中自定义的Banner ALINX AX7Z100 by HAMMER
第二行输出是设备树文件zynq-ax7z100.dts
设置的model
其他对应 ax7z100-common.h
文件的修改项
然后我们可以输入命令printenv sdboot
查看 ax7z100-common.h
文件中设置的SD卡启动配置是否和我们设置的一致
成功启动了u-boot,移植完成!
资源文件下载
我已经将本文中涉及的相关文件上传至我的github仓库 https://github.com/Huge-Hammer/linux-system-porting/tree/main/u-boot
有需要自行下载,但仅供参考
结束语
写这篇文章的初衷是不想用petalinux编译u-boot并且想自定义自己的板子,综合了很多教程写的,可能存在错误,还望大家批评指正文章来源:https://www.toymoban.com/news/detail-466376.html
我是爱学习的诸葛铁锤,下期见,see you!文章来源地址https://www.toymoban.com/news/detail-466376.html
到了这里,关于Linux系统移植一:移植U-BOOT 添加自己的板子并编译(非petalinux版)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!