搜索
bottom↓
回复: 0

《领航者ZYNQ之嵌入式Linux开发指南_V2.0》第二十章 编译ZYNQ镜像

[复制链接]

出0入234汤圆

发表于 2022-1-18 11:38:22 | 显示全部楼层 |阅读模式
1)实验平台:正点原子领航者V2 ZYNQ开发板
2)  章节摘自【正点原子】《领航者ZYNQ之嵌入式Linux开发指南_V2.0》
3)购买链接:https://detail.tmall.com/item.htm?id=609032204975
4)全套实验源码+手册+视频下载地址:http://www.openedv.com/thread-329957-1-1.html
5)正点原子官方B站:https://space.bilibili.com/394620890
6)正点原子FPGA技术交流QQ群:90562473
1.png

2.jpg


3.png


第二十章 另一种方式编译ZYNQ镜像

       本篇是ARM Linux驱动开发篇中的第一章,本章跟驱动开发并没有什么关系,由于前面我们一直都是使用xilinx的petalinux工具编译镜像文件,例如包括u-boot、linux内核、设备树、ZYNQ PL端的bitstream文件以及fsbl等,虽然petalinux功能上比较全面,但是在编译速度上太慢了!完全是在浪费时间,相信大家在使用petalinux的时候已经感受到了它给你带来的无奈之处;为此笔者专门去研究了一下,那本章笔者就带大家通过另外一种比较快的方式编译各种镜像文件。
      
本章采用分步式的方式编译启动开发板所需要的各种镜像文件,虽然步骤比较繁琐,但灵活性比较高;虽然本章使用的是另一种方式编译镜像,但还是得需要用到petalinux提供的一些工具,所以大家一定要安装petalinux。
       1.1创建Petalinux工程,生成BOOT.BIN

       对于ZYNQ而言,一个完整的linux系统包含PS和PL两个构件,其中PS构件包含fsbl、uboot、设备树文件、linux内核、根文件系统共5个要素,PL构件包含bit文件一个要素,当不使用PL的时候,该要素非必须。
       编写linux驱动的时候,经常改动的要素有设备树文件、linux内核、根文件系统,当然如果改动PL的话还需改动bit文件。因而我们将这些要素独立出来,从而方便修改变更。也就是说我们将bit文件从原先的BOOT.BIN文件独立出来,将image.ub文件分开为内核zImage和设备树dtb。另外将根文件系统放到SD卡的EXT4分区,加载启动速度。下面我们正式开始。
       本实验以领航者7010为例,将ZYNQ开发板资料盘(A盘)\4_SourceCode\3_Embedded_Linux\vivado_pro\Navigator_7010\Navigator_7010.sdk文件夹拷贝到Ubuntu系统目录下,例如/home/zynq/hdf/目录,大家根据自己的情况选择目录,如果大家用的是领航者7020,则选择ZYNQ开发板资料盘(A盘)\4_SourceCode\3_Embedded_Linux\vivado_pro\Navigator_7020\Navigator_7020.sdk文件夹。
       创建Petalinux工程的步骤在第六章Petalinux设计流程实战中已讲解,本章就不细述,也可直接使用第六章Petalinux设计流程实战的Petalinux工程。先在Ubuntu主机终端中选一个合适的路径以创建出厂镜像的Petalinux工程,然后在终端中输入如下命令:
  1. source /opt/pkg/petalinux/2018.3/settings.sh                   //设置petalinux工作环境
  2. petalinux-create -t project --template zynq -n ALIENTEK-ZYNQ  //创建Petalinux工程
  3. cd ALIENTEK-ZYNQ                                                                                        //进入到petalinux工程目录下
  4. petalinux-config --get-hw-description ../hdf/Navigator_7010.sdk/                //导入hdf文件
