编辑
2025-01-22
工作知识
0
请注意,本文编写于 135 天前,最后修改于 135 天前,其中某些信息可能已经过时。

目录

一、原始内核位置
二、编译后内核位置
三、编译内核
3.1、sdk模块编译
3.2、build_kernel.sh脚本编译
3.3、 make-ohos.sh脚本编译
3.4、内核分步骤编译
3.4.1 hdfhcshex.o重编译
3.4.2 缺少包pahole工具
3.4.5 编译有不匹配的残留文件

开发Openharmony的设备开发第一步就是移植内核,本文基于openharmony的sdk角度介绍openharmony的内核编译方式和单独编译内核的命令

一、原始内核位置

这里内核有两个位置,一个是内核原始源码位置,这是oh标准内核,位置为/kernel/linux/linux-5.10/

在这个内核上,会添加如下几个依赖仓库的改动如下

"kernel/linux/build" # 编译相关脚本 "kernel/linux/linux-5.10" # 内核仓库 "kernel/linux/patches" # 内核相关补丁 "kernel/linux/config" # 内核的defconfig "kernel/linux/common_modules" # oh特性的内核驱动 "third_party/bounds_checking_function" # libboundscheck库,安全函数,带边界检查的标准函数 "device/soc/hisilicon/common/platform/wifi" # 海思wifi "third_party/FreeBSD/sys/dev/evdev" # evdev 头文件 "drivers/hdf_core" # hdf 核心驱动 "prebuilts/clang/ohos/linux-x86_64/llvm/bin" # llvm

这里值得注意的是,patch目录,它需要对内核合入hdf补丁,并且需要合入rk3568芯片的基础改动的patch,主要如下

└── rk3568_patch ├── kernel.patch # linux-5.10 rk3568 SOC patches └── hdf.patch # linux-5.10 rk3568 定制 HDF patches

我们通常做移植的后续工作是设配oh的硬件抽象层,主要如下

├── adapter ├── bundle.json ├── figures ├── framework ├── interfaces ├── LICENSE ├── OAT.xml ├── README.md └── README_zh.md

二、编译后内核位置

编译后的内核位置为/out/kernel/src_tmp/linux-5.10/, 编译后内核的中间文件位置为/out/kernel/OBJ/linux-5.10/

此时代码是已经合入补丁和相关oh特性功能的代码。

三、编译内核

编译内核可以分为最外层sdk模块编译,内核源码build_kernel.sh脚本编译(合并前),内核源码make-ohos.sh脚本编译(合并后),和内核分步骤编译,可以按需自行编译

3.1、sdk模块编译

对于内核而言,sdk模块编译目前默认不支持,但sdk外层编译有必要解释一下,所以编译内核的最外层sdk编译命令如下

./build.sh --product-name rk3568 --ccache

上述命令可以整体环境编译,故内核也编译了,但是缺点是编译一次时间太长。为了指定模块的单独编译,可以设置--build-target,如下是代码示例

group("make_images") group("eng_system_image") group("eng_chipset_image") group("chip_prod_image") group("sys_prod_image") group("system_image") group("userdata_image") group("vendor_image") group("ramdisk_image") group("updater_ramdisk_image") group("updater_image")

可以知道,通过如下参数指定编译

./build.sh --product-name rk3568 --ccache --build-target make_images ./build.sh --product-name rk3568 --ccache --build-target system_image ./build.sh --product-name rk3568 --ccache --build-target userdata_image

build-target还能通过指定gn路径+目标名指定模块编译,如下

./build.sh --product-name rk3568 --ccache --build-target commonlibrary/c_utils/base:util

这里commonlibrary/c_utils/base是BUILD.gn文件目录,util是BUILD.gn声明的模块名称。

虽然内核不能单独编译,但是执行全量编译只需要等待即可获得boot_linux.img文件

查看build-target支持的选项,如下命令

prebuilts/build-tools/linux-x86/bin/ninja -w dupbuild=warn -C out/rk3568/ -t targets

对于查出来的选项,可以直接用ninja编译模块,以内核举例

prebuilts/build-tools/linux-x86/bin/ninja -w dupbuild=warn -C out/rk3568/ kernel

如果使用hb命令,可以如下编译内核

hb build -T kernel

3.2、build_kernel.sh脚本编译

build_kernel.sh作为内核单模块BUILD.gn拉起的脚本,我们可以主动调用它来单独编译内核,但是前提是代码是全编过一次的,也就是out/rk3568目录存在。编译命令如下

`pwd`/../../device/board/hihope/rk3568/kernel/build_kernel.sh `pwd`/../../kernel/linux/linux-5.10 `pwd`/../../out/rk3568/packages/phone/images `pwd`/../../device/board/hihope/rk3568 vendor/hihope/rk3568 `pwd`/../../ rockchip rk3568 hihope root default disable_lto_O0 enable_ramdisk

这里解释如下

此命令需要绝对路径

