# RISCV-CSKY YOCTO移植过程总结 ## 目录 [TOC] ## 1.**基于YOCTO如何编译驱动** ### 1.1 概述 驱动的编译严重依赖于内核及内核源码的位置,所以提前确保内核编译通过。 基本步骤: 1. 驱动代码 2. 编辑驱动代码的Makefile 3. 添加驱动的.bb 4. 设定驱动代码的层级(通常在recipes-kernel目录下) ### 1.2 前提(重要) 确保 meta-riscv/recipes-kernel/linux/linux-thead_5.10.4.bb里面有下面的代码端 ```bash do_configure_append() { [ -d ${STAGING_KERNEL_DIR} ] && rm -rf ${STAGING_KERNEL_DIR} [ -f ${STAGING_KERNEL_DIR} ] && rm -rf ${STAGING_KERNEL_DIR} ln -s ${S} ${STAGING_KERNEL_DIR} } do_install_append() { [ -f ${STAGING_KERNEL_BUILDDIR} ] && rm -rf ${STAGING_KERNEL_BUILDDIR} [ -d ${STAGING_KERNEL_BUILDDIR} ] && rm -rf ${STAGING_KERNEL_BUILDDIR} ln -s ${B} ${STAGING_KERNEL_BUILDDIR} } ``` 上述代码是对: linux的源码路径${STAGING_KERNEL_DIR}以及内核的编译路径${STAGING_KERNEL_BUILDDIR} 的进行重定义. **注:STAGING_KERNEL_DIR和STAGING_KERNEL_BUILDDIR均为YOCTO框架内变量。** ### 1.3 驱动编译(demo版) #### **1.3 .1 代码结构如下** 驱动层次定义在meta-riscv/recipes-kernel目录下(驱动和内核关系密切,放在这个层下比较合适) ```bash riscv_yocto/meta-riscv/recipes-kernel$ tree hello-mod/ hello-mod/ ├── files │   ├── COPYING │   ├── hello.c │   └── Makefile └── hello-mod_0.1.bb 1 directory, 4 files ``` 以上是一个hello的驱动。 #### **1.3 .2 驱动Makefile说明(可做为模板) ** ```bash obj-m := hello.o SRC := $(shell pwd) all: $(MAKE) -C $(KERNEL_SRC) M=$(SRC) modules_install: $(MAKE) -C $(KERNEL_SRC) M=$(SRC) modules_install clean: rm -f *.o *~ core .depend .*.cmd *.ko *.mod.c rm -f Module.markers Module.symvers modules.order rm -rf .tmp_versions Modules.symvers ``` KERNEL_SRC 为内核编译的过程中传递下来的变量,见下面的代码: ``` openembedded-core/meta/classes/module.bbclass:3:EXTRA_OEMAKE += "KERNEL_SRC=${STAGING_KERNEL_DIR}" ``` 实际上KERNEL_SRC与${STAGING_KERNEL_DIR}是一致的。 #### **1.3 .3 驱动.bb文件说明 ** ```bash SUMMARY = "Example of how to build an external Linux kernel module" LICENSE = "GPLv2" LIC_FILES_CHKSUM = "file://COPYING;md5=12f884d2ae1ff87c09e5b7ccc2c4ca7e" inherit module #管理内核驱动编译 SRC_URI = "file://Makefile \ file://hello.c \ file://COPYING \ " S = "${WORKDIR}" # The inherit of module.bbclass will automatically name module packages with # "kernel-module-" prefix as required by the oe-core build environment. RPROVIDES_${PN} += "kernel-module-hello" #驱动deb包的名称 ``` #### **1.3 .4 编译 ** ```bash bitbake hello-mod ``` ![](resources\驱动编译后目录.png) 1. 生成物的代码结构 ```bash image/ ├── etc │   ├── modprobe.d │   └── modules-load.d ├── lib │   └── modules │   └── extra │   └── hello.ko #生成后的驱动 └── usr └── include └── hello-mod └── Module.symvers #导出的符号表 9 directories, 2 files lqg@etgserver:~/al_yocto/r ``` 2. dep的生成结果 ```bash ./ice/kernel-module-hello-_0.1-r0_riscv64.deb ./ice/hello-mod-dbg_0.1-r0_riscv64.deb ./ice/hello-mod-dev_0.1-r0_riscv64.deb ./ice/hello-mod_0.1-r0_riscv64.deb` ``` ### 1.4 驱动编译(推荐版) 1.3的驱动文件都在meta-riscv/recipes-kerne/hello-mod目下,不便于后期维护和开发,也违背了YOCTO做为模板、工具和方法的初衷,因此比较推荐代码和YOCTO分析的编译驱动的方法。 主要的核心驱动仅仅在.bb文件中对源码的获取方式上。 以hdmi的驱动为例: 1.目录结构 ```bash meta-riscv/recipes-kernel# tree hdmi/ hdmi/ └── kernel-module-hdmi_git.bb ``` 2. kernel-module-hdmi_git.bb文件说明 ```bash 1 SUMMARY = "XXX HDMI Linux Kernel module" 2 DESCRIPTION = "Out-of-tree HDMI kernel modules provider for ice devices" 3 SECTION = "kernel/modules" 4 LICENSE = "GPLv2" 5 LIC_FILES_CHKSUM = "file://LICENSE.md;md5=498a38cdcb922b9e987bbbb46e8a9ee5" 6 7 XLNX_HDMI_VERSION = "5.10.4" 8 PV = "${XLNX_HDMI_VERSION}" 9 10 S = "${WORKDIR}/git" 11 12 BRANCH ?= "rel-v2020.1" 13 REPO ?= "git://github.com/XXX/hdmi-modules.git;protocol=https" #获取仓库的代码 14 SRCREV ?= "3a6e440b50263a3ed99492aba3e507d7c130355c" 15 16 BRANCHARG = "${@['nobranch=1', 'branch=${BRANCH}'][d.getVar('BRANCH', True) != '']}" 17 SRC_URI = "${REPO};${BRANCHARG}" 18 19 inherit module 20 21 EXTRA_OEMAKE += "O=${STAGING_KERNEL_BUILDDIR}" 22 COMPATIBLE_MACHINE = "^$" 23 COMPATIBLE_MACHINE_ice = "ice" 24 COMPATIBLE_MACHINE_versal = "versal" 25 26 PACKAGE_ARCH = "${SOC_FAMILY_ARCH}" ~ ``` ## 2.**基于YOCTO如何编译应用** ### 2.1 概述 应用编译(包括脚本、软件包、so库等)相对于驱动要简单的多。 基本步骤: 1. 应用代码 2. 编辑应用代码的Makefile 3. 添加应用的.bb 4. 设定应用码的层级(通常在recipes-support目录下) ### 2.2 应用编译(demo) #### **2.2.1 代码结构如下** ```bash riscv_yocto/meta-csky/recipes-support$ tree service/ service/ ├── service │   ├── COPYRIGHT │   ├── skeleton │   └── skeleton_test.c └── service_0.1.bb 1 directory, 4 files ``` 本代码简单可以不需要Makefile. #### **2.2.2 应用.bb文件说明 ** ```bash SUMMARY = "The canonical example of init scripts" SECTION = "base" LICENSE = "GPLv2" LIC_FILES_CHKSUM = "file://${WORKDIR}/COPYRIGHT;md5=349c872e0066155e1818b786938876a4" SRC_URI = "file://skeleton \ file://skeleton_test.c \ file://COPYRIGHT \ " do_compile () { ${CC} ${CFLAGS} ${LDFLAGS} ${WORKDIR}/skeleton_test.c -o ${WORKDIR}/skeleton-test #这里可替代Makefile } do_install () { #要安装的文件系统的路径 install -d ${D}${sysconfdir}/init.d cat ${WORKDIR}/skeleton | \ sed -e 's,/etc,${sysconfdir},g' \ -e 's,/usr/sbin,${sbindir},g' \ -e 's,/var,${localstatedir},g' \ -e 's,/usr/bin,${bindir},g' \ -e 's,/usr,${prefix},g' > ${D}${sysconfdir}/init.d/skeleton chmod a+x ${D}${sysconfdir}/init.d/skeleton install -d ${D}${sbindir} install -m 0755 ${WORKDIR}/skeleton-test ${D}${sbindir}/ } RDEPENDS_${PN} = "initscripts" CONFFILES_${PN} += "${sysconfdir}/init.d/skeleton" ``` #### **2.2.3 编译 ** ```bash bitbake service ``` ![](resources\应用编译后目录.png) 1. 生成物的代码结构 ```bash image/ ├── etc │   └── init.d │   └── skeleton └── usr └── sbin └── skeleton-test 4 directories, 2 files ``` 1. dep的生成结果 ``` ./service_0.1-r0_csky.deb ./service-dev_0.1-r0_csky.deb ./service-src_0.1-r0_csky.deb ./service-dbg_0.1-r0_csky.deb ``` so的编译方法与应用类似。 ### 2.3 应用编译(推荐版) 以bootgen的应用为例: 1.目录结构 ```bash riscv_yocto/meta-csky/recipes-supports# tree bootgen/ bootgen/ └── bootgen_1.0.bb 0 directories, 1 file ``` 2.bootgen_1.0.bb文件说明 ```bash SUMMARY = "Building and installing bootgen" DESCRIPTION = "Building and installing bootgen, a xxx tool that lets you stitch binary files together and generate device boot images" LICENSE = "Apache-2.0" LIC_FILES_CHKSUM = "file://LICENSE;md5=be5410bcde8eb6481a6e5d3b22e0740b" S = "${WORKDIR}/git" DEPENDS += "openssl" RDEPENDS_${PN} += "openssl" REPO ?= "git://github.com/xxx/bootgen.git;protocol=https" BRANCH ?= "master" SRCREV ?= "bb38995468d8c830cbbfc5062e903961444c0a3c" BRANCHARG = "${@['nobranch=1', 'branch=${BRANCH}'][d.getVar('BRANCH', True) != '']}" SRC_URI = "${REPO};${BRANCHARG}" EXTRA_OEMAKE += 'CROSS_COMPILER="${CXX}" -C ${S}' #${S} 为源码路径,类似于make -C ${S} 源码自带Makefile CXXFLAGS_append = " -std=c++0x" TARGET_CC_ARCH += "${LDFLAGS}" do_install() { # 安装文件系统路径 install -d ${D}${bindir} install -Dm 0755 ${S}/bootgen ${D}${bindir} } FILES_${PN} = "${bindir}/bootgen" BBCLASSEXTEND = "native nativesdk" ``` ## 3.**基于YOCTO如何追加编译选项** ### 3.1 基于Makefile编译的包 涉及到的关键的变量CXXFLAGS和CFLAGS ```bash CXXFLAGS_append = " -std=c++0x" CFLAGS_append = " -Wa,-mljump" ``` CXXFLAGS针对C++编译器(比如:*-g++) CFLAGS针对C编译器(比如:*-gcc) 修改位置,在相应的包的.bb或.append追加即可 ### 3.2 基于 meson.build编译的包 比如:tmp-glibc/work/csky32-oe-linux/mesa/2_20.2.1-r0/mesa-20.2.1/meson.build ```bash # Arguments for the preprocessor, put these in a separate array from the C and # C++ (cpp in meson terminology) arguments since they need to be added to the # default arguments for both C and C++. pre_args = [ '-D__STDC_CONSTANT_MACROS', '-D__STDC_FORMAT_MACROS', '-D__STDC_LIMIT_MACROS', '-Wa,-mljump', #追加编译选项 '-DPACKAGE_VERSION="@0@"'.format(meson.project_version()), '-DPACKAGE_BUGREPORT="https://gitlab.freedesktop.org/mesa/mesa/-/issues"', ] ``` 修改的位置,只能是对应包的meson.build文件。 ## **4.U-BOOT和KERNEl移植** ### **4.1 关键变量说明** 说明几个YOCTO下与UBOOT和KERNEL相关性比较大变量: ```bash 1. KBUILD_DEFCONFIG #内核 defconfig的文件名称 2. KERNEL_DEVICETREE #内核设备树的名称 3. UBOOT_MACHINE #uboot defconfig的文件名称 4. UBOOT_ENTRYPOINT #uboot内存的启动地址 5. UBOOT_DTB_LOADADDRESS #uboot的加载dtb的地址 ``` 一般这些和machine强相关,一般会定义在meta-riscv/conf/machine/ice.conf ### **4.2 如何指定u-boot和kernel的版本** ```bash PREFERRED_PROVIDER_virtual/kernel ?= "linux-thead" PREFERRED_PROVIDER_virtual/bootloader ?= "u-boot" PREFERRED_VERSION_linux-thead = "5.4.36" #指定内核版本为5.4.36 PREFERRED_VERSION_u-boot = "1:2020.10" #指定u-boot版本为1:2020.10 ``` 一般这些和machine强相关,一般会定义在meta-riscv/conf/machine/ice.conf ```bash #@TYPE: Machine #@NAME: xuantie #@SOC: XuanTie Light #@DESCRIPTION: Machine configuration for the HiFive Unleashed development board require conf/machine/include/thead-base.inc SERIAL_CONSOLES = "115200;ttySIF0" MACHINE_EXTRA_RRECOMMENDS += "kernel-modules" IMAGE_FSTYPES += "ext4" KERNEL_DEVICETREE ?= "thead/ice.dtb" #定位源码 /kernel/arch/riscv/boot/dts/thead下 KBUILD_DEFCONFIG_ice = "ice_defconfig" #定位源码 arch/riscv/configs/下 UBOOT_MACHINE = "ice_evb_c910_defconfig" #定位源码 u-boot/configs/下 UBOOT_ENTRYPOINT = "0x80200000" UBOOT_DTB_LOADADDRESS = "0x82200000" ``` ### **4.3 U-BOOT如何配置** 以下有两种方法,根据情况可以自行选择: #### 4.3.1 手动修改defconfig 首先确定defconfig的文件: ``` UBOOT_MACHINE = "ice_evb_c910_defconfig" #定位源码 u-boot/configs/下 ``` UBOOT_MACHINE变量定义见:meta-riscv/conf/machine/ice.conf 比如ice_evb_c910_defconfig文件,直接可以编辑,但前提是需要对uboot有一定熟悉,否则会产生些错误。 #### 4.3.2 通过menuconfig命令 ```base bitbake u-boot -c menuconfig ``` ![image-20210615170846195](resources\image-uboot_config.png) 根据自己的需求,修改配置。修改完之后“Save”即可。 出现以下提示就修改完成 ```base 0: u-boot-1_2020.10-r0 do_menuconfig - 1s (pid 8071) NOTE: Tasks Summary: Attempted 317 tasks of which 316 didn't need to be rerun and all succeeded. NOTE: Writing buildhistory ``` ### **4.4 Kernel如何配置** 以下有两种方法,根据情况可以自行选择: #### 4.3.1 手动修改defconfig 首先确定defconfig的文件: ``` KBUILD_DEFCONFIG_ice = "ice_defconfig" #定位源码 /kernel/arch/riscv/boot/dts/thead下 ``` KBUILD_DEFCONFIG_ice变量定义见:meta-riscv/conf/machine/ice.conf 比如ice_defconfig文件,直接可以编辑,但前提是需要对内核有一定熟悉,否则会产生些错误。 #### 4.3.2 通过menuconfig命令 ```base bitbake linux-thead -c menuconfig ``` ![image-20210615172501513](resources\image-kernel_config.png) 根据自己的需求,修改配置。修改完之后“Save”即可。 出现以下提示就修改完成 ```bash 0: linux-thead-5.10.4-r0 do_menuconfig - 0s (pid 31979) NOTE: Tasks Summary: Attempted 307 tasks of which 306 didn't need to be rerun and all succeeded. NOTE: Writing buildhistory ``` ### **4.3 U-BOOT移植** 本次移植的重点,不在代码本身,代码正确性在https://gitee.com/thead-linux/u-boot.git仓库确保。在Yocto的主要修改点是 u-boot_%.bbappend 文件。 当然也可以改成u-boot_2020.10.bb (2020.10是版本,和我们仓库的Uboot版本保持一致即可)。 路径:/riscv_yocto/meta-arch/recipes-bsp/u-boot/u-boot_%.bbappend ```bash FILESEXTRAPATHS_prepend := "${THISDIR}/files:" LIC_FILES_CHKSUM = "file://Licenses/README;md5=30503fd321432fc713238f582193b78e" SRC_URI_append_ice = " \ file://tftp-mmc-boot.txt \ " SRC_URI = " \ git://gitee.com/thead-linux/u-boot.git;protocol=http \ " SRCREV = "4f01a69ec30fdfa63413dd958314cb10008e32f6" #来自于https://gitee.com/thead-linux/u-boot.git最后一次提交 #SRCREV="${AUTOREV}"也可以用这个代替,AUTOREV这个变量自动填充最新的commitID ``` 注:**LIC_FILES_CHKSUM**这个变量不确定如何赋值先注掉,编译的时候会有提示: ![](resources\uboot MD5.png) 将“file://Licenses/README;md5=30503fd321432fc713238f582193b78e”赋值给LIC_FILES_CHKSUM即可。 #### **4.3.1 U-BOOT编译** 1. 编译采用bitbake u-boot即可 ![](resources\uboot编译.png) 2. 生成结果 ```bash riscv_yocto/thead-build/ice-base/tmp-glibc/work/ice-oe-linux/u-boot/1_2020.10-r0$ tree image/ image/ ├── boot │   ├── u-boot.bin -> u-boot-ice-2020.10-r0.bin │   └── u-boot-ice-2020.10-r0.bin └── etc ├── u-boot-initial-env -> u-boot-initial-env-ice-2020.10-r0 ├── u-boot-initial-env-ice -> u-boot-initial-env-ice-2020.10-r0 └── u-boot-initial-env-ice-2020.10-r0 2 directories, 5 files ``` ### **4.4 Kernel移植** 本次移植的重点,不在代码本身,代码正确性在https://gitee.com/thead-linux/kernel.git仓库确保。在Yocto的主要修改点是linux-thead_5.10.4.bb文件。 路径:meta-riscv/recipes-kernel/linux/linux-thead_5.10.4.bb ```bash inherit kernel require recipes-kernel/linux/linux-yocto.inc LIC_FILES_CHKSUM = "file://COPYING;md5=6bc538ed5bd9a7fc9398086aedcd7e46" SRC_URI = " \ git://gitee.com/thead-linux/kernel.git;branch=${KMACHINE};protocol=http \ " LINUX_VERSION ?= "${PV}" LINUX_VERSION_EXTENSION ?= "-thead" SRCREV="${AUTOREV}" DEPENDS += "elfutils-native" COMPATIBLE_MACHINE = "${MACHINE}" S = "${WORKDIR}/linux-${PV}" KBUILD_DEFCONFIG_ice = "ice_defconfig" #KBUILD_DEFCONFIG_ice和KBUILD_DEFCONFIG一样, do_configure_append() { [ -d ${STAGING_KERNEL_DIR} ] && rm -rf ${STAGING_KERNEL_DIR} [ -f ${STAGING_KERNEL_DIR} ] && rm -rf ${STAGING_KERNEL_DIR} ln -s ${S} ${STAGING_KERNEL_DIR} } do_install_append() { [ -f ${STAGING_KERNEL_BUILDDIR} ] && rm -rf ${STAGING_KERNEL_BUILDDIR} [ -d ${STAGING_KERNEL_BUILDDIR} ] && t://gitee.com/thead-linux/rm -rf ${STAGING_KERNEL_BUILDDIR} ln -s ${B} ${STAGING_KERNEL_BUILDDIR} } KCONFIG_MODE="--alldefconfig" ``` 注:"**KBUILD_DEFCONFIG_ice**"是"**KBUILD_DEFCONFIG**"的另一种标识方式,以machine相关,也可以是arch相关比如“KBUILD_DEFCONFIG_riscv"。根据需要对变量进行扩展, 下面有链接可以简单熟悉一下:https://blog.csdn.net/guoqx/article/details/117447512,详细需要间yocto官方资料。 #### **4.4.1 Kernel编译** 1.编译采用bitbake linux-thead即可 ![](resources\内核编译.png) 2.生成结果 ```bash riscv_yocto/thead-build/ice-base/tmp-glibc/work/ice-oe-linux/linux-thead/5.10.4-r0$ tree image/ image/ ├── boot │   ├── config-5.10.4-thead │   ├── ice.dtb │   ├── Image-5.10.4-thead │   ├── Module.symvers-5.10.4-thead │   ├── System.map-5.10.4-thead │   ├── uImage-5.10.4-thead │   └── vmlinux-5.10.4-thead ├── etc │   ├── modprobe.d │   └── modules-load.d └── lib └── modules └── 5.10.4-thead ├── kernel │   ├── drivers │   │   ├── usb │   │   │   └── gadget │   │   │   ├── function │   │   │   │   ├── usb_f_acm.ko │   │   │   │   ├── usb_f_mass_storage.ko │   │   │   │   ├── usb_f_obex.ko │   │   │   │   ├── usb_f_serial.ko │   │   │   │   └── u_serial.ko │   │   │   ├── legacy │   │   │   │   ├── g_mass_storage.ko │   │   │   │   └── g_serial.ko │   │   │   └── libcomposite.ko │   │   └── video │   │   └── fbdev │   │   ├── core │   │   │   ├── fb_sys_fops.ko │   │   │   ├── syscopyarea.ko │   │   │   ├── sysfillrect.ko │   │   │   └── sysimgblt.ko │   │   └── vfb.ko │   └── fs │   ├── configfs │   │   └── configfs.ko │   ├── efivarfs │   │   └── efivarfs.ko │   └── nfs │   └── flexfilelayout │   └── nfs_layout_flexfiles.ko ├── modules.builtin ├── modules.builtin.modinfo └── modules.order 21 directories, 26 files ``` ## 5.YOCTO对源码修改后生成补丁的方法 ### 5.1 使用的工具 ```bash devtool(来自于openembedded-core/scripts/devtool) ``` ### 5.2 操作步骤 1. 拉取对应的软件包代码 ```bash devtool modify xxx(软件包名) ``` 2. 修改代码并提交 ```bash 1) 根据自己的需求:在此处对源码(配置文件,脚本)修改。 2) 修改后git commit ``` 3. 生成补丁 ```bash devtool update-recipe -a ${work_path}/meta-riscv(你自己的layer) xxx(软件包名) ``` 5. 删除代码(非必要,根据自己的情况) ```bash devtool reset xxx(软件包名) ``` 6. 编译并测试 ```bash bitbake gxxx(软件包名) 测试补丁和bbappend是否生效 ``` ### 5.3 以libgpg-error为例 1. devtool modify libgpg-error 2. devtool update-recipe -a ~/al_yocto/riscv_yocto/meta-csky/ libgpg-error 生成的补丁信息: ```bash NOTE: Writing append file: /home/lqg/al_yocto/riscv_yocto/meta-csky/recipes-support/libgpg-error/libgpg-error_1.39.bbappend NOTE: Copying 0001-append-csky-header-file.patch to /home/lqg/al_yocto/riscv_yocto/meta-csky/recipes-support/libgpg-error/libgpg-error/0001-append-csky-header-file.patch 生成2个文件: 1. /home/lqg/al_yocto/riscv_yocto/meta-csky/recipes-support/libgpg-error/libgpg-error_1.39.bbappend 2. /home/lqg/al_yocto/riscv_yocto/meta-csky/recipes-support/libgpg-error/libgpg-error/0001-append-csky-header-file.patch ``` 3. devtool reset libgpg-error 4. bitbake libgpg-error 详细参见 [libgpg-error]: resources\基于YOCTO生成补丁的例子-libgpg-error.log 操作log ## 6、生成的镜像 ### 6.1、MINI映像 编译命令: ```bash source openembedded-core/oe-init-build-env thead-build/ice-base bitbake core-image-minimal ``` 映像路径: ```bash thead-build/ice-base/tmp-glibc/deploy/images/ice ``` `deb`包路径: ``` thead-build/ice-base/tmp-glibc/deploy/deb/riscv64 ``` 支持的功能: 1) 网络类 1. 支持ifconfig,dhcpclient,netstat等工具; 2. 支持有线网络正常通信; 3. 支持route/ipmaddr/ping等工具; 2) 文件系统 1. 支持文件系统check工具,支持文件系统格式化工具; 2. 支持文件创建/查看/磁盘空间查看等工具 3. 支持gzip/gnzip/tar等文件压缩/解压工具 3) 其他 1. `支持reboot/sh`utdown等工具 2. 支持登录/修改用户名/密码等工具 3. 支持apt系列工具 4. 支持驱动加载/卸载工具 ### 6.2、XFCE映像 ##### 6.2.1 如何生成包 1.编译命令: ```bash source openembedded-core/oe-init-build-env thead-build/ice-xfce bitbake core-image-minimal-xfce 或 bitbake core-image-xfce ``` 2.映像路径: ``` thead-build/ice-xfce/tmp-glibc/deploy/images/ice ``` 3.`deb`包路径: ``` thead-build/ice-xfce/tmp-glibc/deploy/deb/riscv64 ``` ##### 6.2.2 镜像支持的功能 1) 网络类 1. 支持ifconfig,dhcp,netstat等工具 2. 支持有线网络正常通信 3. 支持route/iptables/ping等基本工具 2) 文件系统类 1. 支持文件系统checek工具,支持文件系统格式化工具; 2. 支持创建/查看/磁盘空间等空间 3. 支持gzip/gnzip/tar等文件压缩解压公爵 3) 音视频 1. 支持ffmpeg 2. 支持gstreamer 3. 支持flac 4) 其他 1. reboot/shutdown/登录/增加用户名/修改密码等工具 2. 支持apt/dpkg工具 3. 支持驱动加载/卸载/查看等工具 ##### 6.2.3 多媒体实例展示 1) 播放H264格式的视频文件 命令: ```bash 1. gst-play-1.0 test.h264 --videosink fbdevsink 2. gst-play-1.0 big_buck_bunny.mp4 --videosink fbdevsink ``` 效果: ![](resources\xfce_h264_mp4.png) 6) VLC推流 命令: ```bash root# vlc -vvv big_buck_bunny.mp4 --sout "#transcode{vb=0,scale=0,acodec=mpga,ab=128,channels=2,samplerate=44100}:rtp{sdp=rtsp://172.16.11.35:8554/test}" ``` 效果: ![](resources\vlc推流.png) ##### 6.2.4 XFCE桌面效果展示 ![](resources\xfce_desktop.png) ### 6.3、GNOME映像 #### 6.3.1 如何生成包 1.编译命令: ```bash source openembedded-core/oe-init-build-env thead-build/ice-gnome bitbake core-image-minimal-gnome 或 bitbake core-image-gnome ``` 2.映像路径: ``` thead-build/ice-gnome/tmp-glibc/deploy/images/ice ``` 3.`deb`包路径: ``` thead-build/ice-gnome/tmp-glibc/deploy/deb/riscv64 ``` #### 6.3.2 镜像支持的功能 1)网络类 1. 支持ifconfig,dhcp,netstat等工具; 2. 支持有线网络正常通信; 3. 支持route/ipmaddr/ping等工具 2) 文件系统 1. 支持文件系统check工具,支持文件系统格式化工具; 2. 支持文件创建/查看/磁盘空间查看等工具 3. 支持gzip/gnzip/tar等文件压缩/解压工具 3) 其他 1. 支持reboot/shutdown等工具 2. 支持登录/修改用户名/密码等工具 3. 支持apt系列工具 4. 支持驱动加载/卸载工具 2. 音视频支持:ffmpeg、gstreamer、vlc #### 6.3.3 多媒体实例展示 gnome播放功能支持: 主要是缺少H264/MPEG等解码库,需要对解码库进行跟新: 1. 跟新libavcodec.so等库,打包在so.tag.gz中,解压后跟新到/usr/lib中; 2. ln -s /usr/lib/libcap-ng.so /usr/lib/ld-linux-riscv64-lp64d.so.1 跟新之后测试命令如下: ```bash gst-play-1.0 big_buck_bunny.mp4 --vediosink fbdevsink ``` ![image-20210606214007109](resources\gnome_mp4.png) ![image-20210606214114989](resources\gnome_mp41.png) ![image-20210606214306237](resources\gnome_mp42.png) #### 6.3.4 GNOME桌面效果展示 ![image-20210606214418314](resources\gnome_desktop1.png) ![image-20210606214445745](resources\gnome_desktop2.png) ![image-20210606215233734](resources\gnome_desktop3.png) ## 7、SDK的编译方法 ### 7.1. SDK映像 编译命令: ```bash source openembedded-core/oe-init-build-env thead-build/ice-gnome bitbake core-image-minimal-gnome -c populate_sdk 备注: image可以任意指定(比如:xfce等) ``` SDK路径: ```bash thead-build/ice-gnome/tmp-glibc/deploy/sdk ``` `sdk`包名称(包含编译器,文件系统库,头文件): ```bash oecore-x86_64-riscv64-toolchain-nodistro.0.sh ``` 安装SDK: ```bash cd thead-build/ice-gnome/tmp-glibc/deploy/sdk sudo ./oecore-x86_64-riscv64-toolchain-nodistro.0.sh -d /opt 备注:更多参数参见--help ``` 使用SDK: ```bash source /opt/environment-setup-riscv64-oe-linux $CC -o test test.c ``` ## 8.基于bb文件的批量编译 ### 8.1、编译的原则 ```bash 针对当前或指定目录下.bb文件编译 ``` ### 8.2、编译脚本名称及用法 ```bash 名称:runbitbake.sh 参数: runbitbake.sh <路径> <开始序号> <路径>: 默认当前路劲那个(.) <开始序号> :默认1 ``` 详细参见 [runbitbake.sh]: resources\runbitbake.sh "runbitbake.sh" ### 8.3、编译产出结果说明 1) result_YYYYMMDD_hh-mm-ss_report.txt (编译结果) 2) bitbake_YYYYMMDD_hh-mm-ss_log.txt (编译过程LOG) 生成的路径在<路径>下 `result_YYYYMMDD_hh-mm-ss_report.txt`内容如下: ```bash # 软件包名 结果 deb数量 bb文件的路劲 1 grub-bootconf OK 3 meta/recipes-bsp/grub/grub-bootconf_1.00.bb 2 grub-efi NG 0 meta/recipes-bsp/grub/grub-efi_2.04.bb 3 grub NG 0 meta/recipes-bsp/grub/grub_2.04.bb 4 acpid OK 5 meta/recipes-bsp/acpid/acpid_2.0.32.bb 5 usbutils OK 6 meta/recipes-bsp/usbutils/usbutils_013.bb ...... ``` `bitbake_YYYYMMDD_hh-mm-ss_log.txt`内容如下: ```bash Build time:Thu Apr 29 12:39:28 CST 2021 Total number of files:[788] Working directory:[/home/lqg/al_yocto/riscv_yocto/openembedded-core/meta/] [1/788] = meta/recipes-bsp/grub/grub-bootconf_1.00.bb [bitbake grub-bootconf] #### make completed successfully ========= [grub-bootconf] deb file(3) ======= grub-bootconf-dev_1.00-r0_csky.deb grub-bootconf_1.00-r0_csky.deb grub-bootconf-dbg_1.00-r0_csky.deb ========= output end ================== ...... #############bitbake result:################ Total number of files:[788] OK number of files:[623] NG number of files:[165] #############bitbake end#################### Detailed report results are as follows: ############################################ meta//result_20210429_12-39-28_report.txt ############################################ ``` ### 8.4 编译例程(以oe-core为例) 1). /riscv_yocto/openembedded-core$ ./runbitbake.sh meta/ 2). 通过以下命令实时观看编译过程 ```bash tail -f bitbake_YYYYMMDD_hh-mm-ss_log.txt tail -f result_YYYYMMDD_hh-mm-ss_report.txt ``` ### 8.4 编译结果 1) CSKY编译结果 | CSKY编译一览表 | | | | | | | | | -------------- | ----------------- | --------------- | ---------- | --------- | ------- | ------- | ---------- | | 大 项 目 | 中  项 目 | | | | | | | | # | 大项目名 | 小项目数 |编译结果 | | | || | 分类 | yocto源码 | meta层 | bb文件个数 | deb数量 | OK个数 | NG个数 | OK率 (%) | | 01 | openembedded-core | meta | 788 | 9411 | 623 | 165 | 79.06% | | 02 | meta-openembedded | meta-webserver | 20 | 135 | 13 | 7 | 65.00% | | 03 | meta-openembedded | meta-xfce | 74 | 3296 | 59 | 15 | 79.73% | | 04 | meta-openembedded | meta-networking | 194 | 1121 | 162 | 32 | 83.51% | | 05 | meta-openembedded | meta-gnome | 93 | 1925 | 50 | 43 | 53.76% | | 06 | meta-openembedded | meta-multimedia | 82 | 402 | 58 | 24 | 70.73% | | **总数** | | | **1251** | **16290** | **965** | **286** | **77.14%** | 2) RISCV编译结果 | RISCV编译一览表 | | | | | | | | | --------------- | ----------------- | --------------- | ---------- | --------- | -------- | ------- | ---------- | | 大 项 目 | 中  项 目 | | | | | | | | # | 大项目名 | 小项目数 | 编译结果 | | | | | | 分类 | yocto源码 | meta层 | bb文件个数 | deb数量 | OK个数 | NG个数 | OK率 (%) | | 01 | openembedded-core | meta | 788 | 11888 | 694 | 94 | 88.07% | | 02 | meta-openembedded | meta-webserver | 20 | 209 | 19 | 1 | 95.00% | | 03 | meta-openembedded | meta-xfce | 74 | 6676 | 67 | 7 | 90.54% | | 04 | meta-openembedded | meta-networking | 194 | 1605 | 179 | 15 | 92.27% | | 05 | meta-openembedded | meta-gnome | 93 | 5112 | 91 | 2 | 97.85% | | 06 | meta-openembedded | meta-multimedia | 82 | 529 | 70 | 12 | 85.37% | | **总数** | | | **1251** | **26019** | **1120** | **131** | **89.53%** | ## 9. CSKY工具链在YOCTO环境移植 ### 9.1. 工具链安装 #### 9.1.1 下载工具链 + sysroot 软件: ```bash csky-linux-gnuabiv2-tools-x86_64-glibc-linux-4.9.56-20210127.tar.gz ``` #### 9.1.2 安装工具链 ```bash mkdir ~/.thead ``` 1). 将下载的 csky-linux-gnuabiv2-tools-x86_64-glibc-linux-4.9.56-20210127.tar.gz 解压到 ~/.thead ```bash tar zxf csky-linux-gnuabiv2-tools-x86_64-glibc-linux-4.9.56-20210127.tar.gz -C ~/.thead ls ~/.thead csky-linux-4.9.56 ln -s ~/.thead/csky-linux-4.9.56 ~/.thead/csky-linux ``` 2). 工具链名重链接 ```bash ln -s csky-linux-gnuabiv2-addr2line csky-linux-addr2line ln -s csky-linux-gnuabiv2-ar csky-linux-ar ln -s csky-linux-gnuabiv2-as csky-linux-as ln -s csky-linux-gnuabiv2-c++ csky-linux-c++ ln -s csky-linux-gnuabiv2-c++filt csky-linux-c++filt ln -s csky-linux-gnuabiv2-cpp csky-linux-cpp ln -s csky-linux-gnuabiv2-elfedit csky-linux-elfedit ln -s csky-linux-gnuabiv2-g++ csky-linux-g++ ln -s csky-linux-gnuabiv2-gcc csky-linux-gcc ln -s csky-linux-gnuabiv2-gcc-6.3.0 csky-linux-gcc-6.3.0 ln -s csky-linux-gnuabiv2-gcc-ar csky-linux-gcc-ar ln -s csky-linux-gnuabiv2-gcc-nm csky-linux-gcc-nm ln -s csky-linux-gnuabiv2-gcc-ranlib csky-linux-gcc-ranlib ln -s csky-linux-gnuabiv2-gcov csky-linux-gcov ln -s csky-linux-gnuabiv2-gcov-tool csky-linux-gcov-tool ln -s csky-linux-gnuabiv2-gdb csky-linux-gdb ln -s csky-linux-gnuabiv2-gfortran csky-linux-gfortran ln -s csky-linux-gnuabiv2-gprof csky-linux-gprof ln -s csky-linux-gnuabiv2-ld csky-linux-ld ln -s csky-linux-gnuabiv2-ld.bfd csky-linux-ld.bfd ln -s csky-linux-gnuabiv2-nm csky-linux-nm ln -s csky-linux-gnuabiv2-objcopy csky-linux-objcopy ln -s csky-linux-gnuabiv2-objdump csky-linux-objdump ln -s csky-linux-gnuabiv2-ranlib csky-linux-ranlib ln -s csky-linux-gnuabiv2-readelf csky-linux-readelf ln -s csky-linux-gnuabiv2-size csky-linux-size ln -s csky-linux-gnuabiv2-strings csky-linux-strings ln -s csky-linux-gnuabiv2-strip csky-linux-strip ``` ### 9.2 创建meta-csky 1). 参考meta-riscv的目录结构创建目录 ```bash cp meta-riscv meta-csky ``` #### 9.2.1 配置修改 修改文件conf/machine/include/thead-base.inc ```bash require conf/machine/include/csky/tune-csky.inc EXTERNAL_TOOLCHAIN ?= "${HOME}/.thead/csky-linux" TCMODE="external" TARGET_PREFIX="csky-linux-gnuabiv2-" TARGET_ARCH="csky" TARGET_OS="linux" ``` 详细参见解压后的meta-csky.tgz tar xzvf meta-csky.tgz . ### 9.3. oe-core中追加对CSKY架构的支持 #### 9.3.1 修改的范围 ```bash modified: meta/classes/kernel-arch.bbclass modified: meta/classes/package.bbclass modified: meta/classes/siteinfo.bbclass modified: meta/lib/oe/elf.py modified: meta/recipes-bsp/opensbi/opensbi_0.8.bb modified: meta/recipes-connectivity/openssl/openssl_1.1.1h.bb ``` #### 9.3.2 修改点如下 ```bash diff --git a/meta/classes/kernel-arch.bbclass b/meta/classes/kernel-arch.bbclass index 07ec242e63..2d6ea39d23 100644 --- a/meta/classes/kernel-arch.bbclass +++ b/meta/classes/kernel-arch.bbclass @@ -31,6 +31,7 @@ def map_kernel_arch(a, d): elif re.match('mips(isa|)(32|64|)(r6|)(el|)$', a): return 'mips' elif re.match('mcf', a): return 'm68k' elif re.match('riscv(32|64|)(eb|)$', a): return 'riscv' + elif re.match('csky', a): return 'csky'diff --git a/meta/classes/package.bbclass b/meta/classes/package.bbclass index e6236c0bb2..191026d344 100644 --- a/meta/classes/package.bbclass +++ b/meta/classes/package.bbclass @@ -1429,7 +1429,8 @@ python populate_packages () { mkdir_recurse(dvar, root, os.path.dirname(file)) fpath = os.path.join(root,file) if not cpath.islink(file): - os.link(file, fpath) + if not os.path.exists(fpath): + os.link(file, fpath) continue ret = bb.utils.copyfile(file, fpath) if ret is False or ret == 0: diff --git a/meta/classes/siteinfo.bbclass b/meta/classes/siteinfo.bbclass index 0bd1f36805..7cd249d94c 100644 --- a/meta/classes/siteinfo.bbclass +++ b/meta/classes/siteinfo.bbclass @@ -54,6 +54,7 @@ def siteinfo_data_for_machine(arch, os, d): "ppc64le" : "endian-little bit-64 powerpc-common", "riscv32": "endian-little bit-32 riscv-common", "riscv64": "endian-little bit-64 riscv-common", + "csky": "endian-little bit-32 csky-common", "sh3": "endian-little bit-32 sh-common", "sh3eb": "endian-big bit-32 sh-common", "sh4": "endian-little bit-32 sh-common", @@ -118,6 +119,8 @@ def siteinfo_data_for_machine(arch, os, d): "riscv64-linux": "riscv64-linux", "riscv64-linux-musl": "riscv64-linux", "x86_64-cygwin": "bit-64", + "csky-linux": "csky-linux", + "csky-linux-musl": "csky-linux", "x86_64-darwin": "bit-64", "x86_64-darwin9": "bit-64", "x86_64-linux": "bit-64", diff --git a/meta/lib/oe/elf.py b/meta/lib/oe/elf.py index df0a4593fa..a861b6f1fe 100644 --- a/meta/lib/oe/elf.py +++ b/meta/lib/oe/elf.py @@ -24,6 +24,7 @@ def machine_dict(d): "microblaze": (189, 0, 0, False, 32), "microblazeel":(189, 0, 0, True, 32), "powerpc": (20, 0, 0, False, 32), + "csky": (252, 0, 0, True, 32), "riscv32": (243, 0, 0, True, 32), "riscv64": (243, 0, 0, True, 64), }, @@ -53,6 +54,7 @@ def machine_dict(d): "mipsisa64r6": ( 8, 0, 0, False, 64), "mipsisa64r6el": ( 8, 0, 0, True, 64), "nios2": (113, 0, 0, True, 32), + "csky": (252, 0, 0, True, 32), "riscv32": (243, 0, 0, True, 32), "riscv64": (243, 0, 0, True, 64), "s390": (22, 0, 0, False, 32), @@ -80,6 +82,7 @@ def machine_dict(d): "mips64el": ( 8, 0, 0, True, 64), "microblaze": (189, 0, 0, False, 32), "microblazeel":(189, 0, 0, True, 32), + "csky": (252, 0, 0, True, 32), "riscv32": (243, 0, 0, True, 32), "riscv64": (243, 0, 0, True, 64), "sh4": ( 42, 0, 0, True, 32), ``` #### 9.3.2 详细参见patch ```bash open-core.diff ``` #### 9.3.3 增加CSKY工具链配置 ```bash meta/conf/machine/include/csky csky/ ├── arch-csky.inc ├── qemuriscv.inc └── tune-csky.inc ``` #### 9.3.4 解压 csky.tgz ```bash cd riscv_yocto/openembedded-core tar xzvf csky.tgz . ``` ### 9.4. 编译 ```bash # 在 yocto 工程根目录 riscv_yocto/ 下执行: sh openembedded-core/envsetup.sh -a csky -i thead-build/ice-base # 将 build 目录指定为 thead-build/ice-base # 确认 downloads 文件夹:设置一个存放 yocto 下载文件的共享目录 SHARE_YOCTO_DOWNLOAD_FILE_FOLDER ln -s SHARE_YOCTO_DOWNLOAD_FILE_FOLDER/ ../downloads # 编译:thead-build/ice-base/conf/auto.conf 中默认设置为 MACHINE ?= "ice" bitbake core-image-minimal # sstate-cache/ 会放在 thead-build/ 下,不同配置可以共享使用 ``` #### 9.4.1 输出 ```bash # 镜像文件 ./build/tmp-glibc/deploy/images/ice ``` ## 10. CSKY与RISCV编译修改说明 ### 10.1 envsetup.sh脚本说明-(新增脚本) ```bash Usage: pack [-cARCH] [-oIMAGE] [-h] -a ARCH (default: riscv) -o IMAGE_DIR (default: thead-build/ice-base) -h print this help message ``` ### 10.2 架构如何匹配 ```bash 架构匹配的统一名称:meta-arch rm -rf $T/meta-arch ln -s $T/meta-$ARCH $T/meta-arch ``` ###5.3 修改bblayers.conf(以ice-base为例) ```bash /riscv_yocto/thead-build/ice-base/conf$ git diff bblayers.conf diff --git a/ice-base/conf/bblayers.conf b/ice-base/conf/bblayers.conf index d6f6ef7..3600ec7 100644 --- a/ice-base/conf/bblayers.conf +++ b/ice-base/conf/bblayers.conf @@ -15,5 +15,5 @@ BBLAYERS ?= " \ ${YOCTOROOT}/meta-openembedded/meta-multimedia \ ${YOCTOROOT}/meta-openembedded/meta-networking \ ${YOCTOROOT}/meta-external-toolchain \ - ${YOCTOROOT}/meta-riscv \ + ${YOCTOROOT}/meta-arch \ " ``` ###5.4 如何编译 1. source openembedded-core/envsetup.sh ```bash Setup env done! Please run config next. ``` 2. config(可以直接config 1或2) ```bash /riscv_yocto/thead-build/ice-base# config You're building on Linux Config menu... pick a combo: 1. riscv 2. csky Which would you like? [Default riscv]: ``` 3. 查看帮助 ```bash /riscv_yocto/thead-build/ice-base# help Invoke ". build/envsetup.sh" from your shell to add the following functions to your environment: == before all == - config: config == build project == - mbase: Build ice_base. - mxfce: Build ice_xfce. - mgnome: Build ice_gnome. - msdk: Build SDK. == jump directory == - ctarget: Jump to target directory. - cdeb: Jump to target deb directory. - cimage: Jump to target image directory. ``` 备注: ice-gnome 和 ice-xfce下的bblayers.conf文件同样修改