从零开始写Linux内核:一书学透核心原理与实现
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

1.1 操作系统概述

操作系统的出现、应用和发展是几十年来计算机领域最重大的进展。它是从无到有、从简单到复杂逐步发展起来的。在这个过程中,出现了很多关于操作系统的基本概念和重要理论。

本节将简述操作系统中最核心的概念,随着编码的不断推进,很多概念的细节将会越来越清晰,到那时,相信读者会对本节提到的概念有更加深入的理解。

1.1.1 功能和架构

操作系统有两个核心职责:一是对硬件进行管理和抽象;二是管理应用并且为它们提供服务。

从硬件设备的角度看,现代计算机系统由各种各样的物理设备组成,例如内存、GPU、网卡等。操作系统的首要职责就是对这些设备进行管理,只有这样,软件才有可能通过GPU进行图像渲染,通过网卡访问互联网。其次,操作系统还要对这些资源进行抽象,从而向应用开发者提供统一的接口,方便开发者访问和使用硬件资源。例如,开发者在创建进程时,只需要面向统一、巨大而且连续的虚拟地址空间进行编程,在32位系统上,虚拟地址空间为4GB,开发者不需要知道物理内存具体有多大、是什么型号的、物理内存地址是否连续等硬件细节。

从应用的角度看,所有的用户应用都受操作系统管理。当新启动一个应用进程的时候,操作系统会为它准备进程控制块、内核栈空间、进程页表等软硬件资源,然后对所有的应用进程进行统一的调度管理。当进程退出时,操作系统负责回收内存资源、销毁页表、通知与该进程有关的其他进程,从而实现对应用进程的管理。

另外,操作系统提供了各种不同功能的接口(人们称之为系统调用),以方便应用程序访问和使用各种资源。例如,应用程序可以通过write接口向屏幕上打印字符串。

由此可以推断,一个最基本的操作系统至少包含以下4个部分。

1)进程管理:负责创建进程、为进程分配资源、管理进程的调度,以及在进程退出时销毁进程关联的资源。

2)内存管理:管理物理内存的分配和回收,创建虚拟内存,向应用程序提供分配和回收内存的接口。

3)输入/输出管理:负责显示器、键盘、鼠标等输入/输出设备的管理,将信息输入到计算机系统中,经过运算和处理以后再输出给用户。磁盘数据的读入/读出也是输入/输出管理的一部分。

4)文件系统:提供文件的增删查改等功能。在Linux的设计哲学中,强调一切皆是文件,它将网络、管道都抽象成了文件,所以文件系统在Linux中扮演着极其重要的角色。

除了这些核心的功能以外,现代系统中还有网络系统、AI加速器等更多复杂的模块。随着我们对操作系统的认识逐渐加深,读者将会很容易推理出这些系统是如何与操作系统的核心模块交互的。

人们把进程管理、内存管理、输入/输出管理文件系统等核心模块统称为操作系统内核,而把网卡、显卡等设备的管理模块统称为设备驱动。在操作系统的发展历史中,内核的设计主要有两种思路,分别是宏内核(Macrokernel)和微内核(Microkernel)。

宏内核是一种将大多数操作系统服务和驱动程序集成在内核空间中的设计。进程管理、内存管理、文件系统管理、设备驱动等组件都作为内核的一部分运行,具有直接访问硬件的权限。

宏内核的系统服务紧密集成,内核中的各个模块可以直接操作硬件资源,因为减少了用户态和内核态之间的切换,处理速度快。但它同时也有一些缺陷。首先是安全性,任何内核模块的错误都可能导致整个系统崩溃,尤其是来自第三方的设备驱动程序,其安全性有可能影响到内核的整体稳定性。其次是内核体积大,针对不同平台的移植难度较高。

微内核的内核空间仅包含最基本的服务(如进程通信和地址空间管理)。文件系统、设备驱动等服务则位于用户空间,通过消息传递机制与内核通信。相比宏内核,微内核只将最基本的功能保留在内核中,其余作为独立的服务运行,而且各服务组件相互独立,运行在用户空间,通过定义良好的接口通信。内核与用户服务运行在不同的地址空间,增强了安全性。

但这种设计也带来了以下三个问题。一是,用户态与内核态频繁切换,导致消息传递延迟;二是实现复杂,消息传递机制和同步问题增加了系统复杂度;三是会导致与直接操作硬件有关的效率下降。

宏内核的典型代表是Linux,微内核的典型代表包括Minix和Windows。这两种设计并不是绝对对立的,现代操作系统设计往往采用混合内核的方式,试图结合两者的优点。

1.1.2 操作系统的发展历史

操作系统的发展历史可以追溯到电子计算机的早期时代,主要包括以下几个阶段。

1)手工操作阶段(20世纪40年代~20世纪50年代):在最早的电子计算机(如ENIAC,1946年诞生)出现时,还没有现代意义上的操作系统。程序员需要手动设置开关和插拔线缆来输入程序指令和数据,然后观察输出结果。这一时期使用穿孔卡片和磁带存储程序。

2)批处理系统(20世纪50年代~20世纪60年代):为了提高效率,出现了批处理系统。用户事先准备好程序和数据,通过穿孔卡片或磁带提交给操作员,由操作员批量处理。计算机自动执行这些作业,完成后通知用户取回结果。这个时期的代表有IBM的OS/360。

3)分时系统(20世纪60年代):分时操作系统允许多个用户通过终端同时连接到一台计算机,每个用户都感觉好像独占了计算机资源。这是多任务处理和交互式计算的开端,UNIX(1969年在贝尔实验室诞生)是此时期的标志性成果。

