鸿蒙内核解析,鸿蒙内核源码分析(内存概念篇)|解读鸿蒙源码

提示:本文基于开源鸿蒙内核分析,官方源码【kernel_liteos_a】官方文档【docs】参考文档【Huawei LiteOS】

本文作者:鸿蒙内核发烧友,用生活场景讲故事的方式去解构内核,一窥究竟,让神秘的内核栩栩如生,浮现眼前。博文全部原创,持续更新,敬请关注。内容仅代表个人观点,错误之处,欢迎大家指正完善。本系列全部文章进入鸿蒙源码分析(总目录)查看

目录

最难讲的章节

坦白讲内存是整个系列里面最难讲的一章,因为概念太多了,笔者写之前查遍了网上资料,发现很多是没有搞清楚就不负责的乱转乱发,越看越晕,脑子里一团浆糊,本来并没那么复杂的概念被复杂化了。笔者坚持原创,不滥竽充数,为自己写和引用的每一个字负责,发布的每篇帖子后续都会反复的修改,查缺补漏,力求描述精准又通俗易懂。喜欢的请收藏。鸿蒙内核知识点非常多,想尽快成体系的整理出来,一来是能加深自己的理解,二来是希望更多人对鸿蒙感兴趣,少走弯路。原创很辛苦,但兴趣使然,值得。本篇重新梳理下内存的概念后再来讲内存。

为什么会懵逼?

会懵逼究其原因,笔者认为关键问题出在概念的分层上,每个层面都有自己的概念,层面搞混了整个就容易乱。还记得系列篇中说 task/线程吗,也是这样的问题,再来回顾一下。对于上层应用比如 java开发者, 接触的是进程和线程的概念,他们会说的new一个线程,task是什么不用去关心。而对于内核层说的就是task 而不是 thread, 但广义上他们是一个意思的,就是程序运行的载体,在系列篇中有详细介绍。其实很多上层开发者不知道main()就是个线程,只是不需要大家去new的而已,因为到了内核层,创建进程的时候会自动创建一个task,入口函数就是main()函数,而大家在程序里new出来的thread到了运行期间也会在内核层创建task,入口函数就是大家熟知的run() 。

所以对内核层来说,只有task 的概念,没有什么线程的说法,也没有什么应用程序的main(),run(),只有入口函数。

typedef VOID *(*TSK_ENTRY_FUNC)(UINTPTR param1,UINTPTR param2,UINTPTR param3,UINTPTR param4);//*kfy task入口函数,切换task的回调

到了CPU层就更简单,连task都没有了, 只有CPU各寄存器值的变化,你给程序计数器PC(ARM的说法)或指令指针寄存器IP(intel的说法)赋予什么值它就运行那个地址的指令,取指令->译码->执行,就这三个动作来回整。 其实应用层不知道task也不妨碍成为一个优秀的工程师,因为设计者的本意就是要分层,让你对底层的概念透明,不要混在一起理解。可树欲静而风不止,你在网上总能看到 线程和task混在一起说和问,并拿来比较的文章和答案。这就有点像关公战秦琼,如果你不了解这是两个世界的人就会一直有个心结在那。

内存的概念也是一样的

对应用层我们会说 逻辑地址,区(代码区,数据区,栈区,堆区)的概念,在这一层我们会知道编译好的代码会放在代码区,全局变量放在数据区,局部变量和代码执行在栈中运行,分配的动态内存是由堆区提供的,至于怎么提供怎么放的,我完全可以不清楚,那是底层的事情。如果笔者告诉你,假如你new出来的10M内存,只用了5M,剩下的5M其实并不属于你,一直是其他进程或线程在使用,你相信吗?什么是逻辑地址,就是按使用人的逻辑来处理的地址,是应用开发者用到能看到的地址,真的物理地址你是看不到的,也不需要看到。

对内核层我们要说 虚拟地址,物理地址,线性地址,映射,段,页表,缺页中断,红黑树,LRU算法这些概念,而不会去说什么逻辑地址。但逻辑地址和虚拟地址其实是一个意思。物理地址是真实的内存地址,有多大的内存就有多少物理地址,那为什么要整出个虚拟地址来,和物理地址是啥关系?答案是:如果没有一个叫MMU(内存管理单元

你可能感兴趣的:(鸿蒙内核解析)