从ZYNQ7000开发板
学会启动嵌入式Linux系统
入门学习:EBAZ4205篇
版权说明
本书由孙宇彤、孙启凡执笔,本书编写时还参考了DeepSeek提供的信息。
本书为作者精校开源版,版权归作者所有。
作者允许读者在注明来源后引用内容,并通知作者。
前 言
学会启动嵌入式Linux系统的入门学习篇是学习的第一阶段,面向对计算机操作比较熟悉,乐于动手实操的读者,具体要求如下:
- 有Linux命令的使用基础;
- 了解嵌入式Linux系统的基本概念;
符合要求的读者只要学完入门学习篇并完成相关操作,应该都能:
- 了解ZYNQ7000开发板嵌入式Linux系统的启动方式;
- 了解ZYNQ7000开发板嵌入式Linux系统启动的过程;
- 了解ZYNQ7000开发板嵌入式Linux系统启动过程涉及的文件;
- 了解与启动相关的Linux命令;
最终体验到EBAZ4205开发板的嵌入式Linux系统的主要启动方式和启动过程,完成嵌入式Linux系统启动的入门学习。
大家在学习中遇到问题,可以加入QQ群:1019216193咨询,作者将及时解答。
2026.8
第一章 认识ZYNQ7000开发板
认识一下ZYNQ7000系列芯片
这篇文章的主角EBAZ4205开发板是一种ZYNQ7000开发板,开发板上的核心芯片就是ZYNQ7000系列芯片,因此我们先来认识一下ZYNQ7000系列芯片。
ZYNQ7000系列芯片是赛灵思(Xilinx,以研发高性能的FPGA产品而知名,目前已经被AMD收购)研发的一款具有里程碑意义的产品,首次将高性能的ARM处理器系统(PS,Processing System)与FPGA可编程逻辑(PL,Programmable Logic)紧密集成在单颗芯片,完美地实现了处理器的顺序执行能力和FPGA的并行处理能力的融合。简单地说,有点像把华山派的剑宗与气宗合二为一的感觉。
图1展示了开发板上的ZYNQ7000系列芯片:

图1 开发板上的ZYNQ7000系列芯片
芯片特色
ZYNQ-7000系列芯片本质是一个以处理器为中心的可编程SoC,因此芯片首先是一个强大的ARM Cortex-A9处理器应用处理器,可以运行像Linux这样的复杂操作系统,并支持多种启动方式,包括利用NAND Flash、SD、JTAG等启动。
其次,ZYNQ-7000系列芯片还拥有一个Xilinx 7系列FPGA,拥有可配置逻辑块以及数字信号处理单元等逻辑资源,可以作为定制硬件加速器、信号处理器或连接专用外设。
传统的“FPGA+外挂CPU”方案存在通信延迟大、功耗高、PCB设计复杂等缺点。ZYNQ的设计者将处理器与FPGA两者置于同一芯片上,通过高速内部总线AMBA(Advanced Microcontroller Bus Architecture,高级微处理器总线结构)互联,实现了高带宽、低延迟的协同工作,保证了数据在处理器和可编程逻辑之间能够高效、低延迟地流动,实现了1+1>2的效果,特别适用于需要大量数据预处理、实时控制、硬件加速的应用场景。
芯片系列
既然称为ZYNQ7000系列芯片,说明ZYNQ7000系列中包含多种型号的芯片,这些芯片具有相同的ZYNQ7000芯片架构,对应不同的硬件规模和芯片性能,以满足不同应用的需求和成本考量。
其中,PS处理器分为单核以及双核两类,单核主打低成本、低功耗市场;双核性能强,是系列中的主流产品,应用范围最广。因此我们一般选用双核的ZYNQ-7000系列芯片。
再来看PL,也就是FPGA部分,双核的ZYNQ-7000系列芯片主要有Z-7010、Z-7015、Z-7020、Z-7030、Z-7035、Z-7045和Z-7100等型号,最后的数字代表了PL部分的规模大小。数字越大,逻辑资源越多,性能越强,价格也越高。
表1列出了三种典型型号Z-7010、 Z-7020和Z-7045的硬件规模:
表1 ZYNQ-7000系列芯片典型型号硬件规模表
| 资源类型 | Z-7010 | Z-7020 | Z-7045 |
|---|---|---|---|
| 逻辑单元 | 28K | 85K | 350 K |
| 查找表 (LUTs) | 17,600 | 53,200 | 218,600 |
| 触发器 (FFs) | 35,200 | 106,400 | 437,200 |
| 块RAM (BRAM) | 60块 | 140块 | 545块 |
| 数字信号处理单元 | 80 | 220 | 900 |
| 最大I/O 引脚数 | 100 | 200 | 362 |
初学者推荐选择Z-7010或者Z-7020芯片,性价比高。
认识一下ZYNQ7000开发板:EBAZ4205
学习ZYNQ7000系列芯片离不开ZYNQ7000开发板,市面上有很多采用ZYNQ-7010或者ZYNQ-7020芯片的开发板,这里我们推荐EBAZ4205开发板用于入门学习。
EBAZ4205开发板是一款基于 Xilinx ZYNQ-7010 芯片的矿机主控板,由于矿机退役,被大量拆机流入市场,经过商家改造后,变成了ZYNQ7000开发板,售价通常在百元级别。图2展示了EBAZ4205开发板的外观。

