Petalinux 工具的设计流程概述
通常 PetaLinux 工具遵循顺序设计流程模型,下表提供了一个标准的设计流程:
需要说明的是以上设计流程不是按部就班的每一步都执行一遍,可以根据使用场景有选择的执行。
利用 petalinux 定制 linux 镜像
创建 Vivado 硬件平台
在创建 Vivado 硬件平台的时候必须包含ZYNQ IP核,且配置ZYNQ的如下外设:
- flash,若采用flash模式启动则必须配置
- ENET,一般Linux都需要有网络
- SD,由于存放Linux根文件系统等
- UART,Linux的终端需要使用串口
- DDR,Linux运行时需要DDR
- 如果使用了带中断信号的IP核需确保中断信号正确连接
配置完成后生成Products,然后编译工程,编译完成后导出xsa文件,如果工程中包含PL资源,在到处xsa时需要选择包含比特模式。
创建 petalinux 工程
将导出的xsa文件复制到Linux中,然后使用 petalinux-create 创建工程
- petalinux-create 命令讲解
# --type|-t project 表示创建的是一个工程,其他的还有apps、modules两个选项
# --template <PLATFORM> 指定平台,支持versal (for Versal™ ACAP)、zynqMP (for Zynq UltraScale+ MPSoC)、zynq (for Zynq-7000 devices)、microblaze (for MicroBlaze™ processor)
# --name|-n <PROJECT_NAME> 指定工程名称,<PROJECT_NAME>既是工程名称
petalinux-create --type|-t project --template <PLATFORM> --name|-n <PROJECT_NAME>
# --source|-s <path-to-bsp> 根据BSP创建工程,<path-to-bsp>既是BSP路径
petalinux-create --type|-t project --source|-s <path-to-bsp>
- 创建zynq平台的空工程
petalinux-create -t project --template zynq -n alientek-pelainux
导入硬件配置
将从vivado中导出的xsa文件拷贝到Linux中,然后 petalinux-config 导入硬件进行配置。
- petalinux-config命令讲解
#进入工程目录
cd alientek-pelainux/
#导入xsa文件配置工程,<PATH-TO-XSA Directory>是文件所在目录,<PATH-TO-XSA>是文件名,若目录中只有一个xsa文件则可以不指定文件名
petalinux-config --get-hw-description <PATH-TO-XSA Directory>/<PATH-TO-XSA>
- 进行配置
cd alientek-pelainux/
petalinux-config --get-hw-description ../xsa-alientek/
导入成功后会打开 petalinux 工程配置窗口。
注意:若后面改变了xsa可以重新执行 petalinux-config --get-hw-description 进行配置。
在配置菜单中选择串口终端,需要结合硬件设计和vivado配置选择
-*- Subsystem AUTO Hardware Settings --->
Serial Settings --->
FSBL Serial stdin/stdout (ps7_uart_1) ---> #根据硬件选择正确的串口号,我这里选择ps7_uart_0
DTG Serial stdin/stdout (ps7_uart_1) ---> #根据硬件选择正确的串口号,我这里选择ps7_uart_0
然后不断选择Exit,然后按回车,在退出配置页面的时候选择< Yes >保存修改内容。
配置设备树文件
petalinux工程有一个用户设备树文件:project-spec/meta-user/recipesbsp/device-tree/files/system-user.dtsi,这个设备树在顶层设备树的最后被包含,所以可以在这个设备中修改已有的节点或者增加新的节点,下面是根据原理图和vivado配置所增加的内容,主要包含led、按键、网口相关内容(设备树需要结合硬件设计和vivado配置进行修改)。
/include/ "system-conf.dtsi"
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/input.h>
#include <dt-bindings/phy/phy.h>
/ {
model = "Alientek Navigator Zynq Development Board";
compatible = "xlnx,zynq-zc702", "xlnx,zynq-7000";
leds {
compatible = "gpio-leds";
gpio-led1 {
label = "pl_led0";
gpios = <&gpio0 63 GPIO_ACTIVE_HIGH>;
default-state = "on";
};
gpio-led2 {
label = "ps_led0";
gpios = <&gpio0 7 GPIO_ACTIVE_HIGH>;
default-state = "on";
};
gpio-led3 {
label = "ps_led1";
gpios = <&gpio0 8 GPIO_ACTIVE_HIGH>;
linux,default-trigger = "heartbeat";
};
};
keys {
compatible = "gpio-keys";
autorepeat;
gpio-key1 {
label = "pl_key0";
gpios = <&gpio0 64 GPIO_ACTIVE_LOW>;
linux,code = <KEY_LEFT>;
gpio-key,wakeup;
autorepeat;
};
gpio-key2 {
label = "ps_key1";
gpios = <&gpio0 12 GPIO_ACTIVE_LOW>;
linux,code = <KEY_UP>;
gpio-key,wakeup;
autorepeat;
};
gpio-key3 {
label = "ps_key2";
gpios = <&gpio0 11 GPIO_ACTIVE_LOW>;
linux,code = <KEY_DOWN>;
gpio-key,wakeup;
autorepeat;
};
};
};
&uart0 {
u-boot,dm-pre-reloc;
status = "okay";
};
&sdhci0 {
u-boot,dm-pre-reloc;
status = "okay";
};
配置软件源
petalinux工程在编译过程中会从网上下载一些数据,若遇到网络问题可能会导致编译失败,因此可以采用本地的源赖进行编译(需要实现到赛灵思官网下载sstate_arm_2020.2.tar.gz和downloads_2020.2.tar.gz),配置流程如下:
- 打开工程配置页面
petalinux-config
- 设置url
Yocto Settings --->
Add pre-mirror url --->
pre-mirror url path #将pre-mirror url path设置为file://downloads_2020.2.tar.gz解压后的目录,我这里是 file:///opt/pkg/petalinux2020.2/downloads
Local sstate feeds settings--->
()local sstate feeds url #将local sstate feeds url设置为sstate_arm_2020.2.tar.gz解压后得到的arm路径下,我这里是/opt/pkg/petalinux2020.2/sstate_arm_2020.2/arm
[ ] Enable Network sstate feeds #取消此项选择
[*] Enable BB NO NETWORK #选中此选项
- 退出并保存配置界面的配置
- 注意:使用本地软件源后配置某些本地软件源中不存在的软件包会报类似下面的错误,此时可以取消[*] Enable BB NO NETWORK选项进行尝试。
编译 petalinux 工程
输入如下命令开始petalinux工程的编译
petalinux-build命令详解
#全部编译
petalinux-build
#编译所选择组件,可选的组件有kernel、u-boot、rootfs
petalinux-build -c <COMPONENT>
编译工程
cd alientek-pelainux/
petalinux-build
生成bin文件
编译结束后可以使用 petalinux-package 打包生成bin文件,用于烧写到flash启动或者通过SD卡启动(petalinux默认配置是通过SD卡启动)。
- 打包命令讲解
# --fsbl <FSBL image> 表示包含fsbl,其中<FSBL image>是fsbl文件路径,默认是编译生成的zynq_fsbl.elf
# --fpga <FPGA bitstream> 表示包含fpga的bit流,<FPGA bitstream>是bit文件路径,默认是images/linux/system.bit
# --u-boot <UBOOT image> 表示包含uboot,<UBOOT image>是uboot文件路径,默认是编译生成的u-boot.elf
# --kernel <KERNEL image> 表示包含内核,<KERNEL image>是内核路径,默认是images/linux/image.ub
# --force 表示覆盖之前生成的bin文件
petalinux-package --boot --fsbl <FSBL image> --fpga <FPGA bitstream> --u-boot <UBOOT image> --kernel <KERNEL image> --force
- 生成bin文件,生成的bin文件在images/linux目录中
petalinux-package --boot --fsbl --fpga --u-boot --force
启动测试
找一张SD卡,格式化为FAT32格式,将编译生成的boot.scr、BOOT.BIN、image.ub拷贝到SD卡中(编译生成文件位于images/linux目录),然后将SD查到开发板的SD0接口,再将开发板设置为SD启动即可,若串口配置正确此时便可通过串口看到启动信息。
petalinux工程其他常用配置
进入petalinux工程目录,执行petalinux-config即可打开petalinux工程的配置菜单,下面介绍一些常用的配置选项:
- 设置固件版本
Firmware Version Configuration --->
(alientek-pelainux) Host name #主机名称
(alientek-pelainux) Product name #产品名称
(1.00) Firmware Versio #固件版本
- 配置跟文件系统类型
Image Packaging Configuration --->
Root filesystem type (INITRD) ---> #可以选择可以选择INITRAMFS、INITRD、JFFS2、NFS、EXT4(SD/eMMC/SATA/USB)等
- 引导映像存储配置
-*- Subsystem AUTO Hardware Settings --->
[*] Advanced bootable images storage Settings --->
boot image settings ---> #选择BOOT.BIN的存储位置
u-boot env partition settings ---> #选择环境变量的存储位置
kernel image settings ---> #选择内核的存储位置
dtb image settings ---> #选择设备树存储位置
若选择将uboot环境变量保存至FAT文件系统还需进行如下配置:
#打开uboot配置菜单
petalinux-config -c u-boot
Environment --->
[*] Environment is in a FAT filesystem #将环境变量存储到FAT文件系统
[ ] Environment is in SPI flash #取消flash存储环境变量的选项
(mmc) Name of the block device for the environment #块设备名称
(0:1) Device and partition for where to store the environemt in FAT #块设备扇区
- Flash分区配置
-*- Subsystem AUTO Hardware Settings --->
Flash Settings --->
Primary Flash (ps7_qspi_0) ---> #flash位于那个SPI接口,若作为启动flash只能接在ps7_qspi_0
*** partition 0 *** #分区0配置
(boot) name
(0x500000) size
*** partition 1 *** #分区1配置
(bootenv) name
(0x20000) size
*** partition 2 *** #分区2配置
(kernel) name
(0xA80000) size
*** partition 3 *** #分区3配置
(spare) name
(0x0) size
*** partition 4 *** #分区4配置
() name
- 配置u-boot
在工程目录中执行如下指令可以打开u-boot配置页面
petalinux-config -c u-boot
- 配置内核
在工程目录中执行如下指令可以打开内核配置页面
petalinux-config -c kernel
- 配置根文件系统
在工程目录中执行如下指令可以打开根文件系统配置页面
petalinux-config -c rootfs
petalinux高级使用
添加预构建库
- 将代码编译为.so文件
- 使用以下命令创建一个petalinux APP
petalinux-create -t apps --template install --name <mylib> --enable #其中<mylib>为petalinux APP名称,注意:petalinux APP名称不能包含“_"和大写字母字符
- 删除原有的project-spec/meta-user/recipes-apps/<mylib>/files/<mylib>文件,将将构建好的动态库拷贝到project-spec/meta-user/recipes-apps/<mylib>/files/路径中
rm project-spec/meta-user/recipes-apps/<mylib>/files/<mylib>
cp <path-to-prebuilt-mylib.so> project-spec/meta-user/recipes-apps/<mylib>/files/ #其中<path-to-prebuilt-mylib.so>为预编译好的动态库文件
- 编辑project-spec/meta-user/recipes-apps/<mylib>/<mylib>.bb文件
gedit project-spec/meta-user/recipes-apps/<mylib>/<mylib>.bb
文件内容如下
# This file is the libs recipe.
#
SUMMARY = "Simple libs application"
SECTION = "PETALINUX/apps"
LICENSE = "MIT"
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"
SRC_URI = "file://<mylib.so> \
"
S = "${WORKDIR}"
TARGET_CC_ARCH += "${LDFLAGS}"
do_install() {
install -d ${D}${libdir}
install -m 0655 ${S}/<mylib.so> ${D}${libdir}
}
FILES_${PN} += "${libdir}"
FILES_SOLIBSDEV = ""
- 其中<mylib.so>是动态库文件名
- 使用petalinux-build进行编译,编译完成后动态库自动被打包到根文件系统中的/usr/lib/目录
添加预构建应用
- 编译应用程序,得到elf文件
- 使用以下命令创建一个petalinux APP
petalinux-create -t apps --template install --name <myapp> --enable #其中<myapp>为petalinux APP名称,注意:petalinux APP名称不能包含“_"和大写字母字符
- 删除原有的project-spec/meta-user/recipes-apps/<myapp>/files/<myapp>文件,将编译好的elf(根据实际情况,不一定是elf文件,只要是可执行文件即可)文件拷贝到project-spec/meta-user/recipes-apps/<myapp>/files路径中
rm project-spec/meta-user/recipes-apps/<myapp>/files/<myapp>
cp <path-to-prebuilt-app> project-spec/meta-user/recipes-apps/<myapp>/files #其中<path-to-prebuilt-app>为预编译好的elf文件
- 编辑project-spec/meta-user/recipes-apps/<myapp>/<myapp>.bb文件
gedit project-spec/meta-user/recipes-apps/<myapp>/<myapp>.bb
文件内容如下
#
# This file is the <myapp> recipe.
#
SUMMARY = "Simple <myapp> application"
SECTION = "PETALINUX/apps"
LICENSE = "MIT"
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"
SRC_URI = "file://<myapp.elf> \
"
S = "${WORKDIR}"
INSANE_SKIP_${PN} += "file-rdeps"
do_install() {
install -d ${D}/${bindir}
install -m 0755 ${S}/<myapp.elf> ${D}/${bindir}
}
- 其中<myapp.elf>为预先编译好的可执行程序文件
- INSANE_SKIP_${PN} += "file-rdeps"表示不检查<myapp.elf>的依赖关系,一般情况下不需要添加这一行,当报“ERROR: dd-lib-test-1.0-r0 do_package_qa: QA Issue: /usr/bin/*** contained in package *** requires ***, but no providers found in RDEPENDS_***? [file-rdeps]”错误时可以考虑添加,但是必须要确保所构建的根文件系统中正确包含所依赖的文件,否则程序无法运行。
- 使用petalinux-build进行编译,编译完成后动态库自动被打包到根文件系统中的/usr/bin/目录
添加自定义库
添加自定义库比较复杂,所以这里以创建一个libsample.so的库为例。
- 使用以下命令创建一个petalinux APP
petalinux-create -t apps --template c --name libsample --enable
- 编辑 project-spec/meta-user/recipes-apps/libsample/libsample.bb
gedit project-spec/meta-user/recipes-apps/libsample/libsample.bb
文件内容如下
#
# This file is the libsample recipe.
#
SUMMARY = "Simple libsample application"
SECTION = "libs"
LICENSE = "MIT"
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"
FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
SRC_URI = " \
file://sample.c \
file://sample.h \
file://Makefile \
"
S = "${WORKDIR}"
PACKAGE_ARCH = "${MACHINE_ARCH}"
PROVIDES = "sample"
TARGET_CC_ARCH += "${LDFLAGS}"
do_install() {
install -d ${D}${libdir}
install -d ${D}${includedir}
oe_libinstall -so libsample ${D}${libdir}
# This is optional and depends if you have any headers to copied along with libraries
# This example includes sample.h to to copied to <TARGET_ROOTFS>/usr/lib/SAMPLE/sample.h
install -d -m 0655 ${D}${includedir}/SAMPLE
install -m 0644 ${S}/*.h ${D}${includedir}/SAMPLE/
}
FILES_${PN} = "${libdir}/*.so.* ${includedir}/*"
FILES_${PN}-dev = "${libdir}/*.so"
- 修改project-spec/meta-user/recipes-apps/libsample/files/Makefile文件
gedit project-spec/meta-user/recipes-apps/libsample/files/Makefile
文件内容如下
APP = sample
LIBSOURCES=*.c
OUTS = *.o
NAME := sample
MAJOR = 1.0
MINOR = 1
VERSION = $(MAJOR).$(MINOR)
all: lib$(NAME).so
lib$(NAME).so.$(VERSION): $(OUTS)
$(CC) $(LDFLAGS) $(OUTS) -shared -Wl,-soname,lib$(NAME).so.$(MAJOR) -o lib$(NAME).so.$(VERSION)
lib$(NAME).so: lib$(NAME).so.$(VERSION)
rm -f lib$(NAME).so.$(MAJOR) lib$(NAME).so
ln -s lib$(NAME).so.$(VERSION) lib$(NAME).so.$(MAJOR)
ln -s lib$(NAME).so.$(MAJOR) lib$(NAME).so
%.o: %.c
$(CC) $(CFLAGS) -c -fPIC $(LIBSOURCES)
clean:
rm -rf *.o *.so *.so.*
- 删除project-spec/meta-user/recipes-apps/libsample/files/libsample.c和project-spec/meta-user/recipes-apps/libsample/files/libsample.h
project-spec/meta-user/recipes-apps/libsample/files/libsample.c
project-spec/meta-user/recipes-apps/libsample/files/libsample.h
- 创建project-spec/meta-user/recipes-apps/libsample/files/sample.c和project-spec/meta-user/recipes-apps/libsample/files/sample.h文件
touch project-spec/meta-user/recipes-apps/libsample/files/sample.c
touch project-spec/meta-user/recipes-apps/libsample/files/sample.h
- 编辑project-spec/meta-user/recipes-apps/libsample/files/sample.c和project-spec/meta-user/recipes-apps/libsample/files/sample.h文件
gedit project-spec/meta-user/recipes-apps/libsample/files/sample.c
gedit project-spec/meta-user/recipes-apps/libsample/files/sample.h
- 使用petalinux-build进行编译,编译完成后动态库自动被打包到根文件系统中的/usr/lib/目录
添加自定义应用
- 使用以下命令创建一个petalinux APP
#<TYPE> 源代码编程语言,可选c、c++、autoconf,默认十c
#<user-application-name> petalinux APP名称,注意:petalinux APP名称不能包含“_"和大写字母字符
petalinux-create -t apps --template <TYPE> --name <user-application-name> --enable
#创建一个c语言的APP
petalinux-create -t apps --name <myapp> --enable
petalinux-create -t apps --template c --name <myapp> --enable
#创建一个C++的APP
petalinux-create -t apps --template c++ --name <myapp> --enable
#创建一个自适应语言的APP
petalinux-create -t apps --template autoconf --name <myapp> --enable
- 进入cd project-spec/meta-user/recipes-apps/<myapp>/files目录
cd project-spec/meta-user/recipes-apps/<myapp>/files
- 编辑<myapp>.c或<myapp>.cpp,实现自己的功能
- 根据实际情况决定是否修改Makefile,如需要链接一些自己的库则需要对Makefile进行相应修改
- 使用petalinux-build进行编译,编译完成后动态库自动被打包到根文件系统中的/usr/bin/目录
添加自定义内核模块
- 使用以下命令创建一个petalinux APP
petalinux-create -t modules --name <mymodule> --enable
- 编辑project-spec/meta-user/recipes-modules//files/.c文件
- 使用petalinux-build进行编译,编译完成后内核模块自动被打包到根文件系统的lib/modules/5.4.0-xilinx-v2020.2/extra目录中,通过modprobe .ko或insmod /lib/modules/5.4.0-xilinx-v2020.2/extra/.ko可以完成模块加载,通过rmmod .ko 可以完成模块卸载
实现自动登录
- 打开跟文件系统配置界面
petalinux-config -c rootfs
- 使能自动登录
Image Features --->
[*] auto-login #选中
- 使用petalinux-build进行编译工程
添加自启动脚本
- 使用以下命令创建一个petalinux APP
petalinux-create -t apps --template install -n <myapp-init> --enable
- 编辑project-spec/meta-user/recipes-apps/<myapp-init>/<myapp-init>.bb文件
gedit project-spec/meta-user/recipes-apps/<myapp-init>/<myapp-init>.bb
文件内容如下
#
# This file is the <myapp-init> recipe.
#
SUMMARY = "Simple <myapp-init> application"
SECTION = "PETALINUX/apps"
LICENSE = "MIT"
LIC_FILES_CHKSUM ="file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"
SRC_URI = "file://<myapp-init> \
"
S = "${WORKDIR}"
FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
inherit update-rc.d
INITSCRIPT_NAME = "<myapp-init>"
INITSCRIPT_PARAMS = "start 99 S ."
do_install() {
install -d ${D}${sysconfdir}/init.d
install -m 0755 ${S}/<myapp-init> ${D}${sysconfdir}/init.d/<myapp-init>
}
FILES_${PN} += "${sysconfdir}/*"
- 其中为自启动脚本的文件名
- 编辑project-spec/meta-user/recipes-apps/<myapp-init>/files/<myapp-init>文件,增加自动时需要执行的程序
- 使用petalinux-build进行编译
删除petalinux APP
- 删除代码
rm -rf user-project/project-spec/meta-user/recipes-apps/<user-app>
- 删除配置信息
#删除文件中与<user-app>相关的配置项
gedit project-spec/meta-user/conf/user-rootfsconfig
#删除文件中与<user-app>相关的配置项,若模块没有使能这里可能没有相关的配置信息
gedit project-spec/configs/rootfs_config
- 重新生成配置文件
#可以通过配置菜单中的“apps --->”或“modules --->”确认删除是否成功
petalinux-config -c rootfs
- 使用petalinux-build进行编译