复制代码
       以上命令执行完成之后会自动在当前目录下创建一个名为ALIENTEK-ZYNQ的文件夹,也就是我们出厂镜像的petalinux工程对应的工程目录。
       注:后面更新vivado工程的时候,只需要从vivado工程中导出hdf文件,并在该Petalinux工程下使用“petalinux-config --get-hw-description hdf文件路径”命令即可。
       hdf文件导入成功之后会自动弹出petalinux工程配置窗口,如下图所示:
第二十章 另一种方式编译ZYNQ镜像1706.png

图 20.1.1 petalinux工程配置窗口

        进入“Subsystem AUTO Hardware Settings”菜单下,首先按照图 6.2.9 配置调试串口,配置完成后,进入“Advanced bootable images storage Settings”菜单中,移动到“dtb image settings”选项,如下图所示:
第二十章 另一种方式编译ZYNQ镜像1947.png

图 20.1.2 移动到“dtb image settings”选项

       进入“dtb image settings”选项并将image storage media设置为primary sd,如下图所示:
第二十章 另一种方式编译ZYNQ镜像2093.png

图 20.1.3设置image storage media为primary sd

       配置完成后,返回到最初的配置界面,进入到“Image Packaging Configuration”菜单下的“Root filesystem type (INITRAMFS)”子菜单下,如下图所示:
第二十章 另一种方式编译ZYNQ镜像2280.png

图 20.1.4 选择“SD card”

       选择“SD card”,按键盘上的“Enter”键返回。
       保存并退出。
       上面的配置是将dtb文件从image.ub文件中独立开来,并将根文件系统放到SD卡的EXT4分区。
       配置完成后,编译uboot,及生成BOOT.BIN文件,命令如下:
  1. petalinux-build -c u-boot
  2. petalinux-package --boot --fsbl --u-boot --force
复制代码
        执行结果如下图所示:
第二十章 另一种方式编译ZYNQ镜像2552.png

图 20.1.5 执行结果

       可以看到BOOT.BIN文件仅包含zynq_fsbl.elf和u-boot.elf文件,而没有包含bit文件,而这两个文件我们基本不会再改动,所以后面无论编写任何linux驱动以及更改Vivado工程,都不会改动BOOT.BIN文件了。
       1.2生成设备树文件
       在Petalinux工程中执行编译uboot后,会在工程的components/plnx_workspace/device-tree/device-tree/目录下生成设备树文件,如下图所示:
第二十章 另一种方式编译ZYNQ镜像2835.png

图 20.2.1 设备树文件

       上图中红框圈出的是我们需要用到的设备树文件,skeleton.dtsi文件我们一般不用。
       Linux设备树是是一个很重要的知识点,将会在后面的章节给大家详细说明,本章先不讲,这些文件后面我们会用到。
       至此,该小节内容结束,请继续下一小节的内容。
       题外话:
       如果读者在实际使用中需要使用新vivado工程的时候,BOOT.BIN文件是不需要变动的,但设备树文件会随着Vivado工程的不同而需要改动,所以需要重新生成设备树文件。
       重新生成设备树文件的方法有如下两种:
       第一种,也就是上一小节注中讲到的‘后面更新vivado工程的时候,只需要从vivado工程中导出hdf文件,并在该Petalinux工程下使用“petalinux-config --get-hw-description hdf文件路径”命令即可’。使用新Vivado工程的hdf文件配置Petalinux工程并不会生成新的设备树文件,还需要执行编译命令才行(不知道是不是Petalinux的一个小bug),例如编译uboot:
  1. petalinux-build -c u-boot
复制代码
       只有在编译完成后,才会在Petalinux工程的components/plnx_workspace/device-tree/device-tree/目录下生成新的设备树文件。
       既然Petalinux可以根据hdf文件描述的硬件信息自动配置U-Boot和内核所需的设备树文件,那么我们是不是也可以通过Petalinux工具的hsi命令来生成呢?
       第二种,使用Petalinux工具的hsi命令和xilinx的device-tree仓库。
       首先需要导入xilinx的device-tree仓库,在我们提供的资料包中已经给大家准备好了,路径为:ZYNQ开发板资料盘(A盘)\4_SourceCode\3_Embedded_Linux\misc\device-tree-xlnx-xilinx-v2018.3.tar.gz,大家也可以通过https://github.com/Xilinx/device-tree-xlnx/releases网址进行下载,选择2018.3版本.tar.gz压缩格式文件,如下所示:
