porting-linux-kernel.md 11.8 KB
Newer Older
D
duangavin123 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
# 一种快速移植OpenHarmony Linux内核的方法

- [摘要](#摘要)
- [移植到三方芯片平台的整体思路概述](#移植到三方芯片平台的整体思路概述)
    - [内核态层和用户态层](#内核态层和用户态层)
    - [获得内核态层的两种方法](#获得内核态层的两种方法)
    - [快速移植到三方芯片平台的流程简介](#快速移植到三方芯片平台的流程简介)
- [移植到三方芯片平台的步骤](#移植到三方芯片平台的步骤)
    - [整体构建环境的准备](#整体构建环境的准备)
    - [内核态基础代码的移植](#内核态基础代码的移植)
    - [内核态必选特性HDF的移植](#内核态必选特性hdf的移植)
    - [编译Image](#编译image)
    - [编译和运行HDF测试用例(可选)](#编译和运行hdf测试用例-可选-)

## 摘要


本文面向希望将OpenHarmony 移植到三方芯片平台硬件的开发者,介绍一种借助三方芯片平台自带Linux内核的现有能力,快速移植OpenHarmony到三方芯片平台的方法。


## 移植到三方芯片平台的整体思路概述


### 内核态层和用户态层

为了更好的解释整个内核移植,首先需要介绍一些概念:

我们可以把OpenHarmony简单的分为

OpenHarmony = OpenHarmony 内核态层 + OpenHarmony 用户态层

![zh-cn_image_0000001162805936](figure/zh-cn_image_0000001162805936.png)

34
其中OpenHarmony 内核态层就是上图的紫色部分,可以看到,它主要由内核本身(如Linux Kernel,LiteOS),和一些运行在内核态的一些特性组成,比如HDF等。
D
duangavin123 已提交
35 36 37 38 39 40 41 42

而OpenHarmony用户态层,在上图,就是紫色之外的部分。可以看到,由下往上看,它主要由系统服务层,框架层,应用层组成。在这儿我们将这三层整体称为“OpenHarmony 用户态层”。

为什么这么区分呢?因为我们这篇文章主要是要讨论如何快速的把OpenHarmony移植到三方芯片平台上。而OpenHarmony的用户态层,整体来说和三方芯片平台的耦合度不高,移植较为方便。而内核态层中的内核本身以及HDF驱动框架等,和三方芯片平台的耦合度较高,是移植的重难点。我们先做这个区分,就是为了先把聚光灯打到我们最需要关注的OpenHarmony内核态层上,开始分析和解题。另外说明,本文只包含Linux内核的快速移植,不包含LiteOS的移植。


### 获得内核态层的两种方法

43 44
为了表述方便,我们在下文部分地方用“OH”代替“OpenHarmony”。

D
duangavin123 已提交
45 46 47 48
将OH 内核态层继续分解

OH 内核态层 =  OH Linux内核 + OH内核态特性(可选特性或者必选特性,如必选特性HDF,今后的可选特性HMDFS等)

49
而OH Linux内核  = 标准LTS Linux 内核  +  三方SoC芯片平台代码  +  OH内核态基础代码(支撑OH用户态层运行的最基础代码)
D
duangavin123 已提交
50

51
因此OH 内核态层 = 标准LTS Linux 内核  +  三方SoC芯片平台代码  +  OH内核态基础代码  + OH内核态特性(如HDF,今后的HMDFS等)
D
duangavin123 已提交
52 53 54

![zh-cn_image_0000001208365855](figure/zh-cn_image_0000001208365855.png)

55
而将前两项组合,标准LTS Linux 内核  +  三方SoC芯片平台代码,其实就是一个三方Linux内核的基础组成。从上面的推导可以看出,OpenHarmony 内核态层其实能够由两种方法得到:
D
duangavin123 已提交
56 57 58 59 60

方法一:OH 内核态层 =  三方Linux内核 +  OH内核态基础代码  + OH内核态特性(如HDF,今后的HMDFS等)

也就是直接借助三方Linux内核,再加上基础OH内核态基础代码、以及HDF等OH内核态特性。

61
方法二:OH 内核态层 =  OH Linux内核 + OH内核态特性(如HDF,今后的HMDFS等)
D
duangavin123 已提交
62 63 64 65 66 67 68 69

也就是直接采用OH Linux内核,然后再加入OH的其他内核态特性。

方案二中的OH Linux内核,当前所支持的三方芯片平台还不够丰富。为了能够响应三方开发者快速移植OpenHarmony到三方芯片平台的要求,下文会着重介绍方法一,即借助三方已有的Linux内核,来快速移植OpenHarmony到三方芯片平台上。


### 快速移植到三方芯片平台的流程简介

70
本节介绍以上的方法一,即借助三方Linux内核,快速的移植OpenHarmony到三方的芯片平台。
D
duangavin123 已提交
71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92

整个移植流程可以分为三步:

1. 准备整体构建环境,包括将三方芯片平台的现有内核代码拷贝到OpenHarmony的整体编译环境下。

2. OpenHarmony内核态基础代码的移植。

3. OpenHarmony内核态必选特性(如HDF等)的移植。

详细步骤在接下来的章节中介绍。


## 移植到三方芯片平台的步骤

下面以树莓派3b (BCM2837) 为例,演示将OpenHarmony移植到树莓派的过程。


### 整体构建环境的准备

1. 将三方内核纳入OpenHarmony编译环境
   完整编译过一遍标准 Hi3516DV300 内核之后,clone 树莓派内核源码并复制到 manifest 输出目录下:

93
   ```
D
duangavin123 已提交
94 95 96 97 98 99
   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
   ```

2. 配置树莓派内核编译环境
100
   ```shell
D
duangavin123 已提交
101 102 103 104 105 106 107 108 109 110 111 112
   # 进入树莓派 kernel 目录
   cd out/KERNEL_OBJ/kernel/src_tmp/linux-rpi3b
   
   # 配置编译环境,使用工程项目自带的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/Hi3516DV300
   ```

3. 注释掉clang不识别的flag
   PROJ_ROOT/out/KERNEL_OBJ/kernel/src_tmp/linux-rpi3b/arch/arm/Makefile 注释掉以下这一行:

113
   ```makefile
D
duangavin123 已提交
114 115 116 117 118 119 120 121
   KBUILD_CFLAGS  +=-fno-omit-frame-pointer -mapcs -mno-sched-prolog
   ```


### 内核态基础代码的移植

目前OpenHarmony内核态的基础代码,主要是日志服务相关。轻量化内核日志服务代码包含:

122
```
D
duangavin123 已提交
123 124 125 126
drivers/staging/hilog
drivers/staging/hievent
```

127
将以上代码,从OpenHarmony内核代码目录kernel/linux/linux-4.19/drivers/staging中,拷贝到out/KERNEL_OBJ/kernel/src_tmp/linux-rpi3b/drivers/staging 下
D
duangavin123 已提交
128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143

在内核config项中打开对应的CONFIG控制宏:CONFIG_HILOG和CONFIG_HIEVENT

具体日志使用说明请参见:[Hilog_lite组件介绍](https://gitee.com/openharmony/hiviewdfx_hilog_lite/blob/master/README_zh.md)


### 内核态必选特性HDF的移植

1. 打HDF 补丁
   在 Linux 内核打 HDF 补丁时,执行补丁 shell 脚本合入 HDF 补丁。

   1. 配置HDF补丁脚本的三个变量参数;
   2. 获取 patch_hdf.sh 脚本;
   3. 执行 patch_hdf.sh 脚本依次传入三个变量参数。
   patch_hdf.sh 脚本三个参数含义为:第一个入参为工程根目录路径,第二入参为内核目录路径,第三个入参为hdf补丁文件。

144
   ```
D
duangavin123 已提交
145 146 147 148 149
   ./patch_hdf.sh [工程根目录路径] [内核目录路径] [hdf补丁文件]
   ```

   以树莓派3b为示例介绍:

150
   ```
D
duangavin123 已提交
151
   # 进入树莓派 kernel 目录
152 153 154 155
   $PROJ_ROOT/drivers/adapter/khdf/linux/patch_hdf.sh \
   $PROJ_ROOT  # 指定工程根目录路径 \
   $PROJ_ROOT/out/KERNEL_OBJ/kernel/src_tmp/linux-rpi3b  # 打补丁的内核目录路径 \
   $PROJ_ROOT/kernel/linux/patches/linux-4.19/hi3516dv300_patch/hdf.patch  # HDF补丁文件
D
duangavin123 已提交
156 157 158 159 160 161 162
   ```

2. 配置config
   提供HDF基本配置,如果需要其他功能,通过 menuconfig 打开对应驱动开关即可。

   HDF补丁执行成功后,默认HDF开关是关闭的,打开HDF基本配置选项如下:

163
   ```
D
duangavin123 已提交
164 165 166 167 168 169 170 171 172 173 174 175
   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相关配置,命令如下:

176
   ```
D
duangavin123 已提交
177 178 179 180
   # 生成 .config 配置文件
   make ${MAKE_OPTIONS} rpi3b_oh_defconfig
   
   # 更改HDF内核配置
181
   make ${MAKE_OPTIONS} menuconfig
D
duangavin123 已提交
182 183 184 185 186 187 188 189 190 191 192
   # [*] Device Drivers
   # [*]   HDF driver framework support --->
   ```

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

   ![zh-cn_image_0000001208524821](figure/zh-cn_image_0000001208524821.png)


### 编译Image

193
```
D
duangavin123 已提交
194 195 196 197 198 199 200 201 202
# 执行编译命令
make ${MAKE_OPTIONS} -j33 zImage
```


### 编译和运行HDF测试用例(可选)

**简介**

203
HDF(Hardware Driver Foundation)自测试用例,用于测试HDF框架和外设的基本功能,本文主要介绍HDF内核态用例测试方法。
D
duangavin123 已提交
204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222

**预置条件**

测试前需要在menuconfig里检查HDF测试开关CONFIG_DRIVERS_HDF_TEST=y,代码全量编译通过。

**用例编译和测试方法**

通过HDC工具把用例执行文件推送到设备中,然后执行用例即可,操作步骤如下:
1. 编译hdf测试用例

2. 用HDC工具推送测试文件到设备中

3. 进入设备data/test目录,执行测试文件即可

用例编译和测试详细步骤如下:

1. 编译hdf测试用例
   编译hdf测试用例命令和文件路径如下:

223
   ```
D
duangavin123 已提交
224 225 226 227 228 229
   ./build.sh --product-name Hi3516DV300 --build-target hdf_test
   ```

   等待编译完成。

2. 将测试文件移动到目标移植设备上(以树莓派为例)
230
   方法一:使用 [hdc_std 工具](http://gitee.com/openharmony/docs/blob/master/zh-cn/device-dev/subsystems/subsys-toolchain-hdc-guide.md)
D
duangavin123 已提交
231 232

   1. 先在树莓派里新建data/test目录
233
       ```
D
duangavin123 已提交
234 235 236
       mkdir -p data/test
       ```
   2. 推送依赖库和测试用例到树莓派
237
       ```
D
duangavin123 已提交
238 239 240 241 242 243 244 245 246 247 248
       hdc file send XXX\out\ohos-arm-release\hdf\hdf\libhdf_test_common.z.so  /system/lib
       hdc file send XXX\out\ohos-arm-release\tests\unittest\hdf\config\hdf_adapter_uhdf_test_config  /data/test
       hdc file send XXX\out\ohos-arm-release\tests\unittest\hdf\devmgr\DevMgrTest  /data/test
       hdc file send XXX\out\ohos-arm-release\tests\unittest\hdf\osal\OsalTest  /data/test
       hdc file send XXX\out\ohos-arm-release\tests\unittest\hdf\sbuf\SbufTest  /data/test
       ```
   方法二:移动到储存卡内,启动树莓派之后装载

   1. 拔掉树莓派连接电脑的串口、USB线,然后拔下数据卡。
   2. 将数据卡插入到电脑的读取口,将编译好的 zImage 和测试文件夹 test/ 下载到电脑,然后移动到数据卡的根目录下。zImage 文件会被替换,请提前做好备份。
   3. 最后将数据卡插回树莓派。
249
       ```
D
duangavin123 已提交
250 251 252 253 254 255 256 257 258 259 260 261 262
       # 让树莓派文件系统读取储存卡根目录
       mount -t vfat /dev/block/mmcblk0p1 /boot
       cd /boot/[测试文件目录]
       # 允许修改系统文件
       mount -o remount,rw /
       # 安装测试用库
       mv libhdf_test_common.z.so /system/lib
       mkdir /data/test
       mv * /data/test
       ```

3. 执行测试
   1. 进入目录执行测试文件目录 data/test
263
       ```
D
duangavin123 已提交
264 265 266
       cd /data/test
       ```
   2. 修改文件执行权限
267
       ```
D
duangavin123 已提交
268 269 270
       chmod 777 hdf_adapter_uhdf_test_config DevMgrTest OsalTest SbufTest
       ```
   3. 开始测试
271
       ```
D
duangavin123 已提交
272 273 274 275 276 277 278
       ./hdf_adapter_uhdf_test_config
       ./DevMgrTest
       ./OsalTest
       ./SbufTest
       ```
   4. 如果所有测试文件输出均显示 PASSED,那么 HDF 功能即安装成功。
       示例:DevMgrTest 用例成功结果显示:
279
              ```
D
duangavin123 已提交
280 281 282 283 284 285 286 287 288 289 290 291 292
              ./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.
              ```