140 likes | 262 Views
主要内容. Linux 内核源代码的获取方式 Linux 源代码的阅读方法和工具 Source Insight 软件使用方法 Linux 内核源代码目录结构 Linux 内核源代码的 C 语言代码 Linux 内核中的汇编语言代码. Linux 内核源代码的获取方式. 商业发行版本附带的发行版内核,通常不是最新的 官方网站: http://www.kernel.org 中国自由软件库 http://freesoft.cei.gov.cn (最新版) 发行商网站 www.redhat.com 大学网站
E N D
主要内容 • Linux内核源代码的获取方式 • Linux源代码的阅读方法和工具 • Source Insight软件使用方法 • Linux内核源代码目录结构 • Linux内核源代码的C语言代码 • Linux内核中的汇编语言代码 Linux操作系统分析
Linux内核源代码的获取方式 • 商业发行版本附带的发行版内核,通常不是最新的 • 官方网站: http://www.kernel.org • 中国自由软件库http://freesoft.cei.gov.cn(最新版) • 发行商网站 • www.redhat.com • 大学网站 • ftp.cis.nctu.edu.cn/Linux/kernel • Nctuccca.edu.cn/OS/Linux/kernel Linux操作系统分析
Linux源代码的阅读方法和工具(1) • Linux源代码的阅读方法 • 阅读顺序 • 纵向,就是顺着程序的执行顺序逐步进行 • 横向,就是分模块进行 • 划分不绝对的,而是经常结合在一起进行 • Linux的启动的代码就可以顺着linux的启动顺序一步一步地读,大致流程如下(以X86平台为例): • ./arch/x86/boot/bootSect.S • ./arch/x86/boot/setup.S • ./arch/x86/kernel/head.S • ./init/main.c中的start_kernel() • 对于内存管理等部分,可以单独拿出来按模块进行阅读分析。 Linux操作系统分析
Linux源代码的阅读方法和工具(2) • windows环境下利用Source Insight阅读工具 • 可从http://www.sourceinsight.com/上边下载30天试用版本 • linux环境下利用lxr(linux cross reference)或glimpse等阅读工具进行阅读 • 建议 • 开始最好按顺序阅读启动代码 • 然后进行专题阅读,如进程部分,内存管理部分等。在每个功能函数内部应该一步步来 • 实际上这是一个反复的过程,不可能读一遍就理解 Linux操作系统分析
Source Insight软件使用方法 • 选择Project菜单下的new,新建一个工程,输入工程名 • 把欲读的源代码加入(可以整个目录加)后,该软件就分析你所加的源代码。分析完后,就可以进行阅读了。 • 打开相要阅读的文件 • 如果想看某一变量的定义 • 先把光标定位于该变量 • 然后点击工具条上的相应选项或从右键菜单中选择 • 该变量的定义就显示出来 • 对于函数的定义与实现也可以同样操作 Linux操作系统分析
Linux内核源代码目录结构(1) • arch 这个子目录包含了此核心源代码所支持的硬件体系结构相关的核心代码。如对于X86平台就是x86。 • include 这个目录包括了核心的大多数include文件。另外对于每种支持的体系结构分别有一个子目录。 • init 此目录包含核心启动代码。 • mm 此目录包含了所有的内存管理代码。与具体硬件体系结构相关的内存管理代码位于arch/*/mm目录下,如对应于X86的就是arch/x86/mm/fault.c 。 • drivers 系统中所有的设备驱动都位于此目录中。它又进一步划分成几类设备驱动,每一种也有对应的子目录,如声卡的驱动对应于drivers/sound。 • ipc 此目录包含了核心的进程间通讯代码。 Linux操作系统分析
Linux内核源代码目录结构(2) • modules 此目录包含已建好可动态加载的模块。 • fs Linux支持的文件系统代码。不同的文件系统有不同的子目录对应,如ext2文件系统对应的就是ext2子目录。 • kernel 主要核心代码。同时与处理器结构相关代码都放在arch/*/kernel目录下。 • net 核心的网络部分代码。里面的每个子目录对应于网络的一个方面。 • lib 此目录包含了核心的库代码。与处理器结构相关库代码被放在arch/*/lib/目录下。 • scripts此目录包含用于配置核心的脚本文件。 • Documentation 此目录是一些文档,起参考作用。 Linux操作系统分析
Linux内核源代码的C语言代码(1) • 内核的主体是以GNU的C语言编写的, GNU对C语言本身在ANSI C的基础上作了不少扩充 • 使用gcc作为编译工具,gcc同时又是C++编译工具 • 内核具有很多C++语言的特点 • gcc从C++语言中吸收了inline和const • 比define更安全,如可定义数据类型等等 • 内核的版本与gcc的版本间有依赖关系 • Long long int,用于支持64位的CPU结构 • 为了防止扩展的属性和保留字与变量名的冲突 • “__保留字__”等价于“保留字” • attribute__((属性)),如 aligned, packed Linux操作系统分析
Linux内核源代码的C语言代码(2) • Do {…}while(0)的作用 • 使{}之间的代码构成一个块 • 执行空操作,如为进程切换作准备 • 举例 • 如果没有Do {…}while(0) Linux操作系统分析
Linux内核源代码的C语言代码(3) • 双链数据结构 • 使得针对这些队列的操作可用于不同数据结构 • 宿主数据结构举例 Linux操作系统分析
Linux内核源代码的C语言代码(4) • 宿主结构起始地址的定位 • 举例 • 当前结构中list的地址 – 当page结构刚好位于地址0时的list地址 Linux操作系统分析
Linux内核中的汇编语言代码 • 为什么使用汇编语言? • C语言没有对应的硬件操作语言,如inb,outb等 • C语言没有对应的CPU特殊指令,如开关中断、寄存器操作等 • 提高时间效率,如系统调用的陷入或返回 • 提高空间效率,如系统第一扇区的引导程序 • 由于Linux使用的编译器是GNU的gcc,所以源代码的汇编大多是GNU汇编语言 • GNU采用的汇编语言是一种介于386汇编语言和C语言之间的中间语言形式 • Linux源代码中汇编语言的使用形式 • 完全汇编代码 • 嵌在C语言程序的汇编片断 • 几个用于引导的Intel格式的汇编语言程序 AT&T格式的GNU汇编 Linux操作系统分析
GNU的x86汇编语言 • 按UNIX领域的用户习惯,GNU使用了AT&T格式 • AT&T格式与Intel格式的区别 • Intel格式大多使用大写字母,而AT&T格式则都使用小写字母 • AT&T格式中寄存器名要加“%”前缀,而Intel格式则不用 • AT&T格式的源操作数在前,而Intel格式则是目标操作数据在前 • AT&T格式的命令用后缀b、w、l表示操作数精度,而Intel格式则用操作数前缀“BYTE PTR”、”WORD PRT”、 ”DWORD PRT” • AT&T格式的直接操作数用$作前缀,而Intel格式则什么也不用 • AT&T格式的jump/call的目标地址前要加上*号,而Intel格式则不用 Linux操作系统分析
嵌在C语言中的汇编语言 • 要解决汇编中的寄存器和C语言中的变量结合的问题 • 嵌在C语言中的386汇编语言程序段,一般由四部分构成(指令部:输出部:输入部:损坏部) • 指令部必须有,也就是汇编语言本身 • 其中的寄存器的样板操作数%0,%1表示由gcc指定通用寄存器 • 具体的寄存器前面就要加上两个% • 输出部,规定对目标操作数如何结合的约束条件 • 输入部,规定对源操作数如何结合的约束条件 • 损坏部,对可能损坏的用于中间结果的寄存器的说明 • gcc会在编译时自动加入保存所使用寄存器的语句,并在执行完汇编语句时将其恢复 Linux操作系统分析