图2 EBAZ4205开发板
EBAZ4205开发板支持运行 Linux 系统及自定义 FPGA 逻辑设计,完整覆盖了开发ZYNQ7000系列芯片的学习内容,成为性价比极为突出的入门级ZYNQ7000开发板。
EBAZ4205开发板除了配备有256MB的DDR3 内存和128MB的NAND Flash外,还配备了百兆以太网口以及SD卡座。另外,开发板还有多个插座,主要用于引出ZYNQ-7010的PL端GPIO端口的各种管脚。
商家提供EBAZ4205开发板初衷是用于学习FPGA的开发,其实利用这块开发板,我们还能学会启动嵌入式Linux系统,达到一鱼两吃的效果。后续内容将基于EBAZ4205开发板,详细介绍开发板的Linux系统启动过程。
改造EBAZ4205开发板供电方式
前面说过商家提供的EBAZ4205开发板用于学习FPGA的开发,需要外加扩展板,才能连接摄像头、实现供电以及提供USB接口。
因为我们选用EBAZ4205开发板来学习嵌入式Linux系统的启动,并不使用扩展板的图像接口,因此通过外加扩展板供电,在学习Linux系统启动时反而很累赘,非常不方便。
其实,不加扩展板也可以为EBAZ4205开发板的供电,这样EBAZ4205开发板就可以单板工作了,将会大大方便后续的Linux系统启动学习过程。
接下来就介绍一下EBAZ4205开发板的供电改造方案,主要有两种方案:
第一种方案是不改开发板,利用开发板6Pin的J4接口来供电。读者可以到淘宝上买一个6pin插头(5559/4.2mm母头),配合一个12V/1A的直流电源,焊接对应的Pin脚接线,自制一个外接电源。最后的成品如图3所示:

图3 EBAZ4205开发板的外接电源
将改造后的电源插入开发板的J4接口,就可以为开发板供电了。
另外一种方案需要改开发板,如图4所示,短接掉开发板背面的D24(有二极管符号),这样就可以直接通过开发板的J3或者J5接口上的VCC和GND管脚引入5V的供电。

图4 短接D24
这种方案的好处是可以通过USB转TTL模块来供电和调测,一举两得,连接方式如图5所示。

