解析Linux内核

1 基本知识

1.1 什么是Linux内核

内核是操作系统的核心部分,为应用程序提供安全访问硬件资源的功能。内核向应用程序提供了统一和简洁的接口,降低应用程序设计的复杂程度,内核可以被看做是一个系统资源管理器,管理计算机系统中的所有软件个硬件。

1.2编译内核

本节介绍在PC上如何编译生成2.6版本的内核目标文件。Linux内核编译配置提供多种方式,如下所述。

  • make config: 基于传统的文本界面配置方式;
  • make menuconfig : 基于文本模式下的图形选单界面;
  • make xconfig : 基于图形窗口模式的配置界面;
  • make oldconfig : 倒入已有的配置

2 Linux内核的子系统

内核是操作系统的核心,Linux内核提供很多基本功能,如虚拟内存、多任务、共享库、需求加载、共享时拷贝、以及网络功能。Linux内核把不同功能分成不同的子系统的方法,通过一种整体的结构功能把各种功能集合在一起,提高了工作效率,同时还提供动态加载模块的方式,为动态修改内核功能提供了灵活性。
在这里插入图片描述

2.1 系统调用接口

SCI 层提供了某些机制执行从用户空间到内核的函数调用,这个接口依赖于体系结构,甚至在相同的处理器家族内也是如此。SCI 实际上是一个非常有用的函数调用多路复用和多路分解服务。在 ./linux/kernel 中您可以找到 SCI 的实现,并在 ./linux/arch 中找到依赖于体系结构的部分。

用户程序通过软件终端后,调用系统内核提供的功能,这个在用户空间和内核提供的服务之间的接口成为称为系统调用。系统调用是Linux内核提供的,用户空间无法直接使用系统调用,在用户进程中使用系统调用必须跨越应用程序和内核的界限。

在这里插入图片描述
下图所示的是一个用户进程中通过GNU C库进行的系统调用示意图,系统调用通过同一入口点传入内核,以i386体系结构为例。


用户应用 C函数库 内核 系统调用 getpid(void) system_call_table[eax] return eax=_NR_getpid加载参数 resume_userspace 用户应用 C函数库 内核 系统调用

当加载了系统C库调用的索引和参数时,就会调用0X80软件中断,它将执行system_call函数,这个函数按照EAX寄存器内容的标示处理所有的系统嗲用。经过几个简单的测试,会使用EAX寄存器内容的索引查system_call_table表得到系统调用的入口,然后执行系统调用。从系统调用返回后,最终执行syscall_exit,并调用resume_userspace函数返回用户空间。

2.2 进程管理子系统

Linux系统是一种动态系统,通过进程管理能够适应不断变化的计算需求。Linux内核实现用户动态创建进程,进程间有等待、互斥等操作。

在Linux内核空间,每个进程都有一个独立的数据结构,用来保存该进程的ID、优先级、地址的空间等信息,这个结构也成为进程控制块。所谓的进程管理就是对进程控制块的管理。Linux的进程是通过fork()系统调用产生的,调用fork()的进程称为父进程,生成的进程称为子进程,子进程被创建时,除了进程ID与父进程不同,其他的数据结构和父进程一样。

让若干进程都在CPU上工作就是进程管理子系统的工作。Linux内核设计了存放进程队列的结构,在一个系统上右若干队列,分别存放不同状态的进程,至少包含的状态有运行、就绪、等待。

2.3 内存管理子系统

内核所管理的另外一个重要资源是内存。为了提高效率,如果由硬件管理虚拟内存,内存是按照所谓的内存页 方式进行管理的(对于大部分体系结构来说都是 4KB)。Linux内核的内存管理子系统管理虚拟内存和物理内存间的映射关系,以及系统可用内存空间。

不过内存管理要管理的可不止 4KB 缓冲区。Linux 提供了对 4KB 缓冲区的抽象,例如 slab 分配器。这种内存管理模式使用 4KB 缓冲区为基数,然后从中分配结构,并跟踪内存页使用情况,比如哪些内存页是满的,哪些页面没有完全使用,哪些页面为空。这样就允许该模式根据系统需要来动态调整内存使用。

为了支持多个用户使用内存,有时会出现可用内存被消耗光的情况。由于这个原因,页面可以移出内存并放入磁盘中。这个过程称为交换,因为页面会被从内存交换到硬盘上。内存管理的源代码可以在 ./linux/mm 中找到。

2.4 虚拟文件系统

虚拟文件系统(VFS)屏蔽了不同文件系统间的差异,向用户提供统一的接口,是Linux内核中的一个软件抽象层。VFS 在 SCI 和内核所支持的文件系统之间提供了一个交换层,如下图所示。
在这里插入图片描述
在 VFS 上面,是对诸如 open、close、read 和 write 之类的函数的一个通用 API 抽象。在 VFS 下面是文件系统抽象,它定义了上层函数的实现方式。它们是给定文件系统(超过 50 个)的插件。文件系统的源代码可以在 ./linux/fs 中找到。VFS根据访问的请求调用不同的文件系统驱动的函数处理用户的请求。

文件系统层之下是缓冲区缓存,它为文件系统层提供了一个通用函数集(与具体文件系统无关)。这个缓存层通过将数据保留一段时间(或者随即预先读取数据以便在需要是就可用)优化了对物理设备的访问。缓冲区缓存之下是设备驱动程序,它实现了特定物理设备的接口。

2.5 网络堆栈

Created with Raphaël 2.2.0 用户进程 套接字 网络协议 网络设备

网络堆栈在设计上遵循模拟协议本身的分层体系结构。回想一下,Internet Protocol (IP) 是传输协议(通常称为传输控制协议或 TCP)下面的核心网络层协议。TCP 上面是 socket 层,它是通过 SCI 进行调用的。

socket 层是网络子系统的标准 API,它为各种网络协议提供了一个用户接口。从原始帧访问到 IP 协议数据单元(PDU),再到 TCP 和 User Datagram Protocol (UDP),socket 层提供了一种标准化的方法来管理连接,并在各个终点之间移动数据。内核中网络源代码可以在 ./linux/net 中找到。

2.6 设备驱动

Linux内核把设备分成3类:块设备、字符设备、网络设备。
在这里插入图片描述
如上体所示用户程序从外部设备请求数据的流程,从图中可看出用户进程访问外部设备是通过设备无关软件进行的,设备无关软件是内核中的各种软件抽象层如VFS。

2.7 依赖体系结构的代码

尽管 Linux 很大程度上独立于所运行的体系结构,但是有些元素则必须考虑体系结构才能正常操作并实现更高效率。./linux/arch 子目录定义了内核源代码中依赖于体系结构的部分,其中包含了各种特定于体系结构的子目录(共同组成了 BSP)。对于一个典型的桌面系统来说,使用的是 i386 目录。每个体系结构子目录都包含了很多其他子目录,每个子目录都关注内核中的一个特定方面,例如引导、内核、内存管理等。这些依赖体系结构的代码可以在 ./linux/arch 中找到。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值