三个进程
鸿蒙有三个特殊的进程,创建顺序如下:
- 2号进程,
KProcess
,为内核态根进程.启动过程中创建. - 0号进程,
KIdle
为内核态第二个进程,它是通过KProcess
fork 而来的.这有点难理解. - 1号进程,
init
,为用户态根进程.由任务SystemInit
创建.
- 发现没有在图中看不到0号进程,在看完本篇之后请想想为什么?
家族式管理
- 进程(process)是家族式管理,总体分为两大家族,用户态家族和内核态家族.
- 用户态的进程是平民阶层,屌丝矮矬穷,干着各行各业的活,权利有限,人数众多,活动范围有限(用户空间).有关单位肯定不能随便进出.这个阶层有个共同的老祖宗g_userInitProcess (1号进程).
- 内核态的进程是贵族阶层,管理平民阶层的,维持平民生活秩序的,拥有超级权限,能访问整个空间和所有资源,人数不多.这个阶层老祖宗是 g_kernelInitProcess(2号进程).
- 两位老祖宗都不是通过fork来的,而是内核强制规定进程ID号,强制写死基因创建的.
- 这两个阶层可以相互流动吗,有没有可能通过高考改变命运? 答案是: 绝对冇可能!!! 龙生龙,凤生凤,老鼠生儿会打洞.从老祖宗创建的那一刻起就被刻在基因里了,抹不掉了. 因为后续所有的进程都是由这两位老同志克隆(clone)来的,没得商量的继承这份基因.
LosProcessCB
有专门的标签来processMode
区分这两个阶层.整个鸿蒙内核源码并没有提供改变命运机会的set
函数.
2号进程 KProcess
2号进程为内核态的老祖宗,是内核创建的首个进程,源码过程如下,省略了不相干的代码.
解读
- main函数在系列篇中会单独讲,请留意自行翻看,它是在开机之初在SVC模式下创建的.
- 内核态老祖宗的名字叫
KProcess
,优先级为最高 0 级,KProcess
进程是长期活跃的,很多重要的任务都会跑在其之下.例如:
Swt_Task
oom_task
system_wq
tcpip_thread
SendToSer
SendToTelnet
eth_irq_task
TouchEventHandler
-
USB_GIANT_Task
此处不细讲这些任务,在其他篇幅有介绍,但光看名字也能猜个八九,请自行翻看.
- 紧接着
KProcess
以CLONE_FILES
的方式 fork了一个 名为KIdle
的子进程(0号进程). - 内核态的所有进程都来自2号进程这位老同志,子子孙孙,代代相传,形成一颗家族树,和人类的传承所不同的是,它们往往是白发人送黑发人,子孙进程往往都是短命鬼,老祖宗最能活,子孙都死绝了它还在,有些收尸的工作要交给它干.
0 号进程 KIdle
0号进程是内核创建的第二个进程,在OsKernelInitProcess
的末尾将KProcess
设为当前进程后,紧接着就fork
了0号进程.为什么一定要先设置当前进程,因为fork需要一个父进程,而此时系统处于启动阶段,并没有当前进程. 是的,您没有看错.进程是操作系统为方便管理资源而衍生出来的概念,系统并不是非要进程,任务才能运行的. 开机阶段就是啥都没有,默认跑在svc模式下,默认起始地址reset_vector
都是由硬件上电后规定的. 进程,线程都是跑起来后慢慢赋予的意义.OsCurrProcessSet
是从软件层面赋予了此为当前进程的这个概念.KProcess
是内核设置的第一个当前进程.有了它,就可以fork, fork, fork !
解读
- 看过fork篇的可能发现了一个参数,
KIdle
被创建的方式和通过系统调用创建的方式不一样,一个用的是CLONE_FILES
,一个是CLONE_SIGHAND
具体的创建方式如下:
-
KIdle
创建了一个名为Idle
的任务,任务的入口函数为OsIdleTask
,这是个空闲任务,啥也不干的.专门用来给cpu休息的,cpu空闲时就待在这个任务里等活干.
- fork 内核态进程和fork用户态进程有个地方会不一样,就是SP寄存器的值.fork用户态的进程一次调用两次返回(父子进程各一次),返回的位置一样(是因为拷贝了父进程陷入内核时的上下文).所以可以通过返回值来判断是父还是子返回.这个在fork篇中有详细的描述.请自行翻看. 但fork内核态进程虽也有两次返回,但是返回的位置却不一样,子进程的返回位置是由内核指定的,例如:
Idle
任务的入口函数为OsIdleTask
.详见代码:
- 结论是创建0号进程中的
OsCreateIdleProcess
调用LOS_Fork
后只会有一次返回.而且返回值为0,因为g_freeProcess
中0号进程还没有被分配.详见代码,注意看最后的注释:
1号进程 init
1号进程为用户态的老祖宗.创建过程如下, 省略了不相干的代码.
解读
- 从代码中可以看出用户态的老祖宗创建过程有点意思,首先它的源头和内核态老祖宗一样都在
OsMain
. - 通过创建一个分离模式,优先级为10的系统任务
SystemInit
,来完成.任务的入口函数SystemInit()
的实现由平台集成商来指定. 本篇采用了hi3516dv300
的实现.也就是说用户态祖宗的创建是在sysTask.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE;//16K
栈中完成的.这个任务归属于内核进程KProcess
. - 用户态老祖宗的名字叫
Init
,优先级为28级. - 用户态的每个进程有独立的虚拟进程空间
vmSpace
,拥有独立的内存映射表(L1,L2表),申请的内存需要重新映射,映射过程在内存系列篇中有详细的说明. -
init
创建了一个任务,任务的入口地址为__user_init_entry
,由编译器指定. - 用户态进程是指应有程序运行的进程,通过动态加载ELF文件的方式启动.具体加载流程系列篇有讲解,不细说.用户态进程运行在用户空间,但通过系统调用可陷入内核空间.具体看这张图:
经常有很多小伙伴抱怨说:不知道学习鸿蒙开发哪些技术?不知道需要重点掌握哪些鸿蒙应用开发知识点?
为了能够帮助到大家能够有规划的学习,这里特别整理了一套纯血版鸿蒙(HarmonyOS Next)全栈开发技术的学习路线,包含了鸿蒙开发必掌握的核心知识要点,内容有(ArkTS、ArkUI开发组件、Stage模型、多端部署、分布式应用开发、WebGL、元服务、OpenHarmony多媒体技术、Napi组件、OpenHarmony内核、OpenHarmony驱动开发、系统定制移植等等)鸿蒙(HarmonyOS NEXT)技术知识点。
《鸿蒙 (Harmony OS)开发学习手册》(共计892页)
如何快速入门?
1.基本概念
2.构建第一个ArkTS应用
3.……
开发基础知识:
1.应用基础知识
2.配置文件
3.应用数据管理
4.应用安全管理
5.应用隐私保护
6.三方应用调用管控机制
7.资源分类与访问
8.学习ArkTS语言
9.……
基于ArkTS 开发
1.Ability开发
2.UI开发
3.公共事件与通知
4.窗口管理
5.媒体
6.安全
7.网络与链接
8.电话服务
9.数据管理
10.后台任务(Background Task)管理
11.设备管理
12.设备使用信息统计
13.DFX
14.国际化开发
15.折叠屏系列
16.……
鸿蒙开发面试真题(含参考答案)
OpenHarmony 开发环境搭建
《OpenHarmony源码解析》
- 搭建开发环境
- Windows 开发环境的搭建
- Ubuntu 开发环境搭建
- Linux 与 Windows 之间的文件共享
- ……
- 系统架构分析
- 构建子系统
- 启动流程
- 子系统
- 分布式任务调度子系统
- 分布式通信子系统
- 驱动子系统
- ……
OpenHarmony 设备开发学习手册
写在最后
如果你觉得这篇内容对你还蛮有帮助,我想邀请你帮我三个小忙:
- 点赞,转发,有你们的 『点赞和评论』,才是我创造的动力。
- 关注小编,同时可以期待后续文章ing🚀,不定期分享原创知识。