图5 用USB转TTL模块为EBAZ4205开发板供电
附带说一下,板上的串口插座J7虽然也有VCC,但是不能作为供电使用,供电还是要通过J3或J5接口上的VCC管脚。
从我的实际使用的效果看,推荐大家采用第二种方案来供电,更加简洁和方便。
解决了供电问题后,后续我们就在EBAZ4205开发板,开始学习嵌入式Linux系统的启动过程。
第二章 体验自带的NAND Flash启动方式
认识一下NAND Flash
从这里开始我们进入正题,也就是讲解EBAZ4205开发板上的嵌入式Linux系统是怎么启动的。
其实EBAZ4205开发板本身是具备启动能力的,硬件上已经固化为从开发板上的NAND Flash启动嵌入式Linux系统。因此我们首先来了解一下标配的NAND Flash启动方式。
附带说一下,ZYNQ7000系列芯片支持多种启动方式,NAND Flash只是其中一种启动方式。
所谓Flash,就是一种可以擦写的存放数据的存储芯片,由于断电也可以保存数据,属于非易失性存储芯片,等价于电脑的硬盘。
Flash芯片有NOR和NAND两种实现技术:
- NOR :Intel公司1988年开发出了NOR Flash技术。NOR Flash容量小,写入和擦除速度较低。
- NAND :东芝公司1989年发表了NAND Flash技术。NAND Flash 容量大,改写速度快,SD卡、TF卡、手机、平板的GB级别Flash一般都采用NAND技术。EBAZ4205开发板也采用了NAND Flash技术,Flash具体型号是万邦W29N01HV,存储容量是128MB。
体验开发板的启动过程
准备工作
为了体验EBAZ4205开发板的NAND启动方式,除了要准备USB-TTL的模块、在电脑上安装USB-TTL的模块的驱动外,我们还需要在电脑上安装与EBAZ4205开发板通信的软件,也就是远程终端工具,通过电脑远程操作开发板的嵌入式Linux系统。
假定大家采用Windows系统,我推荐安装远程终端工具xshell或者串口调测工具sscom。这两个工具的具体的安装过程请大家自行搜索网上的介绍,这里就不赘述了。
连接并上电启动
启动EBAZ4205开发板时,先将USB转TTL模块与开发板的J7与J3连接好,如图1所示,再插入电脑的USB口。这时开发板开始上电启动,可以看到板上有绿灯亮起。

图1 EBAZ4205开发板上电启动
远程终端的配置
接着在电脑中找到新增的串口,记录串口的端口号。在xshell中增加一个会话,采用串口连接,波特率设为115200,端口号为新增串口的端口号,如图2所示。

图2 xshell中设置串口连接
会话建好后,点击连接,就会出现终端界面。
在终端的界面,可以看到启动过程的大量信息,代表嵌入式Linux系统正在启动。
启动完成后,在终端的界面出现用户名和密码的输入界面,等待用户登录。
PetaLinux 2016.4 zedboard-zynq7 /dev/ttyPS0
zedboard-zynq7 login:
根据网上的攻略,我们可以修改EBAZ4205开发板自带嵌入式Linux系统root用户的登录密码,进入Linux系统。
如果看到如下的提示符,代表连接EBAZ4205嵌入式Linux系统成功,已经以root用户成功登录到了EBAZ4205:
root@zedboard-zynq7:~#
获取系统信息
登入系统后,我们首先查看系统的版本。在终端界面中输入 uname -a,将看到如下的输出:
root@zedboard-zynq7:~# uname -a
Linux zedboard-zynq7 4.6.0-xilinx #5 SMP PREEMPT Mon May 8 14:36:49 CST 2017 armv7l GNU/Linux
可见这个Linux系统是4.6.0版内核,属于比较老的内核。附带说一下,输入Linux命令需要区分大小写,命令与参数之间需要有空格。
接下来,我们查看系统的内存。在终端界面中输入 free -m,将看到如下的输出:
root@zedboard-zynq7:~# free -m
total used free shared buffers cached
Mem: 246 12 233 0 0 2
-/+ buffers/cache: 9 236
Swap: 0 0 0
说明开发板的内存的确是256MB。
接下来,我们查看系统的存储空间。在终端界面中输入 df -h,将看到如下的输出:
root@zedboard-zynq7:~# df -h
Filesystem Size Used Available Use% Mounted on
/dev/root 64.0M 37.9M 26.1M 59% /
devtmpfs 64.0K 0 64.0K 0% /dev
tmpfs 123.1M 28.0K 123.0M 0% /run
tmpfs 123.1M 40.0K 123.0M 0% /var/volatile
tmpfs 64.0K 0 64.0K 0% /dev
第一行的数据对应Linux系统的根目录,不难看出其大小为64MB,已经使用了59%的容量,还剩余26MB。
检查TF卡
前面讲过,商家EBAZ4205开发板配置了TF卡槽,可以读写TF卡。
我们插入一张TF卡,并登入系统后,输入 mount,将显示:
root@zedboard-zynq7:~# mount
/dev/root on / type jffs2 (rw,relatime)
devtmpfs on /dev type devtmpfs (rw,relatime,size=117312k,nr_inodes=29328,mode=755)
proc on /proc type proc (rw,relatime)
sysfs on /sys type sysfs (rw,relatime)
tmpfs on /run type tmpfs (rw,nosuid,nodev,mode=755)
tmpfs on /var/volatile type tmpfs (rw,relatime)
tmpfs on /dev type tmpfs (rw,relatime,size=64k,mode=755)
devpts on /dev/pts type devpts (rw,relatime,mode=600)
/dev/mmcblk0p1 on /run/media/mmcblk0p1 type vfat (rw,relatime,fmask=0000,dmask=0000,allow_utime=0022,codepage=437,iocharset=iso8859-1,shortname=mixed,errors=remount-ro)
/dev/mmcblk0p2 on /run/media/mmcblk0p2 type ext4 (rw,relatime,data=ordered)
从最后两行不难看出,TF卡已经被识别并成功挂载。
启动过程介绍
EBAZ4205开发板启动成功后,大家最关心的就是Linux系统是怎么启动的,也就是启动过程。
简单一句话,由于采用了ZYNQ7000芯片,因此启动过程由ZYNQ7000芯片来决定。
ZYNQ芯片启动过程的四个阶段
ZYNQ芯片的嵌入式Linux系统启动过程如图3所示,分为ROM启动→FSBL(第一阶段引导加载器)→U-Boot(通用启动器)→内核运行等四个阶段,以下就按照启动过程的顺序,简单介绍每一阶段的运行机制。在深入学习篇将会读者详细介绍每个过程。