build_kernel.sh需要11个形参分别如下 $1=../../kernel/linux/linux-5.10 # pushd 参数,切换目录到linux-5.10上 $2=out/rk3568/packages/phone/images # 镜像输出目录 $3=device/board/hihope/rk3568 # BUILD_SCRIPT_PATH变量 $4=vendor/hihope/rk3568 # PRODUCT_PATH变量 $5=`pwd` # ROOT_DIR变量 $6=rockchip # DEVICE_COMPANY变量 $7=rk3568 # DEVICE_NAME变量 $8=hihope # PRODUCT_COMPANY变量 $9=root # KERNEL_FORM变量 $10=default # KERNEL_PROD变量 $11=disable_lto_O0 # ENABLE_LTO_O0变量 $12=enable_ramdisk # 判断是否生成ramdisk

此命令如果是第一次运行,会自动打patch和复制oh特性驱动代码。如果不是第一次运行,则跳过不应用补丁,直接开始编译。此命令会主动拷贝文件到out/rk3568/packages/phone/images目录。

3.3、 make-ohos.sh脚本编译

根据对build_kernel.sh的解析,为了在代码目录out/kernel/src_tmp/linux-5.10直接编译,可以直接如下命令编译

KBUILD_OUTPUT=../../OBJ/linux-5.10 PRODUCT_PATH=vendor/hihope/rk3568 DEVICE_COMPANY=rockchip DEVICE_NAME=rk3568 PRODUCT_COMPANY=hihope GPUDRIVER=mali ./make-ohos.sh TB-RK3568X0 enable_ramdisk

对于参数解析如下:

KBUILD_OUTPUT:指定内核编译中间文件位置 PRODUCT_PATH:指定产品路径,khdf需要使用 GPUDRIVER: 指定显卡驱动,瑞芯微支持mali和panfrost两种驱动 TB-RK3568X0:指定开发板类型,当前oh的sdk只支持TB-RK3568X0和TB-RK3568X10两款开发板,两个开发板对应的设备树不一样而已,其他没区别 enable_ramdisk:指定生成ramdisk镜像

通过上述命令可以在源码目录生成boot_linux目录和boot_linux.img,注意,此时的boot_linux.img不会主动复制到out/rk3568/packages/phone/images目录。

3.4、内核分步骤编译

内核编译分三个步骤

编译defconfig 编译ko模块 编译image内核二进制

内核打包通过mke2fs打包ext2格式的镜像,通过make-boot.sh打包

涉及命令主要如下:

make KBUILD_OUTPUT=../../OBJ/linux-5.10 PRODUCT_PATH=vendor/hihope/rk3568 LLVM=1 LLVM_IAS=1 CROSS_COMPILE=aarch64-linux-gnu- ARCH=arm64 rockchip_linux_defconfig make KBUILD_OUTPUT=../../OBJ/linux-5.10 PRODUCT_PATH=vendor/hihope/rk3568 LLVM=1 LLVM_IAS=1 CROSS_COMPILE=aarch64-linux-gnu- ARCH=arm64 modules_prepare rm -rf ../../../kernel/vendor/hihope/rk3568/hdf_config/khdf/hdf_test/ make KBUILD_OUTPUT=../../OBJ/linux-5.10 PRODUCT_PATH=vendor/hihope/rk3568 LLVM=1 LLVM_IAS=1 CROSS_COMPILE=aarch64-linux-gnu- ARCH=arm64 rk3568-toybrick-x0-linux.img -j96

这时候内核已经编译成Image文件,需要手动cp一下

cp ../../OBJ/linux-5.10/arch/arm64/boot/Image boot_linux/extlinux/Image

然后运行make-boot.sh脚本打包boot_linux.img

./make-boot.sh ../../../

此时boot_linux.img文件存放在/rk3568/packages/phone/images/内

3.4.1 hdf_hcs_hex.o重编译

默认的hdf_test在单编译的时候会报错如下:

ld.lld: error: drivers/built-in.a(../../../vendor/hihope/rk3568/hdf_config/khdf/hdf_test/hdf_hcs_hex.o): Invalid value (Producer: 'LLVM15.0.4' Reader: 'LLVM 12.0.1')

上述日志说明hdf_hcs_hex.o和当前单编的llvm版本不一样,所以删除.o即可,如下操作

rm -rf ../../../kernel/vendor/hihope/rk3568/hdf_config/khdf/hdf_test/

3.4.2 缺少包pahole工具

缺少工具是因为缺少包导致,错误信息如下

BTF: .tmp_vmlinux.btf: pahole (pahole) is not available

安装dwarves包即可

apt install dwarves

3.4.5 编译有不匹配的残留文件

如果编译环境出问题,如下命令清理一下

KBUILD_OUTPUT=../../OBJ/linux-5.10 make LLVM=1 LLVM_IAS=1 CROSS_COMPILE=aarch64-linux-gnu- ARCH=arm64 PRODUCT_PATH=vendor/hihope/rk3568 DEVICE_COMPANY=rockchip mrproper

如果是误操作在out/kernel/src_tmp/linux-5.10编译了中间文件,则需要在本目录操作mrproper,如下

make LLVM=1 LLVM_IAS=1 CROSS_COMPILE=aarch64-linux-gnu- ARCH=arm64 PRODUCT_PATH=vendor/hihope/rk3568 DEVICE_COMPANY=rockchip mrproper