一種快速移植 OpenHarmony Linux 內(nèi)核的方法

移植概述

本文面向希望將 OpenHarmony 移植到三方芯片平臺硬件的開發(fā)者,介紹一種借助三方芯片平臺自帶 Linux 內(nèi)核的現(xiàn)有能力,快速移植 OpenHarmony 到三方芯片平臺的方法。

移植到三方芯片平臺的整體思路

內(nèi)核態(tài)層和用戶態(tài)層

為了更好的解釋整個內(nèi)核移植,首先需要介紹一些概念:
我們可以把 OpenHarmony 簡單的分為
OpenHarmony = OpenHarmony 內(nèi)核態(tài)層 + OpenHarmony 用戶態(tài)層

其中 OpenHarmony 內(nèi)核層就是上圖的紫色部分,可以看到,它主要由內(nèi)核本身(如 Linux Kernel,LiteOS),和一些運行在內(nèi)核態(tài)的一些特性組成,比如 HDF 等。
而 OpenHarmony 用戶態(tài)層,在上圖,就是紫色之外的部分??梢钥吹?,由下往上看,它主要由系統(tǒng)服務(wù)層,框架層,應(yīng)用層組成。在這兒我們將這三層整體稱為“OpenHarmony 用戶態(tài)層”。
為什么這么區(qū)分呢?因為我們這篇文章主要是要討論如何快速的把 OpenHarmony 移植到三方芯片平臺上。而 OpenHarmony 的用戶態(tài)層,整體來說和三方芯片平臺的耦合度不高,移植較為方便。而內(nèi)核態(tài)層中的內(nèi)核本身以及 HDF 驅(qū)動框架等,和三方芯片平臺的耦合度較高,是移植的重難點。我們先做這個區(qū)分,就是為了先把聚光燈打到我們最需要關(guān)注的 OpenHarmony 內(nèi)核態(tài)層上,開始分析和解題。另外說明,本文只包含 Linux 內(nèi)核的快速移植,不包含 LiteOS 的移植。

獲得內(nèi)核態(tài)層的兩種方法

為了表述方便,我們在下文部分地方用“OH”代替“OpenHarmony”。
將 OH 內(nèi)核態(tài)層繼續(xù)分解

而將前兩項組合,標(biāo)準(zhǔn) LTS Linux 內(nèi)核 + 三方 SoC 芯片平臺代碼,其實就是一個三方 Linux 內(nèi)核的基礎(chǔ)組成。從上面的推導(dǎo)可以看出,OpenHarmony 內(nèi)核態(tài)層其實能夠由兩種方法得到:

方法一:OH 內(nèi)核態(tài)層 = 三方 Linux 內(nèi)核 + OH 內(nèi)核態(tài)基礎(chǔ)代碼 + OH 內(nèi)核態(tài)特性(如 HDF,今后的 HMDFS 等)
也就是直接借助三方 Linux 內(nèi)核,再加上基礎(chǔ) OH 內(nèi)核態(tài)基礎(chǔ)代碼、以及 HDF 等 OH 內(nèi)核態(tài)特性。

方法二:OH 內(nèi)核態(tài)層 = OH Linux 內(nèi)核 + OH 內(nèi)核態(tài)特性(如 HDF,今后的 HMDFS 等)
也就是直接采用 OHLinux 內(nèi)核,然后再加入 OH 的其他內(nèi)核態(tài)特性。

當(dāng)前方法二中 OHLinux 內(nèi)核支持的三方芯片平臺還不夠豐富。為了能夠響應(yīng)三方開發(fā)者快速移植 OpenHarmony 的要求,下文會著重介紹方法一,即借助三方已有的 Linux 內(nèi)核,來快速移植 OpenHarmony。

借助已有 Linux 內(nèi)核來移植 OpenHarmony 的流程

整個移植流程可以分為三步:

  1. 準(zhǔn)備整體構(gòu)建環(huán)境,包括將三方芯片平臺的現(xiàn)有內(nèi)核代碼拷貝到 OpenHarmony 的整體編譯環(huán)境下。
  2. OpenHarmony 內(nèi)核態(tài)基礎(chǔ)代碼的移植。
  3. OpenHarmony 內(nèi)核態(tài)必選特性(如 HDF 等)的移植。
    詳細(xì)步驟在接下來的章節(jié)中介紹。

移植到三方芯片平臺的步驟

下面以樹莓派 3b (BCM2837) 為例,演示將 OpenHarmony 移植到樹莓派的過程。