图3 ZYNQ芯片的Linux系统启动过程
ROM启动阶段
ROM启动阶段是启动的第一步,所谓的ROM指的是固化在ZYNQ芯片内部的不可修改代码,负责最基础的硬件初始化和加载FSBL(第一阶段引导加载器),以下用BootROM来描述。
BootROM完成以下功能:
- 检测启动模式
- 搜索BOOT.BIN
- 加载FSBL
FSBL阶段
BOOTROM结束后,就进入了FSBL阶段。FSBL是用户可修改的启动加载程序,是BOOT.BIN的一部分,主要完成更复杂的硬件初始化和后续镜像加载。
U-Boot阶段
FSBL结束后,就进入了U-Boot阶段,U-Boot是一段代码,也是BOOT.BIN的一部分。
U-Boot的这个U代表通用的意思,因此引入U-Boot这个中间件后,可以增强启动的灵活性,这样就可以支持各种芯片架构、各种操作系统以及各种外设的启动了。比如openwrt,就采用了U-Boot;ZYNQ7000芯片,同样也采用了U-Boot。
具体而言,EBAZ4205开发板的U-Boot用于加载设备树、Linux操作系统内核、根文件系统,并运行系统内核。
内核运行阶段
内核运行也分为多个阶段进行,包括内核解压与启动、挂载根文件系统和进行系统初始化。
内核运行后,嵌入式Linux系统就启动成功了。
NAND分区
从EBAZ4205开发板启动过程不难看出,启动涉及到了多个关键模块,需要在启动过程中逐一加载。
这些启动相关的模块存储在NAND Flash芯片中,而NAND Flash芯片类似于硬盘,可以被分区,为了方便管理,这些模块被分别存储到了Flash不同的分区。
在嵌入式linux系统,Flash的分区称为MTD(Memory Technology Device,存储技术设备)分区,而MTD是Linux系统用来管理Flash的子系统。
接下来我们来了解EBAZ4205的Flash芯片的具体分区情况。
我们登录嵌入式linux系统后,输入 cat /proc/mtd 命令:
root@zedboard-zynq7:~# cat /proc/mtd
dev: size erasesize name
mtd0: 00300000 00020000 "nand-fsbl-uboot"
mtd1: 00500000 00020000 "nand-linux"
mtd2: 00020000 00020000 "nand-device-tree"
mtd3: 00a00000 00020000 "nand-rootfs"
mtd4: 01000000 00020000 "nand-jffs2"
mtd5: 00800000 00020000 "nand-bitstream"
mtd6: 04000000 00020000 "nand-allrootfs"
mtd7: 013e0000 00020000 "nand-release"
mtd8: 00200000 00020000 "nand-reserve"
可以看到EBAZ4205有9个MTD分区,还可以看到每个MTD分区的编号、名称以及大小。
我们再输入 dmesg | grep nand-,还可以看到EBAZ4205每个MTD分区的起始和终止地址(其实是终止地址+1):
root@zedboard-zynq7:~# dmesg | grep nand-
0x000000000000-0x000000300000 : "nand-fsbl-uboot"
0x000000300000-0x000000800000 : "nand-linux"
0x000000800000-0x000000820000 : "nand-device-tree"
0x000000820000-0x000001220000 : "nand-rootfs"
0x000001220000-0x000002220000 : "nand-jffs2"
0x000002220000-0x000002a20000 : "nand-bitstream"
0x000002a20000-0x000006a20000 : "nand-allrootfs"
0x000006a20000-0x000007e00000 : "nand-release"
0x000007e00000-0x000008000000 : "nand-reserve"
这样,我们就可以做出MTD分区的分布表,如表1所示,不难看出其中第一个分区的内容就是前面讲到过的BOOT.BIN:
表1 EBAZ4205开发板的MTD分区
| 起始地址 | 终止地址+1 | 大小(MB) | 分区名 | 说明 |
|---|---|---|---|---|
| 0x000000000000 | 0x000000300000 | 3 | "nand-fsbl-uboot" | BOOT.BIN |
| 0x000000300000 | 0x000000800000 | 5 | "nand-linux" | 内核 |
| 0x000000800000 | 0x000000820000 | 0.128 | "nand-device-tree" | 设备树 |
| 0x000000820000 | 0x000001220000 | 10 | "nand-rootfs" | 备用 |
| 0x000001220000 | 0x000002220000 | 16 | "nand-jffs2" | Jffs2文件分区 |
| 0x000002220000 | 0x000002a20000 | 8 | "nand-bitstream" | 比特流 |
| 0x000002a20000 | 0x000006a20000 | 64 | "nand-allrootfs" | 根文件系统 |
| 0x000006a20000 | 0x000007e00000 | 19.872 | "nand-release" | 备用 |
| 0x000007e00000 | 0x000008000000 | 2 | "nand-reserve" | 备用 |
我们还可以输入 mtdinfo /dev/mtd0 命令,查看指定的mtd分区的详细信息:
root@zedboard-zynq7:~# mtdinfo /dev/mtd0
mtd0
Name: nand-fsbl-uboot
Type: nand
Eraseblock size: 131072 bytes, 128.0 KiB
Amount of eraseblocks: 24 (3145728 bytes, 3.0 MiB)
Minimum input/output unit size: 2048 bytes
Sub-page size: 512 bytes
OOB size: 64 bytes
Character device major/minor: 90:0
Bad blocks are allowed: true
Device is writable: true
小结
本章我们认识了NAND Flash技术,体验了EBAZ4205开发板自带的NAND Flash启动过程,了解了嵌入式Linux系统的启动过程,并查看了嵌入式Linux系统的信息以及MTD分区的概况。
第三章 体验SD混合启动
改造启动方式
前面我们已经用EBAZ4205开发板缺省的NAND方式启动了板载的嵌入式Linux系统。
但是这套系统也有很大的缺点,就是启动方式已经固化,不能调整,这样就无法深入学习嵌入式Linux系统的启动。
相反地,如果采用SD启动方式,操作系统的可用空间将更多、系统将更为强大、配置将更为灵活。
为此,我们需要将EBAZ4205改造为采用SD启动,这样才能进入后续内容的学习。
采用SD启动需要具备三个条件,一个是硬件上有TF的卡槽,这个商家已经代为安装了,并且前面也测试过,可以正常挂载TF卡。
另外一个条件是改变启动相关引脚配置,简单地说就是将开发板背面的电阻R2578焊下,移至R2577位置重新焊接,如图1所示,开发板即可实现从NAND Flash启动变为SD启动。

