OpenHarmony - 小型系统内核(LiteOS-A)(一)

OpenHarmony - 小型系统内核(LiteOS-A)(一)


一、小型系统内核概述

简介

OpenHarmony 轻量级内核是基于IoT领域轻量级物联网操作系统Huawei LiteOS内核演进发展的新一代内核,包含LiteOS-M和LiteOS-A两类内核。LiteOS-M内核主要应用于轻量系统,面向的MCU(Microprocessor Unit)一般是百K级内存,可支持MPU(Memory Protection Unit)隔离,业界类似的内核有FreeRTOS或ThreadX等;LiteOS-A内核主要应用于小型系统,面向设备一般是M级内存,可支持MMU(Memory Management Unit)隔离,业界类似的内核有Zircon或Darwin等。

说明: OpenHarmony针对不同量级的系统,分别使用了不同形态的内核,小型系统支持LiteOS和Linux,本开发指南适用于LiteOS-A内核,linux内核的相关操作请参考Linux内核概述

为适应IoT产业的高速发展,OpenHarmony 轻量级内核不断优化和扩展,能够带给应用开发者友好的开发体验和统一开放的生态系统能力。轻量级内核LiteOS-A重要的新特性如下:

  • 新增了丰富的内核机制 新增虚拟内存、系统调用、多核、轻量级IPC(Inter-Process Communication,进程间通信)、DAC(Discretionary Access Control,自主访问控制)等机制,丰富了内核能力;为了更好的兼容软件和开发者体验,新增支持多进程,使得应用之间内存隔离、相互不影响,提升系统的健壮性。

  • 引入统一驱动框架HDF(Hardware Driver Foundation) 引入统一驱动框架HDF,统一驱动标准,为设备厂商提供了更统一的接入方式,使驱动更加容易移植,力求做到一次开发,多系统部署。

  • 支持1200+标准POSIX接口 更加全面的支持POSIX标准接口,使得应用软件易于开发和移植,给应用开发者提供了更友好的开发体验。

  • 内核和硬件高解耦 轻量级内核与硬件高度解耦,新增单板,内核代码不用修改。

内核架构

轻量级内核主要由基础内核、扩展组件、HDF框架、POSIX接口组成。轻量级内核的文件系统、网络协议等扩展功能(没有像微内核那样运行在用户态)运行在内核地址空间,主要考虑组件之间直接函数调用比进程间通信或远程过程调用要快得多。

图1 OpenHarmony LiteOS-A内核架构图

  • 基础内核主要包括内核的基础机制,如调度、内存管理、中断异常等

  • 扩展组件主要包括文件系统、网络协议和安全等扩展功能

  • HDF框架是外设驱动统一标准框架

  • POSIX接口是为兼容POSIX标准的应用方便移植到OpenHarmony

基础内核

基础内核组件实现精简,主要包括内核的基础机制,如调度、内存管理、中断异常、内核通信等;

  • 进程管理:支持进程和线程,基于Task实现进程,进程独立4GiB地址空间

  • 多核调度:支持任务和中断亲核性设置,支持绑核运行

  • 实时调度:支持高优先级抢占,同优先级时间片轮转

  • 虚拟内存:内核空间静态映射到0-1GiB地址,用户空间映射到1-4GiB地址

  • 内核通信:事件、信号量、互斥锁、队列

  • 时间管理:软件定时器、系统时钟

文件系统

轻量级内核支持FAT,JFFS2,NFS,ramfs,procfs等众多文件系统,并对外提供完整的POSIX标准的操作接口;内部使用VFS层作为统一的适配层框架,方便移植新的文件系统,各个文件系统也能自动利用VFS层提供的丰富的功能。

主要特性有:

  • 完整的POSIX接口支持。

  • 文件级缓存(pagecache)。

  • 磁盘级缓存(bcache)。

  • 目录缓存(pathcache)。

  • DAC能力。

  • 支持嵌套挂载及文件系统堆叠等。

  • 支持特性的裁剪和资源占用的灵活配置。