準(zhǔn)備整體構(gòu)建環(huán)境

  1. 將三方內(nèi)核納入 OpenHarmony 編譯環(huán)境。
    完整編譯過一遍標(biāo)準(zhǔn) Hi3516DV300 的內(nèi)核之后,clone 樹莓派內(nèi)核源碼并復(fù)制到 manifest 輸出目錄下:
    export PROJ_ROOT=[OpenHarmony manifest]
    git clone https://gitee.com/xfan1024/oh-rpi3b-kernel.git
    cp -r oh-rpi3b-kernel $PROJ_ROOT/out/KERNEL_OBJ/kernel/src_tmp/linux-rpi3b
  1. 配置樹莓派內(nèi)核編譯環(huán)境。
    # 進入樹莓派kernel目錄
    cd out/KERNEL_OBJ/kernel/src_tmp/linux-rpi3b
    # 配置編譯環(huán)境,使用工程項目自帶的clang
    export PATH=$PROJ_ROOT/prebuilts/clang/ohos/linux-x86_64/llvm/bin:$PROJ_ROOT/prebuilts/gcc/linux-x86/arm/gcc-linaro-7.5.0-arm-linux-gnueabi/bin/:$PATH
    export MAKE_OPTIONS="ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- CC=clang HOSTCC=clang"
    export PRODUCT_PATH=vendor/hisilicon/hispark_taurus_linux
  1. 注釋掉 clang 不識別的 flag。
    PROJ_ROOT/out/KERNEL_OBJ/kernel/src_tmp/linux-rpi3b/arch/arm/Makefile 注釋掉以下這一行:
    KBUILD_CFLAGS  +=-fno-omit-frame-pointer -mapcs -mno-sched-prolog

移植內(nèi)核態(tài)基礎(chǔ)代碼

目前 OpenHarmony 內(nèi)核態(tài)的基礎(chǔ)代碼,主要是日志服務(wù)相關(guān)。輕量化內(nèi)核日志服務(wù)代碼包含:

drivers/staging/hilog
drivers/staging/hievent

將以上代碼,從 OpenHarmony 內(nèi)核代碼目錄 kernel/linux/linux-4.19/drivers/staging 中,拷貝到 out/KERNEL_OBJ/kernel/src_tmp/linux-rpi3b/drivers/staging 下。
在三方內(nèi)核的 drivers/staging/Kconfig 文件內(nèi)增加如下代碼:

source "drivers/staging/hilog/Kconfig"
source "drivers/staging/hievent/Kconfig"

在三方內(nèi)核的 drivers/staging/Makefile 文件內(nèi)增加如下代碼:

obj-$(CONFIG_HILOG)             += hilog/
obj-$(CONFIG_HIEVENT)           += hievent/

在內(nèi)核 config 項中打開對應(yīng)的 CONFIG 控制宏:CONFIG_HILOG 和 CONFIG_HIEVENT。
具體日志使用說明請參見:Hilog_lite 組件介紹

移植內(nèi)核態(tài)必選特性 HDF

  1. 打 HDF 補丁。
    在 Linux 內(nèi)核打 HDF 補丁時,執(zhí)行補丁 shell 腳本合入 HDF 補丁。

    1. 配置 HDF 補丁腳本的四個變量參數(shù)。
    2. 獲取 patch_hdf.sh 腳本。
    3. 執(zhí)行 patch_hdf.sh 腳本依次傳入四個變量參數(shù)。
      patch_hdf.sh 腳本四個參數(shù)含義為:第一個入?yún)楣こ谈夸浡窂?,第二入?yún)閮?nèi)核目錄路徑,第三個入?yún)閮?nèi)核版本路徑,第四個參數(shù)是當(dāng)前設(shè)備名。
    ./patch_hdf.sh [工程根目錄路徑] [內(nèi)核目錄路徑] [內(nèi)核補丁路徑] [設(shè)備名]

以3b 為示例介紹:

    PROJ_ROOT/drivers/hdf_core/adapter/khdf/linux/patch_hdf.sh \
    PROJ_ROOT  # 指定工程根目錄路徑 \
    PROJ_ROOT/out/KERNEL_OBJ/kernel/src_tmp/linux-rpi3b  # 打補丁的內(nèi)核目錄路徑 \
    PROJ_ROOT/kernel/linux/patches/linux-4.19 # 內(nèi)核補丁路徑.\
    hi3516dv300 # 設(shè)備名.
  1. 配置 config。
    提供 HDF 基本配置,如果需要其他功能,通過 menuconfig 打開對應(yīng)驅(qū)動開關(guān)即可。
    HDF 補丁執(zhí)行成功后,默認(rèn) HDF 開關(guān)是關(guān)閉的,打開 HDF 基本配置選項如下:
    CONFIG_DRIVERS_HDF=y
    CONFIG_HDF_SUPPORT_LEVEL=2
    CONFIG_DRIVERS_HDF_PLATFORM=y
    CONFIG_DRIVERS_HDF_PLATFORM_MIPI_DSI=y
    CONFIG_DRIVERS_HDF_PLATFORM_GPIO=y
    CONFIG_DRIVERS_HDF_PLATFORM_I2C=y
    CONFIG_DRIVERS_HDF_PLATFORM_UART=y
    CONFIG_DRIVERS_HDF_TEST=y

