编辑语:
为助力“玄铁杯”RISC-V应用创新大赛的顺利进行,协助参赛者快速上手操作大赛提供的RISC-V开发套件,OCC推出RISC-V大赛开发套件解析系列内容,从硬件特点到例程开发为开发者详细解读大赛开发套件。
根据上期内容介绍,开发者将完成开发环境的搭建,实现【D1哪吒开发板】的初步上手。Yocto是Linux开发中常会用到工具,本期我们将为Linux开发者介绍D1 Yocto,本文将主要讲解D1 Yocto的目录结构,Image生成方式,以及如何添加App。
01 Yocto目录介绍
1.1 概述
本章节介绍D1 Yocto目录结构。本章节尽量以列举的方式说明各个目录个作用,并挑出重点关注的目录和文件加以着重说明。
1.2 顶层目录结构
- meta-d1:存放D1芯片的应用、补丁等
- meta-external-toolchain:外部工具链描述
- meta-openembedded:对openembedded-core的一个补充
- meta-riscv:针对RISC-V设备的补充描述
- openembedded-core:包含当前版本的核心元数据的层的 OpenEmbedded
- riscv-toolchain:工具链
- thead-build:构建目录
1.3 D1相关目录结构
1.3.1 目录介绍
- meta-d1/conf:存放D1芯片配置,包括Linux和uboot配置等
- meta-d1/recipes-ai:空
- meta-d1/recipes-bsp:d1 bsp描述,包括uboot描述
- meta-d1/recipes-connectivity:Wi-Fi BT等软件描述meta-d1/recipes-core:image核心配置,busybox等配置
- meta-d1/recipes-devtools:开发工具的描述
- meta-d1/recipes-extended:外部软件的描述
- meta-d1/recipes-kernel:内核相关描述
- meta-d1/recipes-multimedia:多媒体相关描述
- meta-d1/recipes-security:安全软件相关描述
- meta-d1/recipes-support:ntp等描述
- thead-build/d1-miniapp/conf:构建相关的配置
- thead-build/d1-miniapp/pack:全志打包工具
1.3.2 关键目录和文件介绍
- meta-d1/conf/machine/d1.conf:kernel,uboot的D1板级相关配置
- meta-d1/conf/machine/include/thead-base.inc:工具链、kernel、uboot相关通用配置
- meta-d1/recipes-kernel/linux/linux-thead_5.4.61.bb:linux内核的下载路径等配置
- meta-d1/recipes-bsp/u-boot/u-boot_2018.05.bb:uboot的下载路径等配置
- meta-d1/recipes-extended/haas-ui:haas-ui-demo库
- meta-d1/recipes-extended/kv:kv文件系统
- meta-d1/recipes-extended/voice:语音AI demo
- meta-d1/recipes-extended/media/media-service-tplayer:基于tplayer的多媒体播放器
- thead-build/d1-miniapp/conf/auto.conf:机器名,版本号等定义
- thead-build/d1-miniapp/conf/bblayers.conf:选择哪些meta目录
- thead-build/d1-miniapp/conf/local.conf:下载目录,缓存目录等定义
- thead-build/d1-miniapp/pack/pack.sh:打包脚本
- thead-build/d1-miniapp/pack/prebuilts:预编译好的文件存放目录
1.4. 实战示例
1.4.1 增加目录
目前,D1 工程构建时,会寻找以下几个目录:
openembedded-core/meta meta-openembedded/meta-oe meta-openembedded/meta-python meta-openembedded/meta-multimedia meta-openembedded/meta-networking meta-openembedded/meta-gnome meta-external-toolchain meta-riscv meta-d1
那么如果需要增加一个 meta-abcd 的目录。需要在thead-build/d1-miniapp/conf/bblayers.conf 文件中的 BBLAYERS 变量中增加一行:${YOCTOROOT}/meta-abcd \
1.4.2 修改下载目录
目前,开源软件包默认下载在 thead-build/downloads 目录下,那么如果要修改成其它目录,比如修改成 thead-build/abcd。需要修改 thead-build/d1-miniapp/conf/local.conf文件中的 DL_DIR 变量为 "${TOPDIR}/../abcd"
1.4.2.1 避免 downloads 被误删
downloads 目录下的开源软件包下载起来会花费非常长的时间,为了避免被误删除,可以使用软链接的方式,这样当 d1_yocto 整个目录被删除后,downloads 目录下的内容仍然保留,每次下载完成 d1_yocto 目录后,只需要做一个软链接即可。
$ mkdir ~/yocto-downloads/ $ cd thead-build/ $ rm downloads -rf && ln -s ~/yocto-downloads downloads # 完成后,开源软件包会被下载到 ~/yocto-downloads/ 下,只要保证该目录不被删除即可
1.5. 官方参考
英文版 Yocto工程参考手册:
02 Yocto生成Image
2.1 概述
本章节介绍 D1 Yocto 生成各种镜像的方法。D1 Yocto 可以生成 Develop 镜像,也可以生成 Release 镜像;可以生成默认输出到 LCD 的镜像,也可以生成默认输出到 HDMI 的镜像。那么这是如何分类的,本文将针对上述几点展开讲解。
2.2 Yocto 原生镜像和全志刷机镜像
根据功能不同,镜像可以分成 Yocto 原生镜像和全志刷机镜像。
2.2.1 Yocto 原生镜像
包括 elf,bin,dtb,ext4,squashfs 等业界常规格式的镜像。Yocto 原生镜像生成在 thead-build/d1-miniapp/tmp-glibc/deploy/images/d1 目录下。
2.2.1.1 镜像说明
镜像 |
说明 |
d1-image-miniapp--d1-.ext4 |
ext4 格式的 rootfs 镜像包 |
d1-image-miniapp--d1-.squashfs |
squashfs 格式的 rootfs 镜像包 |
| ImageuImageImage-d1.binuImage-d1.bin | Linux 内核镜像 || u-boot.binu-boot-d1.bin | u-boot 镜像 || fw_jump.elffw_jump.bin | opensbi 镜像 || d1_hdmi_*.dtb | 默认输出到 HDMI 的 dtb 配置 || d1_lcd_*.dtb | 默认输出到 LCD 的 dtb 配置 |
2.2.1.2 构建命令
bitbake d1-image-miniapp-dev 或者 bitbake d1-image-miniapp-release命令都可以生成上述镜像。
2.2.2 全志刷机镜像
则特指以 .img 命名的,PhoenixSuit 刷机软件可识别的镜像。全志刷机镜像生成在 thead-build/d1-miniapp/pack 目录。现在以 yocto_d1-nezha_uart0.img 命名,是 pack 工具生成的一种特殊格式的镜像,它是由 Linux 内核、uboot、dtb、rootfs 等镜像打包而成。使用 PhoenixSuit 刷机软件烧写后,上述子镜像都会被烧写进 NandFlash 或者 SD 卡。其分区信息描述在 thead-build/d1-miniapp/pack/prebuilts/sys_partition.fex 文件中。
2.2.2.1 构建命令
./pack.sh d1-image-miniapp-dev 或者 ./pack.sh d1-image-miniapp-release 命令都可以生成上述镜像。
2.3 Release 镜像和 Develop 镜像
根据配置不同,镜像可以分成 Develop 镜像和 Release 镜像。Release 镜像只包含必须的功能;Develop 镜像包含更多的开发调试工具。
2.3.1 Release 镜像
Release 镜像包含了 D1 Miniapp 的基本应用,包括 haas-ui、wpa-supplicant 等基础应用,还有 os-release 等基本信息。Release 镜像描述在 meta-d1/recipes-core/images/d1-image-miniapp-release.bb 文件中。
2.3.1.1 构建命令
bitbake d1-image-miniapp-release 加上 ./pack.sh d1-image-miniapp-release两个命令组合生成。
2.3.2 Develop 镜像
Develop 基于 Release 镜像,在 Release 镜像基础上增加了 gdb strace perf tcpdump 等多种开发调试工具。它的镜像包更大,功能更多,开发时推荐该配置。Develop 镜像描述在 meta-d1/recipes-core/images/d1-image-miniapp-dev.bb 文件中。
3.2.1 构建命令
bitbake d1-image-miniapp-dev 加上 ./pack.sh d1-image-miniapp-dev两个命令组合生成。
2.4 LCD 镜像和 HDMI 镜像
D1 镜像支持默认输出到 LCD 或者 HDMI,两者的区别主要在 dtb 的配置上不同。pack 脚本提供了生成两种镜像的命令。
2.4.1 构建命令
./pack.sh d1-image-miniapp-dev lcd_800x480./pack.sh d1-image-miniapp-dev lcd_1280x800./pack.sh d1-image-miniapp-dev hdmi_800x480./pack.sh d1-image-miniapp-dev hdmi_1280x800./pack.sh d1-image-miniapp-dev hdmi_auto或者./pack.sh d1-image-miniapp-release lcd_800x480./pack.sh d1-image-miniapp-release lcd_1280x800./pack.sh d1-image-miniapp-release hdmi_800x480./pack.sh d1-image-miniapp-release hdmi_1280x800./pack.sh d1-image-miniapp-release hdmi_auto
2.4.2 如何增加一种分辨率
如果要增加一种分辨率,比如 hdmi_960×540。需要增加如下几个修改点:
修改点1:Linux内核
- arch/riscv/boot/dts/sunxi/ 目录下增加一个文件 d1_hdmi_960x540.dts,可以参考 d1_hdmi_800x480.dts 文件。
- d1_hdmi_960x540.dts 文件中,修改 &disp 的 fb0_width = <960>; fb0_height = <540>;
修改点2:u-boot
- arch/riscv/dts/ 目录下增加两个文件 sun20iw1p1-soc-system_hdmi_960x540.dts 和 uboot_hdmi_960x540.dts
- sun20iw1p1-soc-system_hdmi_960x540.dts 文件最后一行包含 uboot_hdmi_960x540.dts
- uboot_hdmi_960x540.dts 文件中,修改 &disp 的 fb0_width = <960>; fb0_height = <540>;
修改点3:meta-d1
- conf/machine/d1.conf 文件,KERNEL_DEVICETREE 增加一个 sunxi/d1_hdmi_960x540.dtb
03 Yocto增加APP
3.1 概述
本章节介绍如何在D1 Yocto上增加APP。增加后APP后,构建时可以自动被打包进去。下面将从增加开源APP和自定义APP两种方式展开介绍。
3.2 增加开源APP
增加开源APP的方法比较简单。比如增加gdb调试工具,只需要在 meta-d1/recipes-core/images/d1-image-miniapp-dev.bb 文件中加一项:
CORE_IMAGE_EXTRA_INSTALL += " gdb "
然后,执行bitbake 构建镜像,gdb就会存放到rootfs中。
3.3 增加自定义APP
增加自定义APP的方法较为复杂。比如增加一个voice-service程序。下面将详细介绍方法:
3.3.1 创建目录
meta-d1/recipes-extended/voice/用来存放voice-servic服务及其bb文件
meta-d1/recipes-extended/voice/voice-service/用来存放voice-service服务的可执行文件
3.3.2 创建bb文件
meta-d1/recipes-extended/voice/voice-sevice.bb用来描述voice-service的bb文件。描述
DESCRIPTION = "Voice service files"
LICENSE
LICENSE = "GPLv2" LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/GPL-2.0;md5=801f80980d171dd6425610833a22dbe6"
该软件适用的机器下例表示适用d1芯片
COMPATIBLE_MACHINE = "(^d1*)"
依赖的库描述依赖库后,yocto会自动构建依赖库。
RDEPENDS_${PN} += " alsa-lib dbus libcap liblzma openssl libevent log4cpp jsoncpp libidn2 \ libopus libcurl gnutls nettle zlib libunistring gmp libgmpxx "
源文件描述该应用涉及到的所有文件。
SRC_URI = "\ file://voice_service.sh \ file://voice-service \ file://voice.service \ file://voice.conf \ file://voice-dbus.conf \ file://message.wav \ file://libalibabacloud-idst-common.so \ file://libalibabacloud-idst-speech.so \ file://libuuid.so.1 \ file://libuuid.so.1.0.0 \ file://libvoice.so \ "
应用安装描述各个文件安装到哪个目录。以及启动方式为systemd和sysvinit时的安装方式。
do_install() { install -d ${D}${base_libdir}/firmware install -d ${D}${bindir} install -d ${D}${libdir} install -d ${D}${sysconfdir}/dbus-1/system.d/ install -m 0755 ${WORKDIR}/voice-service ${D}${bindir}/voice-service install -m 0644 ${WORKDIR}/voice.conf ${D}${sysconfdir}/voice.conf install -m 0644 ${WORKDIR}/message.wav ${D}${base_libdir}/firmware/message.wav install -m 0644 ${WORKDIR}/lib*.so* ${D}${libdir}/ install -m 0644 ${WORKDIR}/voice-dbus.conf ${D}${sysconfdir}/dbus-1/system.d/voice-dbus.conf if ${@bb.utils.contains('DISTRO_FEATURES', 'systemd', 'true', 'false', d)}; then install -d ${D}${systemd_system_unitdir} install -m 0644 ${WORKDIR}/voice.service ${D}${systemd_system_unitdir}/voice.service fi if ${@bb.utils.contains('DISTRO_FEATURES', 'sysvinit', 'true', 'false', d)}; then install -d ${D}${sysconfdir}/init.d install -m 0755 ${WORKDIR}/voice_service.sh ${D}${sysconfdir}/init.d update-rc.d -r ${D} voice_service.sh start 19 5 3 2 . fi }
systemd启动方式描述当启动方式为systemd时,systemd 服务描述文件为voice.service,服务默认使能。
SYSTEMD_SERVICE_${PN} = "voice.service" SYSTEMD_AUTO_ENABLE_${PN} = "enable"
3.3.3 创建systemd服务文件
meta-d1/recipes-extended/voice/voice-sevice/voice.service当systemd启动时才需要该文件。注意:d1 yocto默认使用sysvinit启动方式,所以理论上不需要该文件。但是为了程序的鲁棒性,建议创建该文件。
[Unit] Description=Voice Service [Service] Type=dbus BusName=org.voice.server ExecStart=/usr/bin/voice-service ExecStop=/usr/bin/killall -9 voice-service [Install] WantedBy=multi-user.target
3.3.4 把APP加入image
在meta-d1/recipes-core/images/d1-image-miniapp-release.bb或者meta-d1/recipes-core/images/d1-image-miniapp-dev.bb文件中,加入下面代码。
CORE_IMAGE_EXTRA_INSTALL += " voice-sevice"
04 下期预告
以上即为本期全部内容,下期内容我们将为大家分享关于D1哪吒开发板的Haas UI实战。欢迎大家持续关注RISC-V大赛开发套件解析系列内容。