网络协议

轻量级内核网络协议基于开源lwIP(lightweight IP)构建,对lwIP的RAM占用进行优化,同时提高lwIP的传输性能。

  • 协议: IP、IPv6、 ICMP、 ND、MLD、 UDP、 TCP、IGMP、ARP、PPPoS、PPPoE

  • API:socket API

  • 扩展特性:多网络接口IP转发、TCP拥塞控制、RTT估计和快速恢复/快速重传

  • 应用程序:HTTP(S)服务、SNTP客户端、SMTP(S)客户端、ping工具、NetBIOS名称服务、mDNS响应程序、MQTT客户端、TFTP服务、DHCP客户端、DNS客户端、AutoIP/APIPA(零配置)、SNMP代理

HDF框架

轻量级内核集成HDF框架,HDF框架旨在为开发者提供更精准、更高效的开发环境,力求做到一次开发,多系统部署。

  • 支持多内核平台

  • 支持用户态驱动

  • 可配置组件化驱动模型

  • 基于消息的驱动接口模型

  • 基于对象的驱动、设备管理

  • HDI(Hardware Device Interface)统一硬件接口

  • 支持电源管理、PnP

扩展组件

对内核功能进行扩展,可选但很重要的机制。

  • 动态链接:支持标准ELF链接执行、加载地址随机化

  • 进程通信:支持轻量级LiteIPC,同时也支持标准的Mqueue、Pipe、Fifo、Signal等机制

  • 系统调用:支持170+系统调用,同时有支持VDSO机制

  • 权限管理:支持进程粒度的特权划分和管控,UGO三种权限配置

目录

复制代码
/kernel/liteos_a
├── apps                   # 用户态的init和shell应用程序
├── arch                   # 体系架构的目录,如arm等
│   └── arm                # arm架构代码
├── bsd                    # freebsd相关的驱动和适配层模块代码引入,例如USB等
├── compat                 # 内核接口兼容性目录
│   └── posix              # posix相关接口
├── drivers                # 内核驱动
│   └── char               # 字符设备
│       ├── mem            # 访问物理IO设备驱动
│       ├── quickstart     # 系统快速启动接口目录
│       ├── random         # 随机数设备驱动
│       └── video          # framebuffer驱动框架
├── figures                # 内核架构图
├── fs                     # 文件系统模块,主要来源于NuttX开源项目
│   ├── fat                # fat文件系统
│   ├── jffs2              # jffs2文件系统
│   ├── include            # 对外暴露头文件存放目录
│   ├── nfs                # nfs文件系统
│   ├── proc               # proc文件系统
│   ├── ramfs              # ramfs文件系统
│   └── vfs                # vfs层
├── kernel                 # 进程、内存、IPC等模块
│   ├── base               # 基础内核,包括调度、内存等模块
│   ├── common             # 内核通用组件
│   ├── extended           # 扩展内核,包括动态加载、vdso、liteipc等模块
│   ├── include            # 对外暴露头文件存放目录
│   └── user               # 加载init进程
├── lib                    # 内核的lib库
├── net                    # 网络模块,主要来源于lwip开源项目
├── platform               # 支持不同的芯片平台代码,如Hi3516DV300等
│   ├── hw                 # 时钟与中断相关逻辑代码
│   ├── include            # 对外暴露头文件存放目录
│   └── uart               # 串口相关逻辑代码
├── security               # 安全特性相关的代码,包括进程权限管理和虚拟id映射管理
├── shell                  # 接收用户输入的命令,内核去执行
├── syscall                # 系统调用
├── testsuilts             # 测试套件
└── tools                  # 构建工具及相关配置和代码

约束

  • 开发语言:C/C++;
  • 适用于Hi3516DV300单板;
  • Hi3516DV300默认使用FAT文件系统。

使用说明

