《Linux操作系统预备知识课件.ppt》由会员分享,可在线阅读,更多相关《Linux操作系统预备知识课件.ppt(65页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、1Linux内核分析The Analysis of the Linux KernelLinux 操作系统分析2教材Linux内核源代码情景分析毛德操 胡希明著浙江大学出版社2001年9月第1版 Linux 操作系统分析3参考书目Linux Kernel 中文版,David A Rusling 著Linux 内核完全注释,赵炯著,www.oldlinux.org,2003 年1.2.2 修正版Linux 内核2.4 版源代码分析大全,李善平等著,机械工业出版社,2002 年1 月第1 版UNIX 操作系统设计,M J Bach 著,机械工业出版社,2001 年 现代操作系统 英文,Andrew
2、S.Tanenbaum 著,机械工业出版社,2002 年 动手写自己的操作系统,于渊编著,电子工业出版社,2005 年8 月Linux 操作系统分析4本课程需要的基础知识 具备操作系统的基础知识 具备C 语言程序设计的基础知识 粗通汇编语言编程 熟悉UNIX 用户界面,略知微机系统结构,尤其是保护模式,分段、分页机制。Linux 操作系统分析5第一章 预备知识 本章主要内容q Linux 内核的基础知识*为什么分析操作系统?*为个么选择Linux?*Linux 和Linux 内核的关系*Linux 的技术特点*Linux 内核的组成结构及版本*Linux 源代码的分析方法、工具q 其他相关基础
3、知识*Linux 内核源代码中的C 语言代码的特点*Linux 内核源代码中的汇编语言代码的特点*x86 的虚拟存储技术Linux 操作系统分析6为什么分析操作系统?分析操作系统的目的q 深入理解一个操作系统的内在机制及其实现机理q 学习系统软件的设计方法和实现技巧q 研究和分析制约操作系统性能的原因 不同于学习操作系统的使用q 普通用户学习通过操作界面使用操作系统q 程序设计者学习通过系统调用使用操作系统q 操作系统的设计目的就是为上述两类用户提供统一的使用方式Linux 操作系统分析7为什么选择分析Linux?从其发展历史看,它属于现在得到广泛应用的UNIX 家族,并已被大量用户认可和接受
4、 集中了全世界众多操作系统黑客的技术精华 在嵌入式和实时操作系统方面有大量的社会需求 源代码开放,容易获取并学习未来24个月嵌入式操作系统的应用调查(2000.9)Linux 操作系统分析8Linux内核的组成 存储管理 进程管理 设备管理 文件系统 进程间通信 网络Linux 操作系统分析9Linux的内核结构图Linux 操作系统分析10Linux内核源代码目录结构(1)arch 这个子目录包含了此核心源代码所支持的硬件体系结构相关的核心代码。如对于X86 平台就是x86。include 这个目录包括了核心的大多数include 文件。另外对于每种支持的体系结构分别有一个子目录。init
5、此目录包含核心启动代码。mm 此目录包含了所有的内存管理代码。与具体硬件体系结构相关的内存管理代码位于arch/*/mm 目录下,如对应于X86 的就是arch/x86/mm/fault.c。drivers 系统中所有的设备驱动都位于此目录中。它又进一步划分成几类设备驱动,每一种也有对应的子目录,如声卡的驱动对应于drivers/sound。ipc 此目录包含了核心的进程间通讯代码。Linux 操作系统分析11Linux内核源代码目录结构(2)modules 此目录包含已建好可动态加载的模块。fs Linux 支持的文件系统代码。不同的文件系统有不同的子目录对应,如ext2 文件系统对应的就是
6、ext2 子目录。kernel 主要核心代码。同时与处理器结构相关代码都放在arch/*/kernel 目录下。net 核心的网络部分代码。里面的每个子目录对应于网络的一个方面。lib 此目录包含了核心的库代码。与处理器结构相关库代码被放在arch/*/lib/目录下。scripts 此目录包含用于配置核心的脚本文件。Documentation 此目录是一些文档,起参考作用。Linux 操作系统分析12Linux内核源代码的获取方式 商业发行版本附带的发行版内核,通常不是最新的 官方网站:http:/www.kernel.org 中国自由软件库http:/(最新版)发行商网站q 大学网站q N
7、 操作系统分析13Linux源代码的阅读方法和工具(1)Linux 源代码的阅读方法q 阅读顺序*纵向,就是顺着程序的执行顺序逐步进行*横向,就是分模块进行*划分不绝对的,而是经常结合在一起进行q Linux 的启动的代码就可以顺着linux 的启动顺序一步一步地读,大致流程如下(以X86 平台为例):*./arch/x86/boot/bootSect.S*./arch/x86/boot/setup.S*./arch/x86/kernel/head.S*./init/main.c 中的start_kernel()q 对于内存管理等部分,可以单独拿出来按模块进行阅读分析。Linux 操作系统分析
8、14Linux 操作系统分析15Linux源代码的阅读方法和工具(2)q windows 环境下利用Source Insight 阅读工具可从http:/天试用版本q linux 环境下利用lxr(linux cross reference)或glimpse等阅读工具进行阅读 建议q 开始最好按顺序阅读启动代码q 然后进行专题阅读,如进程部分,内存管理部分等。在每个功能函数内部应该一步步来q 实际上这是一个反复的过程,不可能读一遍就理解Linux 操作系统分析16Source Insight软件使用方法 选择Project 菜单下的new,新建一个工程,输入工程名 把欲读的源代码加入(可以整个
9、目录加)后,该软件就分析你所加的源代码。分析完后,就可以进行阅读了。打开相要阅读的文件 如果想看某一变量的定义q 先把光标定位于该变量q 然后点击工具条上的相应选项或从右键菜单中选择q 该变量的定义就显示出来 对于函数的定义与实现也可以同样操作Linux 操作系统分析17Linux内核源代码的C语言代码(1)内核的主体是以GNU 的C 语言编写的,GNU 对C 语言本身在ANSI C 的基础上作了不少扩充 使用gcc 作为编译工具,gcc 同时又是C+编译工具q 内核具有很多C+语言的特点q gcc 从C+语言中吸收了inline 和const比define 更安全,如可定义数据类型等等q 内
10、核的版本与gcc 的版本间有依赖关系Long long int,用于支持64 位的CPU 结构 为了防止扩展的属性和保留字与变量名的冲突q“_ 保留字_”等价于“保留字”q attribute_(属性),如 aligned,packedLinux 操作系统分析18Gcc 从 C+语言中吸收了“inline”和“const”。其实,GNU 的 C 和 C+是合为一体的,gcc 既是 C 编译又是 C+编译,所以从 C+中吸收一些东西到 C 中是很自然的。从功能上说,inline 函数的使用与#define 宏定义相似,但更有相对的独立性,也更安全。使用 inline 函数也有利于程序调试。如果编
11、译时不加优化,则这些 inline 函数就是普通的,独立的函数,更便于调试。调试好以后,再采用优化重新编译一次,这些 inline 函数就像宏操作一样融入了引用处的代码中,有利于提高运行效率。由于 inline 函数的大量使用,相当一部分代码从.c 文件移入了.h 文件中。Linux 操作系统分析19Linux内核源代码的C语言代码(2)Do while(0)的作用q 使 之间的代码构成一个块q 执行空操作,如为进程切换作准备 举例 如果没有Do while(0)Linux 操作系统分析20Linux内核源代码的C语言代码(3)双链数据结构q 使得针对这些队列的操作可用于不同数据结构 宿主数据
12、结构举例Linux 操作系统分析21Linux内核源代码的C语言代码(4)宿主结构起始地址的定位 举例当前结构中list 的地址 当page 结构刚好位于地址0 时的list 地址Linux 操作系统分析22Linux内核中的汇编语言代码 为什么使用汇编语言?q C 语言没有对应的硬件操作语言,如inb,outb 等q C 语言没有对应的CPU 特殊指令,如开关中断、寄存器操作等q 提高时间效率,如系统调用的陷入或返回q 提高空间效率,如系统第一扇区的引导程序 由于Linux 使用的编译器是GNU 的gcc,所以源代码的汇编大多是GNU 汇编语言q GNU 采用的汇编语言是一种介于386 汇编
13、语言和C 语言之间的中间语言形式 Linux 源代码中汇编语言的使用形式q 完全汇编代码q 嵌在C 语言程序的汇编片断q 几个用于引导的Intel 格式的汇编语言程序AT&T 格式的GNU 汇编Linux 操作系统分析23GNU的x86汇编语言 按UNIX 领域的用户习惯,GNU 使用了AT&T 格式 AT&T 格式与Intel 格式的区别(教材P2223)q Intel 格式大多使用大写字母,而AT&T 格式则都使用小写字母q AT&T 格式中寄存器名要加“”前缀,而Intel 格式则不用q AT&T 格式的源操作数在前,而Intel 格式则是目标操作数据在前q AT&T 格式的命令用后缀b
14、、w、l 表示操作数精度,而Intel 格式则用操作数前缀“BYTE PTR”、”WORD PRT”、”DWORD PRT”q AT&T 格式的直接操作数用$作前缀,而Intel 格式则什么也不用q AT&T 格式的jump/call 的目标地址前要加上*号,而Intel 格式则不用Linux 操作系统分析24嵌在C语言中的汇编语言 要解决汇编中的寄存器和C 语言中的变量结合的问题 嵌在C 语言中的386 汇编语言程序段,一般由四部分构成(指令部:输出部:输入部:损坏部)q 指令部必须有,也就是汇编语言本身*其中的寄存器的样板操作数%0,%1 表示由gcc 指定通用寄存器*具体的寄存器前面就要
15、加上两个%q 输出部,规定对目标操作数如何结合的约束条件q 输入部,规定对源操作数如何结合的约束条件q 损坏部,对可能损坏的用于中间结果的寄存器的说明gcc 会在编译时自动加入保存所使用寄存器的语句,并在执行完汇编语句时将其恢复Linux 操作系统分析25X86系列的寻址方式 实地址模式q 寻址范围1MB(220),始用于16 位的8086 和8088q 用CS、DS、SS、ES 解决数据地址总线与ALU 宽度不一致问题q 有分段雏形,但不具备段的范围限长和特权级别等保护机制 保护模式q 始于286,完善于386。继承了实模式下的16 位寄存器q 直接寻址范围4GB(232),虚拟存储空间可达
16、64TB(246)q 提供了实现分段和分页的虚拟存储的硬件机制q 是操作系统实现多进程存储管理以及提供存储保护的硬件基础Linux 操作系统分析26Linux 的每个进程享有4GB 的内存空间,0-3GB 属于用户空间,3 4GB 属于内核空间,内核空间对常规内存、I/O 设备内存以及高端内存存在不同的处理方式。Linux 操作系统分析27如图3.4 所示,Linux 虚拟文件系统(VFS)隐藏各种了硬件的具体细节,为所有的设备提供了统一的接口。而且,它独立于各个具体的文件系统,是对各种文件系统的一个抽象,它使用超级块super block 存放文件系统相关信息,使用索引节点inode存放文件
17、的物理信息,使用目录项dentry 存放文件的逻辑信息。Linux 操作系统分析28X86的虚拟地址空间 为了支持分段机制,x86 把其虚拟地址空间分成大小不同的存储段 逻辑地址(又称虚拟地址)q 指令中访问存储空间的地址称为逻辑地址,它由选段符寄存器(14bit)和段内偏移地址合并确定(32bit)逻辑地址空间(又称虚拟地址空间)q 逻辑地址空间是由逻辑地址所确定的内存访问空间,也就是x86 的所有虚拟地址空间q 16 K 个段,每段最大4GB,逻辑地址空间共为64TB(246)Linux 操作系统分析29X86虚拟地址空间的划分x86 把逻辑地址空间分成性质不同的两部分:q 全局地址空间。
18、*由系统中所有进程共享,通常存放操作系统资源和共享数据*共8K 个段,最大空间32TBq 局部地址空间。*由各个进程自己使用,用于存储进程各自的代码和数据等。*共8K 个段,最大空间32TB 划分依据q 段选择符寄存器的TI 位q 全局地址空间和局部地址空间各占整个虚拟存储空间的一半,大小为32TBLinux 操作系统分析30选段符寄存器 Linux 操作系统分析31分段机制 将虚拟地址空间转换为线性地址空间q 为每个进程提供独立的4GB 的线性地址空间q 为进程内的不同段提供不同的操作权限Linux 操作系统分析32X86的线性地址空间 线性地址q 每个进程独自拥有的虚拟存储空间的地址q X
19、86 的线性由段选择符寄存器所指向的段描述符中规定的基地址(32bit)和段内偏移地址相加确定(32bit)线性地址空间(又称进程空间)q 线性地址所确定的空间为每个进程能够自己独立使用的存储空间,称为线性地址空间,或进程空间q X86 的线性地址空间的大小为4Gq 线性地址空间依然是虚拟存储空间q 操作系统的数据和代码被映射到所有进程的进程空间Linux 操作系统分析33X86线性地址空间的划分 每个进程的线性地址空间被分成q 系统区(0 级)q 用户区(3 级)系统区,用于存放操作系统的代码、数据和各种全局数据结构。用户区,用于存放进程的代码、数据、堆栈以及进程的各种数据结构Linux 操
20、作系统分析34分页机制 分页机制把线性地址转换为物理地址q 把物理内存和每个进程的线性空间分成大小为4KB 的页面q 实现两者之间页面的映射Linux 操作系统分析35x86的地址转换过程X86 设置专门的存储管理单元(MMU)负责将CPU给出的虚拟地址转换为对应的物理地址Linux 操作系统分析36MMU的位置和功能X86 的CPU 使用的是虚拟地址Linux 操作系统分析37MMU实现地址转换的过程Linux 操作系统分析38段描述符 分段机制中每个段的各种属性由段描述符(8Byte)来描述 段描述符分为两种q 系统段描述符(s=0)*用于特殊的系统段,如TSS 描述符,LDT 描述符等*
21、段描述符粒度位G 是0,表明系统段以字节为单位*系统段的最大空间为220个字节q 常规段描述符(s=1)*用于程序的数据段和代码段*如果段描述符粒度位G 是1,表明常规段以页面为单位*常规段的最大空间为220个页面Linux 操作系统分析39访问权限与type的定义Linux 操作系统分析40段描述符表(DT)段描述符作为表项存储在段描述符表DTq GDT,全局段存储在全局描述符表*GDT 由所有的进程共享,系统中只有一个GDT*GDT 的起始位置存放在寄存器GDTR,需要特权指令才能设置q LDT,局部段存储在局部描述符表*每个进程都有属于它的LDT*LDT 的起始位置存放在寄存器LDTR,
22、需要特权指令才能设置 段描述符表是特殊的段,所以系统的GDT 和各个进程的LDT 都存放在线性地址空间的特定区域内。Linux 操作系统分析41全局描述符表(GDT)GDT 中一般包括三种不同种类的描述符。q 系统内核代码段和数据段的描述符q 进程状态段(TSS)的描述符q LDT 描述符,偏移记录在TSS 中GDT 的最大空间为64KB,每个段描述符占8 个字节,所以正好可以放下8K 个全局段Linux 操作系统分析42GDTR寄存器GDTR 存放GDT 的起始位置,需要特权指令才能设置GDTR 寄存器的长度为48 位q 高32 位表示基地址(线性地址)q 低16 位表示GDT 的大小Lin
23、ux 操作系统分析43局部描述符表LDT 每个进程都有属于它的LDT 每个LDT 最大为216(64K)字节,每项大小为8 字节。即每个进程最多有的8k(216 8)个局部段第0段 NULL descriptor 第1段 用户态代码段 起始虚址0X00000000 段长3G字节 特权级3第2段 用户态数据段 起始虚址0X00000000 段长3G字节 特权级3Linux 操作系统分析44LDTR寄存器LDTR 寄存器的长度为64 位q 高16 位存储当前进程的LDT 的描述符在GDT 中的位置可通过特权指令设置q 后48 位为高速缓存,其中高32 位表示基地址,低16 位表示LDT 的大小Li
24、nux 操作系统分析45由LDTR确定LDT地址的过程Linux 操作系统分析46分段机制中地址的转换 分段机制中地址的转换过程q 与实模式相同,首先根据指令性质来确定应该使用哪一个段寄存器q 根据段寄存器的内容,找到相应的“地址段描述结构”q 从地址段描述结构中得到基地址q 将指令中发出的地址作为位移,与段描述结构中规定的段长度相比,检查是否越界q 根据指令的性质和段描述符中的访问权限来确定是否越权q 将指令中发出的地址作为位移,与基地址相加而得出实际的“物理地址”(线性地址)使用与寄存器对应的“影子”结构缓存相应的段描述符q 增加安全性q 加快地址转换速度Linux 操作系统分析47带有高
25、速缓存的选段符寄存器Linux 操作系统分析48x86的平面地址 相对于“段寄存器/偏移量”的“层次”结构,符合以下条件的地址称为“平面(flat)地址”q 每个段描述符的基地址设为0q 每个段的长度设置为最大(4GB)Linux 的内存管理采用平面地址,这是由gcc 编译器决定的 平面地址并没有绕过段描述符、段寄存器这样的段式内存管理机制,而只是这一机制的一个应用特例Linux 操作系统分析49分页机制 分页机制把线性地址转换为物理地址q 把物理内存和每个进程的线性空间被划分成分成大小为4KB 的页面,q 每个页面的高20 位为页面序号,起始地址的低12 位为0q 为了程序能够运行,为线性空
26、间的页面在物理内存中找一物理页面对应,并记录其页面序号之间的对应关系q 相互对应两页面的页内地址偏移(低12 位地址)相同 进程的线性空间的分页q 每个进程4GB 的线性地址空间可划分成1M 个页面 物理内存的分页q 根据物理内存的实际大小划分成若干个页面Linux 操作系统分析50控制寄存器(CR)组Linux 操作系统分析51线性空间的两级分组4GB 直接分成4KB 需要页表有1M 个表项 两级分组q 首先将4GB 空间划分成1K 个4MB 的块,由页表目录描述q 再将每个4MB 的块划分成1K 个4KB 的页,由页表描述32 位的线性地址被划分成三部分q 页表目录偏移地址(10bit),
27、即块号q 页表偏移地址(10bit),即块中的页号q 页内偏移地址(12bit)线性空间页号Linux 操作系统分析52两级页表结构 页表目录和页表都必需保存在物理地址空间 页表目录表、页表和页面的大小均为4KB 每个页表目录表和页表各有1024 个表项Linux 操作系统分析53页表目录表 每个进程设置一个页表目录表q 包括1024 个表项。每个表项是4 字节,指向一个页表q 页表目录表大小为4KB 页表目录表的表项结构Linux 操作系统分析54页表 每进程最多可有1024 个页表q 每个页表有1024 表项,每个表项的长度是4 字节,指向一个物理页面q 每个页表的大小为4KB 页表的表项
28、结构q AVL 供操作系统自行定义使用。q A 访问位 A=1 表示页表或页面已被访问过,q U/S 用户/系统访问权限位U/S=1 表示用户访问级,U/S=0 表示系统访问级。q W/R 读/写保护位,W/R=1 表示允许写入和读取,W/R=0 表示不允许写入,仅允许读取。q D 修改位 D=1 表示该页面已被修改过,q P 存在位,P=1 表示该页表或页面在物理存储器中,Linux 操作系统分析55线性地址到物理地址的转换Linux 操作系统分析56页面高速缓存寄存器 为了降低页目录和页表的查询次数而设置 缓存32 项CPU 最近使用的线性页面对应的物理页面号,平均可达98 的命中率。Li
29、nux 操作系统分析57x86的多任务机制 为了使CPU 可以快速地从一个任务切换到另一个任务,x86 设置了q 任务状态段TSS存储CPU 管理一个任务时所需的各种信息q 任务寄存器TR对过指向TSS 来快速确定当前执行的任务有16 位的可见部分,表示TSS 在GDT 中的偏移有不可见部分,缓存当前TSS 的基地址和限长Linux 操作系统分析58任务状态段TSS的内容Linux 操作系统分析59Linux 设备驱动入门Linux 操作系统分析60Linux 操作系统分析61Linux 操作系统分析62Linux 操作系统分析63Linux 操作系统分析64网络接口提供了对各种网络的标准的存取和各种网络硬件的支持。网络接口可分为网络协议和网络驱动程序,网络协议部分负责实现每一种可能的网络传输协议,网络设备驱动程序负责与硬件设备进行通信,每一种可能的硬件设备都有相应的设备驱动程序。Linux 操作系统分析65Linux 操作系统分析