Linux内核剖析入门针对很多Linux爱好者对内核很有兴趣却无从下口,本文致力介绍一种剖析linux核源码的入门方式,而不是解说linux复杂的内核机制;一.核心源程序的文件组织:1.Linux核心源程序一般都安装在/usr/src/linux下,但是它有一个特别简单的编号约定:任何质数的核心(比如2.0.30)都是一个稳定地发行的核心,而任何质数的核心(比如2.1.42)都是一个开发中的核心。本文基于稳定的2.2.5源代码,第二部份的实现平台为RedhatLinux6.02.核心源程序的文件按树状结构进行组织,在源程序树的最下层你会看见这样一些目录:Arch:arch子目录包括了所有和体系结构相关的核心代码。它的每一个子目录都代表一种支持的体系结构,比如i386就是关于intelcpu及与之相兼容体系结构的子目录。PC机通常都基于此目录;Include:include子目录包括编译核心所须要的大部份头文件。与平台无关的头文include/linux子目录下,与intelcpu相关的头文件在include/asm-i386子目录下,include/scsi目录则是有关scsi设备的头文件目录;Init:这个目录包含核心的初始化代码Version.c,这是研究核心怎样工作的一个特别好的起点。

Mm:这个目录包括所有独立于cpu体系结构的显存管理代码,如页式储存管理显存的分配和释放等;而和体系结构相关的显存管理代码则坐落arch/*/mm/,比如arch/i386/mm/Fault.cKernel:主要的核心代码,此目录下的文件实现了大多数linux的内核函数,其中最重要的文件当属sched.c;同样,和体系结构相关的代码在arch/*/kernel每种驱动程序又各占用一个子目录:如linux 内核文件全分析,/block下为块设备驱动程序,例如ide(ide.c)。假如你希望查看所有可能包含文件系统的设备是怎样初始化的,你可以看drivers/block/genhd.cdevice_setup()。它除了初始化硬碟,也初始化网路,由于安装nfs文件系统的时侯须要网路其他Lib放置核心的库代码Net,核心与网路相关的代码Ipc,这个目录包含核心的进程间通信的代码所有的文件系统代码和各种类型的文件操作代码,它的每一个子目录支持一个文件系统,比如fatext2;Scripts,此目录包含用于配置核心的文件等。通常,在每位目录下,都有一个.depend文件和一个Makefile文件,这两个文件都是编译时使用的辅助文件,仔细阅读这两个文件对弄清各个文件这间的联系和依托关系很有帮助;并且,在有的目录下还有Readme文件,它是对该目录下的文件的一些说明,同样有利于我们对内核源码的理解;二.剖析实战:为你的内核降低一个系统调用其实,Linux的内核源码用树状结构组织得十分合理、科学,把功能相关联的文件都置于同一个子目录下,这样促使程序更具可读性。

但是,Linux的内核源码实在是太大并且十分复杂,虽然采用了很合理的文件组织方式linux 内核文件全分析,在不同目录下的文件之间还是有好多的关联,剖析核心的一部份代码一般会要查看其它的几个相关的文件,但是可能这种文件还不在同一个子目录下。体系的庞大复杂和文件之间关联的纷繁复杂,可能就是好多人对其望而生畏的主要诱因。其实,这些令人生畏的劳动所带来的回报也是十分令人着迷的:你除了可以从小学到好多的计算机的底层的知识(如下边将提到的系统的引导),感受到整个操作系统体系结构的精妙和在解决某个具体细节问题时,算法的巧妙;并且更重要的是:在源码的剖析过程中,你都会被一点一点地、潜移默化地专业化;甚至,只要剖析非常之一的代码后,你还会深刻地感受到,哪些样的代码才是一个专业的程序员写的,哪些样的代码是一个业余爱好者写的。为了使读者能更好的感受到这一特性,下边举了一个具体的内核剖析实例,希望能通过这个实例,使读者对Linux的内核的组织有些具体的认识,从中读者也可以学到一些对内核的剖析技巧。以下即为剖析实例:【一】操作平台硬件:cpuintelPentiumII软件:RedhatLinux6.0;内核版本2.2.5【二】相关内核源代码剖析1.系统的引导和初始化:Linux系统的引导有好几种方法:常见的有Lilo,Loadin引导和Linux的自举引导(bootsect-loader而前者所对应源程序为arch/i386/boot/bootsect.S,它为实模式的汇编程序linux系统入门学习,限于篇幅在此不做剖析;无论是哪种引导方法,最后都要跳转到arch/i386/Kernel/setup.Ssetup.S主要是进行时模式下的初始化linux系统入门学习,为系统步入保护模式做打算;随后,系统执行arch/i386/kernel/head.S对经压缩后储存的内核要先执行arch/i386/boot/compressed/head.S);head.S中定义的一段汇编程序setup_idt,它负责构建一张256idt表(InterruptDescriptorTable),其中包括系统调用总控程序system_call的入口地址;其实,除此之外,head.S还要做一些其他的初始化工作;2.系统初始化后运行的第一个内核程序asmlinkagevoid__initstart_kernel(void)定义在/usr/src/linux/init/main.c它通过调用usr/src/linux/arch/i386/kernel/traps.c中的一个函数void__inittrap_init(void)把各自陷和中断服务程序的入口地址设置到idt其中系统调用总控程序system_cal就是中断服务程序之一;void__inittrap_init(void)函数则通过调用一个宏set_system_gate(SYSCALL_VECTOR,&system_call);把系统调用总控程序的入口挂在中断0x80其中SYSCALL_VECTOR是定义在/usr/src/linux/arch/i386/kernel/irq.hsystem_call即为中断总控程序的入口地址中断总控程序用汇编语言定义在/usr/src/linux/arch/i386/kernel/entry.S并依据系统调用向量,使处理机跳转到保存在sys_call_table表中的相应系统服务类库的入口而系统调用向量则定义在/usr/src/linux/include/asm-386/unistd.hsys_call_table表定义在/usr/src/linux/arch/i386/kernel/entry.S同时在/usr/src/linux/include/asm-386/unistd.h中也定义了系统调用的用户编程插口linux的系统调用也象dos系统的int21h中断服务它把0x80之后转入保存在sys_call_table表中的各类中断服务类库的入口地址要降低一个系统调用就必须在sys_call_table表中降低一并在其中保存好自己的系统服务类库的入口地址,之后重新编译内核,其实,系统服务类库是必不可少的。

由此可知在此版linux内核源程序中,与系统调用相关的源程序文件就包括以下这种1.arch/i386/boot/bootsect.S2.arch/i386/Kernel/setup.S3.arch/i386/boot/compressed/head.S4.arch/i386/kernel/head.S5.init/main.c6.arch/i386/kernel/traps.c7.arch/i386/kernel/entry.S8.arch/i386/kernel/irq.h9.include/asm-386/unistd.h其实,这只是涉及到的几个主要文件。而事实上,降低系统调用真正要更改文件只有include/asm-386/unistd.harch/i386/kernel/entry.S两个;kernel/sys.c中降低系统服务类库如下:asmlinkageintsys_addtotal(intnumdata)inti=0,enddata=0;while(i

linux 内核文件全分析_linux内核源代码情景分析(下册)_linux 内核文件全分析

本文原创地址://lrxjmw.cn/yzjdlhymdrmf.html编辑:刘遄,审核员:暂无