图1 重新焊接EBAZ4205开发板的电阻
最后一个条件是准备一张16GB或以上容量的空闲TF卡,格式化为FAT32的文件系统,然后下载百度网盘链接中SD混合启动目录,将目录中的boot.bin以及uEnv.txt两个文件拷到TF卡根目录下。其中,boot.bin是启动过程的第一个模块,而uEnv.txt存放有U-Boot使用的环境变量。
体验SD混合启动方式
准备工作结束后,我们首先不插TF卡,用前面的方法启动EBAZ4205开发板,会发现上电后EBAZ4205没有任何反应,绿灯也没有亮,这说明启动方式已经更改成功。
接下来,我们拔下USB转TTL模块,给EBAZ4205开发板断电。然后在TF卡槽插入做好的TF卡,USB转TTL模块插入电脑,给EBAZ4205开发板再次上电,这时我们可以看到绿灯点亮,并且xShell中也可以看到Linux系统启动的过程,并最终出现登录的提示符,说明SD方式启动成功。
大家会奇怪,TF卡上明明只有两个很小的文件,为什么就能启动Linux系统?
其实,这是我们平时的一个误区,就是认为采用SD启动时,NAND Flash存放的启动模块就无法使用了。
恰恰相反,得益与U-Boot的强大功能,我们只需要TF卡上放置Boot.bin和uEnv.txt两个文件,就可以实现从SD启动时读取NAND Flash上原有的启动内容,上电后就可以顺利进入到NAND Flash上自带的Linux系统,非常简单地验证SD启动的效果。
这种启动方式即混合启动,也就是启动的内容一部分在TF卡上,另外一部分在NAND Flash上,采用混合的模式,共同完成启动的过程。
当然,混合启动方式对uEnv.txt有要求,必须像如下的内容:
uenvcmd=run nandboot
kernel_load_address=0x2080000
kernel_size=0x500000
devicetree_load_address=0x2000000
devicetree_size=0x20000
nandboot=echo Origin Version: Copying Linux from NAND Flash to RAM... && nand info && run nandroot && nand read ${kernel_load_address} 0x300000 ${kernel_size} && nand read ${devicetree_load_address} 0x800000 ${devicetree_size} && bootm ${kernel_load_address} - ${devicetree_load_address}
nandroot=setenv bootargs 'console=ttyPS0,115200 root=/dev/mtdblock6 rootfstype=jffs2 noinitrd rw rootwait'
附带说一下,U-Boot对uEnv.txt的格式也有严格的要求,必须采用Unix类型的换行符,不能采用Windows类型的换行符。因此第一个uEnv.txt最好是下载后使用,不要直接在Windows系统中创建。
SD混合启动过程介绍
SD混合启动的过程
采用SD混合启动方式的ZYNQ芯片的嵌入式Linux系统启动过程如图2所示,依然分为ROM启动→FSBL→U-Boot→内核运行等四个阶段,其中深色背景框说明SD混合启动方式与NAND启动方式有所不同。

