【移植】OpenHarmony 小型系统Linux内核

178 阅读5分钟

Linux 内核

移植概述

Linux 内核移植主要涉及基于 linux 内核基线合入三方芯片补丁后,进行基础的内核编译构建及验证。

基本信息

当前 Linux 内核基线是基于 Linux 社区 4.19 LTS 版本演进,合入 CVE 及 bugfix 补丁。具体信息参考 代码库 ,对应 repo 工程代码路径为 kernel/linux-4.19

Bootloader

可以使用芯片厂商自带的 Bootloader,或者是开源 Uboot 等加载内核镜像。比如为支持 Hi3516DV300 开发板,OpenHarmony 引入的开源  Uboot 。

适配编译和烧录启动

  1. 准备内核 config(特别是芯片相关的 config)。 config 文件所在源码目录:kernel/linux/config/ 以 hi3516dv300 芯片为例,可在对应的 linux-4.19/arch/arm/configs/ 目录下新建 <YOUR_CHIP>_small_defconfig,如 hi3516dv300_small_defconfig 表示针对 hi3516dv300 小型系统的 defconfig。该 config 文件可以由基础 defconfig 文件 small_common_defconfig 与该芯片相关的 config 组合生成。

  2. 准备芯片补丁。 补丁文件所在源码目录:kernel/linux/patches/linux-4.19 以 hi3516dv300 芯片为例,参考已有的 patch 目录 hi3516dv300_small_patch 目录,新建 <YOUR_CHIP>_patch 目录,放置相关芯片补丁,注意 hdf.patch 等驱动补丁。

  3. 编译。 具体内核编译入口脚本位于工程目录 kernel/linux/patches/ 下面,版本级整编命令会通过 BUILD.gn 进入 kernel_module_build.sh 和 kernel.mk,需要在这 2 个文件中针对性进行 patch 及 defconfig 文件路径、编译器、芯片架构、内核 Image 格式等的适配。 通过编译错误日志调整补丁,典型错误场景: (1)补丁合入失败,出现冲突,需要进行上下文适配修改。 (2)编译失败,内核版本差异(函数实现调整等)需要针对性进行内核适配。

    注意:

    • 参考 kernel.mk,在 OpenHarmony 工程的编译构建流程中会拷贝 kernel/linux-4.19 的代码环境后进行打补丁动作,在使用版本级编译命令前,需要 kernel/linux-4.19 保持原代码环境。
    • 对应拷贝后的目录位于:out/<***>/kernel/linux-4.19,可以在该目录下进行补丁的修改适配。
  4. 烧录启动。 由于不同芯片的开发板的烧录方式不一样,此处不表述具体的烧录方式。需要注意烧录的各镜像的大小及启动参数的配置,参考 hi3516dv300 采用 uboot 启动参数:

    setenv bootargs 'mem=128M console=ttyAMA0,115200 root=/dev/mmcblk0p3 ro rootfstype=ext4 rootwait blkdevparts=mmcblk0:1M(boot),9M(kernel),50M(rootfs),50M(userfs)'
DD一下:欢迎大家关注工粽号<程序猿百晓生>,可以了解到以下知识点。
`欢迎大家关注工粽号<程序猿百晓生>,可以了解到以下知识点。`
1.OpenHarmony开发基础
2.OpenHarmony北向开发环境搭建
3.鸿蒙南向开发环境的搭建
4.鸿蒙生态应用开发白皮书V2.0 & V3.0
5.鸿蒙开发面试真题(含参考答案) 
6.TypeScript入门学习手册
7.OpenHarmony 经典面试题(含参考答案)
8.OpenHarmony设备开发入门【最新版】
9.沉浸式剖析OpenHarmony源代码
10.系统定制指南
11.【OpenHarmony】Uboot 驱动加载流程
12.OpenHarmony构建系统--GN与子系统、部件、模块详解
13.ohos开机init启动流程
14.鸿蒙版性能优化指南
.......

验证

调试 init 进程、启动 shell 和运行简单的用户态程序,验证内核移植是否成功。OpenHarmony 小型系统的 OS 镜像结构以及 linux 用户态的启动流程如下图 1 所示: 图 1 基于 linux 内核的 OS 镜像结构和用户态程序启动流程

基于上述流程,推荐按以下步骤完成验证:

  1. 制作根文件系统镜像。 请参考 新建芯片解决方案和产品解决方案 生成根文件系统镜像 rootfs.img。从上图可以看到启动过程与产品配置强相关,在制作 rootfs.img 过程中请完成如下四种配置:

    • 组件配置 产品组件配置文件 vendor/{company}/{product}/config.json 需配置启动恢复子系统(startup)的 init_lite 组件和内核子系统的 linux_4_1_9 组件。
    • 系统服务配置 系统服务配置文件 vendor/{company}/{product}/init_configs/init_xxx.cfg 需要启动 shell 服务。
    • 文件系统配置 文件系统配置 vendor/{company}/{product}/fs.yml 中需要创建 /bin/sh -> mksh 和 /lib/ld-musl-arm.so.1 -> libc.so 软连接,这两个文件分别是 shell 可执行程序和可执行程序依赖的 c 库。
    • 启动配置 启动配置在 vendor/{company}/{product}/init_configs/etc 目录下,包括 fstab、rsS 和 Sxxx 文件,请按开发板实际情况配置。 编译完成后,可通过检查产品编译输出目录下的 rootfs 内容,确认 rootfs.img 文件生成是否符合预期。
  2. 调试 init 进程和 shell。 烧录 rootfs.img 并调试 init 进程和 shell,不同厂商的开发板的烧录工具和流程可能不同,请按芯片解决方案提供的流程进行烧录。烧录 rootfs.img 前请确认 bootloader 和 linux 内核启动正常。如果 rootfs.img 被内核正常挂载,接着将运行 /bin/init 程序,init 进程为用户态的第一个应用程序,它的运行意味着用户态的开始。 init 程序首先会调用 /etc/init.d/rcS 脚本,rcS 脚本执行第一条命令为 /bin/mount -a,该命令会加载 fstab 文件,在 fstab 中的命令执行完后 rcS 将顺序调用 Sxxx 脚本完成设备节点创建和扫描、文件权限配置等操作。

最后,init 程序会读取 init.cfg 系统服务配置文件。根据步骤 1 中的设置,init 程序将会启动 shell。如果上述流程运行正常,系统则会进入 shell。

若串口有如下版本号日志打印,则表示 init 程序启动正常:

图 2 init 启动正常日志

正常进入 shell 后执行 ls 命令,串口打印信息如下图:

图 3 正常进入 shell 后输入 ls 命令串口打印

  1. 配置 NFS。 init 进程和 shell 正常启动后,以服务端 IP 为 192.168.1.22、客户端 IP 为 192.168.1.4 为例,可在根目录执行如下命令开启 NFS:
    ifconfig eth0 192.168.1.4 netmask 255.255.255.0
    mkdir -p /storgage/nfs
    mount -t nfs -o nolock,addr=192.168.1.22 192.168.1.22:/nfs /storage/nfs