第二十章 另一种方式编译ZYNQ镜像3889.png

图 20.2.2 设备树仓库下载

       Xilinx device-tree描述了设备与设备树之间的匹配关系,将下载好或是资料包中的device-tree-xlnx-xilinx-v2018.3.tar.gz压缩文件拷贝到Ubuntu系统目录下,例如/home/zynq/device-tree,大家根据自己的情况选择,然后将其解压当前目录,解压之后会产生一个device-tree-xlnx-xilinx-v2018.3文件夹,如下所示:
第二十章 另一种方式编译ZYNQ镜像4152.png

图 20.2.3 device-tree目录

       那么device-tree-xlnx-xilinx-v2018.3目录就是我们所需要的device-tree仓库。接下来我们执行hsi命令进入到hsi命令模式,如下所示:
  1. hsi
复制代码
第二十章 另一种方式编译ZYNQ镜像4310.png

图 20.2.4 hsi命令行

       执行命令之后就可以进入到hsi命令行模式下了,hsi命令行模式就跟我们的linux命令行模式差不多,都可以执行命令,只不过执行的命令不同;hsi命令是petalinux工具提供的,所以一定安装petalinux才行;在这个模式下可以执行一些命令,例如执行下面这条命令可以得到新的Vivado工程的设备树文件:
  1. open_hw_design /home/zynq/hdf/Navigator_7010.sdk/design_navigator_7010_wrapper.hdf
  2. set_repo_path /home/zynq/device-tree/device-tree-xlnx-xilinx-v2018.3
  3. create_sw_design device-tree -os device_tree -proc ps7_cortexa9_0
  4. generate_target -dir /home/zynq/linux/dts
复制代码
第二十章 另一种方式编译ZYNQ镜像4786.png

图 20.2.5 生成设备树文件

       首先也是通过open_hw_design命令打开hdf文件,然后使用set_repo_path命令设置device-tree仓库所在路径,例如/home/zynq/device-tree/device-tree-xlnx-xilinx-v2018.3;使用create_sw_design创建软件设计,” -os device_tree”指定了软件设计的类型,我们这里使用device-tree表示它是一个设备树类型,” -proc ps7_cortexa9_0”指定处理器的名称,在hsi命令模式下使用”xxxx -help”可以查看xxxx命令的用法说明,这里就不给大家列举了;最后使用generate_target命令去产生目标,也就是我们的设备树文件,” -dir /home/zynq/linux/dts”指定路径。
此时我们可以退出hsi命令行模式,在hsi命令行模式下执行exit命令退出该模式:
  1. exit
复制代码
第二十章 另一种方式编译ZYNQ镜像5259.png

图 20.2.6 退出hsi命令行模式

       进入到/home/zynq/linux/dts目录下,可以看到自动配置产生的.dts和.dtsi文件,如下所示:
第二十章 另一种方式编译ZYNQ镜像5381.png