或者通過 menuconfig 界面打開 HDF 相關(guān)配置,命令如下:

    # 生成 .config 配置文件
    make ${MAKE_OPTIONS} rpi3b_oh_defconfig
    # 更改HDF內(nèi)核配置
    make ${MAKE_OPTIONS} menuconfig
    # [*] Device Drivers
    # [*]   HDF driver framework support --->

配置如下(在 Device Drivers -> HDF driver framework support 目錄下):

編譯 Image

# 執(zhí)行編譯命令
make ${MAKE_OPTIONS} -j33 zImage

編譯和運行 HDF 測試用例(可選)

簡介
HDF(Hardware Driver Foundation)自測試用例,用于測試 HDF 框架和外設(shè)的基本功能,本文主要介紹 HDF 內(nèi)核態(tài)用例測試方法。
預(yù)置條件
測試前需要在 menuconfig 里檢查 HDF 測試開關(guān) CONFIG_DRIVERS_HDF_TEST=y,代碼全量編譯通過。
用例編譯和測試方法
通過 hdc_std 工具把用例執(zhí)行文件推送到設(shè)備中,然后執(zhí)行用例即可,操作步驟如下:

  1. 編譯 hdf 測試用例。

  2. 用 hdc_std 工具推送測試文件到設(shè)備中。

  3. 進入設(shè)備 data/test 目錄,執(zhí)行測試文件即可。
    用例編譯和測試詳細(xì)步驟如下:

  4. 編譯 hdf 測試用例。
    編譯 hdf 測試用例命令和文件路徑如下:

    ./build.sh --product-name hispark_taurus_standard --build-target hdf_test
等待編譯完成。
  1. 將測試文件移動到目標(biāo)移植設(shè)備上(以樹莓派為例)。

方法一:使用 hdc_std 工具。

  1. 先在樹莓派里新建 data/test 目錄。
mkdir -p data/test
  1. 推送依賴庫和測試用例到樹莓派。
hdc file send XXX\out\{device_name}\hdf\hdf\libhdf_test_common.z.so  /system/lib
       hdc file send XXX\out\{device_name}\tests\unittest\hdf\config\hdf_adapter_uhdf_test_config  /data/test
       hdc file send XXX\out\{device_name}\tests\unittest\hdf\devmgr\DevMgrTest  /data/test
       hdc file send XXX\out\{device_name}\tests\unittest\hdf\osal\OsalTest  /data/test
       hdc file send XXX\out\{device_name}\tests\unittest\hdf\sbuf\SbufTest  /data/test

方法二:移動到儲存卡內(nèi),啟動樹莓派之后裝載。
1. 拔掉樹莓派連接電腦的串口、USB 線,然后拔下數(shù)據(jù)卡。
2. 將數(shù)據(jù)卡插入到電腦的讀取口,將編譯好的 zImage 和測試文件夾 test/下載到電腦,然后移動到數(shù)據(jù)卡的根目錄下。zImage 文件會被替換,請?zhí)崆白龊脗浞荨?br> 3. 最后將數(shù)據(jù)卡插回樹莓派。

    # 讓樹莓派文件系統(tǒng)讀取儲存卡根目錄
    mount -t vfat /dev/block/mmcblk0p1 /boot
    cd /boot/[測試文件目錄]
    # 允許修改系統(tǒng)文件
    mount -o remount,rw /
    # 安裝測試用庫
    mv libhdf_test_common.z.so /system/lib
    mkdir /data/test
    mv * /data/test
  1. 執(zhí)行測試

1.進入目錄執(zhí)行測試文件目錄 data/test。

cd /data/test

2.修改文件執(zhí)行權(quán)限。

        chmod 777 hdf_adapter_uhdf_test_config DevMgrTest OsalTest SbufTest

3.開始測試。

        ./hdf_adapter_uhdf_test_config
        ./DevMgrTest
        ./OsalTest
        ./SbufTest

4.如果所有測試文件輸出均顯示 PASSED,那么 HDF 功能即安裝成功。

示例:DevMgrTest 用例成功結(jié)果顯示:

./DevMgrTest
Running main() from gmock_main.cc
[==========] Running 1 test from 1 test case.
[----------] Global test environment set-up.
[----------] 1 test from DevMgrTest
[ RUN      ] DevMgrTest.DriverLoaderTest_001
[       OK ] DevMgrTest.DriverLoaderTest_001 (0 ms)
[----------] 1 test from DevMgrTest (0 ms total)
[----------] Global test environment tear-down
Gtest xml output finished
[==========] 1 test from 1 test case ran. (0 ms total)
[  PASSED  ] 1 test.

寫在最后

如果你覺得這篇內(nèi)容對你還蠻有幫助,我想邀請你幫我三個小忙

  • 點贊,轉(zhuǎn)發(fā),有你們的 『點贊和評論』,才是我創(chuàng)造的動力。
  • 關(guān)注小編,同時可以期待后續(xù)文章ing??,不定期分享原創(chuàng)知識。
  • 想要獲取更多完整鴻蒙最新學(xué)習(xí)知識點,請移步前往小編:https://gitee.com/MNxiaona/733GH/blob/master/jianshu
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容