# 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 <arch_name>

== 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文件同样修改