图 20.2.7 生成设备树文件

       对于这两种方法各有优劣。第一种方法直接使用Petalinux工具解决,方便,但是Petalinux工具编译慢,修改一次Vivado工程就需要重新编译一次Petalinux工程。第二种方法麻烦,但在需要经常更改Vivado工程的情况下就比第一种方法效率高,而且也可以将第二种方法使用的命令写成脚本形式方便执行,参见20.6小节。在第四十八章我们演示了使用第一种方法生成新Vivado工程对应的设备树文件。
       1.3编译kernel
       本篇教程不使用前面移植后的Linux内核源码,我们用一份新的xilinx官方2018.3版本(这个版本是xilinx设定的版本,其linux版本为4.14.0)的内核源码,源码已经提供给大家了,路径为:ZYNQ开发板资料盘(A盘)\4_SourceCode\3_Embedded_Linux\资源文件\kernel\linux-xlnx-xilinx-v2018.3.tar.gz,大家也可以通过https://github.com/Xilinx/linux-xlnx/releases网址进行下载。
       将内核源码压缩包文件拷贝到Ubuntu系统目录中,例如/home/zynq/linux/kernel目录,并将其解压到当前目录,解压之后会产生一个linux-xlnx-xilinx-v2018.3文件夹,进入到该目录下,就可以看到内核源码目录下的文件和文件夹了,如下所示:
第二十章 另一种方式编译ZYNQ镜像6158.png

图 20.3.1 内核源码目录

       本小节我们直接在内核源码目录下进行编译,而不使用petalinux工具,因为内核也是经常改动的,而Petalinux编译慢。直接在内核源码目录下进行编译的知识前面都已经给大家介绍过了。
       1、添加设备树文件
       将前面生成的设备树文件(笔者这里生成的设备树文件在Petalinux工程的components/plnx_workspace/device-tree/device-tree/目录下)pcw.dtsi、pl.dtsi、system-top.dts以及zynq-7000.dtsi四个文件直接拷贝到内核源码目录下的arch/arm/boot/dts目录中。
       接下来我们需要对system-top.dts文件进行一个简单地修改,打开system-top.dts文件,修改之前内容如下:
  1. 示例代码 20.3.1 system-top.dts修改之前
  2.   1 /*
  3.   2  * CAUTION: This file is automatically generated by Xilinx.
  4.   3  * Version: HSI
  5.   4  * Today is: Mon Mar 16 02:51:23 2020
  6.   5  */
  7.   6
  8.   7
  9.   8 /dts-v1/;
  10.   9 #include "zynq-7000.dtsi"
  11. 10 #include "pl.dtsi"
  12. 11 #include "pcw.dtsi"
  13. 12 / {
  14. 13         chosen {
  15. 14                 bootargs = "earlycon";
  16. 15                 stdout-path = "serial0:115200n8";
  17. 16         };
  18. 17         aliases {
  19. 18                 ethernet0 = &gem0;
  20. 19                 i2c0 = &i2c2;
  21. 20                 i2c1 = &i2c0;
  22. 21                 i2c2 = &i2c1;
  23. 22                 serial0 = &uart0;
  24. 23                 serial1 = &uart1;
  25. 24                 spi0 = &qspi;
  26. 25         };
  27. 26         memory {
  28. 27                 device_type = "memory";
  29. 28                 reg = <0x0 0x20000000>;
  30. 29         };
  31. 30 };
