深入解析Linux内核初始化过程

5星 · 超过95%的资源 需积分: 0 495 下载量 165 浏览量 更新于2024-07-31 8 收藏 1.4MB PDF 举报
"疯狂内核之——内核初始化" 在深入探讨Linux内核初始化的过程中,我们需要了解从硬件上电到操作系统完全启动的整个流程。本文主要分为五个部分,详细阐述了内核从创建到运行的各个关键阶段。 1. **引子**: - **上电**:计算机电源开启后,硬件开始进行自检(POST),然后进入基本输入输出系统(BIOS)。 - **BIOS时代**:BIOS执行硬件初始化,并根据用户设置加载启动设备的引导程序。 - **内核引导程序**:引导程序负责加载内核映像到内存并准备执行,如GRUB或LILO。 2. **内核映像的形成**: - **Makefile预备知识**:介绍了Makefile的书写规则、变量、条件判断、函数以及隐含规则和模式规则,这些都是构建内核的构建工具KBuild的基础。 - **KBuild体系**:讲解内核目标、主机程序和编译标志,以及如何通过Makefile进行递归编译、链接内核镜像(vmlinux)和制作可引导的bzImage。 3. **实模式下的内核代码**: - **内核映像内存布局**:内核映像在内存中的分布,包括不同部分如引导扇区、初始化数据等。 - **header.S**:实模式下的汇编代码,包括无用的bootsect代码,初始化头变量,为C语言环境做准备。 - **main函数**:实模式下的主要入口点,涉及复制初始化头变量,初始化堆,CPU支持检查,BIOS模式设置,内存检测,键盘配置,系统环境表填充,IST信息设置和视频模式设置。 - **go_to_protected_mode**:转换到保护模式的关键函数,包括禁止中断,打开A20线,安装临时GDT,以及第一次启动保护模式。 4. **保护模式下的内核代码**: - **32位x86保护模式**:内核解压缩前期工作,解压缩内核,第二次启动保护模式,首次启用分页管理和初始化0号进程。 - **向start_kernel进发**:涉及中断描述符表初始化,第三次启动保护模式,启动x86虚拟机。 5. **走向现代:start_kernel函数**: - **初始化同步与互斥环境**:包括中断屏蔽,大内核锁,时钟通知链,激活第一个CPU,地址散列,打印版本信息。 - **setup_arch**:拷贝可用内存区信息,计算总页面数,建立永久内核页表,二次启动分页,构建内存管理架构,以及其他初始化工作。 - **设置每CPU环境**,初始化内存管理区列表,使用early_res分配内存,初始化虚拟文件系统,异常服务,内存管理,调度程序,中断处理系统,包括APIC中断,本地软时钟,软中断,定时器中断等。 - **后start_kernel时代**:创建1号进程,子系统初始化,启动shell环境等,完成内核初始化的最后步骤。 本文详细阐述了从硬件启动到Linux内核完全初始化的复杂过程,涵盖从低级的实模式转换到保护模式,再到内核的高级功能初始化,为理解Linux内核的工作原理提供了深入洞察。对于想要深入研究操作系统内核设计和实现的读者来说,这是一份非常有价值的参考资料。
768 浏览量
目录 1 虚拟文件系统概述 5 1.1 通用文件模型 7 1.2 VFS所处理的系统调用 9 2 虚拟文件系统架构 11 2.1 VFS对象数据结构 11 2.1.1 超级块对象 11 2.1.2 索引节点对象 15 2.1.3 文件对象 18 2.1.4 目录项对象 22 2.2 把Linux中的VFS对象串联起来 24 2.2.1 与进程相关的文件 25 2.2.2 索引节点高速缓存 29 2.2.3 目录项高速缓存 30 2.2.4 VFS对象的具体实现 32 2.3 文件系统的注册与安装 38 2.3.1 文件系统类型注册 38 2.3.2 文件系统安装数据结构 41 2.3.3 安装普通文件系统 52 2.3.4 分配超级块对象 58 2.3.5 安装根文件系统 60 2.3.6 卸载文件系统 65 2.4 路径名的查找 66 2.4.1 查找路径名的一般流程 67 2.4.2 父路径名查找 82 2.4.3 符号链接的查找 84 2.5 VFS系统调用的实现 88 2.5.1 open()系统调用 88 2.5.2 read()和write()系统调用 96 2.5.3 close()系统调用 97 3 第二扩展文件系统 99 3.1 Ext2磁盘数据结构 101 3.1.1 磁盘超级块 102 3.1.2 组描述符和位图 105 3.1.3 磁盘索引节点表 105 3.2 VFS接口数据结构 110 3.2.1 Ext2 超级块对象 110 3.2.2 Ext2 的索引节点对象 121 3.2.3 创建Ext2文件系统 124 3.2.4 Ext2的方法总结 126 3.3 Ext2索引节点分配 129 3.3.1 创建索引节点 130 3.3.2 删除索引节点 143 3.4 Ext2数据块分配 144 3.4.1 数据块寻址 145 3.4.2 文件的洞 147 3.4.3 分配数据块 148 4 页面高速缓存 160 4.1 页高速缓存数据结构 160 4.1.1 address_space对象 161 4.1.2 基树 164 4.2 高速缓存底层处理函数 166 4.2.1 查找页 166 4.2.2 增加页 168 4.2.3 删除页 173 4.3 文件系统与高速缓存 175 4.3.1 缓冲头数据结构 175 4.3.2 分配块设备缓冲区页 178 4.3.3 释放块设备缓冲区页 184 4.4 在页高速缓存中搜索块 185 4.4.1 __find_get_block()函数 185 4.4.2 __getblk()函数 188 4.4.3 __bread()函数 190 4.5 把脏页写入磁盘 191 4.5.1 pdflush内核线程 192 4.5.2 搜索要刷新的脏页 193 4.5.3 回写陈旧的脏页 196 5 文件读写 199 5.1 系统调用VFS层的处理 200 5.2 第二扩展文件系统Ext2层的处理 201 5.2.1 Ext2的磁盘布局 202 5.2.2 Ext2的超级块对象 206 5.2.3 Ext2索引节点对象的创建 210 5.2.4 Ext2索引节点对象的读取 218 5.2.5 Ext2层读文件入口函数 225 5.3 页高速缓存层的处理 237 5.3.1 创建一个bio请求 238 5.3.2 得到文件的逻辑块号 244 5.3.3 普通文件的readpage方法 251 5.3.4 块设备文件的readpage方法 252 5.3.5 文件的预读 260 5.4 通用块层的处理 264 5.4.1 块设备的基础知识 265 5.4.2 通用块层相关数据结构 269 5.4.3 提交I/O传输请求 271 5.4.4 请求队列描述符 273 5.5 块设备I/O调度层的处理 281 5.5.1 块设备的初始化 284 5.5.2 建立块设备驱动环境 288 5.5.3 关联block_device结构 295 5.5.4 为设备建立请求队列 306 5.5.5 块设备I/O调度程序 311 5.5.6 真实的I/O调度层处理 321 5.6 块设备驱动层的处理 330 5.6.1 scsi总线驱动的初始化 330 5.6.2 scsi设备驱动体系架构 342 5.6.3 scsi块设备驱动层处理 347 5.6.4 scsi命令的执行 369 5.6.5 scsi命令的第一次转变 372 5.6.6 scsi命令的第二次转变 380 5.7 写文件 384 5.7.1 generic file_write函数 384 5.7.2 普通文件的prepare_write方法 386 5.7.3 块设备文件的prepare_write方法 387 5.7.4 将脏页写到磁盘 388 6 直接I/O与异步I/O 391 6.1 直接I/O 391 6.2 异步I/O 393 6.2.1 Linux 2.6中的异步I/O 394 6.2.2 异步I/O环境 394 6.2.3 提交异步I/O操作 395