图2 ZYNQ芯片的Linux系统SD混合启动过程
ROM启动阶段
ROM启动阶段是启动的第一步,所谓的ROM指的是固化在ZYNQ芯片内部的不可修改代码,负责最基础的硬件初始化和加载FSBL(第一阶段引导加载器),以下用BootROM来描述。
BootROM完成以下功能:
- 检测启动模式
- 初始化SD卡设备
- 读取分区表MBR
- 访问文件系统
- 读取BOOT.BIN
- 校验BOOT.BIN
- 解析分区
- 搬迁FSBL
- 加载FSBL
FSBL阶段
BOOTROM结束后,就进入了FSBL阶段,FSBL相关功能如下所示:
- 初始化PS端
- 检测启动设备
- 解析BOOT.BIN
- 加载FPGA比特流
- 加载U-Boot
SD启动与NAND Flash启动的主要差别就是,SD启动时BOOT.BIN文件需要从SD上读取,而不是NAND Flash。
U-Boot阶段
FSBL结束后,就进入了U-Boot阶段,用于加载Linux操作系统内核。
U-Boot需要完成如下工作:
- 外设驱动
- 环境变量
- 加载内核
- 加载设备树
- 设置启动参数
- 启动内核
SD启动与NAND启动的另外一个重要差别就是,SD启动时U-Boot的环境变量来自SD卡上的环境变量文件uEnv.txt,这样就可以灵活修改启动配置,适配不同的启动需求。
内核运行阶段
内核运行阶段首先进行内核解压与启动,主要工作有:
- U-Boot将控制权转交给内核uImage
- uImage解压自身
- 初始化基本硬件
- 加载设备树
- 解析并展开设备树
接下来,挂载根文件系统。
最后进行系统初始化。
这一阶段,SD启动与NAND启动的工作是一致的,没有差别。
小结
本章我们改造了EBAZ4205开发板的启动方式,体验了EBAZ4205开发板的SD混合启动过程。
第四章 体验基于SD的分区启动方式
了解一下SD分区启动方式
前面我们已经用EBAZ4205开发板SD方式启动了板载的嵌入式Linux系统。
但是,这套板载的嵌入式Linux系统存在不少问题,比如内核版本比较低,内置的工具不齐全,甚至没有opkg,没有办法安装新的系统工具,因此使用起来非常不便。
既然我们已经采用SD启动,就可以借鉴树莓派或者ADALM Pluto的启动方式,将启动相关的文件和Linux系统都放到TF卡上,用TF卡上的全新Linux系统替换掉板载的嵌入式Linux系统。这种方式与之前介绍的混合启动方式不同,是一种完全的SD启动方式。
在树莓派系统中,TF卡做成两个分区,一个分区是启动分区,放置了启动文件。这个分区采用FAT的文件系统,可以通过windows系统访问,方便进行配置;另外一个分区是EXT4文件分区,运行树莓派的Raspberry Pi OS,也就是一种Linux系统。
从技术上说,树莓派的启动方式就是基于SD的分区启动方式。
业界知名的ADI公司的ADALM Pluto软件无线电设备,也借鉴了树莓派的启动方式。市面上发售的ZYNQ开发板R210,标配也是基于SD的分区启动方式。
如何制作支持分区启动的TF卡呢?通常有两种方法:
第一种方法是自行生成全套的启动文件以及Linux系统。这是网上介绍的主流方法,比如简书上就有详细的操作步骤。
这种方法需要安装Vivado工具以及编译用的Linux环境,安装要求高,步骤很多,操作复杂,适合有一定经验的读者。
考虑到我们系列文章面向的是入门读者,因此就没有选择这种全自制的开荒方案,而是选用了第二种简洁的方案,也就是借鉴了深入学习中使用的ZYNQ开发板R210的启动TF卡制作方案。
制作TF启动卡
我们首先 下载树莓派的镜像烧写工具:Raspberry Pi imager,然后安装Raspberry Pi imager,如图1所示。

