从运行状态角度来看 分为 内核+根文件系统
从静态角度来看 分为 磁盘分区+相关文件
内核调用
第一个方式:调用内核过于复杂,所以有些内核开发人员创建了库文件,通过调用库文件来调用内核程序。那么shell就是通过调用库的用户接口(用户程序)
第二个方式:程序开发人员很牛B,他为了追求效率,他自己编写程序直接调用内核程序。
内核设计流派
1、单内核设计
把所有功能集成与同一程序。方便使用,但是一个功能出了问题就影响整个程序。linux就是例子
2、微内核设计
每种功能使用一个单独的子系统实现。管理较为复杂,但是各功能之间相互影响较小。但是各种内核之间的兼容性就麻烦了。Windows Solaris就是例子
Linux内核特点
1、支持模块化,.ko(kernel object)
2、支持模块化运行时动态状态或卸载
Linux内核组成
核心文件
vmlinuz-3.10.0-693xxxx 就是内核文件。
模块文件
这个就是对应内核的模块文件,如果管理员安装了多个内核版本,那么在这个目录下就会有多个模块文件
这个就是模块文件中的内容。
在kernel目录中又有一些系统必须的文件,比如说一些驱动文件
ramdisk文件(可选)
现在假设内核程序已经在内存当中了(如何载入的先不讨论),那么内核的第一件事情就是装载根文件系统(加载init文件,开启各种进程),装载根文件系统需要挂在分区,挂载分区就需要硬盘驱动,硬盘的驱动在根文件系统内。这样就矛盾了,简单的来说挂载根文件系统需要驱动,而驱动又在根文件系统中。
怎么办?将内存的一部分当做磁盘来用,这个过程中有个伪根文件系统,用于将实际的根分区挂载,并读取init文件。真正的根文件系统上线后,伪根文件系统就失效了。这个伪根文件系统是在第一次安装操作系统的时候,系统根据实际磁盘生成的。
伪文件系统在一定条件下是不需要的,如果在编译内核的时候就知道实际磁盘的驱动,那么就可以将磁盘的驱动直接编译到内核中。
这个就是ramdisk文件,在CentOS6之前该文件为initrd文件,到了CentOS6就转换成ramdisk文件了,因为磁盘到内存必须有缓存,但是实际的数据就在内存中,不需要缓冲区。
内核实现的功能
1、进程管理
进程调度
进程的创建
进程销毁
2、内存管理
进程间通信简称IPC、通信机制有1、消息队列 2、semerphor 3、shm(共享内存)
socket是两个主机进程间通信的机制
3、网络协议栈
各种主机间进程的通信都需要通过网络协议,这种公共的服务需要在内核中实现。
4、文件系统
运行中的系统环境分为两层:1、内核空间 2、用户空间
用户空间中运行了各种应用程序
内核空间中运行了内核代码,这个代码一般都需要特权级操作。
那么如果用户的应用程序需要使用硬件资源时,用户空间的代码会调用内核空间 的代码,由内核代为完成硬件资源操作。
5、驱动程序
6、安全功能
启动分区(/boot)
用于存放内核代码的存储空间。在内核程序启动之前是没有根文件系统的,只有内核启动之后才去识别根文件系统。推荐boot分区使用普通分区
根文件系统(rootfs)
必须符合FHS结构(特定目录结构,比如包含/bin /sbin /proc)等目录。其中init文件是最重要的文件,因为init是启动其他进程的父进程,一切进程都来源于init
所以根文件系统只是一个叫法,根文件系统本身不存在,如果一个文件系统结构符合FHS结构,并包含了特定的目录,那么这个文件系统就叫做根文件系统。(在本机第二块硬盘上安装grub,并做简要执行命令的实验中,这个现象非常明显,在根文件系统中,只有相应的目录,每个目录都没有对应的文件,但是还是可以运行系统的。)
现在就有了一个比较烧脑的问题,内核代码存放在/boot目录中,只有内核启动了才能识别根(简单来讲,使用内核需要根文件系统,但是挂在根文件系统需要内核),那么在启动系统的时候如何去找/boot目录呢?所以在内核程序启动之前需要一个程序将内核代码放入内存运行。
原文地址:http://blog.51cto.com/yueyue207/2126692