快速移植 OpenHarmony Linux 内核到三方 ARM64 平台
官方的文档我觉得是最终的产品形态,一个新品在开发移植过程中不太可能一步到位,尤其是非官方支持版本,所以多少还是要拆分下。
准备整体构建环境
1 准备代码
理论上path不是问题,只要找到就好。这里就把要用的三方内核,比如我的是Linux-5.4就放到Linux目录下。
tj@ubuntu:~/code/oh-3.2.2/kernel/linux$ ls
build config linux-5.10 linux-5.4 patches third_party vendor
2 配置ARM64编译环境
check build/kernel.mk:
31 CLANG_HOST_TOOLCHAIN := $(OHOS_BUILD_HOME)/prebuilts/clang/ohos/linux-x86_64/llvm/bin
32 KERNEL_HOSTCC := $(CLANG_HOST_TOOLCHAIN)/clang
33 KERNEL_PREBUILT_MAKE := make
34 CLANG_CC := $(CLANG_HOST_TOOLCHAIN)/clang
39 else ifeq ($(KERNEL_ARCH), arm64)
40 KERNEL_TARGET_TOOLCHAIN := $(PREBUILTS_GCC_DIR)/linux-x86/aarch64/gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu/bin
41 KERNEL_TARGET_TOOLCHAIN_PREFIX := $(KERNEL_TARGET_TOOLCHAIN)/aarch64-linux-gnu-
进入Linux-5.4:
export PATH=./../../prebuilts/clang/ohos/linux-x86_64/llvm/bin:./../../prebuilts/gcc/linux-x86/aarch64/gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu/bin/:$PATH
export MAKE_OPTIONS="ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- CC=clang HOSTCC=clang"
3 编译Image和模块
移植前先编译一次三方内核,确保无误。
make $MAKE_OPTIONS O=out/ -j4
make $MAKE_OPTIONS O=out/ -j4 modules
移植内核态基础代码
官方文档提到的hilog/hievent:
drivers/staging/hilog
drivers/staging/hievent
还有这几个特性:
drivers/staging/hisysevent
drivers/staging/hungtask
drivers/staging/zerohung
drivers/staging/blackbox
对应的头文件:
include/dfx/hiview_hisysevent.h | 67 ++
include/dfx/hung_wp_screen.h | 24 +
include/dfx/hungtask_base.h | 111 ++
include/dfx/zrhung.h | 11 +
include/linux/blackbox.h | 84 ++
include/linux/blackbox_common.h | 44 +
include/linux/blackbox_storage.h | 22 +
drivers下还有个accesstokenid特性,改的地方还不只一处:
tj@ubuntu:~/ohos-3.2.2/kernel/linux/linux-5.10$ grep -R ACCESS_TOKENID --exclude-dir=accesstokenid
include/linux/sched.h:#ifdef CONFIG_ACCESS_TOKENID
drivers/Makefile:obj-$(CONFIG_ACCESS_TOKENID) += accesstokenid/
drivers/android/binder.c:#ifdef CONFIG_ACCESS_TOKENID
drivers/android/binder.c:#define ENABLE_ACCESS_TOKENID 1
drivers/android/binder.c:#define ENABLE_ACCESS_TOKENID 0
drivers/android/binder.c:#endif /* CONFIG_ACCESS_TOKENID */
drivers/android/binder.c:#define ACCESS_TOKENID_FEATURE_VALUE (ENABLE_ACCESS_TOKENID << 0)
drivers/android/binder.c:#define BINDER_CURRENT_FEATURE_SET ACCESS_TOKENID_FEATURE_VALUE
drivers/android/binder.c:#ifdef CONFIG_ACCESS_TOKENID
drivers/android/binder.c:#endif /* CONFIG_ACCESS_TOKENID */
drivers/android/binder.c:#ifdef CONFIG_ACCESS_TOKENID
drivers/android/binder.c:#endif /* CONFIG_ACCESS_TOKENID */
drivers/android/binder.c:#ifdef CONFIG_ACCESS_TOKENID
drivers/android/binder.c:#endif /* CONFIG_ACCESS_TOKENID */
drivers/android/binder.c:#ifdef CONFIG_ACCESS_TOKENID
drivers/android/binder.c:#endif /* CONFIG_ACCESS_TOKENID */
drivers/android/binder.c:#ifdef CONFIG_ACCESS_TOKENID
drivers/android/binder.c:#endif /* CONFIG_ACCESS_TOKENID */
fs/proc/base.c:#ifdef CONFIG_ACCESS_TOKENID
fs/proc/base.c:#endif /* CONFIG_ACCESS_TOKENID */
fs/proc/base.c:#ifdef CONFIG_ACCESS_TOKENID
fs/proc/base.c:#ifdef CONFIG_ACCESS_TOKENID
kernel/fork.c:#ifdef CONFIG_ACCESS_TOKENID
看了下 caller path:
base/security/access_token
所以说,要拿一个非官方支持的内核版本落地产品,不是说不能做,还是要考虑清楚。
移植内核态必选特性HDF
官方的打hdf patch方法, 看kernel.mk:
83 $(hide) $(OHOS_BUILD_HOME)/drivers/hdf_core/adapter/khdf/linux/patch_hdf.sh $(OHOS_BUILD_HOME) $(KERNEL_SRC_TMP_PATH) $(KERNEL_PATCH_PATH) $(DEVICE_NAME)
patch_hdf.sh:
65 function main()
66 {
67 cd $KERNEL_BUILD_ROOT
68 put_hdf_patch
69 ln_hdf_repos
70 copy_external_compents
71 cd -
72 }
put_hdf_patch
:
55 function put_hdf_patch()
56 {
57 HDF_PATCH_FILE=${KERNEL_PATCH_PATH}/${DEVICE_NAME}_patch/hdf.patch
58 if [ ! -e "${HDF_PATCH_FILE}" ]
59 then
60 HDF_PATCH_FILE=${KERNEL_PATCH_PATH}/${HDF_COMMON_PATCH}_patch/hdf.patch
61 fi
62 patch -p1 < $HDF_PATCH_FILE
63 }
我们这里用的是60行通用的hdf.patch:
kernel/linux/patches/linux-5.10/common_patch/hdf.patch
这个patch是给5.10用,我们是5.4,直接打多少应该是有问题的,还好只有300多行,手动改改即可。
然后,注掉这个put_hdf_patch
, 跑下patch_hdf.sh即可, 多了个PRODUCT_PATH
:
export PRODUCT_PATH=vendor/$your_product
使能几个,最大的问题就是有很多下面这类错误:
../drivers/hdf/khdf/manager/../../../..//framework/core/host/src/hdf_device_node.c:156:27: error: ISO C90 forbids mixing declarations and code [-Werror,-Wdeclaration-after-statement]
struct HdfServiceInfo servInfo;
code是这样写的:
149 int HdfDeviceNodePublishPublicService(struct HdfDeviceNode *devNode)
150 {
151 int ret;
152 if (devNode == NULL || devNode->deviceObject.service == NULL) {
153 HDF_LOGE("failed to publish public service, devNode is NULL");
154 return HDF_FAILURE;
155 }
156 struct HdfServiceInfo servInfo;
157 HdfServiceInfoInit(&servInfo, devNode);
158 ret = DevSvcManagerClntAddService(&devNode->deviceObject, &servInfo);
159 if (ret == HDF_SUCCESS) {
160 devNode->servStatus = true;
161 }
162
C90不允许declaration-after-statement
,看了下5.4/5.10还是gnu89, 上游已经更新到gnu11了,照样改过来fix即可。
整个移植下来的感觉就是你可以把它当成个黑盒,不需要有太多的Linux Kernel背景。
参考
本站采用CC BY-NC-SA 4.0进行许可 | 转载请注明原文链接 - 快速移植 OpenHarmony Linux 内核到三方 ARM64 平台