前言

虽可使用Petalinux进行移植,简单方便,但为了更清楚明白的了解整个流程,还是尝试了一波手动移植。

参考资料

ZYNQ Linux 移植:包含petalinux移植和手动移植debian9

ZYNQ #5 - 从vivado工程开始,从emmc启动Linux_里先森-CSDN博客

流程

对于手动移植,所需的文件为:

BOOT.bin(FSBL+fpga_bit文件+u_boot.elf)、uImage、devicetree.dtb、uEnv.txt、文件系统

文件放置位置说明:

FLASH:BOOT.bin(FSBL+fpga_bit文件+u_boot.elf)

EMMC:

第一个分区放置:uImage、devicetree.dtb、uEnv.txt

第二个分区放置:文件系统

启动流程为:板子设置为QSPI启动模式,FSBL执行调u-boot执行,u-boot根据uEnv.txt调EMMC分区1中的内核执行,内核最后跳到分区二中的文件系统。

FSBL、bit文件、uImage、文件系统都可复用SD卡移植模式下的内容:参考参考资料第一个链接。

本文章主要讲述的重点在于:u-boot、设备树、uEnv.txt的更改部分

板子主要信息说明:板子芯片:ZYNQ7035,板子的调试打印串口为PS0,板子上有SD卡(SD0)、EMMC(SD1),板子上有FLASH。其他外设不赘述。

u-boot移植说明:

