本篇关键词:、、、
下载 >> 离线文档.鸿蒙内核源码分析(百篇博客分析.挖透鸿蒙内核).pdf
基础知识相关篇为:
- v01.12 鸿蒙内核源码分析(双向链表) | 谁是内核最重要结构体
- v02.01 鸿蒙内核源码分析(内核概念) | 名不正则言不顺
- v03.02 鸿蒙内核源码分析(源码结构) | 宏观尺度看内核结构
- v04.01 鸿蒙内核源码分析(地址空间) | 内核如何看待空间
- v05.03 鸿蒙内核源码分析(计时单位) | 内核如何看待时间
- v06.01 鸿蒙内核源码分析(优雅的宏) | 编译器也喜欢复制粘贴
- v07.01 鸿蒙内核源码分析(钩子框架) | 万物皆可HOOK
- v08.04 鸿蒙内核源码分析(位图管理) | 一分钱被掰成八半使用
- v09.01 鸿蒙内核源码分析(POSIX) | 操作系统界的话事人
- v10.01 鸿蒙内核源码分析(main函数) | 要走了无数码农的第一次
几个概念
您肯定听过 API
,Posix
,C
语言库函数,系统调用这些概念,但之间有什么区别和联系,估计一些人没弄明白,本篇重点把它们整明白了。
API
: 搞应用开发的同学不会陌生,应用编程接口的缩写 ,它是对函数的定义,规定了这个函数的功能。任何公司,个人都可以定义自有特色的API
。可以称之为 私有标准 。打个比方就相当于是地方方言,十里不同音,只有这个地方的人能搞懂,对外会带来极高的沟通成本。Posix
:Unix
开源后很多公司都推出了不同的版本的Unix
系统。他们的API
各不相同。这给软件的移植带来了很大的困难。于是IEEE
制定了基于Unix
的可移植操作系统接口,目的是为了统一这些 私有标准 , 可以称之为 公共的类Unix接口标准,所以posix
标准也是一种API
,IEEE
这个协会很牛,制定过很多标准,涵盖太空、计算机、电信、生物医学、电力及消费性电子产品等领域,可以说是科技界标准话事人。对应地方方言,它就相当于是普通话,其实呢它也是一种方言。- C语言库函数: 是基于
Posix
标准的具体实现, 相当于中国人说的普通话。 - 系统调用: 是内核对外提供的服务总称, 它一般被C语言库函数所调用, 相当于政府对老百姓的办事窗口, 想访问内部资源就需要填表格, 走流程。
POSIX简介
当前的POSIX主要分为四个部分:
XBD(Base Definitions):包含一些通用的术语、概念、接口以及工具函数(cd,mkdir, cp,mv等)和头文件定义(stdio.h, stdlib.h,pthread.h等)。
XSH(System Interfaces):包含系统服务函数的定义,例如线程、套接字、标准IO、信号处理、错误处理等。
XCU(Shell and Utilities):包含shell脚本书写的语法、关键字以及工具函数(break,cd,cp,continue,pwd,return)的定义。
XRAT(Rationale):包含与本标准有关的历史信息以及采用或舍弃某功能的扩展基本原理。 具体查看 >> 官方网站 | opengroup 目前单一UNIX规范第4版中定义了
1447
个接口。XBD XSH XCU 全部的 82 1191 174 1447
鸿蒙支持部分标准POSIX
接口 ,并不是很多 >> 可查看源码 compat/posix
compat/posix/src
├── map_error.c //错误码映射 例如: ENOERR EINTR ESRCH
├── malloc.c //内存分配 例如: malloc zalloc r
├── misc.c //系统信息
├── mqueue.c //消息队列
├── posix_memalign.c //内存对齐分配
├── pprivate.h //描述 _pthread_data 结构体
├── pthread.c //线程
├── pthread_attr.c //线程属性
├── pthread_cond.c //线程条件
├── pthread_mutex.c //线程互斥
├── sched.c //任务调度
├── semaphore.c //信号量
├── socket.c //网络
└── time.c //时间
2
3
4
5
6
7
8
9
10
11
12
13
14
15
系统调用
syscall/
├── Makefile
├── fs_syscall.c //文件模块
├── ipc_syscall.c //进程通讯模块
├── los_syscall.c //系统调用主功能函数
├── los_syscall.h
├── misc_syscall.c //信息配置
├── net_syscall.c //网络模块
├── process_syscall.c //进程模块
├── syscall_lookup.h
├── syscall_pub.c //公有模块
├── syscall_pub.h
├── time_syscall.c //时间模块
└── vm_syscall.c //内存模块
2
3
4
5
6
7
8
9
10
11
12
13
14
系统调用的实现函数
OsArmA32SyscallHandle
,实现过程在 v95.xx 鸿蒙内核源码分析(系统调用篇) 中详细说明
进程控制类系统调用,主要有:
- 创建和终止进程的系统调用。
- 获得和设置进程属性的系统调用。
- 等待某事件出现的系统调用。
SysFork
,SysWait
,SysSetProcessGroupID
,SysGetUserID
,SysSchedYield
,SysThreadJoin
,SysIoctl
文件操纵类系统调用,主要有:
- 创建和删除文件。
- 打开和关闭文件的系统调用。
- 读和写文件的系统调用。
SysPipe
,SysOpen
,SysStat
,SysRead
,SysWrite
,SysCreat
,SysIoctl
进程通讯类系统调用,主要有:
SysMqOpen
,SysSigAction
,SysKill
,SysMqNotify
,SysMqTimedSend
网络类系统调用,主要有:
SysSocket
,SysBind
,SysConnect
,SysListen
,SysAccept
,SysRecv
信息配置类系统调用,主要有:
SysReboot
,SysInfo
,SysGetrusage
,SysSysconf
时间类系统调用,主要有:
SysTimerCreate
,SysTimerDelete
,SysClockGettime
,SysSetiTimer
内存类系统调用,主要有:
SysMmap
,SysMunmap
,SysBrk
,SysMremap
,SysShmGet
,SysShmAt
,SysShmCtl
,SysShmDt
musl | C标准库函数
musl
,一种C
标准库,官方网站 ,主要使用于以Linux
内核为主的操作系统上,鸿蒙内核也使用了它,目标为嵌入式系统与移动设备,采用MIT
许可证发布。作者为瑞奇·费尔克(Rich Felker
)。开发此库的目的是写一份干净、高效、符合标准的C
标准库。Musl
声称与POSIX 2008
标准和C11
标准兼容。musl
是一个非常庞大提供给应用程序使用的工具库,例如: 学习C语言的第一段代码
#include <stdio.h>
int main() {
printf("Hello, World!");
return 0;
}
2
3
4
5
中的printf
就是由stdio.h
提供,由标准库实现的。这是个可变参数实现函数。
int printf(const char *restrict fmt, ...)
{
int ret;
va_list ap;
va_start(ap, fmt);
ret = vfprintf(stdout, fmt, ap);
va_end(ap);
return ret;
}
2
3
4
5
6
7
8
9
如果你一直往下追,你会追到系统调用 write
ssize_t write(int fd, const void *buf, size_t count)
{
return syscall_cp(SYS_write, fd, buf, count);
}
2
3
4
5
void SyscallHandleInit(void)
{
#define SYSCALL_HAND_DEF(id, fun, rType, nArg) \
if ((id) < SYS_CALL_NUM) { \
g_syscallHandle[(id)] = (UINTPTR)(fun); \
g_syscallNArgs[(id) / NARG_PER_BYTE] |= ((id) & 1) ? (nArg) << NARG_BITS : (nArg); \
} \
#include "syscall_lookup.h"
#undef SYSCALL_HAND_DEF
}
2
3
4
5
6
7
8
9
10
11
\code-v1.1.1-LTS\prebuilts\lite\sysroot\usr\include\arm-liteos\bits\syscall.h
#define __NR_restart_syscall 0
#define __NR_exit 1
#define __NR_fork 2
#define __NR_read 3
#define __NR_write 4
#define __NR_open 5
#define __NR_close 6
#define __NR_creat 8
#define __NR_link 9
2
3
4
5
6
7
8
9
#define SYS_restart_syscall 0
#define SYS_exit 1
#define SYS_fork 2
#define SYS_read 3
#define SYS_write 4
#define SYS_open 5
#define SYS_close 6
#define SYS_creat 8
#define SYS_link 9
ssize_t read(int fd, void *buf, size_t count)
{
return syscall_cp(SYS_read, fd, buf, count);
}
#define __syscall_cp(...) __SYSCALL_DISP(__syscall_cp,__VA_ARGS__)
#define syscall_cp(...) __syscall_ret(__syscall_cp(__VA_ARGS__))
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
\code-v1.1.1-LTS\third_party\musl\src\thread\arm\syscall_cp.s
__syscall_cp_asm:
mov ip,sp
stmfd sp!,{r4,r5,r6,r7}
__cp_begin:
ldr r0,[r0]
cmp r0,#0
bne __cp_cancel
mov r7,r1 //R7寄存器保存软中断号
mov r0,r2
mov r1,r3
ldmfd ip,{r2,r3,r4,r5,r6}
svc 0 //原 SWI 指令, 软中断指令
__cp_end:
ldmfd sp!,{r4,r5,r6,r7}
bx lr
__cp_cancel:
ldmfd sp!,{r4,r5,r6,r7}
b __cancel
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
- 其中最重要的命令就是 svc 0,通过这条指令切换到
svc
模式(svc
替代了以前的swi
指令,是arm
提供的系统调用指令),进入到软件中断处理函数(SWI handler
)。
问题
那可能有人会问了,操作系统有抽象层,那硬件有没有抽象层,规定处理器内核与外设的接口,统一了内核访问外设寄存器的方法,从而简化了软件的开发,提高重用度,降低软硬件接口开发成本。有的,就是CMSIS
( Cortex Microcontroller Software Interface Standard)缩写,中文为Cortex系列微控制器软件接口标准。此标准是ARM公司,芯片供应商以及软件供应商共同制定的,包含以下组件:
CMSIS-CORE
:提供与 Cortex-M0、Cortex-M3、Cortex-M4、SC000 和 SC300 处理器与外围寄存器之间的接口CMSIS-DSP
:包含以定点(分数 q7、q15、q31)和单精度浮点(32 位)实现的 60 多种函数的 DSP 库CMSIS-RTOS API
:用于线程控制、资源和时间管理的实时操作系统的标准化编程接口CMSIS-SVD
:包含完整微控制器系统(包括外设)的程序员视图的系统视图描述 XML 文件 此标准可进行全面扩展,以确保适用于所有 Cortex-M 处理器系列微控制器。其中包括所有设备:从最小的 8 KB 设备,直至带有精密通信外设(例如以太网或 USB)的设备。(内核外设功能的内存要求小于 1 KB 代码,低于 10 字节 RAM)。
百文说内核 | 抓住主脉络
- 百文相当于摸出内核的肌肉和器官系统,让人开始丰满有立体感,因是直接从注释源码起步,在加注释过程中,每每有心得处就整理,慢慢形成了以下文章。内容立足源码,常以生活场景打比方尽可能多的将内核知识点置入某种场景,具有画面感,容易理解记忆。说别人能听得懂的话很重要! 百篇博客绝不是百度教条式的在说一堆诘屈聱牙的概念,那没什么意思。更希望让内核变得栩栩如生,倍感亲切。
- 与代码需不断
debug
一样,文章内容会存在不少错漏之处,请多包涵,但会反复修正,持续更新,v**.xx
代表文章序号和修改的次数,精雕细琢,言简意赅,力求打造精品内容。 - 百文在 < 鸿蒙研究站 | 开源中国 | 博客园 | 51cto | csdn | 知乎 | 掘金 > 站点发布,百篇博客系列目录如下。
按功能模块:
百万注源码 | 处处扣细节
百万汉字注解内核目的是要看清楚其毛细血管,细胞结构,等于在拿放大镜看内核。内核并不神秘,带着问题去源码中找答案是很容易上瘾的,你会发现很多文章对一些问题的解读是错误的,或者说不深刻难以自圆其说,你会慢慢形成自己新的解读,而新的解读又会碰到新的问题,如此层层递进,滚滚向前,拿着放大镜根本不愿意放手。
关注不迷路 | 代码即人生
- 互联网从业十五年,计算机硕士,技术副总裁
- 关注我,持续更新四十年,即聊技术也聊人生
- 交有趣靠谱的人;做难而正确的事
- 不做作,不炒作,只唯真
- 不唯上,不唯书,只唯实
据说喜欢 点赞 + 分享 的,后来都成了大神。😃