复制代码
       这里我们对该文件进行一个简单地修改,修改之后如下所示:
  1. 示例代码 20.3.2 system-top.dts修改之后
  2.   1 /*
  3.   2  * CAUTION: This file is automatically generated by Xilinx.
  4.   3  * Version: HSI
  5.   4  * Today is: Mon Mar 16 02:51:23 2020
  6.   5  */
  7.   6
  8.   7
  9.   8 /dts-v1/;
  10.   9 #include "zynq-7000.dtsi"
  11. 10 #include "pl.dtsi"
  12. 11 #include "pcw.dtsi"
  13. 12 / {
  14. 13         model = "Alientek ZYNQ Development Board";
  15. 14
  16. 15         chosen {
  17. 16                 bootargs = "console=ttyPS0,115200 earlyprintk root=/dev/mmcblk0p2 rw rootwait";
  18. 17                 stdout-path = "serial0:115200n8";
  19. 18         };
  20. 19         aliases {
  21. 20                 ethernet0 = &gem0;
  22. 21                 i2c0 = &i2c2;
  23. 22                 i2c1 = &i2c0;
  24. 23                 i2c2 = &i2c1;
  25. 24                 serial0 = &uart0;
  26. 25                 serial1 = &uart1;
  27. 26                 spi0 = &qspi;
  28. 27         };
  29. 28         memory {
  30. 29                 device_type = "memory";
  31. 30                 reg = <0x0 0x20000000>;
  32. 31         };
  33. 32 };
  34. 33
  35. 34 &gem0 {
  36. 35         local-mac-address = [00 0a 35 00 1e 53];
  37. 36 };
  38. 37
  39. 38 &qspi {
  40. 39         #address-cells = <1>;
  41. 40         #size-cells = <0>;
  42. 41         flash0: flash@0 {
  43. 42                 compatible = "n25q512a","micron,m25p80";
  44. 43                 reg = <0x0>;
  45. 44                 #address-cells = <1>;
  46. 45                 #size-cells = <1>;
  47. 46                 spi-max-frequency = <50000000>;
  48. 47                 partition@0x00000000 {
  49. 48                         label = "boot";
  50. 49                         reg = <0x00000000 0x00500000>;
  51. 50                 };
  52. 51                 partition@0x00500000 {
  53. 52                         label = "bootenv";
  54. 53                         reg = <0x00500000 0x00020000>;
  55. 54                 };
  56. 55                 partition@0x00520000 {
  57. 56                         label = "kernel";
  58. 57                         reg = <0x00520000 0x00a80000>;
  59. 58                 };
  60. 59                 partition@0x00fa0000 {
  61. 60                         label = "spare";
  62. 61                         reg = <0x00fa0000 0x00000000>;
  63. 62                 };
  64. 63         };
  65. 64 };
复制代码
       修改完成之后保存退出即可!
       以上主要修改了bootargs属性、添加了model属性、网口0的MAC地址以及给qspi进行了分区操作。修改完成之后,我们还需要修改arch/arm/boot/dts目录下的Makefile文件,将设备树添加上去,如下:
第二十章 另一种方式编译ZYNQ镜像9713.png

图 20.3.2 Makefile中添加设备树

       修改完成之后保存退出即可!
       2、defconfig配置
       在内核源码目录下执行下面这条命令对内核进行defconfig配置:
  1. make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- xilinx_zynq_defconfig
复制代码
第二十章 另一种方式编译ZYNQ镜像9915.png

图 20.3.3 defconfig配置

       命令这里就不给大家解释了,前面我们已经解释过,需要注意的是命令中间的空格不要漏掉了,因为以前发现很多初学者老是会漏掉这些空格,这样就导致命令执行失败。
       3、menuconfig配置
       这里我们暂时就不进行配置,以后有需要的时候再配,先保持默认!
       4、编译内核
       执行下面这条命令编译内核源码:
  1. make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- zImage -j10
复制代码
第二十章 另一种方式编译ZYNQ镜像10187.png

图 20.3.4 编译内核

第二十章 另一种方式编译ZYNQ镜像10246.png

图 20.3.5 编译完成

       编译完成之后会在arch/arm/boot/目录下生成一个名为zImage的内核镜像文件,后面我们在用。
       5、编译设备树
       在内核里边我们需要单独编译出设备树的dtb文件,前面已经将我们所需要的设备树文件拷贝到内核的arch/arm/boot/dts目录下了,接下来执行下面这条命令编译system-top.dtb文件:
  1. make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- system-top.dtb -j10
复制代码
第二十章 另一种方式编译ZYNQ镜像10534.png

图 20.3.6 编译设备树

       编译成功之后会在arch/arm/boot/dts目录下生成system-top.dtb文件。
       1.4编译rootfs
       根文件系统我们直接使用petalinux进行编译即可。进入到Petalinux工程目录下,为了免去后面每次启动linux都要手动输入密码进入系统,所以我们先配置根文件系统免密码登录,进入根文件系统配置界面的命令如下
  1. petalinux-config -c rootfs
