目录分析
在OpenHarmony
编译过程中,内核源码是不变的,内核源码保存在kernel/linux/linux-5.10/
下,并且永远不被修改。
在编译内核前,会将内核源码复制到内核临时源码目录out/kernel/src_tmp/linux-5.10/
下,然后再以打补丁的方式进行修改。
在编译命令./build.sh --product-name rk3568 --ccache
中,用--product
命令指定了rk3568
。
通过查阅文档得知,这个product
参数是在vendor
文件夹中所指定的。
❯ vim vendor/hihope/rk3568/config.json
{ "product_name": "rk3568", "device_company": "rockchip", "device_build_path": "device/board/hihope/rk3568", "target_cpu": "arm", "type": "standard", "version": "3.0", "board": "rk3568", ... }
|
在该配置文件中指定了product_name
为rk3568
的目标的编译路径是device/board/hihope/rk3568
。
❯ cd device/board/hihope/rk3568 ❯ ls audio_drivers bootanimation BUILD.gn camera cfg config.gni device.gni distributedhardware kernel loader ohos.build startup updater wifi
|
目标的编译路径下面有很多文件,我们关心的是内核移植,所以只需要看kernel
文件夹。
❯ cd kernel && ls BUILD.gn build_kernel.sh dts JL201 logo.bmp logo_kernel.bmp ov8858.c
|
先从BUILD.gn
文件开始看:
❯ cat BUILD.gn ··· import("//build/config/clang/clang.gni") import("//build/ohos.gni") kernel_build_script_dir = "//kernel/linux/linux-5.10" kernel_source_dir = "//kernel/linux/linux-5.10"
action("kernel") { script = "build_kernel.sh" sources = [ kernel_source_dir ]
product_path = "vendor/$product_company/$product_name" outputs = [ "$root_build_dir/../kernel/src_tmp/linux-5.10/boot_linux" ] args = [ rebase_path(kernel_build_script_dir, root_build_dir), rebase_path("$root_build_dir/packages/phone/images"), rebase_path("//device/board/hihope/$device_name"), product_path, rebase_path("$root_build_dir/../.."), device_company, device_name, product_company, ] ··· }
|
可以看到当构建流执行到这里的时候会直接执行build_kernel.sh
这个脚本,并且传入一些参数。
编译流程
查看build_kernel.sh
这个脚本:
set -e
pushd ${1} ROOT_DIR=${5} export PRODUCT_PATH=${4} export DEVICE_COMPANY=${6} export DEVICE_NAME=${7} export PRODUCT_COMPANY=${8} ENABLE_LTO_O0=${9}
KERNEL_SRC_TMP_PATH=${ROOT_DIR}/out/kernel/src_tmp/linux-5.10 KERNEL_OBJ_TMP_PATH=${ROOT_DIR}/out/kernel/OBJ/linux-5.10 KERNEL_SOURCE=${ROOT_DIR}/kernel/linux/linux-5.10 KERNEL_PATCH_PATH=${ROOT_DIR}/kernel/linux/patches/linux-5.10 KERNEL_PATCH=${ROOT_DIR}/kernel/linux/patches/linux-5.10/rk3568_patch/kernel.patch KERNEL_CONFIG_FILE=${ROOT_DIR}/kernel/linux/config/linux-5.10/arch/arm64/configs/rk3568_standard_defconfig NEWIP_PATCH_FILE=${ROOT_DIR}/foundation/communication/sfc/newip/apply_newip.sh
rm -rf ${KERNEL_SRC_TMP_PATH} mkdir -p ${KERNEL_SRC_TMP_PATH}
rm -rf ${KERNEL_OBJ_TMP_PATH} mkdir -p ${KERNEL_OBJ_TMP_PATH} export KBUILD_OUTPUT=${KERNEL_OBJ_TMP_PATH}
cp -arf ${KERNEL_SOURCE}/* ${KERNEL_SRC_TMP_PATH}/
cd ${KERNEL_SRC_TMP_PATH}
bash ${ROOT_DIR}/drivers/hdf_core/adapter/khdf/linux/patch_hdf.sh ${ROOT_DIR} ${KERNEL_SRC_TMP_PATH} ${KERNEL_PATCH_PATH} ${DEVICE_NAME}
patch -p1 < ${KERNEL_PATCH}
if [ -f $NEWIP_PATCH_FILE ]; then bash $NEWIP_PATCH_FILE ${ROOT_DIR} ${KERNEL_SRC_TMP_PATH} ${DEVICE_NAME} linux-5.10 fi
cp -rf ${3}/kernel/logo* ${KERNEL_SRC_TMP_PATH}/
cp -rf ${KERNEL_CONFIG_FILE} ${KERNEL_SRC_TMP_PATH}/arch/arm64/configs/rockchip_linux_defconfig
ramdisk_arg="disable_ramdisk" make_ohos_env="GPUDRIVER=mali" for i in "$@" do case $i in enable_ramdisk) ramdisk_arg=enable_ramdisk ;; enable_mesa3d) make_ohos_env="GPUDRIVER=mesa3d" python ${ROOT_DIR}/third_party/mesa3d/ohos/modifyDtsi.py ${KERNEL_SRC_TMP_PATH}/arch/arm64/boot/dts/rockchip/rk3568.dtsi ;; esac done eval $make_ohos_env ./make-ohos.sh TB-RK3568X0 $ramdisk_arg ${ENABLE_LTO_O0}
mkdir -p ${2}
if [ "enable_ramdisk" != "${10}" ]; then cp ${KERNEL_OBJ_TMP_PATH}/boot_linux.img ${2}/boot_linux.img fi cp ${KERNEL_OBJ_TMP_PATH}/resource.img ${2}/resource.img cp ${3}/loader/parameter.txt ${2}/parameter.txt cp ${3}/loader/MiniLoaderAll.bin ${2}/MiniLoaderAll.bin cp ${3}/loader/uboot.img ${2}/uboot.img cp ${3}/loader/config.cfg ${2}/config.cfg popd
../kernel/src_tmp/linux-5.10/make-boot.sh ..
|
变量解释
- KERNEL_SRC_TMP_PATH: 源码临时路径,在编译流程中,内核的原源码是不变的,需要将内核源码复制到这个路径下,然后对这个路径下的内核源码进行打补丁。
- KERNEL_OBJ_TMP_PATH: 目标临时路径。
- KERNEL_SOURCE: 内核原源码路径
- KERNEL_PATCH_PATH: 内核补丁路径
- KERNEL_PATCH: 内核补丁文件
- KERNEL_CONFIG_FILE: 内核配置文件
- NEWIP_PATCH_FILE: newip补丁文件
脚本解释
将内核源码复制到内核临时源码目录并且进入:
rm -rf ${KERNEL_SRC_TMP_PATH} mkdir -p ${KERNEL_SRC_TMP_PATH}
rm -rf ${KERNEL_OBJ_TMP_PATH} mkdir -p ${KERNEL_OBJ_TMP_PATH} export KBUILD_OUTPUT=${KERNEL_OBJ_TMP_PATH}
cp -arf ${KERNEL_SOURCE}/* ${KERNEL_SRC_TMP_PATH}/
cd ${KERNEL_SRC_TMP_PATH}
|
对内核源码进行打补丁:
bash ${ROOT_DIR}/drivers/hdf_core/adapter/khdf/linux/patch_hdf.sh ${ROOT_DIR} ${KERNEL_SRC_TMP_PATH} ${KERNEL_PATCH_PATH} ${DEVICE_NAME}
patch -p1 < ${KERNEL_PATCH}
|
其中HDF的补丁调用到了drivers/hdf_core/adapter/khdf/linux/patch_hdf.sh
这个脚本,脚本参数如下:
- OH工程根目录,绝对路径
- 内核临时目录,绝对路径
- 内核补丁路径,绝对路径
- 设备名称
patch_hdf.sh
脚本对于补丁的搜索:
function put_hdf_patch() { HDF_PATCH_FILE=${KERNEL_PATCH_PATH}/${DEVICE_NAME}_patch/hdf.patch if [ ! -e "${HDF_PATCH_FILE}" ] then HDF_PATCH_FILE=${KERNEL_PATCH_PATH}/${HDF_COMMON_PATCH}_patch/hdf.patch fi patch -p1 < $HDF_PATCH_FILE }
|
可以看到此脚本是根据补丁路径+设备名称找到hdf.patch
这个补丁。
拷贝开机logo和配置文件:
cp -rf ${3}/kernel/logo* ${KERNEL_SRC_TMP_PATH}/
cp -rf ${KERNEL_CONFIG_FILE} ${KERNEL_SRC_TMP_PATH}/arch/arm64/configs/rockchip_linux_defconfig
|
创建env和执行编译脚本:
ramdisk_arg="disable_ramdisk" make_ohos_env="GPUDRIVER=mali" for i in "$@" do case $i in enable_ramdisk) ramdisk_arg=enable_ramdisk ;; enable_mesa3d) make_ohos_env="GPUDRIVER=mesa3d" python ${ROOT_DIR}/third_party/mesa3d/ohos/modifyDtsi.py ${KERNEL_SRC_TMP_PATH}/arch/arm64/boot/dts/rockchip/rk3568.dtsi ;; esac done eval $make_ohos_env ./make-ohos.sh TB-RK3568X0 $ramdisk_arg ${ENABLE_LTO_O0}
|
make-ohos.sh
脚本在内核临时源码目录,TB-RK3568X0
是选择设备树的。
make-ohos.sh
脚本中关于设备树如下:
··· model_list=( "TB-RK3568X0 arm64 0xfe660000 rk3568-xxx Image rockchip_linux_defconfig" )
···
|
其中TB-RK3568X0
是设备树目标名字, rk3568-xxx
是具体的设备树名字,注意,没有后缀。
回到build_kernel.sh
,创建编译文件目录并且拷贝过去:
mkdir -p ${2}
if [ "enable_ramdisk" != "${10}" ]; then cp ${KERNEL_OBJ_TMP_PATH}/boot_linux.img ${2}/boot_linux.img fi cp ${KERNEL_OBJ_TMP_PATH}/resource.img ${2}/resource.img cp ${3}/loader/parameter.txt ${2}/parameter.txt cp ${3}/loader/MiniLoaderAll.bin ${2}/MiniLoaderAll.bin cp ${3}/loader/uboot.img ${2}/uboot.img cp ${3}/loader/config.cfg ${2}/config.cfg popd
|
执行生成boot_linux.img
脚本:
../kernel/src_tmp/linux-5.10/make-boot.sh ..
|