OpenHarmony LiteOS-A内核支持Hi3516DV300单板。开发者可基于此单板开发运行自己的应用程序。

准备

开发者需要在Linux上搭建编译环境

获取源码

在Linux服务器上下载并解压一套源代码,源码获取方式参考源码获取

编译构建

如果这是您的首次应用程序开发,可参考:

相关仓

内核子系统

drivers_liteos

kernel_liteos_a


二、内核启动

2.1、内核态启动

内核启动流程

内核启动流程包含汇编启动阶段和C语言启动阶段2部分,如图1所示。汇编启动阶段完成CPU初始设置,关闭dcache/icache,使能FPU及neon,设置MMU建立虚实地址映射,设置系统栈,清理bss段,调用C语言main函数等。C语言启动阶段包含OsMain函数及开始调度等,其中如图1所示,OsMain函数用于内核基础初始化和架构、板级初始化等,其整体由内核启动框架主导初始化流程,图中右边区域为启动框架中可接受外部模块注册启动的阶段,各个阶段的说明如下表1所示。

图1 内核启动流程图

表1 启动框架层级

层级 说明
LOS_INIT_LEVEL_EARLIEST 最早期初始化。 说明:不依赖架构,单板以及后续模块会对其有依赖的纯软件模块初始化。 例如:Trace模块。
LOS_INIT_LEVEL_ARCH_EARLY 架构早期初始化。 说明:架构相关,后续模块会对其有依赖的模块初始化,如启动过程中非必需的功能,建议放到LOS_INIT_LEVEL_ARCH层。
LOS_INIT_LEVEL_PLATFORM_EARLY 平台早期初始化。 说明:单板平台、驱动相关,后续模块会对其有依赖的模块初始化,如启动过程中必需的功能,建议放到LOS_INIT_LEVEL_PLATFORM层。 例如:uart模块。
LOS_INIT_LEVEL_KMOD_PREVM 内存初始化前的内核模块初始化。 说明:在内存初始化之前需要使能的模块初始化。
LOS_INIT_LEVEL_VM_COMPLETE 基础内存就绪后的初始化。 说明:此时内存初始化完毕,需要进行使能且不依赖进程间通讯机制与系统进程的模块初始化。 例如:共享内存功能。
LOS_INIT_LEVEL_ARCH 架构后期初始化。 说明:架构拓展功能相关,后续模块会对其有依赖的模块初始化。
LOS_INIT_LEVEL_PLATFORM 平台后期初始化。 说明:单板平台、驱动相关,后续模块会对其有依赖的模块初始化。 例如:驱动内核抽象层初始化(mmc、mtd)。
LOS_INIT_LEVEL_KMOD_BASIC 内核基础模块初始化。 说明:内核可拆卸的基础模块初始化。 例如:VFS初始化。
LOS_INIT_LEVEL_KMOD_EXTENDED 内核扩展模块初始化。 说明:内核可拆卸的扩展模块初始化。 例如:系统调用初始化、ProcFS初始化、Futex初始化、HiLog初始化、HiEvent初始化、LiteIPC初始化。
LOS_INIT_LEVEL_KMOD_TASK 内核任务创建。 说明:进行内核任务的创建(内核任务,软件定时器任务)。 例如:资源回收系统常驻任务的创建、SystemInit任务创建、CPU占用率统计任务创建。
LOS_INIT_LEVEL_FINISH 内核初始化完成。

编程样例

实例描述

新增一个内核模块,需要在内核初始化时进行该模块的初始化,则通过内核启动框架将该模块的初始化函数注册进内核启动流程中。

为方便学习,本演示代码直接在 . kernel /liteos_a/testsuites /kernel /src /osTest.c中编译验证即可。

示例代码

复制代码
/* 内核启动框架头文件 */
#include "los_init.h"

/* 新增模块的初始化函数 */
unsigned int OsSampleModInit(void)
{
    PRINTK("OsSampleModInit SUCCESS!\n");
}