图1 安装Raspberry Pi imager
我们选择I accept the agreement,指定安装路径,点击next进行安装,如图2所示。

图2 安装Raspberry Pi imager的过程
接下来下载百度网盘上转存的R210的系统镜像: 2019_R1-2020_06_22.zip。
随后找一张16GB或更大的空闲TF卡,插入电脑,运行之前安装好的树莓派的镜像烧写工具, 出现如图3所示的界面,用来设置TF卡的烧录参数。

图3 Raspberry Pi imager的界面
设置烧录参数时, “树莓派设备”项不用选择,“操作系统”项先选择“使用自定义镜像”,再选择刚刚下载的R210的系统镜像,“存储设备”选择对应的TF卡,如图4和图5所示。

图4 选择操作系统

图5 选择存储设备
当出现如图6的烧录参数界面时,点击下一步。

图6 查看烧录参数
出现图7所示的弹窗时,点击最右边的否,烧录过程就启动了。

图7 不应用自定义系统配置
烧录过程需要运行5到10分钟。烧录完成后,将TF卡重新插拔,就可以在windows系统中看到boot分区。
接下来,我们要下载百度网盘链接中SD分区启动目录中的文件,包括Boot.bin、uEnv.txt、devicetree.dtb以及uImage等4个文件,并将这四个文件复制到TF卡boot分区根目录,就完成了TF启动卡的制作。
体验SD分区启动方式
制作好TF启动卡后,我们先拔下USB转TTL模块,给EBAZ4205断电。然后在TF卡槽插入做好的TF启动卡,USB转TTL模块插入电脑,给EBAZ4205再次上电,这时我们可以看到绿灯点亮,并且xShell中也可以看到Linux系统启动的过程,并最终无需登录,直接进入了Linux系统,说明SD分区方式启动成功。
Welcome to Linaro 14.04 (GNU/Linux 4.14.0 armv7l)
* Documentation: https://wiki.analog.com/ https://ez.analog.com/
New release '16.04.6 LTS' available.
Run 'do-release-upgrade' to upgrade to it.
root@analog:~#
再次强调一下,U-Boot对uEnv.txt的格式有严格的要求,必须采用Unix类型的换行符,不能采用Windows类型的换行符。因此uEnv.txt最好是下载后使用,不要直接在Windows系统中创建。
认识一下启动相关文件
接下来,我们认识一下Linux系统启动用到的3个主要文件:uEnv.txt、devicetree.dtb以及uImage。
uEnv.txt
uEnv.txt是个文本文件,存放有U-Boot使用的环境变量,具体内容如下:
bootargs=console=ttyPS0,115200 root=/dev/mmcblk0p2 rw earlycon rootfstype=ext4 rootwait cpuidle.off=1
uenvcmd=run tfboot
kernel_image=uImage
kernel_load_address=0x2080000
devicetree_image=devicetree.dtb
devicetree_load_address=0x2000000
tfboot=echo Copying Linux from SD to RAM... && fatload mmc 0 ${devicetree_load_address} ${devicetree_image} && fatload mmc 0 ${kernel_load_address} ${kernel_image} && bootm ${kernel_load_address} - ${devicetree_load_address}
uEnv.txt中的环境变量包括变量以及命令脚本两种类型,比如上文中的bootargs、kernel_image等,均为变量;uenvcmd 和tfboot就是命令脚本。
不难看出,分区启动与混合启动的uEnv.txt是完全不同的。
devicetree.dtb
devicetree.dtb是一个二进制文件,是系统设备树信息的编译结果。设备树指的是嵌入式Linux系统所支持的硬件设备,相当于EBAZ4205开发板的硬件信息。
devicetree.dtb由U-Boot加载,分区启动使用的设备树文件存放在TF的boot分区,方便修改和更新。
uImage
uImage是一个二进制文件,包括文件头以及一个压缩的嵌入式Linux内核镜像。文件头中包含内核镜像的各种信息,而Linux内核镜像包含了各种硬件设备的驱动。
uImage同样由U-Boot加载,分区启动使用的内核镜像文件存放在TF的boot分区,方便修改和更新。
SD分区启动过程介绍
SD分区启动的过程
采用SD分区启动方式的ZYNQ芯片的嵌入式Linux系统启动过程如图8所示,依然分为ROM启动→FSBL→U-Boot→内核运行等四个阶段,其中深色背景框说明SD分区启动方式与混合启动方式有所不同。