1.下载u-boot源码:git clone [https://github.com/Xilinx/u-boot-xlnx.git](https://github.com/Xilinx/u-boot-xlnx.git)

NOTE:u-boot xilinx-v2018.3版本的zynq-common.h跟xilinx-v2018.1版本的不一样,这里检出v2018.1版本使用。

主要是CONFIG_EXTRA_ENV_SETTINGS 环境变量不一致。

默认的如下所示:

/* Default environment */
#ifndef CONFIG_EXTRA_ENV_SETTINGS
#define CONFIG_EXTRA_ENV_SETTINGS \
"ethaddr=00:0a:35:00:01:22\0" \
"kernel_image=uImage\0" \
"kernel_load_address=0x2080000\0" \
"ramdisk_image=uramdisk.image.gz\0" \
"ramdisk_load_address=0x4000000\0" \
"devicetree_image=devicetree.dtb\0" \
"devicetree_load_address=0x2000000\0" \
"bitstream_image=system.bit.bin\0" \
"boot_image=BOOT.bin\0" \
"loadbit_addr=0x100000\0" \
"loadbootenv_addr=0x2000000\0" \
"kernel_size=0x500000\0" \
"devicetree_size=0x20000\0" \
"ramdisk_size=0x5E0000\0" \
"boot_size=0xF00000\0" \
"fdt_high=0x20000000\0" \
"initrd_high=0x20000000\0" \
"bootenv=uEnv.txt\0" \
"loadbootenv=load mmc 0 ${loadbootenv_addr} ${bootenv}\0" \
"importbootenv=echo Importing environment from SD ...; " \
"env import -t ${loadbootenv_addr} $filesize\0" \
"sd_uEnvtxt_existence_test=test -e mmc 0 /uEnv.txt\0" \
"preboot=if test $modeboot = sdboot && env run sd_uEnvtxt_existence_test; " \
"then if env run loadbootenv; " \
"then env run importbootenv; " \
"fi; " \
"fi; \0" \
"mmc_loadbit=echo Loading bitstream from SD/MMC/eMMC to RAM.. && " \
"mmcinfo && " \
"load mmc 0 ${loadbit_addr} ${bitstream_image} && " \
"fpga load 0 ${loadbit_addr} ${filesize}\0" \
"norboot=echo Copying Linux from NOR flash to RAM... && " \
"cp.b 0xE2100000 ${kernel_load_address} ${kernel_size} && " \
"cp.b 0xE2600000 ${devicetree_load_address} ${devicetree_size} && " \
"echo Copying ramdisk... && " \
"cp.b 0xE2620000 ${ramdisk_load_address} ${ramdisk_size} && " \
"bootm ${kernel_load_address} ${ramdisk_load_address} ${devicetree_load_address}\0" \
"qspiboot=echo Copying Linux from QSPI flash to RAM... && " \
"sf probe 0 0 0 && " \
"sf read ${kernel_load_address} 0x100000 ${kernel_size} && " \
"sf read ${devicetree_load_address} 0x600000 ${devicetree_size} && " \
"echo Copying ramdisk... && " \
"sf read ${ramdisk_load_address} 0x620000 ${ramdisk_size} && " \
"bootm ${kernel_load_address} ${ramdisk_load_address} ${devicetree_load_address}\0" \
"uenvboot=" \
"if run loadbootenv; then " \
"echo Loaded environment from ${bootenv}; " \
"run importbootenv; " \
"fi; " \
"if test -n $uenvcmd; then " \
"echo Running uenvcmd ...; " \
"run uenvcmd; " \
"fi\0" \
"sdboot=if mmcinfo; then " \
"run uenvboot; " \
"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}; " \
"fi\0" \
"usbboot=if usb start; then " \
"run uenvboot; " \
"echo Copying Linux from USB to RAM... && " \
"load usb 0 ${kernel_load_address} ${kernel_image} && " \
"load usb 0 ${devicetree_load_address} ${devicetree_image} && " \
"load usb 0 ${ramdisk_load_address} ${ramdisk_image} && " \
"bootm ${kernel_load_address} ${ramdisk_load_address} ${devicetree_load_address}; " \
"fi\0" \
"nandboot=echo Copying Linux from NAND flash to RAM... && " \
"nand read ${kernel_load_address} 0x100000 ${kernel_size} && " \
"nand read ${devicetree_load_address} 0x600000 ${devicetree_size} && " \
"echo Copying ramdisk... && " \
"nand read ${ramdisk_load_address} 0x620000 ${ramdisk_size} && " \
"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" \
"rsa_norboot=echo Copying Image from NOR flash to RAM... && " \
"cp.b 0xE2100000 0x100000 ${boot_size} && " \
"zynqrsa 0x100000 && " \
"bootm ${kernel_load_address} ${ramdisk_load_address} ${devicetree_load_address}\0" \
"rsa_nandboot=echo Copying Image from NAND flash to RAM... && " \
"nand read 0x100000 0x0 ${boot_size} && " \
"zynqrsa 0x100000 && " \
"bootm ${kernel_load_address} ${ramdisk_load_address} ${devicetree_load_address}\0" \
"rsa_qspiboot=echo Copying Image from QSPI flash to RAM... && " \
"sf probe 0 0 0 && " \
"sf read 0x100000 0x0 ${boot_size} && " \
"zynqrsa 0x100000 && " \
"bootm ${kernel_load_address} ${ramdisk_load_address} ${devicetree_load_address}\0" \
"rsa_sdboot=echo Copying Image from SD to RAM... && " \
"load mmc 0 0x100000 ${boot_image} && " \
"zynqrsa 0x100000 && " \
"bootm ${kernel_load_address} ${ramdisk_load_address} ${devicetree_load_address}\0" \
"rsa_jtagboot=echo TFTPing Image to RAM... && " \
"tftpboot 0x100000 ${boot_image} && " \
"zynqrsa 0x100000 && " \
"bootm ${kernel_load_address} ${ramdisk_load_address} ${devicetree_load_address}\0" \
DFU_ALT_INFO \
BOOTENV
#endif

可以看到其上定义了一堆的东西及不同的启动指令。

不同的启动指令由#define CONFIG_BOOTCOMMAND指定。

这里想FLASH+EMMC启动,则可以选择sdboot,同时因为EMMC是SD1,所以上述的文件需要进行更改:更改uEnv.txt的存储位置为mmc 1;去掉sdboot中的ramdisk,及存储kernel、设备树位置为mmc 1;修改bootm参数。

	"loadbootenv=load mmc 1 ${loadbootenv_addr} ${bootenv}\0" \
"importbootenv=echo Importing environment from SD ...; " \
"env import -t ${loadbootenv_addr} $filesize\0" \
"sd_uEnvtxt_existence_test=test -e mmc 1 /uEnv.txt\0" \
"sdboot=if mmcinfo; then " \
"run uenvboot; " \
"echo Copying Linux from hahahah SD to RAM... && " \
"load mmc 1 ${kernel_load_address} ${kernel_image} && " \
"load mmc 1 ${devicetree_load_address} ${devicetree_image} && " \
"bootm ${kernel_load_address} - ${devicetree_load_address}; " \
"fi\0" \

上述命令的执行逻辑为:u-boot启动后,执行sdboot指令:

(1)装载uEnv.txt文件并运行;

(2)装载内核、设备树;

(3)运行;

2.由于是自己做的板子,则可以基于类似的板子defconfig进行修改适配u-boot:这里使用zynq_zed_defconfig文件:

(1)增加传统镜像文件支持:CONFIG_IMAGE_FORMAT_LEGACY=y

(2)因为已经知道是从EMMC启动相关文件,则可直接指定:CONFIG_BOOTCOMMAND="mmc dev 1;run sdboot"

mmc dev 1是为了避免u-boot死锁bug(移植petalinux中u-boot存在,为官方bug,这里加上,不知道有没有用);sdboot会直接调用执行zynq-common.h中的对应选项。

(3)因为板子上串口使用的是PS0,修改:CONFIG_DEBUG_UART_BASE=0xe0000000(地址可在设备树中查看)

文件参考:

CONFIG_ARM=y
CONFIG_ARCH_ZYNQ=y
CONFIG_SYS_TEXT_BASE=0x4000000
CONFIG_SPL_STACK_R_ADDR=0x200000
CONFIG_DEFAULT_DEVICE_TREE="zynq-zed"
CONFIG_DEBUG_UART=y
CONFIG_DISTRO_DEFAULTS=y
CONFIG_IMAGE_FORMAT_LEGACY=y
CONFIG_FIT=y
CONFIG_FIT_SIGNATURE=y
CONFIG_FIT_VERBOSE=y
CONFIG_BOOTCOMMAND="mmc dev 1;run sdboot"
# CONFIG_DISPLAY_CPUINFO is not set
CONFIG_SPL=y
CONFIG_SPL_STACK_R=y
CONFIG_SPL_OS_BOOT=y
CONFIG_SYS_PROMPT="Zynq> "
CONFIG_CMD_THOR_DOWNLOAD=y
CONFIG_CMD_DFU=y
# CONFIG_CMD_FLASH is not set
CONFIG_CMD_FPGA_LOADBP=y
CONFIG_CMD_FPGA_LOADFS=y
CONFIG_CMD_FPGA_LOADMK=y
CONFIG_CMD_FPGA_LOADP=y
CONFIG_CMD_GPIO=y
CONFIG_CMD_MMC=y
CONFIG_CMD_SF=y
CONFIG_CMD_USB=y
# CONFIG_CMD_SETEXPR is not set
CONFIG_CMD_TFTPPUT=y
CONFIG_CMD_CACHE=y
CONFIG_CMD_EXT4_WRITE=y
CONFIG_OF_EMBED=y
CONFIG_ENV_IS_IN_SPI_FLASH=y
CONFIG_NET_RANDOM_ETHADDR=y
CONFIG_SPL_DM_SEQ_ALIAS=y
CONFIG_DFU_MMC=y
CONFIG_DFU_RAM=y
CONFIG_FPGA_XILINX=y
CONFIG_DM_GPIO=y
CONFIG_MMC_SDHCI=y
CONFIG_MMC_SDHCI_ZYNQ=y
CONFIG_SPI_FLASH=y
CONFIG_SPI_FLASH_BAR=y
CONFIG_SF_DUAL_FLASH=y
CONFIG_SPI_FLASH_SPANSION=y
CONFIG_SPI_FLASH_STMICRO=y
CONFIG_SPI_FLASH_WINBOND=y
CONFIG_PHY_MARVELL=y
CONFIG_PHY_REALTEK=y
CONFIG_PHY_XILINX=y
CONFIG_ZYNQ_GEM=y
CONFIG_DEBUG_UART_ZYNQ=y
CONFIG_DEBUG_UART_BASE=0xe0000000
CONFIG_DEBUG_UART_CLOCK=50000000
CONFIG_ZYNQ_SERIAL=y
CONFIG_ZYNQ_QSPI=y
CONFIG_USB=y
CONFIG_USB_EHCI_HCD=y
CONFIG_USB_ULPI_VIEWPORT=y
CONFIG_USB_ULPI=y
CONFIG_USB_STORAGE=y
CONFIG_USB_GADGET=y
CONFIG_USB_GADGET_MANUFACTURER="Xilinx"
CONFIG_USB_GADGET_VENDOR_NUM=0x03fd
CONFIG_USB_GADGET_PRODUCT_NUM=0x0300
CONFIG_CI_UDC=y
CONFIG_USB_GADGET_DOWNLOAD=y

3.修改u-boot的设备树:实际上u-boot也带了设备树,这里需要进行修改:

(1)修改uart为uart0;

(2)修改SD为mmc1;

(3)去除QSPI中的分区表;

文件参考:

/*
* Xilinx ZED board DTS
*
* Copyright (C) 2011 - 2015 Xilinx
* Copyright (C) 2012 National Instruments Corp.
*
* SPDX-License-Identifier: GPL-2.0+
*/
/dts-v1/;
#include "zynq-7000.dtsi" / {
model = "Zynq Zed Development Board";
compatible = "xlnx,zynq-zed", "xlnx,zynq-7000"; aliases {
ethernet0 = &gem0;
serial0 = &uart0;
spi0 = &qspi;
mmc1 = &sdhci1;
}; memory@0 {
device_type = "memory";
reg = <0x0 0x20000000>;
}; chosen {
bootargs = "";
stdout-path = "serial0:115200n8";
}; usb_phy0: phy0@e0002000 {
compatible = "ulpi-phy";
#phy-cells = <0>;
reg = <0xe0002000 0x1000>;
view-port = <0x0170>;
drv-vbus;
};
}; &clkc {
ps-clk-frequency = <33333333>;
}; &gem0 {
status = "okay";
phy-mode = "rgmii-id";
phy-handle = <&ethernet_phy>; ethernet_phy: ethernet-phy@0 {
reg = <0>;
device_type = "ethernet-phy";
};
}; &qspi {
u-boot,dm-pre-reloc;
status = "okay";
is-dual = <0>;
num-cs = <1>;
flash@0 {
compatible = "n25q128a11";
reg = <0x0>;
spi-tx-bus-width = <1>;
spi-rx-bus-width = <4>;
spi-max-frequency = <50000000>;
#address-cells = <1>;
#size-cells = <1>; };
}; &sdhci1 {
u-boot,dm-pre-reloc;
status = "okay";
}; &uart0 {
u-boot,dm-pre-reloc;
status = "okay";
}; &usb0 {
status = "okay";
dr_mode = "host";
usb-phy = <&usb_phy0>;
};
  1. 编译u-boot:

清除中间编译:

make distclean

使用配置文件:

make CROSS_COMPILE=arm-linux-gnueabihf- zynq_zed_defconfig

通过下述指令可在界面中uboot进行进一步修改配置:改defconfig文件也可以,暂时默认即可

make CROSS_COMPILE=arm-linux-gnueabihf- menuconfig

工具编译:

make CROSS_COMPILE=arm-linux-gnueabihf- tools

编译u-boot:

make CROSS_COMPILE=arm-linux-gnueabihf-

  1. 修改总设备树的boottags:console=ttyPS0,115200n8 root=/dev/mmcblk1p2 rw noinitrd rootfstype=ext4 rootwait

  2. 修改uEnv.txt为:mmc 0修改为mmc 1;root=/dev/mmcblk1p2

bootargs=console=ttyPS0,115200 root=/dev/mmcblk1p2 rw earlyprintk rootfstype=ext4 rootwait
load_image=fatload mmc 1 ${kernel_load_address} ${kernel_image} && fatload mmc 1 ${devicetree_load_address} ${devicetree_image}
uenvcmd=echo Copying Linux from SD to RAM... && mmcinfo && run load_image && bootm ${kernel_load_address} - ${devicetree_load_address}
  1. 组装BOOT.bin,不赘述。
  2. 烧录BOOT.bin到FLASH,对EMMC进行分区,EMMC分区一中放置uImage、devicetree.dtb、uEnv.txt,EMMC分区二中放置文件系统即可。
  3. 启动。
U-Boot 2018.01-dirty (Jul 26 2021 - 20:05:00 +0800)

Model: Zynq Zed Development Board
Board: Xilinx Zynq
Silicon: v3.1
DRAM: ECC disabled 512 MiB
MMC: sdhci_transfer_data: Error detected in status(0x208000)!
sdhci@e0101000: 1 (eMMC)
SF: Detected s25fl128s_64k with page size 256 Bytes, erase size 64 KiB, total 16 MiB
*** Warning - bad CRC, using default environment In: serial@e0000000
Out: serial@e0000000
Err: serial@e0000000
Net: ZYNQ GEM: e000b000, phyaddr 0, interface rgmii-id
eth0: ethernet@e000b000
Hit any key to stop autoboot: 0
sdhci_transfer_data: Error detected in status(0x208000)!
switch to partitions #0, OK
mmc1(part 0) is current device
Device: sdhci@e0101000
Manufacturer ID: 13
OEM: 14e
Name: Q2J55
Tran Speed: 25000000
Rd Block Len: 512
MMC version 5.0
High Capacity: Yes
Capacity: 7.1 GiB
Bus Width: 4-bit
Erase Group Size: 512 KiB
HC WP Group Size: 8 MiB
User Capacity: 7.1 GiB WRREL
Boot Capacity: 16 MiB ENH
RPMB Capacity: 4 MiB ENH
reading uEnv.txt
356 bytes read in 11 ms (31.3 KiB/s)
Loaded environment from uEnv.txt
Importing environment from SD ...
Running uenvcmd ...
Copying Linux from SD to RAM...
Device: sdhci@e0101000
Manufacturer ID: 13
OEM: 14e
Name: Q2J55
Tran Speed: 25000000
Rd Block Len: 512
MMC version 5.0
High Capacity: Yes
Capacity: 7.1 GiB
Bus Width: 4-bit
Erase Group Size: 512 KiB
HC WP Group Size: 8 MiB
User Capacity: 7.1 GiB WRREL
Boot Capacity: 16 MiB ENH
RPMB Capacity: 4 MiB ENH
reading uImage
4001616 bytes read in 377 ms (10.1 MiB/s)
reading devicetree.dtb
17052 bytes read in 18 ms (924.8 KiB/s)
## Booting kernel from Legacy Image at 02080000 ...
Image Name: Linux-4.14.0-xilinx
Image Type: ARM Linux Kernel Image (uncompressed)
Data Size: 4001552 Bytes = 3.8 MiB
Load Address: 00008000
Entry Point: 00008000
Verifying Checksum ... OK
## Flattened Device Tree blob at 02000000
Booting using the fdt blob at 0x2000000
Loading Kernel Image ... OK
Loading Device Tree to 1eb12000, end 1eb1929b ... OK

以上。

ZYNQ FLASH+EMMC手动移植LINUX启动的更多相关文章

  1. Zynq ZC706 传统方式移植Linux -- 编译kernel 文件系统 devicetree

    1.kernel 实际操作时候,下面两条命令就够了. make ARCH=arm xilinx_zynq_defconfig make ARCH=arm CROSS_COMPILE=arm-xilin ...

  2. Zynq ZC706 传统方式移植Linux -- 编译u-boot

    我用的是zc706不是zed 基本思路是: 1.安装交叉编译工具(见 https://www.cnblogs.com/idyllcheung/p/10532654.html ) 2.下载xilinx ...

  3. ZYNQ Linux 移植:包含petalinux移植和手动移植debian9

    参考: https://electronut.in/workflow-for-using-linux-on-xilinx-zynq/ https://blog.csdn.net/m0_37545528 ...

  4. S04_CH01_搭建工程移植LINUX/测试EMMC/VGA

    S04_CH01_搭建工程移植LINUX/测试EMMC/VGA 1.1概述: 本章内容是在已经提供安装了VIVADO2015.4 的ubuntu系统下,进行.大家可以下周我们已经提供的虚拟机镜像,我们 ...

  5. u-boot 移植 --->6、引导Linux启动测试

    在引导Linux开机之前需要先清楚Linux启动的必要或者说是先决条件,这里就是提到了u-boot的作用了引用百度云---主要用于嵌入式系统的引导加载,其实在我调试下来总结一下就是初始化硬件这里的硬件 ...

  6. ZYNQ跑系统 系列(二) petalinux方式移植linux

    三.搭建petalinux工程 0.定位目录    先在shell中找一个准备存放工程的地方,(我的是home/hlf/PRO),命令行cd home/hlf/PRO 1.定位编译链    根据安装p ...

  7. Xilinx zynq-7000系列FPGA移植Linux操作系统详细教程

    Xilinx zynq-7000系列FPGA移植Linux操作系统详细教程 一:前言 最近手上压了一块米联客的Miz7035,一块xilinx zynq-7000系列的开发板,想着正好学习一下linu ...

  8. 在基于or1200处理器的SoC上移植linux

    经历了前端的艰苦奋斗.SoC前端设计已经调试完毕,如今直接进入uboot移植   首先cd入u-boot-master 找到子文件夹include下得de2_115.h文件进行改动: (下一步计划:加 ...

  9. 嵌入式Linux启动优化手记2&nbsp;U…

    参考一下 原文地址:U-boot优化">嵌入式Linux启动优化手记2 U-boot优化作者:ZhaoJunling 既然不能使用新的U-boot,那就优化一点是一点,慢慢干吧. 1. ...

随机推荐

  1. Xshell6会话管理器无意中关闭,在哪里打开

    一.进入查看 二.勾选则弹出,然后双击窗口即可

  2. httprunner中的分层(api、testcase、testsuite)及实际使用

    一.分层思想 api定义层:最底下的一层是api的定义层testcase层:测试用例层,调用定义层的内容testsuite:测试套件层 二.分层案例设计实现实践举例 1.api 层: 2.testca ...

  3. 4.2tensorflow多层感知器MLP识别手写数字最易懂实例代码

    自己开发了一个股票智能分析软件,功能很强大,需要的点击下面的链接获取: https://www.cnblogs.com/bclshuai/p/11380657.html 1.1  多层感知器MLP(m ...

  4. Mybati-Plus的用法 记录

    参考文件下载地址:  https://files.cnblogs.com/files/bulter/MyBatis-Plus.zip --------------------------------- ...

  5. Go语言中底层数组和切片的关系以及数组扩容规则

    Go语言中底层数组和切片的关系以及数组扩容规则 demo package main import ( "fmt" ) func main() { // 声明一个底层数组,长度为10 ...

  6. 第三方模块npm

    npm介绍 npm 全名 node package manager   node包管理工具,增删查改 如果npm操作太慢,可以安装npm镜像 npm的下载 比如全局下载一个jquery文件,全局下载的 ...

  7. 基于gitlab 打tag形成版本视图源码包和可执行包

    实现步骤说明 第一步创建发布tag 创建的tag生成效果 第二步进入release 第三步到制品库去拷贝编译可执行包的下载地址 右键复制链接下载地址 编辑tag信息 填写编译后可执行文件的安装包 最终 ...

  8. AcWing 1127. 香甜的黄油

    农夫John发现了做出全威斯康辛州最甜的黄油的方法:糖. 把糖放在一片牧场上,他知道 N 只奶牛会过来舔它,这样就能做出能卖好价钱的超甜黄油. 当然,他将付出额外的费用在奶牛上. 农夫John很狡猾, ...

  9. Java读取文件创建时间和最后修改时间

    import java.io.BufferedReader; import java.io.File; import java.io.IOException; import java.io.Input ...

  10. 结构型模式 -- 代理模式(静态代理&动态代理)

    静态代理: 真实角色和代理角色实现相同的接口,代理角色拥有真实角色的引用.代理角色去执行方法,对于某些"真正"需要真实角色自己执行的方法时,在代理角色内部就调用真实角色的方法,其他 ...