程序笔记   发布时间:2022-07-17  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了ZYNQ FLASH+EMMC手动移植LINUX启动大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。

前言

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

ZYNQ FLASH+EMMC手动移植LINUX启动

资料

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"	
	"kernel_image=uImage"	
	"kernel_load_address=0x2080000" 
	"ramdisk_image=uramdisk.image.gz"	
	"ramdisk_load_address=0x4000000"	
	"deviCETree_image=deviCETree.dtb"	
	"deviCETree_load_address=0x2000000"	
	"bitstream_image=system.bit.bin"	
	"boot_image=BOOT.bin"	
	"loadbit_addr=0x100000"	
	"loadbootenv_addr=0x2000000" 
	"kernel_size=0x500000"	
	"deviCETree_size=0x20000"	
	"ramdisk_size=0x5E0000"	
	"boot_size=0xF00000"	
	"fdt_high=0x20000000"	
	"initrd_high=0x20000000"	
	"bootenv=uEnv.txt" 
	"loadbootenv=load mmc 0 ${loadbootenv_addr} ${Bootenv}" 
	"importbootenv=echo ImporTing environment from SD ...; " 
		"env import -t ${loadbootenv_addr} $filesize" 
	"sd_uEnvtxt_existence_test=test -e mmc 0 /uEnv.txt" 
	"preboot=if test $modeboot = sdboot && env run sd_uEnvtxt_existence_test; " 
			"then if env run loadbootenv; " 
				"then env run importbootenv; " 
			"fi; " 
		"fi; " 
	"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}" 
	"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}" 
	"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}" 
	"uenvboot=" 
		"if run loadbootenv; then " 
			"echo Loaded environment from ${Bootenv}; " 
			"run importbootenv; " 
		"fi; " 
		"if test -n $uenvcmd; then " 
			"echo Running uenvcmd ...; " 
			"run uenvcmd; " 
		"fi" 
	"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" 
	"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" 
	"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}" 
	"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}" 
	"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}" 
	"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}" 
	"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}" 
	"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}" 
	"rsa_jtagboot=echo TFTPing Image to RAm... && " 
		"tftpboot 0x100000 ${Boot_imagE} && " 
		"zynqrsa 0x100000 && " 
		"bootm ${kernel_load_address} ${ramdisk_load_address} ${deviCETree_load_address}" 
		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}" 
	"importbootenv=echo ImporTing environment from SD ...; " 
		"env import -t ${loadbootenv_addr} $filesize" 
	"sd_uEnvtxt_existence_test=test -e mmc 1 /uEnv.txt" 
"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" 

上述命令的执行逻辑为: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"

@H_276_0@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也带了设备树,这里需要进行修改:

ZYNQ FLASH+EMMC手动移植LINUX启动

(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:

清除中间编译:

@H_613_3@make distclean

使用配置文件:

@H_613_3@make CROSS_COMPILE=arm-linux-gnueabihf- zynq_zed_defconfig

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

@H_613_3@make CROSS_COMPILE=arm-linux-gnueabihf- menuconfig

工具编译:

@H_613_3@make CROSS_COMPILE=arm-linux-gnueabihf- tools

编译u-boot:

@H_613_3@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, @R_366_10586@l 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启动全部内容,希望文章能够帮你解决ZYNQ FLASH+EMMC手动移植LINUX启动所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。