4)实时操作系统(20世纪60年代~20世纪70年代):针对特定应用(如工业控制和航空航天)的实时操作系统(RTOS)被开发出来,其强调对外部事件的快速响应,保证数据处理的及时性。

5)个人计算机操作系统(20世纪70年代~20世纪80年代):随着个人计算机的普及,出现了多种个人计算机操作系统,如CP/M、Apple Macintosh的System 1(1984年),以及后来主导市场的Microsoft MS-DOS(1981年)和Windows(1985年首次发布图形界面版本)。

6)图形用户界面(GUI)的兴起(20世纪80年代):Apple Macintosh和随后的Windows 3.x推动了图形用户界面的广泛使用,使得计算机对用户更加友好。

7)现代操作系统与网络(20世纪90年代至今):Linux(1991年)作为开源操作系统迅速崛起,成为服务器和部分桌面计算机的选择。Windows 95及后续版本进一步普及了网络功能和个人计算机的多媒体能力。随着互联网的发展,操作系统开始集成更强大的网络和安全性特性。

8)移动操作系统(21世纪初至今):随着智能手机和平板电脑的兴起,iOS(2007年)和Android(2008年)成为移动设备上的主流操作系统,开启了移动计算的新纪元。

9)云计算与跨平台操作系统(21世纪10年代至今):云计算技术的成熟促进了操作系统向云端的迁移,例如Chrome OS,它强调通过网络应用来完成大部分计算任务。同时,跨平台操作系统(如Windows 10和macOS Catalina)开始支持运行原本为其他平台设计的应用程序。

10)物联网(IoT)操作系统(21世纪10年代至今):面向物联网设备的轻量级操作系统(如FreeRTOS、RTOS、mbed OS等)为智能家居、可穿戴设备等物联网应用的发展奠定了基础。

操作系统的发展持续受到技术进步、用户需求变化和新应用场景的驱动,不断向着更高的效率、更好的用户体验和更强的安全性方向演进。

从操作系统的发展历史中可以看出,Linux并不是一个凭空出现的伟大发明,它是基于历史上的各种优秀实践不断演化而来的。早期的Linux和Minix有着密切的关系,事实上Linux最初就是在Minix操作系统的基础上开发出来的。

Minix是由荷兰计算机科学家Andrew Tanenbaum教授在1987年开发的一个操作系统,主要用于教学和研究目的。Minix是一个非常小巧的操作系统,只有几千行代码,但是其设计与实现思路非常精妙和先进。因此,Minix成为当时操作系统领域内的一个重要研究对象,也吸引了很多人的关注和研究。直到现在,Minix系统仍然在不断地演进。作为一个优秀的微内核系统,Minix不仅具有研究价值,也有很重要的实用价值。

Linus Torvalds在1991年开始开发Linux操作系统的时候,初衷是想创建一个类似于UNIX的操作系统,以便进行编程和学术研究。当时,Linus使用的是一台386处理器的PC,并且他已经接触过Minix操作系统。因此,Linus选择了Minix的设计和实现思路作为Linux的基础,并采用了Minix的文件系统、进程调度等基本功能,同时,Linus还根据自己的需求和想法,对Minix的代码进行了改进和优化,以使其更加适合自己使用。可以说早期的Linux和Minix之间具有非常紧密的关系。

随着时间的推移,Linux内核经历了许多版本的更新,每个版本都引入了一些新的功能和改进,以提高Linux的性能、稳定性和安全性。

在Linux发展的早期阶段,有几个重要的版本,它们的发布时间和相关特性如下所示。

1)Linux 0.01(1991年):这是第一个非公开发布的Linux版本,由Linus Torvalds在1991年9月发布。它只有几千行代码,实现了UNIX操作系统的基本功能。

2)Linux 0.12(1992年):是Linux内核的第一个公开发布版本。这个版本引入了文件系统、交换分区和进程调度等基本功能。本书也将以这个版本为目标,一步步地实现它。

3)Linux 0.95(1993年):引入了虚拟内存管理和TCP/IP协议栈等功能。这使得Linux可以更好地适应网络环境,并提高了系统的性能和可靠性。

4)Linux 1.0(1994年):一个具有里程碑意义的版本。它引入了对多处理器系统和动态加载内核模块的支持,同时加入了许多新的驱动程序和工具。这使得Linux可以更好地适应企业级服务器等领域的需求。

5)Linux 2.0(1996年):是一个比较成熟和稳定的版本。这个版本引入了SMP(Symmetric Multiprocessing,对称多处理)和更多硬件设备(如SCSI和USB)的支持,同时加入了许多新的驱动程序和工具。

6)Linux 3.0(2011年):尽管版本号跳跃较大,但此版本主要是为了纪念Linux诞生20周年,同时也引入了一些新的特性,进行了一些功能改进。

7)Linux 4.0(2015年):新增了对新的CPU架构的支持,以及能更好地支持电源管理与容器技术(如Docker)。

8)Linux内核5.0(2019年):此版本继续提升硬件支持,引入了多项安全增强措施,并优化了对现代硬件和云环境的支持。

随着时间的推移,Linux逐渐成为一款功能强大、灵活、安全和高效的操作系统,并得到越来越多开发者和用户的支持。Linux已经成为世界上最流行的操作系统之一,被广泛应用于服务器、超级计算机、移动设备、嵌入式系统等领域。

了解了操作系统和Linux的基础知识以后,接下来就着手开发Linux内核。