前情提要:从零开始的ZYNQ学习(基于矿卡EBAZ4205)(一)
本文由长春理工大学电子信息工程学院C&I实验室所有,已获得原作者发布授权。转载请注明出处。
本文编写过程中参考了很多前辈的记录,在此表示感谢,已将所有参考项列于文末。
当前版本R1.0(预发布)。
作者联系方式:E-mail: [email protected]
网上有大佬前辈从源码构建了矿卡可用的镜像,参见zynq[2] Linux from scratch,实在是太详细了,因此不再重复(实际上是我太懒不想去做)。本章尝试使用官方提供的Petalinux工具生成启动镜像,使用TF卡启动方式验证镜像的正确性,并将其烧录到NAND Flash中。
本章涉及到的外设有:DDR、UART1、TF、NET0。
PetaLinux 是一种嵌入式Linux软件开发套件(SDK),主要用于XILINX FPGA基片上系统设计。由于其采用Buildroot构建系统,因此可以在简单的配置下,一步生成所需要的bootloader、kernel、rootfs镜像以及应用软件库。
Petalinux由Xilinx官方提供,对于不同版本的Vivado,Petalinux也有对应的版本,安装时需注意选择和区分。
这里必须得意一下,安装流程我曾经在CSDN上写过,庆幸于使用的同样是Markdown语言,我可以轻松将那些文字和图片拷贝过来,哈哈。
对于使用流程来说,大部分人可能还是比较喜欢Windows环境,而且因为本机安装的是Windows,而计算机硬件的资源又有限,所以在虚拟机中运行XILINX所有的开发工具不太方便。在参考了大部分开发环境搭建方式后,个人觉得“在Windows下使用Vivado生成板级描述文件,传到虚拟机中使用Petalinux生成烧录镜像,再使用Windows下的SDK进行烧写”的开发方式是在本地计算机资源有限的情况下比较容易被接受的。
安装准备包括安装文件和参考文件。
安装文件的名称是petalinux-v2017.4-final-installer.run,官方网站可以下载,页面链接:
XILINX下载页-petalinux存档
安装包选择其中MD5值为9b406fa5cc732da52944b3ce6718e19d的7.86GB的单文件。
UG1144是非常实用的手册,该用户指南中介绍了Petalinux的一切官方让你知道的。上图中的右侧,点击 Petalinux工具文档 项,在页面中找到 《UG1144 - PetaLinux 工具文档:参考指南 (中文版) (v2019.1)》 文档下载之(当然你照着这篇文章安装的话可以不用参考此指南)。
可能你想问,我安装的是2017.4版本的Petalinux,为什么这里要下载的是2019.1版本的呢?因为截至目前,官网中只有这个版本的UG1144是中文的,读起来比较顺畅,而且与2017.4版本在大体描述上相差不大(…也许吧)。
搭建过程网上有的是说明,在此只说一下硬盘空间分配的问题,我把我目前安装完之后的情况告诉你,在Ubuntu采用最小安装、移除无关组件、安装必要组件、安装vmware-tool、保存安装文件和安装完之后的文件的情况下,硬盘占用小于30GB。
注意,这个版本的Petalinux推荐使用Ubuntu16.04.6LTS进行安装,因为其它版本的Ubuntu对它的支持可能不是很好,会出问题,比如在Ubuntu18.04中,安装后执行settings.sh后会出现下图所示错误、以及使用petalinux-build命令编译的时候会出现“需要支持en_US.UTF8”等问题,而在Ubuntu16.04中是正常的。比如:
《UG1144 - PetaLinux 工具文档:参考指南 (中文版) (v2019.1)》文档对Ubuntu下依赖包的配置描述不完全适用于2017.4版本的Petalinux。Petalinux2017.4的依赖包如下,直接复制粘贴运行就行了(其中有可能安装时会重复,但是无关紧要),安装时注意保持网络畅通:
sudo apt install make net-tools libncurses-dev libncurses-dev zlib1g:i386 flex libssl-dev bison libselinux1 gnupg wget diffstat chrpath socat xterm autoconf libtool tftpd unzip texinfo zlib1g-dev gcc-multilib build-essential gzip pax screen gawk tofrodos xvfb python git libsdl1.2-dev libglib2.0-dev
首先要注意此程序不能在root权限下安装,比如运行前加“sudo”是不行的,它会提示并且运行不下去。
在运行时如果不指定安装的目录,会安装到安装文件所在目录下,而且还不会自动新建文件夹,如果安装到opt之类的目录,记得把目录权限改成rwxr-xr-x(755),不然等上十几分钟之后安装不了心情是很崩溃的。
./petalinux-v2017.4-final-installer.run /安装位置
安装流程大致为:对安装包校验->解压文件->确认3个协议->(安装目录提示——如果没有指明目录的话)->完成安装。
首先进入到安装目录下执行:
source settings.sh
而后在终端中输入 petalinux- 并按两次TAB键,如果出现命令补全提示,那么就是OK了。
如果这台虚拟机只用来开发Petalinux,那么可以把source语句写入到.bashrc文件中,这样在每次启动终端的时候都会自动加载了。
即在~/.bashrc文件最后增加如下语句:
source /petalinux安装路径/settings.sh
那这些petalinux命令是用来干嘛的呢?参考手册中13页中的说明如下:
至此,Petalinux2017.4在Ubuntu16.04下的环境配置完成。
在使用Etron的DRAM版本的矿卡上,建议断开R1485电阻并焊接C377、C380电容(22pF)和Y3晶振(25.000MHz)为IP101GA提供时钟信号,否则在U-Boot和Linux下网络功能将不可用。具体说明参见4.6-(1)小节。
注:为方便本章后续调试,建议修改R2584和R2577电阻接法,使用开关选择启动引脚MIO[5]为高电平或低电平,进而实现TF卡启动方式和NAND启动方式的切换。
若采用上图焊接方法,确认无误后切记固定,防止外力导致电阻焊盘脱落!
Vivado工程的修改紧接着5.4-(2)小节进行,TF卡可用于内核镜像的快速验证,网口则是Linux开发的必备接口。
在ZYNQ配置界面“MIO Configuration”中,继续勾选“ENET 0”和“SD 0”:
其中,ENET 0的IO选择EMIO,因为在PS_MIO[16:27]中,MIO[24]和MIO[25]已经被UART1占用了。SD 0的IO保持默认,其CD、WP和Power均不需选择,因为矿卡上未做引出。
注:因为SD 0仅引出了数据/时钟引脚,故不支持插拔检测。例如从NAND启动后再插入TF卡,不会自动生成设备节点;在TF卡空闲状态下带电拔出后重新插入不一定会影响后续读写等。
解释:在ZYNQ中,EMIO是指从PL端引出的PS端口,与此相对的MIO是在PS内部集成,功能固定的具有复用功能的引脚。
在“Clock Configuration”中,设置ENET 0为百兆速度:
接着,把之前裸机调试时精简掉的选项增加上(注:暂不清楚是否有必要):
最后,增加一个TTC模块,Linux需要它:
因为矿卡的网口通过EMIO引出,因此需手动分配这些引脚。另外,由于IP101GA是千兆网卡,查看原理图可知,其TXD和RXD共有8个,而在百兆网卡使用的MII接口中,TXD和RXD仅有4个,故需显式地增加两个Concat模块将8位转为4位,否则多余的引脚引出但未分配IO,最后生成比特流文件时会报错。
注:在ZYNQ的Block Design中,Concat IP可用于将分离的线拼接成单一线输出,相当于Verilog描述的拼接操作。其输入端口数和位宽均可配置。在其它参考设计中,有使用Slice模块代替下图中xlconcat_1模块的,其最终实现效果与下图所示一致。
增加IP核的操作与增加ZYNQ7的IP核操作相同。
最后将这些器件按照下图所示连接起来:
注:可通过右键端口->“Make External”做端口引出;通过右键端口->“Disconnect Pin”取消引出。
点击左侧边栏“Run Synthesis(运行综合)”,综合过程中会弹出关于数据位宽的警告,此处忽略:
而后点击“Open Synthesized Design(打开综合设计)”对网口的引脚进行分配,在弹出的框中点“Define Target”
set_property IOSTANDARD LVCMOS33 [get_ports ENET0_GMII_RX_CLK_0]
set_property IOSTANDARD LVCMOS33 [get_ports ENET0_GMII_TX_CLK_0]
set_property IOSTANDARD LVCMOS33 [get_ports {ENET0_GMII_TX_EN_0[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports {enet0_gmii_txd[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports {enet0_gmii_txd[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {enet0_gmii_txd[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {enet0_gmii_txd[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports ENET0_GMII_RX_DV_0]
set_property IOSTANDARD LVCMOS33 [get_ports MDIO_ETHERNET_0_0_mdc]
set_property IOSTANDARD LVCMOS33 [get_ports MDIO_ETHERNET_0_0_mdio_io]
set_property IOSTANDARD LVCMOS33 [get_ports {enet0_gmii_rxd[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports {enet0_gmii_rxd[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {enet0_gmii_rxd[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {enet0_gmii_rxd[3]}]
set_property PACKAGE_PIN U14 [get_ports ENET0_GMII_RX_CLK_0]
set_property PACKAGE_PIN U15 [get_ports ENET0_GMII_TX_CLK_0]
set_property PACKAGE_PIN W19 [get_ports {ENET0_GMII_TX_EN_0[0]}]
set_property PACKAGE_PIN W18 [get_ports {enet0_gmii_txd[0]}]
set_property PACKAGE_PIN Y18 [get_ports {enet0_gmii_txd[1]}]
set_property PACKAGE_PIN V18 [get_ports {enet0_gmii_txd[2]}]
set_property PACKAGE_PIN Y19 [get_ports {enet0_gmii_txd[3]}]
set_property PACKAGE_PIN W16 [get_ports ENET0_GMII_RX_DV_0]
set_property PACKAGE_PIN W15 [get_ports MDIO_ETHERNET_0_0_mdc]
set_property PACKAGE_PIN Y14 [get_ports MDIO_ETHERNET_0_0_mdio_io]
set_property PACKAGE_PIN Y16 [get_ports {enet0_gmii_rxd[0]}]
set_property PACKAGE_PIN V16 [get_ports {enet0_gmii_rxd[1]}]
set_property PACKAGE_PIN V17 [get_ports {enet0_gmii_rxd[2]}]
set_property PACKAGE_PIN Y17 [get_ports {enet0_gmii_rxd[3]}]
此处EMIO的设计流程大致为:将设计图中的端口名与PL端扩展IO建立对应关系,并对这些扩展IO的基本属性和状态进行设置即可。
Ctrl+S保存,此时效果如下:
直接点击左侧边栏的“Generate Bitstream(生成比特流)”,一键完成综合、实现和比特流生成。
注:这里点击“Generate Bitstream”只是为了方便,Petalinux构建过程中将基于hdf文件自动生成FSBL和需要的比特流文件。
接续上一步,Petalinux需要Vivado生成的硬件描述文件(*.hdf)作为生成镜像的配置依据,且可自动生成FSBL和比特流文件。因此SDK中只需要建立前文中适配矿卡的下载用FSBL即可。
恭喜你走到这一步!接下来我们转到Ubuntu平台,开始激动人心的Petalinux工程!
注意:这里假设你已经安装好了Petalinux2017.4环境。
注意:请确保每一次打开Terminal运行“petalinux-xxx”命令之前,总是执行了“source settings.sh”操作。每次打开Terminal都需重新进行该操作。
说明:本文示例目录在/home/wind/下(我的用户名为wind),后续示例基于此路径。
在当前用户目录下打开Terminal,执行:
petalinux-create --type project --template zynq --name EBAZ4205-linux
即可在当前目录下建立一个名为EBAZ4205-linux、面向ZYNQ的空白Petalinux工程。
将Vivado中导出的硬件描述文件(*.hdf)拷贝到Petalinux工程目录下,并在工程目录执行:
petalinux-config --get-hw-description=./
即可完成工程的初始化。
在工程目录下执行:
petalinux-config
进入Petalinux的配置菜单,并做以下修改:
注:在“Linux Components Selection”项中我们可以看到其中默认已经勾选了自动生成FSBL。
修改“Subsystem AUTO Hardware Settings(子系统自动硬件设置)”->“Advance bootable images storage Settings(高级启动镜像存储设置)”->“boot image settings(启动镜像设置)”->“image storage media(镜像存储介质)”,如果需要从NAND Flash启动,请选择“primary flash(Flash优先)”,如果需要从TF卡启动,请选择“primary sd(SD优先)”;
注:在此修改过程中可注意到,启动镜像名(默认为BOOT.BIN)在此处修改。
修改“Subsystem AUTO Hardware Settings(子系统自动硬件设置)”->“Advance bootable images storage Settings(高级启动镜像存储设置)”->“kernel image settings(内核镜像设置)”->“image storage media(镜像存储介质)”,如果需要从NAND Flash启动,请选择“primary flash(Flash优先)”,如果需要从TF卡启动,请选择“primary sd(SD优先)”;
注:在此修改过程中可注意到,Uboot载入的镜像名(默认为image.ub)在此处修改。
修改“u-boot Configuration”->“netboot offset”项的值为0x08000000;
注:该值为Uboot将镜像加载到的内存地址,默认为0x10000000,即256MiB,然而矿卡采用的DDR3是单片的256MiB颗粒,如果保持默认值,会在启动时出现以下提示:
...... Loading Kernel Image ... OK Loading Ramdisk to 07a8a000, end 07fff726 ... OK ERROR: image is not a fdt - must RESET the board to recover. FDT creation failed! hanging...### ERROR ### Please RESET the board ###
建议修改“Image Packaging Configuration(镜像打包配置)”,取消选择“Copy final images to tftpboot(拷贝最终镜像到tftp启动目录)”,这可以消除掉编译结束后的恼人提示,让结果展示的更加完美一点>v<;
建议修改“Image Packaging Configuration(镜像打包配置)”->“Root filesystem type(根文件系统类型)”为“INITRAMFS”,这将使本章进行的更加顺利,并降低学习难度。
注:不要因为从TF卡启动而将此项选择为“SD Card”,否则默认将从TF卡的第二分区启动根文件系统,而本章还没进行到“制作、构建和移植根文件系统”那一步。
而后保存并退出,等待命令完成。
在工程目录下执行:
petalinux-config -c u-boot
进入Uboot的配置菜单,并可做以下修改:
建议修改“delay in seconds before automatically booting”为2(秒),减少系统启动时间,从而提高调试效率;
建议使能“Networking support”项,以便于网络调试;
建议在“Command line interface”->“Network commands”中,增加对tftp相关命令和ping命令的支持,以便于网络调试;
可以修改“Command line interface”->“Shell prompt”为自己喜欢的字符。
而后保存并退出,等待命令完成。
在工程目录下执行:
petalinux-build
有记录如此说:二次修改后可使用:
petalinux-build -x mrproper -f
清除编译缓存以防止出现修改不生效的情况。
注意:此命令会重置整个工程目录,petalinux-config需要重新读取hdf文件,但u-boot等的配置文件不会被重置。
注:作者在首次编译通过后,使用该命令清除缓存,再次编译出现了不通过的情况,不知何故。
编译可能需要几十分钟(取决于计算机配置),编译完成后,在./images/linux/下存放着生成的镜像文件。
在工程目录下执行:
cd ./images/linux/
petalinux-package --boot --format BIN --fsbl zynq_fsbl.elf --fpga ZYNQ7010_wrapper.bit --u-boot
即可在当前目录下生成BOOT.BIN和image.ub两个文件,其中BOOT.BIN=FSBL+bitstream+SSBL(U-Boot);image.ub=dtb+kernel+rootfs。
注:如果./images/linux/下已经存在BOOT.BIN和image.ub文件,则需在上述命令末尾增加“–force”以执行覆盖,否则会出现失败提示。
取一张TF卡,格式化为FAT或FAT32,将上一步生成的BOOT.BIN和image.ub保存其中。插入到矿卡的TF卡槽中,并设置矿卡为SD启动方式。连接调试串口到计算机并在终端中打开,矿卡上电即可看到输出。默认的用户名和密码均为“root”。
注:需从TF卡启动时,请确保Petalinux工程配置中“image storage media(镜像存储介质)”设置为“primary sd(SD优先)”,修改后需重新编译并生成镜像。详见6.4-(3)-2)章节。
首先,为了使Petalinux构建出从NAND启动的镜像,需确保Petalinux工程配置中“image storage media(镜像存储介质)”设置为“primary flash(Flash优先)”。详见6.4-(3)-2)章节。
注:如果将TF卡启动镜像的BOOT.BIN下载到NAND,其Uboot依然会尝试从MMC加载,纵使SD卡存在且存有有效镜像,这也不是我们希望的。
TF和NAND启动方式最大的不同在于,前者使用的启动命令:
fatload mmc SD器件号[0,1] 内存载入地址 镜像名称
是基于文件名的,因为文件系统的存在,文件的存储位置显得不那么重要。但在NAND启动方式中,Uboot使用的:
nand read 内存载入地址 存储起始地址 数据长度
则是基于地址的拷贝。因此,我们需要对Uboot分区做一些调整。
在这里我们不妨贴出两种启动方式下的Uboot启动指令,在Uboot命令行执行:
printenv
即可打印当前Uboot环境设置,它们有点多,因此我只摘抄了默认启动指令部分。
SD启动方式的启动指令如下:
bootcmd=run default_bootcmd default_bootcmd=run cp_kernel2ram && bootm ${netstart} cp_kernel2ram=mmcinfo && fatload mmc 0 0x8000000 image.ub netstart=0x8000000
NAND启动方式的启动指令如下:
bootcmd=run default_bootcmd default_bootcmd=run cp_kernel2ram && bootm ${netstart} cp_kernel2ram=nand read ${netstart} ${kernelstart} ${kernelsize} netstart=0x08000000 kernelstart=0x300000 kernelsize=0xa00000
这里的具体设置与后文匹配。
在工程目录下执行:
petalinux-config
进入Petalinux工程配置,修改“Subsystem AUTO Hardware Settings(子系统自动硬件设置)”->“Flash Settings(Flash设置)”为下图所示的参数:
注:这些参数取决于生成的镜像的大小,上面的设置留出了一部分余量。
而后执行编译和打包,重新生成BOOT.BIN和image.ub文件,具体过程如前文所述。
打开Xilinx SDK的下载界面,连接好矿卡的JTAG、串口线和供电。首先烧录BOOT.BIN,注意BOOT.BIN的偏移为0:
而后再下载image.ub,将该文件重命名为*.bin,因为SDK的下载器只认.mcs和.bin类型的文件。另外别忘了设置下载偏移:
确保矿卡为NAND启动方式。连接调试串口到计算机并在终端中打开,矿卡重新上电即可看到输出。默认的用户名和密码均为“root”。
注:Uboot启动时打印:
*** Warning - bad CRC, using default environment
表示从bootenv空间(前文分配的0x2E0000~0x300000)读取的数据的CRC校验不正确,这是因为首次下载时该区域中没有有效内容,只需在Uboot命令行中执行一次:
saveenv
保存启动环境配置到指定分区即可消除该警告。
在已经有Uboot的情况下,可使用Uboot本身提供的读写命令烧录镜像,这里用此方式尝试一下吧!这里使用的终端软件为SecureCRT V8.5.3。
在Uboot命令行执行:
mw.b 0x800000 ff 0xA00000 #将内存中8MiB~18MiB的空间全部填充0xFF
loadb 0x800000 #使用Kermit传输,向0x800000地址写入二进制数据
而后选择“传输”->“发送Kermit(K)…”,找到image.ub文件并发送(下图中发送的是之前改名之后的image.bin):
发送有点慢,它的速度还是很稳定的,所以剩余时间也基本是它显示的时长,趁着它下载,起来走动走动休息一下吧!
完成后依次执行以下命令将内存中的镜像拷贝到NAND中:
nand erase 0x300000 0xA00000 #擦除NAND Flash中3MiB~13MiB的空间
nand write 0x800000 0x300000 0xA00000 #将内存中的数据写入到NAND Flash
整个过程的打印如下:
如果你有过嵌入式开发经验,一定见过许多种不同的启动镜像结构,例如海思的uboot+kernel(with dtb)+rootfs的形式、全志的u-boot spl+u-boot+dtb+kernel+rootfs的形式等等,更别说从网络启动以及众多的文件系统类型。但是Petalinux中使用的image.ub是什么?
还记得Petalinux的编译过程吗?我觉得大部分人都会在第一次编译的时候兴奋地盯着屏幕看完这一整个过程的。你会发现petalinux-build命令的执行过程中依然包含了对u-boot和kernel的单独编译,在工程目录下的./images/linux/下生成的文件也证实了这一点。另外,在配置Petalinux的时候,有指定启动镜像名称的设置项。好吧,不卖关子了,馅儿都快漏出来了,image.ub是由mkimage命令生成的镜像,是一种打包文件。(Linux中“打包”的想法真是很常见呢!)
在Terminal中运行如下命令:
mkimage -l image.ub
可查看某次生成的image.ub的文件组织结构如下:
FIT description: U-Boot fitImage for plnx_arm kernel
Created: Sat Nov 7 14:30:08 2020
Image 0 (kernel@0)
Description: Linux Kernel
Created: Sat Nov 7 14:30:08 2020
Type: Kernel Image
Compression: uncompressed
Data Size: 3745696 Bytes = 3657.91 kB = 3.57 MB
Architecture: ARM
OS: Linux
Load Address: 0x00008000
Entry Point: 0x00008000
Hash algo: sha1
Hash value: bacb21fcc869a66f89282c1445a1bf233792c66f
Image 1 (fdt@0)
Description: Flattened Device Tree blob
Created: Sat Nov 7 14:30:08 2020
Type: Flat Device Tree
Compression: uncompressed
Data Size: 13641 Bytes = 13.32 kB = 0.01 MB
Architecture: ARM
Hash algo: sha1
Hash value: 4df8b976010f034a10f63072b61051413c6ed443
Image 2 (ramdisk@0)
Description: ramdisk
Created: Sat Nov 7 14:30:08 2020
Type: RAMDisk Image
Compression: uncompressed
Data Size: 5723987 Bytes = 5589.83 kB = 5.46 MB
Architecture: ARM
OS: Linux
Load Address: unavailable
Entry Point: unavailable
Hash algo: sha1
Hash value: 726dbb5b6575cdf601e6ad4973507afcd1f68b79
Default Configuration: 'conf@1'
Configuration 0 (conf@1)
Description: Boot Linux kernel with FDT blob + ramdisk
Kernel: kernel@0
Init Ramdisk: ramdisk@0
FDT: fdt@0
Configuration 1 (conf@2)
Description: Boot Linux kernel with FDT blob
Kernel: kernel@0
FDT: fdt@0
从上述信息中,我们可以发现,在所生成的image.ub中,打包了Kernel镜像、FDT设备树、一个RAMDisk镜像和两份配置,一份启动到RAMDisk,另一份则仅启动到Kernel。
在早期的Uboot镜像格式中,Kernel(±dtb)被包装成uImage的形式,即在二进制文件前增加一个文件头,用以说明压缩格式、镜像类型等。随着FDT(Flattened Device Tree,扁平设备树)在ARM中逐渐普及,为了达成“同一内核”的目标,Uboot设计了一种全新的镜像格式,即FIT uImage,FIT即Flattened Image Tree(扁平镜像树)。FIT格式可以在一个文件中包含多个镜像和配置,这样同一份镜像文件就可以适配多个平台。
FIT镜像的使用依赖其中保存的配置项,使用非默认配置项可使用如下Uboot命令(其中#和@必须有,配置号参照上面的文件结构):
bootm 镜像所在内存地址#conf@配置号
具体的内容可参见这篇博文:u-boot FIT image介绍
我们在配置Petalinux的时候选择的根文件系统类型为“INITRAMFS”,还记得吗?这种文件系统在启动时加载到内存,因为其运行基于内存,因此读写速度很快,但它是一个只读文件系统。因此想要将矿卡作为开发板,则最好的方法还是使用可读写的文件系统管理存储器。
当然我不打算在这章尝试使用NAND常用的yaffs2或者TF卡常用的ext4,那是后面章节要做的事情,我只是想稍微了解一下RAMFS,并记录下来而已。
“Initramfs”背后似乎隐藏着一个庞大的故事个长长的时间线。在了解Initramfs之前,我们要首先了解Initrd(Init RAM Disk,初始化RAM磁盘)。Initrd是一个在系统引导过程中挂载的、以磁盘结构存储在内存中的临时根文件系统,用来支持两阶段的引导过程。Initrd中包含必要的工具和脚本,用于在将控制权交给根文件系统上的init应用程序之前挂载所需的文件系统。Linux内核在此根磁盘上触发安装脚本(通常称为 linuxrc,但该名称不是必需的),此脚本的工作是准备系统、切换到真正的根文件系统,然后调用init。
虽然在一些情况下使用Initrd是必要的,但是它有一些缺点:
Initramfs 的诞生就是为了解决这些问题。Initramfs基于tmpfs,使用cpio进行归档,通过gzip进行压缩,它不是一个单独的块设备,所以没有缓存和额外的开销。
更多的介绍来源已放在文末参考资料列表中。
本文编写过程中参考的所有资料均列在下方。本文若与任何列表之外的文章、博客、视频、教程等描述相同或相似则纯属巧合。
另在此处再次对以下资料的作者们表示感谢。
————2020-11-17 @燕卫博————