复制代码
       进入“Image Features  --->”菜单下,使能“debug-tweaks”,如下图所示:
第二十章 另一种方式编译ZYNQ镜像10838.png

图 20.4.1使能“debug-tweaks”

       这样配置后,会自动登录,不用再手动输入用户名和密码,方便调试。
       配置完成后,保存退出。
       接下来直接编译根文件系统:
  1. petalinux-build -c rootfs
复制代码
第二十章 另一种方式编译ZYNQ镜像10992.png

图 20.4.2 编译根文件系统

       等待其编译完成,完成之后产生的根文件系统压缩包在images/linux目录下,如下所示:
第二十章 另一种方式编译ZYNQ镜像11100.png

图 20.4.3 产生的根文件系统压缩包

       因为我们要使用SD卡启动,并且SD卡会有一个EXT4格式的分区专门存放根文件系统,所以我们要使用压缩格式的根文件系统,例如rootfs.tar.gz或rootfs.tar.bz2。
       1.5启动开发板
       经过上面一系列的过程之后,我们就已经得到了启动开发板的所有所需的镜像文件了。例如我们使用petalinux工具会生成image.ub和BOOT.BIN文件,使用这两个文件我们就可以启动开发板了,但是这里我们不这样做。
       前面给大家介绍过image.ub这个文件的本质,那么它其实是多个文件组合在一起的,包括内核镜像、dtb以及根文件系统,这样的做法有一个弊端,不够灵活,一个变了整个image.ub文件就得重新制作一遍,很麻烦。同样BOOT.BIN文件是fsbl镜像、u-boot镜像以及pl端bit文件集合在一起的,那么既然是集合在一起的,那么我们单独使用也是可以的嘛。
       所以我们这里的思路就是将内核镜像文件zImage、内核设备树文件以及根文件系统从image.ub文件中分离出来;而将bit文件从BOOT.BIN文件中分离出来,这样做之后我们的SD卡中将会存在5部分内容:zImage、dtb、rootfs、bit以及BOOT.BIN(fsbl镜像与u-boot镜像的集合体),明确之后我们将他们拷贝到我们的SD卡中。
       1、制作SD启动卡
       SD启动卡的制作方式在6.2.10小节当中已经给大家介绍过了,这里不再细说,笔者直接将一张16G的TF卡格式化了2个分区,FAT32和EXT4,如下所示:
第二十章 另一种方式编译ZYNQ镜像11840.png

图 20.5.1 SD启动卡分区信息

        2、拷贝镜像到FAT分区
        将前面过程当中生成的各种镜像文件拷贝到SD启动卡的FAT分区,包括zImage(内核镜像,内核源码目录arch/arm/boot/zImage)、system-top.dtb(内核设备树dtb文件,内核源码目录arch/arm/boot/dts/system-top.dtb)、system.bit(pl端bitstream文件,Petalinux工程目录下的images/linux/system.bit)。大家根据自己前面步骤当中文件存放的目录去找到相应的这些镜像文件。
       接下来我们需要将BOOT.BIN文件拷贝到FAT分区,那么此时来看看我们的FAT分区有哪些文件:
第二十章 另一种方式编译ZYNQ镜像12204.png

图 20.5.2 FAT分区中的文件

        为了方便、好看,笔者将system-top.dtb文件进行了重命名system.dtb,如下:
第二十章 另一种方式编译ZYNQ镜像12316.png

图 20.5.3 文件重命名

       3、将根文件系统解压到EXT4分区
       接下来我们需要将20.4小节编译的根文件系统压缩包文件解压到SD启动卡的EXT4分区,这里笔者使用rootfs.tar.gz压缩包文件,进入到rootfs.tar.gz压缩包文件所在目录,执行解压命令:
  1. sudo tar -xzf rootfs.tar.gz -C /media/linux/rootfs
复制代码
第二十章 另一种方式编译ZYNQ镜像12574.png