图8 ZYNQ芯片的Linux系统SD分区启动过程
不难看出,在ROM启动和FSBL这两个阶段,SD分区启动方式与混合启动方式是一致的,因此我们就跳过这两个阶段,只介绍后续有差别的阶段。如果读者对这两个阶段感兴趣,可以查看前面的内容。
U-Boot阶段
FSBL结束后,就进入了U-Boot阶段,用于加载Linux操作系统内核。
SD分区启动与混合启动的主要差别就是U-Boot使用的环境变量文件uEnv.txt内容不同,这样可以适配不同的启动需求。
另外一个显著差别是U-Boot加载的Linux系统内核有区别,相对而言SD分区启动使用的内核版本更高。
内核运行阶段
这一阶段,SD分区启动与混合启动的工作方式大体一致,主要差别是Linux系统的根文件系统存放地点不同:SD分区启动时根文件系统来自TF卡的分区,而混合启动时根文件系统来自MTD分区。
由于TF卡分区的容量远远大于MTD分区,因此SD分区启动时系统可以安装更多的应用软件与工具,系统的功能更为强大。
小结
本章我们制作了用于EBAZ4205开发板的TF启动卡,利用该TF卡启动了EBAZ4205开发板,体验了EBAZ4205开发板的SD分区启动过程,并对比了SD分区启动与混合启动方式的差别。
至此,嵌入式Linux系统启动的入门学习已经完成,接下来大家可以开启嵌入式Linux系统启动的深入学习之旅。