开源鸿蒙轻量系统源码分析
作者 | 将狼才鲸 |
---|---|
日期 | 2024-03-28 |
一、前言
-
之前单独的LiteOS是通过Makefile编译的,当前的开源鸿蒙LiteOS-M和LiteOS-A是通过gn和ninja编译的。
-
Gitee官方只介绍了LiteOS-M的gn + ninja编译的流程,针对M3使用Keil编译的流程可能要参考社区代码
- harmonyos_next / stm32f103_simulator_keil
- OpenHarmony / kernel_liteos_m
- 使用Keil编译ARM Cortex-M3时,只需要kernel_liteos_m仓库和Keil工程仓库,不需要全量的OpenHarmony代码
-
由此可知,开源鸿蒙轻量系统只是简单的由LiteOS-M内核 + 一些芯片厂商的驱动组成
-
LiteOS-M 编码规范
-
- 轻量系统STM32F407芯片移植案例
- 确定主频、选定默认打印输出的串口、printf标准输入输出重定向到默认串口、指定内存范围给内核、提供定时器给内核
- 移植芯片内核架构的流程
- LiteOS-M内核BUILD.gn编写指南
- 轻量系统STM32F407芯片移植案例
二、源码分析
- 源码下载:OpenHarmony / kernel_liteos_m
- 代码总量只有8M,代码量和uC/OS这类操作系统类似,因为代码量不多,因此一个人也是能分析完的;uC/OS虽然是开源、个人免费,但是商用是要收费的,所以ARM Cortex-M之类的芯片使用LiteOS-M或者RT-Thread这类操作系统还是蛮划算的,需要技术支持的话也可以找相关公司进行付费咨询。
- 代码结构如下:
jim@DESKTOP-SVP3BEM MINGW64 /d/1_git/openHarmony/kernel/liteos_m (master)
$ tree .
.
|-- BUILD.gn /* 老版本的LiteOS使用Makefile编译,新版本还可以用gn + ninja */
|-- Kconfig
|-- Makefile
|-- arch /* 硬件相关的代码,按内核IP公司 - IP系列进行区分 */
| |-- BUILD.gn
| |-- Kconfig
| |-- arm
| | |-- BUILD.gn
| | |-- Kconfig
| | |-- arm9
| | | .......
| | |-- common /* 相同芯片内核IP公司通用的函数和接口 */
| | | |-- BUILD.gn
| | | |-- los_common_interrupt.c
| | | `-- los_common_interrupt.h
| | |-- cortex-m3 /* M3只支持Keil编译,之后的版本如M4、Cortex-A则是在Linux + gcc下编译 */
| | | `-- keil /* 操作系统底层相关的支持,也是操作系统移植的重点 */
| | | |-- los_arch_atomic.h
| | | |-- los_arch_context.h
| | | |-- los_arch_interrupt.h
| | | |-- los_arch_timer.h
| | | |-- los_atomic.S
| | | |-- los_context.c
| | | |-- los_dispatch.S
| | | |-- los_exc.S
| | | |-- los_interrupt.c
| | | |-- los_startup.s /* 芯片上电后执行的第二行代码,芯片上电后的第一行代码一般都融合进了编译器中,由芯片原厂实现,写代码时看不到 */
| | | `-- los_timer.c /* 需要给操作系统的定时器接口,用于时间片轮转 */
| | |-- cortex-m33
| | | ......
| | |-- cortex-m4
| | | .......
| | |-- cortex-m55
| | | .......
| | |-- cortex-m7
| | | .......
| |-- csky
| | .......
| |-- include /* 所有芯片对操作系统暴露出的统一接口 */
| | |-- los_arch.h
| | |-- los_atomic.h
| | |-- los_context.h
| | |-- los_interrupt.h
| | |-- los_mpu.h
| | `-- los_timer.h
| |-- risc-v
| | ......
| `-- xtensa
| ......
| /* arch结构和Linux源码类似,一组类似的模块会暴露出统一的接口放在.h中,而.c的实现会分散到各处的不同模块,这和普通裸机代码中.c和.h在一起的结构不一样 */
|-- bundle.json
|-- components /* 支持的插件,可选 */
| |-- BUILD.gn
| |-- backtrace
| | |-- BUILD.gn
| | |-- los_backtrace.c
| | `-- los_backtrace.h
| |-- cppsupport /* 是否支持C++ */
| | |-- BUILD.gn
| | |-- los_cppsupport.c
| | `-- los_cppsupport.h
| |-- cpup
| | |-- BUILD.gn
| | |-- los_cpup.c
| | `-- los_cpup.h
| |-- debugtools
| | |-- BUILD.gn
| | |-- los_debugtools.h
| | |-- los_hwidump.c
| | |-- los_schedtrace.c
| | `-- los_stackdump.c
| |-- dynlink
| | |-- BUILD.gn
| | |-- los_dynlink.c
| | |-- los_dynlink.h
| | `-- script
| | `-- so_parse
| |-- exchook
| | |-- BUILD.gn
| | |-- los_exc_info.c
| | |-- los_exc_info.h
| | |-- los_exchook.c
| | `-- los_exchook.h
| |-- fs /* 操作系统的四大模块之一:文件系统 */
| | |-- BUILD.gn
| | |-- Kconfig
| | |-- fatfs /* FAT32最常用,可以用于U盘、Flash、网盘等 */
| | | |-- BUILD.gn
| | | |-- Kconfig
| | | |-- fatfs.c
| | | |-- fatfs.h
| | | `-- fatfs_conf.h
| | |-- littlefs
| | | ......
| | `-- vfs
| | ......
| |-- iar_tls
| | |-- los_iar_tls.c
| | `-- los_iar_tls.h
| |-- lmk
| | |-- BUILD.gn
| | |-- los_lmk.c
| | `-- los_lmk.h
| |-- lms
| | |-- BUILD.gn
| | |-- Kconfig
| | |-- lms_libc.c
| | |-- los_lms.c
| | |-- los_lms.h
| | `-- los_lms_pri.h
| |-- net /* 操作系统的第五大功能:通信/网络通信 */
| | |-- BUILD.gn
| | |-- lwip-2.1 /* 像网络、U盘之类的大型通信类驱动代码会很多,有时甚至会比操作系统本身的代码量还多 */
| | | |-- BUILD.gn
| | | |-- enhancement
| | | | `-- src
| | | | |-- fixme.c
| | | | `-- lwip_ifaddrs.c
| | | |-- lwip_porting.gni
| | | `-- porting
| | | |-- include
| | | | |-- arch
| | | | | |-- cc.h
| | | | | |-- perf.h
| | | | | `-- sys_arch.h
| | | | |-- lwip
| | | | | |-- api_shell.h
| | | | | |-- dhcp.h
| | | | | |-- inet.h
| | | | | |-- lwipopts.h
| | | | | |-- netdb.h
| | | | | |-- netif.h
| | | | | |-- netifapi.h
| | | | | `-- sockets.h
| | | | `-- lwipopts.h
| | | `-- src
| | | |-- api_shell.c
| | | |-- driverif.c
| | | |-- lwip_init.c
| | | |-- netdb_porting.c
| | | |-- sockets_porting.c
| | | `-- sys_arch.c
| | `-- test
| | ......
| |-- power /* 低功耗模块 */
| | |-- BUILD.gn
| | |-- los_pm.c
| | `-- los_pm.h
| |-- security /* 权限管理模块 */
| | |-- BUILD.gn
| | |-- box
| | | |-- BUILD.gn
| | | |-- los_box.c
| | | `-- los_box.h
| | |-- syscall
| | | |-- BUILD.gn
| | | |-- los_syscall.c
| | | |-- los_syscall.h
| | | |-- pthread_syscall.c
| | | `-- syscall_lookup.h
| | `-- userlib
| | `-- BUILD.gn
| |-- shell /* 命令行 */
| | |-- BUILD.gn
| | |-- Kconfig
| | |-- include
| | | |-- shcmd.h
| | | |-- shcmdparse.h
| | | |-- shell.h
| | | |-- shmsg.h
| | | `-- show.h
| | `-- src
| | |-- base
| | | |-- shcmd.c
| | | |-- shcmdparse.c
| | | |-- shmsg.c
| | | `-- show.c
| | `-- cmds
| | |-- date_shell.c
| | |-- fullpath.c
| | |-- mempt_shellcmd.c
| | |-- shell_shellcmd.c
| | |-- task_shellcmd.c
| | `-- vfs_shellcmd.c
| |-- signal
| | |-- BUILD.gn
| | |-- Kconfig
| | |-- los_signal.c
| | `-- los_signal.h
| `-- trace /* 调试程序用 */
| ......
|-- config.gni
|-- config_iccarm.gni
|-- drivers /* 操作系统四大模块之二:设备管理 */
| `-- Kconfig
| /* 具体的外设驱动由芯片原厂在上层文件夹的device和vendor文件夹中提供 */
|-- figures /* 几张介绍本操作系统内核结构的图片 */
| ......
|-- kal
| |-- BUILD.gn
| |-- Kconfig
| |-- cmsis /* ARM格式的中间件统一接口 */
| | |-- BUILD.gn
| | |-- Kconfig
| | |-- cmsis_liteos2.c
| | |-- cmsis_os.h
| | |-- cmsis_os2.h
| | |-- hos_cmsis_adp.h
| | `-- kal.h
| |-- libc /* C语言标准库,其实现一般都是在编译器中,由芯片原厂完成,所以这里只有头文件 */
| | |-- BUILD.gn
| | |-- Kconfig
| | |-- iccarm
| | | `-- BUILD.gn
| | |-- musl
| | | `-- BUILD.gn
| | `-- newlib
| | |-- BUILD.gn
| | `-- porting
| | |-- include
| | | |-- arpa
| | | | `-- inet.h
| | | |-- byteswap.h
| | | |-- dirent.h
| | | |-- endian.h
| | | |-- ifaddrs.h
| | | |-- limits.h
| | | |-- malloc.h
| | | |-- mqueue.h
| | | |-- net
| | | | |-- ethernet.h
| | | | |-- if.h
| | | | `-- if_arp.h
| | | |-- netdb.h
| | | |-- netinet
| | | | |-- if_ether.h
| | | | |-- in.h
| | | | |-- ip.h
| | | | `-- tcp.h
| | | |-- poll.h
| | | |-- semaphore.h
| | | |-- sys
| | | | |-- _pthreadtypes.h
| | | | |-- fcntl.h
| | | | |-- features.h
| | | | |-- ioctl.h
| | | | |-- mount.h
| | | | |-- prctl.h
| | | | |-- sched.h
| | | | |-- select.h
| | | | |-- socket.h
| | | | |-- statfs.h
| | | | |-- uio.h
| | | | `-- un.h
| | | `-- time.h
| | `-- src
| | |-- hook_adapt.c
| | `-- network
| | |-- htonl.c
| | |-- htons.c
| | |-- ntohl.c
| | `-- ntohs.c
| |-- libsec
| | `-- BUILD.gn
| `-- posix /* 操作系统给应用暴露出来的通用接口 */
| |-- BUILD.gn
| |-- Kconfig
| |-- include
| | |-- libc.h
| | |-- pipe_impl.h
| | |-- poll_impl.h
| | `-- rtc_time_hook.h
| `-- src
| |-- errno.c
| |-- libc.c
| |-- libc_config.h
| |-- malloc.c /* 操作系统的四大模块之三:内存管理 */
| |-- map_error.c
| |-- map_error.h
| |-- mqueue.c
| |-- mqueue_impl.h
| |-- pipe.c
| |-- poll.c
| |-- pthread.c
| |-- pthread_attr.c
| |-- pthread_cond.c
| |-- pthread_mutex.c
| |-- semaphore.c
| |-- signal.c
| |-- time.c
| `-- time_internal.h
|-- kernel /* 操作系统的四大模块之四:进程管理 */
| |-- BUILD.gn
| |-- include
| | |-- los_config.h
| | |-- los_event.h
| | |-- los_membox.h
| | |-- los_memory.h
| | |-- los_mux.h
| | |-- los_queue.h
| | |-- los_sched.h
| | |-- los_sem.h
| | |-- los_sortlink.h
| | |-- los_swtmr.h
| | |-- los_task.h
| | `-- los_tick.h
| `-- src
| |-- los_event.c
| |-- los_init.c
| |-- los_mux.c
| |-- los_queue.c
| |-- los_sched.c
| |-- los_sem.c
| |-- los_sortlink.c
| |-- los_swtmr.c
| |-- los_task.c
| |-- los_tick.c
| `-- mm
| |-- los_membox.c
| `-- los_memory.c
|-- liteos.gni
|-- testsuites /* 移植系统后进行自测用的,不用关心 */
| ......
|-- tools
| `-- mem_analysis.py
`-- utils
|-- BUILD.gn
|-- internal
| |-- los_hook_types.h
| `-- los_hook_types_parse.h
|-- los_compiler.h
|-- los_debug.c
|-- los_debug.h /* 串口调试输出的级别 */
|-- los_error.c
|-- los_error.h /* 所有模块都会用的,要返回的错误码 */
|-- los_hook.c
|-- los_hook.h
|-- los_list.h /* 链表,队列、模块缓存的基础 */
`-- los_reg.h
198 directories, 1571 files
- 基础的操作系统内核代码里没有太多可借鉴的软件结构,它们都是针对某一项功能而实现一项功能,通用的东西较少,接下来我会从操作系统移植的角度稍微分析一下。