图 20.5.4 解压rootfs.tar.gz

       /media/linux/rootfs是笔者的SD启动卡对应的EXT4分区的挂载点,注意解压的时候需要使用前面要加sudo,也就是要以root用户的身份进行解压。解压完成之后执行sync命令将数据同步到SD卡中,之后卸载SD启动卡,卸载成功之后拔掉它。
第二十章 另一种方式编译ZYNQ镜像12771.png

图 20.5.5 卸载SD启动卡

       4、启动开发板
       将我们做好的启动卡插入开发板,连接电源、串口启动,打印信息如下所示:
第二十章 另一种方式编译ZYNQ镜像12876.png

图 20.5.6 开发板启动

       在U-Boot启动2秒倒计时之前,按回车或者是空格键停止启动,进入到U-Boot的命令行模式,因为现在不能直接启动,我们需要对U-Boot环境变量进行修改,在U-Boot命令行下执行下面这些命令设置环境变量,如下所示:
第二十章 另一种方式编译ZYNQ镜像13046.png

图 20.5.7 设置环境变量

  1. 示例代码 20.5.1 U-Boot环境变量设置
  2. env default -a
  3. setenv bitstream_load_address 0x100000
  4. setenv bitstream_image system.bit
  5. setenv bitstream_size 0x300000
  6. setenv kernel_img zImage
  7. setenv dtbnetstart 0x2000000
  8. setenv netstart 0x2080000

  9. setenv default_bootcmd '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} && run cp_kernel2ram && run cp_dtb2ram && bootz ${netstart} - ${dtbnetstart}; fi'
复制代码
       关于U-Boot命令的使用在前面已经给大家讲解过,不过这里也给大家简单地说明一下我们设置的这些环境变量的作用:
       首先第一条命令就是将uboot的环境还原到当前设置;第二条命令我们设置了bitstream_load_address变量存放bitstream文件从SD卡中拷贝到内存中的地址;第三条命设置了bitstream_image变量等于SD卡中bitstream文件的名字,也就是system.bit;第四条命设置了bitstream_size变量等于bitstream文件的大小;第五条命令设置了kernel_img变量等于SD卡中内核镜像的名字,也就是zImage;第六条命令设置了dtbnetstart变量,也就是设备树dtb文件从SD卡拷贝到内存中的地址;第七条命令设置了netstart变量,也就是内核镜像文件从SD卡拷贝到内存中的地址。dtbnetstart和netstarte变量在我们的这个U-Boot中默认是有的,只不过它们的内容并不适合当前的环境,所以需要重新设定。
       最后一条命令设置了default_bootcmd变量,该变量在我们使用的这个U-Boot中也是存在的,这里也是对它重新定义,这个变量的内容很长,我们可以把它的内容整理一下,如下:
  1. 示例代码 20.5.2 sdboot变量内容整理
  2. if mmcinfo; then
  3.     run uenvboot;
  4.     echo Copying Linux from SD to RAM... &&                                        // 打印字符串
  5.     load mmc 0 ${bitstream_load_address} ${bitstream_image} &&                // 从SD卡拷贝bitstream文件到内存
  6.     fpga loadb 0 ${bitstream_load_address} ${bitstream_size} &&        // 从内存中加载bitstream数据到FPGA
  7.     run cp_kernel2ram &&            // 从SD卡拷贝内核镜像到内存
  8.     run cp_dtb2ram &&        // 从SD卡拷贝设备树到内存
  9.     bootz ${netstart} - ${dtbnetstart};        // bootz启动内核
  10. fi
复制代码
      “&&”符号其实就是C语言中”与”,跟C语言里面的作用一样,${xxx}就是变量的引用,if … fi这个就是if条件判断语句了,fi表示条件判断的结束,U-Boot里边的这种语法很简单地,就不给大家细说了,如果不明白可以在网上找找资料。
       前面跟大家讲过,U-Boot中的bootcmd变量的作用,U-Boot启动内核或在命令行下执行boot命令时其实就是去执行bootcmd,那我们来看看bootcmd的内容是什么:
第二十章 另一种方式编译ZYNQ镜像14898.png

图 20.5.8 bootcmd的内容

       从上图可以知道,bootcmd的内容其实就是运行default_bootcmd,也就是上面定义的那个。
       变量设置完成之后,执行saveenv命令保存环境变量到QSPI Flash中,那么下次就不用再设置了
  1. savenev
复制代码
第二十章 另一种方式编译ZYNQ镜像15075.png

图 20.5.9 保存环境变量

       保存完成后执行boot命令启动内核或者执行reset重启开发板:
  1. boot
复制代码
第二十章 另一种方式编译ZYNQ镜像15174.png

图 20.5.10 启动内核(boot命令到内核启动信息太长,截内核启动部分)

第二十章 另一种方式编译ZYNQ镜像15259.png

图 20.5.11 进入系统

       后面我们的驱动开发篇将以本章使用的U-Boot源码、内核源码等进行开发工作。
       1.6tcl脚本
       前面我们在hsi终端下通过执行相应的命令去获取bit文件、自动生成设备树以及构建一个fsbl源码等,觉得这样非常的不方便,每次都要先执行hsi命令进入到hsi终端模式,然后在一个一个命令敲,这样感觉非常不好,那可不可以像shell命令一样,创建一个shell脚本之类的呢?其实是可以的,我们可以创建一个后缀名为.tcl的脚本,然后把我们的命令添加上去,然后直接执行这个脚本就行了。
       例如我在Ubuntu目录下新建一个hsi_test.tcl文件,内容如下所示:
  1.   1
  2.   2 hsi::open_hw_design /home/zynq/hdf/Navigator_7010.sdk/design_navigator_7010_wrapper.hdf
复制代码
       文件中的hsi::open_hw_design xxx.hdf就表示执行his的open_hw_design命令,后面跟着的参数就是对应的hdf文件路径了,例如我们将20.2小节中执行的命令写入到hsi_test.tcl脚本中,如下所示:
  1. 示例代码 20.6.1 tcl脚本示例 hsi_test.tcl内容
  2. 1 # tcl script test
  3. 2
  4. 3 hsi::open_hw_design /home/zynq/hdf/Navigator_7010.sdk/design_navigator_7010_wrapper.hdf
  5. 4 hsi::set_repo_path /home/zynq/device-tree/device-tree-xlnx-xilinx-v2018.3
  6. 5 hsi::create_sw_design device-tree -os device_tree -proc ps7_cortexa9_0
  7. 6 hsi::generate_target -dir /home/zynq/linux/dts
  8. 7
复制代码
       第一行#号表示注释。
       那我们如何执行hsi_test.tcl脚本呢?执行方法如下所示:
  1. xsct hsi_test.tcl
复制代码
第二十章 另一种方式编译ZYNQ镜像16302.png

图 20.6.1 运行hsi_test.tcl脚本

     “xsct xxx.tcl”即可!xsct也是petalinux工具安装的时候自带的,它也是命令行终端,例如运行xsct命令就会进入到xsct终端模式,如下所示:
第二十章 另一种方式编译ZYNQ镜像16455.png

图 20.6.2 xsct终端

       例如我们在xsct终端下也可以执行脚本中的命令,例如:
第二十章 另一种方式编译ZYNQ镜像16544.png

图 20.6.3 xsct运行hsi命令

       所以当我们执行”xsct hsi_test.tcl”命令时其实就是类似于将hsi_test.tcl交给xsct去解析并运行。
       关于xsct、hsi以及tcl脚本等更多的内容这里就不讲了,笔者对这些没有什么深入的了解!如果大家感兴趣自己去网上找找相关的资料。


回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子论坛 ( 公安交互式论坛备案:44190002001997 粤ICP备09047143号 )

GMT+8, 2022-7-7 03:43

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表