linux内核完全注解
进程调度模块负责控制进程对CPU资源的使用。
linux内核完全注解
linux 内核的完全注解是一本非常详细的书籍,它对 Linux 内核的各个方面进行了详细的解释和注解。
这本书包含了从内核启动、进程管理、内存管理、文件系统、网络协议栈等方面的内容。
它不仅详细地介绍了每个组件的工作原理,还深入探讨了内核的一些高级特性和技术细节。
进程管理
进程创建和销毁:可以使用系统调用 fork() 来创建一个新进程,使用 exit() 来终止一个进程。此外,还有一些其他的系统调用,如 exec(),可以用来在一个进程中启动另一个程序。
进程状态:每个进程都有一个状态,如运行、等待、停止等。可以使用 ps 命令或 top 命令来查看当前系统中所有进程的状态。
进程调度:Linux 内核使用一种称为时间片轮转的调度算法来管理进程。这意味着每个进程都会被分配一定数量的 CPU 时间,然后被挂起并等待下一次调度。
进程间通信:进程可以通过管道、共享内存、消息队列等方式进行通信。Linux 内核提供了一些系统调用,如 pipe()、shmget()、msgget() 等,来实现这些通信方式。
进程权限:每个进程都有一个用户 ID 和组 ID,用于限制进程的操作权限。此外,Linux 还提供了一些安全机制,如 SELinux、AppArmor 等,来保护系统免受恶意进程的攻击。
内核启动
内核启动是操作系统启动的第一个阶段,它是将内核加载到内存中并开始执行的过程。在这个过程中,系统会进行硬件自检、初始化硬件设备、挂载文件系统等操作。内核启动过程的具体步骤与操作系统的版本和配置有关,但一般来说,它包括以下几个阶段:
BIOS/UEFI阶段:计算机开机后,首先会执行BIOS或UEFI程序,进行硬件自检和初始化。
Bootloader阶段:接着,BIOS/UEFI会将控制权交给引导加载程序,如GRUB或LILO等。引导加载程序会在硬盘上查找内核镜像文件,并将内核加载到内存中。
内核初始化阶段:一旦内核被加载到内存中,它会进行一系列的初始化操作,如初始化内存管理、文件系统、进程管理等。
用户空间启动阶段:最后,内核会启动用户空间程序,如init或systemd等,以完成系统初始化,并启动用户应用程序。
硬件自检:
lshw:
localhost.localdomain
的主要用途是在本地计算机上访问运行在该计算机上的服务或应用程序。
内核模式和用户模式
CPU会根据代码的特权级别来决定代码能够访问哪些资源。
内核模式是CPU的最高特权级别,它允许代码访问所有的系统资源,包括内存、I/O设备等。
而用户模式则是CPU的较低特权级别,它只允许代码访问受限的资源。
内核模式和用户模式区别
当操作系统启动时,所有的代码都运行在内核模式下,直到操作系统初始化完成后,操作系统会将CPU的特权级别切换到用户模式,让用户程序可以运行。
当用户程序需要访问系统资源时,需要通过系统调用的方式将CPU的特权级别切换到内核模式,让操作系统内核来完成相应的操作,然后再将CPU的特权级别切换回用户模式,让用户程序继续运行。
整体式单内核模式和层次式微内核模式
Linux 操作系统采用了层次式微内核模式,将操作系统的功能划分为不同的层次,例如硬件抽象层、内存管理层、进程管理层、网络层等等,
并将这些层次的功能分别实现在不同的模块中。Windows 操作系统采用了整体式单内核模式,将所有的操作系统功能都集成在一个单独的内核中。
这种设计模式使得 Windows 内核具有较高的性能和较少的开销,但是由于所有的功能都集成在一个内核中,因此它的可靠性和安全性可能会受到影响。
linux模块
Linux 操作系统中的不同模块,它们通常可以在/proc文件系统中找到。
/proc文件系统是一个虚拟文件系统,它提供了有关系统内核和进程的详细信息,包括硬件、内存、网络、文件系统等。
在/proc文件系统中,每个进程都有一个对应的目录,其中包含有关该进程的信息。
此外,还有一些文件和目录提供有关系统硬件和内核的信息,例如/proc/cpuinfo文件提供有关 CPU 的信息,/proc/meminfo文件提供有关内存的信息,/proc/net目录提供有关网络的信息等等。如果您想查看有关特定模块的信息,请查看相关文档或使用命令行工具,例如lsmod命令可以列出当前加载的内核模块。
内核体系结构
用户空间和内核空间:Linux 内核将系统空间分为用户空间和内核空间两部分。用户空间是应用程序运行的空间,而内核空间是操作系统内核运行的空间。
进程管理:进程管理是 Linux 内核的核心功能之一,它负责管理和调度系统中的进程。
内存管理:内存管理是 Linux 内核的另一个核心功能,它负责管理系统中的内存资源,包括虚拟内存、物理内存和交换空间等。
文件系统:文件系统是 Linux 内核的另一个重要组成部分,它负责管理系统中的文件和目录,包括文件的创建、读取、写入和删除等操作。
网络协议栈:网络协议栈是 Linux 内核的重要组成部分,它负责管理系统中的网络连接和通信。
设备驱动程序:设备驱动程序是 Linux 内核的另一个重要组成部分,它负责管理系统中的硬件设备,并提供对设备的操作接口。
系统调用接口:系统调用接口是 Linux 内核和用户空间之间的接口,它提供了用户空间访问内核功能的接口。
假设您正在开发一个在线购物平台,您需要实现以下功能:
用户可以在平台上注册账户,登录和注销。
用户可以浏览和搜索商品,将商品添加到购物车或收藏夹中。
用户可以结算购物车中的商品,进行支付和查看订单历史。
管理员可以管理平台上的商品,包括添加、编辑和删除商品信息。
管理员可以管理用户账户,包括禁用和删除用户账户。
在不同的层次上实现这些功能,可以采用不同的技术和方法。以下是一些可能的实现方式:
前端实现:使用 HTML、CSS 和 JavaScript 等前端技术,实现用户界面和交互逻辑。这种方式需要与后端进行交互,以获取和提交数据。前端可以使用框架和库来简化开发,如 React、Vue、Angular 等。
后端实现:使用服务器端编程语言和框架,如 Node.js、Java、Python、Ruby 等,实现业务逻辑和数据处理。后端可以使用数据库来存储和管理数据,如 MySQL、PostgreSQL、MongoDB 等。
API 实现:使用 RESTful API 或 GraphQL 等接口规范,实现前后端之间的数据交互和通信。API 可以使用开源工具和框架来实现,如 Express、Django、Flask 等。
微服务实现:将功能模块拆分为独立的服务,通过 API 或消息队列等方式进行通信和协作。微服务可以使用 Docker、Kubernetes 等容器技术来部署和管理。
云服务实现:将应用部署到云端,使用云计算平台和服务来实现弹性扩展、负载均衡、安全性等需求。云服务可以使用 AWS、Azure、Google Cloud 等云平台来实现。
这些实现方式各有优劣,需要根据具体的需求和条件来选择。例如,前端实现可以提供良好的用户体验和交互效果,但需要考虑浏览器兼容性和性能问题;后端实现可以提供更强大的业务逻辑和数据处理能力,但需要考虑并发性和可扩展性问题;微服务实现可以提供更灵活和独立的服务架构,但需要考虑服务间通信和维护成本问题;云服务实现可以提供更高的可用性和安全性,但需要考虑成本和依赖云平台的问题。
主程序层,执行系统调用的服务层,支持系统调用的底层函数
主程序层负责接收用户输入,调用服务层进行计算,并将结果输出给用户。
服务层负责实现各种运算的功能,并通过调用底层函数来实现运算功能。
底层函数负责实现具体的运算功能。
进程状态:
运行态(R):表示进程正在运行或等待 CPU 时间片。
等待态(S):表示进程正在等待某个事件的发生,比如等待 I/O 完成或等待信号。
停止态(T):表示进程已经被停止,比如被 SIGSTOP 信号停止。
僵尸态(Z):表示进程已经终止,但其父进程还没有调用 wait 系统调用来获取其状态信息。
睡眠态(D):表示进程正在睡眠,等待某个事件的发生,比如等待硬件中断或等待文件系统操作完成。
停滞态(I):表示进程正在等待某个资源,比如等待磁盘 I/O 完成或等待网络数据包到达。
进程初始化
进程初始化是指当操作系统启动一个新的进程时,该进程需要进行一系列的初始化工作以准备好运行。这些初始化工作包括但不限于:
分配内存空间:进程需要分配一定的内存空间来存储它的代码、数据和堆栈等信息。
加载可执行文件:进程需要将其对应的可执行文件从磁盘加载到内存中。
设置执行环境:进程需要设置一些环境变量,如 PATH 和 LD_LIBRARY_PATH 等,以便能够正确地执行其依赖的库文件和其他程序。
初始化全局变量:进程需要初始化其所依赖的全局变量,以便后续的代码能够正确地访问它们。
建立堆栈和栈帧:进程需要建立自己的堆栈和栈帧,以便函数调用和返回时能够正确地保存和恢复现场。
建立信号处理器:进程需要建立自己的信号处理器,以便能够正确地处理来自操作系统的信号。
初始化文件描述符:进程需要初始化其所依赖的文件描述符,以便后续的代码能够正确地访问它们
创建新的进程
分配进程控制块(Process Control Block,PCB):操作系统需要为新进程分配一个 PCB,该 PCB 包含了进程的基本信息,如进程 ID、状态、优先级等。
分配资源:新进程需要分配一些资源,如内存、文件描述符等,以便能够执行其任务。
复制父进程的地址空间:如果新进程是由现有进程 fork 出来的,则需要将父进程的地址空间复制到新进程中。如果是全新的进程,则需要将可执行文件加载到新进程的地址空间中。
设置进程的上下文:新进程需要设置自己的上下文,如堆栈、程序计数器等,以便能够正确地执行其代码。
设置进程的环境变量:新进程需要设置自己的环境变量,以便能够正确地执行其依赖的库文件和其他程序。
启动新进程:操作系统需要启动新进程,以便让其开始执行。
进程调度
先来先服务调度算法(First-Come, First-Served,FCFS):按照进程到达的先后顺序,依次为每个进程分配 CPU 时间。
短作业优先调度算法(Shortest-Job-First,SJF):按照进程需要的 CPU 时间长度,为需要 CPU 时间的进程分配时间片,优先分配需要时间较短的进程。
优先级调度算法(Priority Scheduling):为每个进程分配一个优先级,按照优先级高低依次为进程分配 CPU 时间。
时间片轮转调度算法(Round-Robin,RR):为每个进程分配一个固定的时间片,当时间片用完后,将 CPU 时间分配给下一个进程。
多级反馈队列调度算法(Multilevel Feedback Queue,MFQ):将进程按照优先级分成多个队列,每个队列分配不同的时间片,优先级高的进程可以从低优先级队列中抢占 CPU 时间。
linux源代码
/arch:包含针对不同体系结构的内核源代码,如 x86、ARM、MIPS 等。
/block:包含块设备驱动程序的源代码。
/crypto:包含加密和解密算法的源代码。
/drivers:包含设备驱动程序的源代码,如网络设备驱动、USB 设备驱动、声卡驱动等。
/fs:包含文件系统相关的源代码,如 ext4、NTFS、FAT 等。
/include:包含内核头文件。
/init:包含内核初始化相关的源代码。
/ipc:包含进程间通信相关的源代码,如消息队列、共享内存等。
/kernel:包含内核核心代码,如调度程序、进程管理、中断处理等。
/lib:包含内核库函数的源代码。
/mm:包含内存管理相关的源代码,如虚拟内存管理、物理内存管理等。
/net:包含网络相关的源代码,如 TCP/IP 协议栈、网络设备驱动等。
/samples:包含示例程序的源代码。
/scripts:包含构建和编译内核的脚本文件。
/security:包含安全模块的源代码。
/sound:包含声卡驱动程序的源代码。
/usr:包含用户空间工具的源代码,如 GNU 工具链、库函数等。
/virt:包含虚拟化相关的源代码,如 KVM、Xen 等。
yum install kernel-devel
linux下的Makefile文件
RAMDISK:定义了 RAM 磁盘设备的大小,单位是块。
AS86 和 LD86:分别定义了 as86 和 ld86 的命令行参数。
AS、LD、LDFLAGS、CC 和 CFLAGS:分别定义了 gas、gld、链接器参数、gcc 和编译器参数,用于编译和链接内核。
CPP:定义了 cpp 的命令行参数,用于预处理源代码。
ROOT_DEV:定义了默认的根设备,可以是软盘、/dev/xxxx 或空,如果为空,则使用默认的 /dev/hd6。
.c.s、.s.o 和 .c.o:定义了三个规则,用于将 C 源代码文件编译成汇编代码文件和目标文件。
all:定义了一个规则,用于编译内核镜像。
Image:定义了一个规则,用于生成内核镜像。
disk:定义了一个规则,用于将内核镜像写入软盘。
tools/build:定义了一个规则,用于编译 tools/build.c 文件。
boot/head.o:定义了一个规则,用于将 boot/head.s 文件编译成目标文件。
tools/system:定义了一个规则,用于生成内核系统。
kernel/math/math.a、kernel/blk_drv/blk_drv.a、kernel/chr_drv/chr_drv.a、kernel/kernel.o、mm/mm.o、fs/fs.o 和 lib/lib.a:分别定义了生成各个组件的规则。
boot/setup 和 boot/bootsect:分别定义了生成 boot/setup 和 boot/bootsect 的规则。
tmp.s:定义了一个规则,用于生成临时文件 tmp.s。
clean:定义了一个规则,用于清理生成的文件。
backup:定义了一个规则,用于备份文件。
dep:定义了一个规则,用于生成依赖关系。
BIOS 自检和 POST(Power-On Self-Test):计算机开机时,BIOS(Basic Input/Output System)会进行自检和 POST 操作,以确保硬件正常工作。
加载 bootloader:BIOS 会将控制权转移到 bootloader,例如 GRUB(GRand Unified Bootloader)或 LILO(LInux LOader),以加载 Linux 内核。
加载内核:bootloader 会读取内核映像文件(例如 vmlinuz),并将其加载到内存中。
初始化内核:内核启动后,会进行一系列的初始化操作,包括初始化进程、文件系统、设备驱动程序、网络等。
启动 init 进程:在内核初始化完成后,会启动 init 进程,init 进程是 Linux 系统中的第一个用户空间进程,它会读取配置文件(例如 /etc/inittab),并根据配置文件中的设置启动其他进程和服务。
用户登录:一旦 init 进程启动完成,用户就可以登录系统了。
Linux内核boot目录
bootsect.s:这个文件是启动扇区程序的一部分,它的主要作用是加载第一个扇区的代码,该代码将负责加载操作系统的内核文件。在 bootsect.s 中,主要完成了对硬件的初始化、对内存的检测和对内核文件的加载等操作。
head.s:这个文件是内核头文件的一部分,它的主要作用是为操作系统内核提供一个基本的环境,包括设置栈、清零 BSS 段、设置全局描述符表等。在系统启动时,head.s 会被加载到内存中,为内核的运行提供基础支持。
setup.s:这个文件是内核安装程序的一部分,它的主要作用是在系统引导时将内核文件加载到内存中,并为内核的运行提供必要的环境。在 setup.s 中,主要完成了对硬件的初始化、对内存的检测和对内核文件的加载等操作。setup.s 还会设置系统的根文件系统,并初始化系统的进程和文件系统等。
扇区程序
在计算机启动时,BIOS会读取磁盘的第一个扇区,也就是主引导记录(Master Boot Record,MBR),
其中包含了引导程序和分区表等信息。引导程序会加载操作系统的内核代码,并将控制权交给操作系统。
CPU工作模式
保护模式是一种CPU工作模式,它可以提供更高级的内存管理和保护机制,同时支持更大的内存寻址空间和更快的处理速度。
在保护模式下,CPU可以访问4GB以上的内存,使用32位或64位的寻址方式,同时支持多任务和虚拟内存等高级特性。
保护模式下,操作系统可以为每个进程分配独立的内存空间,从而实现进程间的隔离和保护。