Linux系统移植一:移植U-BOOT 添加自己的板子并编译(非petalinux版)

环境

  1. hdf设计:vivado 2017.4套件
  2. 交叉编译环境: arm-linux-gnueabihf-
  3. 虚拟机Linux系统版本:ubuntu 16.04
  4. 开发板:ALINX AX7Z100 开发板(ZYNQ7100)

Zynq Linux系统启动流程

在这里插入图片描述

Linux移植流程和思路

不使用petalinux工具,尽管它提升了开发效率,能直接生成BOOT.BINimage.ub
但是这种方法既不利于学习移植过程,又不灵活,一旦有什么新的需要就得重新编译

嵌入式Linux系统移植主要由四大部分组成:

  1. 搭建交叉编译开发环境
  2. bootloader的选择和移植
  3. kernel的配置、编译、和移植
  4. 根文件系统的制作

整体的思路如图,即将比特流文件system.bitBOOT.BIN文件中分离出来,同时将fbsl镜像和u-boot镜像合成BOOT.bin文件
将内核镜像文件zImage、内核设备树system.dtb文件以及根文件系统rootfsimage.ub中分离出来
将SD卡格式化并划分为FAT32EXT4两个区,分别启动镜像和根文件系统

请添加图片描述

本文主要来移植 bootloader,最常用的是U-BOOT ,下面就让我们开始吧
目标:编译出 u-boot 镜像文件

SDK由hdf文件得到设备树文件

下载设备树源码

下载地址为:https://github.com/Xilinx/device-tree-xlnx/tags,我这里下载的是2017.4版本的

准备hdf文件

vivado里面设计,编译导出生成hdf文件

生成设备树文件

  1. 解压设备树源码,拷贝到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.dtszynq-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测试

  1. 设置开发板启动模式为 JTAG,连接串口并打开串口软件
  2. 上电,ubuntu连接 JTAG 的 USB 接口
  3. 配置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并且想自定义自己的板子,综合了很多教程写的,可能存在错误,还望大家批评指正

我是爱学习的诸葛铁锤,下期见,see you!

猜你喜欢

转载自blog.csdn.net/qq_41873311/article/details/128138579