
我们平时运行的程序,每个程序各运行几十毫秒,大家来回轮换,这样子我们看起来这些程序好像在“同时”运行一样。应用程序之所以能够被 *** 作系统通过时间片的方式调度,是因为对于CPU而言,普通的应用程序和 *** 作系统的内核运行在不同的特权级别上,我们叫作rings。应用程序运行在Ring 3,而内核运行在Ring 0。
随着科技的发展, *** 作系统变得越来越复杂,内核里面的东西也越来越多。人们也就开始考虑是否应该改变原有的架构,从而提高 *** 作系统的性能和稳定性,主要是精简内核降低开发的复杂度,还有就是把各种程序尽可能的隔离,保证一个程序的崩溃不会牵连到其他的程序。上世纪80年代人们讨论得火热的微内核就是这样一种架构。
微内核考虑在 *** 作系统的内核中保留 *** 作系统最基本的功能,也就是任务调度、内存和设备的抽象和管理。其他的功能全部从内核移出,放到用户态中了实现,并以C/S模式对其他应用程序提供服务。
微内核带来的好处主要是稳定性和实时性,即内核中模块数量少了,结构更精简更优化了,能够影响内核的程序和驱动也减少了,稳定性随之提高;另外就是实时性,内核精简了以后,响应的时延的减小。不过并不是精简了以后会使得性能提升,微内核使得内核中只有最关键的部分,其他模块和系统功能全部作为独立模块放到用户态空间中运行,功能分散了以后增加了通信的成本。不过微内核 *** 作系统的特点尤其适合工控系统的控制,而且设计简单,在小型的系统中有不少的应用。另外亦有不少实时 *** 作系统是使用微内核架构设计。
所有的理论设计,放到现实的工程中都是要做折衷的。所以有混合内核的出现,综合宏内核和微内核的不同优点,在两个方案中折衷设计。OS X和Windows就属于这类。至于Linux,上千万行代码,架构岂是说改就能改的。使用Linux构建的系统,不少都是要追求性能的吧,前面也说到微内核会降低性能,在Linux中,我们为了使得一个事情性能更高,往往还要把这个模块放到内核中运行,比如PF_RING。所以在需要考虑性能的时候,微内核又显得不那么合适,像微软一样取一个折衷算是一个好的办法。
Linux 内核中可使用宏 __setup() 处理内核的启动参数 cmdline 的解析。
文件: include/linux/init.h
定义:
通过宏展开可以看出:宏 __setup() 主要是定义了一个 obs_kernel_param 类型的结构体变量 __setup_fn 。
以 RockPI 4A 单板 Debian 系统 Linux 4.4 内核为例,介绍 init 参数的解析方法。
1、cmdline参数
在 Debian 系统中,通过 extlinux.conf 文件传递启动参数,其中 init=/sbin/init ,如下:
2、__setup()宏定义
在 Linux 内核中,解析 init 参数的 __setup() 实现如下:
3、__setup()宏展开
展开宏 __setup("init=", init_setup) ,即:
内核编译完成后,在内核符号表 System.map 文件中,可以看到 __setup_init_setup :
4、函数调用流程
内核启动后, init_setup() 函数的调用流程如下:
首先,Linux本身在实现之初仅仅作为Linus一个业余项目而存在。而Monolithic Kernel由于不需要处理消息队列等等原因从实现角度来说比Micro Kernel更为方便,我个人认为这是Linus采用Monolithic Kernel的原因之一。其他原因可能是他本人从情感上喜欢这一架构,也可能他顺延模仿的Unix或者认为现有Micro Kernel消息传递的实现代码很ugly。但这些原因并不是重点,重点在于他的作品与采用Micro Kernel的Minix相比,它的易用性更好。 Minix为了尽可能兼容更多的硬件设备,做到更加全面的兼容性,在实现上尽量避免利用单一某种处理器的新特性,这也是导致其效率不高的原因之一。而Linux则认为 *** 作系统只需要对用户态程序保持统一的API即可保证兼容性,底层硬件的驱动等支持可以扩充,并且工作量不大。在编写Linux的开始阶段,仅支持在当时使用人数占多数的i386架构,但在内存管理,网络等模块上实现均优于Minix,因此取得了大量用户的支持,并最终流行。欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)