/* 在启动框架的目标层级中注册新增模块 */
LOS_MODULE_INIT(OsSampleModInit, LOS_INIT_LEVEL_KMOD_EXTENDED);

结果验证

复制代码
main core booting up...

/* 根据实际运行环境,过程打印会有差异 */
// ......

/* 打印测试代码新增模块初始化函数 */
OsSampleModInit SUCCESS!

根据上述系统启动阶段的打印可知,内核在启动时进行了该注册模块的初始化函数调用,完成该模块的初始化操作。

说明: 启动框架中同一层级内的注册模块不能有依赖关系,建议新增模块按照上述启动阶段进行模块初始化的拆分,按需注册启动。

可通过查看系统编译生成文件OHOS_Image.map中.rodata.init.kernel.*段内的符号表来了解当前已注册进内核启动框架中的各个模块初始化入口,以及检查新注册的模块初始化入口是否生效。

2.2、用户态启动

用户态根进程启动

根进程是系统第一个用户态进程,进程ID为1,它是所有用户态进程的祖先。

图1 进程树示意图

根进程的启动过程

使用链接脚本将如下init启动代码放置到系统镜像指定位置。

复制代码
#define LITE_USER_SEC_ENTRY   __attribute__((section(".user.entry")))
LITE_USER_SEC_ENTRY VOID OsUserInit(VOID *args)
{
#ifdef LOSCFG_KERNEL_DYNLOAD
    sys_call3(__NR_execve, (UINTPTR)g_initPath, 0, 0);
#endif
    while (true) {
    }
}

上述启动代码已在 kernel/liteos_a/kernel/user/src/los_user_init.c 中,g_initPath 根据启动设置的不同,其值为 /dev/shm/init 或 /bin/init。

系统启动阶段,OsUserInitProcess启动init进程。具体过程如下:

  1. 由内核OsLoadUserInit加载上述代码。

  2. 创建新的进程空间,启动/bin/init进程。

根进程的职责

  • 启动关键系统程序或服务,如交互进程shell。

    说明: 在OpenHarmony 中init 进程通过读取/etc/init.cfg,根据配置执行指定命令,或启动指定进程(详见:init启动引导)。

  • 监控回收孤儿进程,清理子进程中的僵尸进程。

用户态程序运行

用户态程序启动有如下常见方式:

  • shell命令启动进程。

    复制代码
    OHOS $ exec helloworld
    OHOS $ ./helloworld
    OHOS $ /bin/helloworld
  • 通过POSIX接口启动新进程。 Fork方法创建一个新的进程,exec类接口执行一个全新的进程。

相关推荐
世人万千丶1 小时前
鸿蒙日志体系高级应用:HiLog分级输出/隐私脱敏/远程日志采集/线上问题精准溯源方案
学习·harmonyos·鸿蒙
奔跑中的小象2 小时前
统信UOS + 天数AI卡部署SGLang服务手册
人工智能·uos·sglang·天数智芯
DevSecOps选型指南2 小时前
中国版Mythos,为何是悬镜安全灵脉CodeAI?
人工智能·安全
Shockang2 小时前
LangGraph 状态机实战
人工智能
刹那芳华19922 小时前
循环神经网络的从零开始实现(RNN)
人工智能·rnn·深度学习
阿童木写作2 小时前
跨境图片翻译工具多合一,批量图片视频字幕翻译加智能抠图
人工智能·python·音视频·语音识别
科技之门2 小时前
AI3D从建模到贴图、绑骨和动画的完整流程怎么做?V2Fun完整工作流指南
人工智能·3d·贴图
宇宙第一小趴菜2 小时前
二、机器学习的应用领域和发展史
人工智能·机器学习
前端开发江鸟2 小时前
我写过 MCP Server,却一直以为 MCP 只有 Tool
人工智能
天国梦3 小时前
自习室智能化升级避坑指南:天学网AI智习室方案实测与选型建议
大数据·人工智能