第15章解析Linux内核_第1页
第15章解析Linux内核_第2页
第15章解析Linux内核_第3页
第15章解析Linux内核_第4页
第15章解析Linux内核_第5页
已阅读5页,还剩52页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第15章解析Linux内核第一页,共57页。15.1基本知识15.1.1什么是Linux内核15.1.2Linux内核版本15.1.3如何获取Linux内核代码15.1.4编译内核第二页,共57页。15.1.1什么是Linux内核内核是操作系统的核心部分,为应用程序提供安全访问硬件资源的功能。直接操作计算机硬件是很复杂的,内核通过硬件抽象的方法屏蔽了硬件的复杂性和多样性。通过硬件抽象的方法,内核向应用程序提供了统一和简洁的接口,应用程序设计复杂程度降低。Linux内核最早是芬兰大学生LinusTorvalds由于个人兴趣编写的,并且在1991年发布。从Linux0.12版本开始,使用GNU()的GPL(通用公共许可协议)自由软件许可协议。第三页,共57页。15.1.2Linux内核版本Linux内核版本号采用两个“.”分割的3个数字来标示,形式为X.Y.Z。其中,X是主要版本号,Y是次要版本号,Z代表补丁版本号。奇数代表不稳定的版本;偶数代表稳定的版本。第四页,共57页。15.1.3如何获取Linux内核代码Linux内核代码的官方站点是。下载Linux内核代码后,会得到一个类似linux-2.6.xx.tar.gz或者linux-2.6.xx-tar.bz2形式的压缩文件,xx代表版本号。在Linux系统上,通常把这个文件存放在/usr/src目录下,便于以后使用。第五页,共57页。15.1.4编译内核内核编译主要分成配置和编译两部分,其中配置是关键,许多问题都是出在配置环节。Linux内核编译配置提供多种方式:makeconfig:基于传统的文本界面配置方式;makemenuconfig:基于文本模式下的图形选单界面;makexconfig:基于图形窗口模式的配置界面;makeoldconfig:导入已有的配置。第六页,共57页。15.2Linux内核的子系统15.2.1系统调用接口15.2.2进程管理子系统15.2.3内存管理子系统15.2.4虚拟文件系统15.2.5网络堆栈15.2.6设备驱动15.2.7依赖体系结构的代码第七页,共57页。15.2.1系统调用接口用户程序通过软件中断后,调用系统内核提供的功能,这个在用户空间和内核提供的服务之间的接口称为系统调用。第八页,共57页。15.2.2进程管理子系统Linux内核通过进程管理子系统实现了进程有关的操作。Linux系统是一种动态系统,通过进程管理能够适应不断变化的计算需求。在一个系统上可以有多个进程,但是一般情况下只有一个CPU,在同一个时刻只能有一个进程在工作,即使有多个CPU,也不可能和进程的数量一样多。如果让若干的进程都能在CPU上工作,这就是进程管理子系统的工作。第九页,共57页。15.2.3内存管理子系统Linux内核的内存管理子系统管理虚拟内存与物理内存之间的映射关系,以及系统可用内存空间。为了解决物理内存被耗尽的问题,内存管理子系统规定页面可以移出内存并放入磁盘中,这个过程称为交换。第十页,共57页。15.2.4虚拟文件系统虚拟文件系统屏蔽了不同文件系统间的差异,向用户提供了统一的接口。虚拟文件系统,即VFS(Virtual)是Linux内核中的一个软件抽象层。通过使用同一套文件I/O系统调用即可对Linux中的任意文件进行操作而无须考虑其所在的具体文件系统格式;更进一步,文件操作可以在不同文件系统之间进行。第十一页,共57页。15.2.5网络堆栈socket相关的函数也是通过内核的子系统完成的,担当这部分任务的是内核的网络子系统,一些资料里也把这部分代码称为“网络堆栈”。Linux的网络堆栈部分沿袭了传统的层次结构,网络数据从用户进程到达实际的网络设备需要4个层次。Linux内核网络子系统定义了4个实体:网络协议套接字设备接口网络缓冲区第十二页,共57页。15.2.6设备驱动Linux内核把设备分成3类:块设备、字符设备和网络设备。Linux内核对设备按照主设备号和从设备号的方法访问,主设备号描述控制设备的驱动程序,从设备号区分同一个驱动程序的不同设备。第十三页,共57页。15.2.7依赖体系结构的代码Linux内核支持众多体系结构,内核把与设备无关的代码放在arch目录下,对应的头文件放在include/asm-<体系名称>目录下。在arch目录里,每个子目录对应一种体系结构,存放这种体系结构对应的代码。第十四页,共57页。15.3Linux内核代码的工程结构15.3.1源代码目录布局15.3.2几个重要的Linux内核文件第十五页,共57页。15.3.1源代码目录布局目录名称作

用arch这个子目录包含了此核心源代码所支持的硬件体系结构相关的核心代码。如对于X86平台就是i386include这个目录包括了核心的大多数include文件。另外对于每种支持的体系结构分别有一个子目录init此目录包含核心启动代码mm此目录包含了所有的内存管理代码。与具体硬件体系结构相关的内存管理代码位于arch/*/mm目录下,如对应于X86的就是arch/i386/mm/fault.cdrivers系统中所有的设备驱动都位于此目录中。它又进一步划分成几类设备驱动,每一种也有对应的子目录,如声卡的驱动对应于drivers/soundipc此目录包含了核心的进程间通信代码modules此目录包含已建好可动态加载的模块fsLinux支持的文件系统代码。不同的文件系统由不同的子目录对应,如ext2文件系统对应的就是ext2子目录kernel主要核心代码。同时与处理器结构相关代码都放在arch/*/kernel目录下net核心的网络部分代码。里面的每个子目录对应于网络的一个方面lib此目录包含了核心的库代码。与处理器结构相关库代码被放在arch/*/lib/目录下scripts此目录包含用于配置核心的脚本文件Documentation此目录是一些文档,起参考作用第十六页,共57页。15.3.2几个重要的Linux内核文件当用户编译一个Linux内核代码后,会生成几个文件:vmlinuz、initrd.img,以及System.map,如果读者配置过grub引导管理器程序,会在/boot目录下看到这几个文件。1.vmlinuz文件2.initrd文件3.System.map文件第十七页,共57页。1.vmlinuz文件vmlinuz文件是可引导的、压缩的内核文件,该文件仅包含了一个最小功能的内核,在PC上通常是先执行vmlinuz,之后加载initrd.img文件,最后加载根分区。第十八页,共57页。2.initrd文件initrd是initialramdisk的缩写,就是由Bootloader初始化的内存盘。在Linux内核启动之前,Bootloader会把存储介质(例如闪存)中的initrd文件加载到内存,内核启动时会在访问到真正的根文件系统前访问内存中的initrd文件系统。如果Bootloader配置了initrd,内核启动被分成两个阶段:第一阶段先加载initrd文件系统中的驱动程序模块;第二阶段才会执行真正的根文件系统中的/sbin/init进程。第十九页,共57页。3.System.map文件System.map是内核符号表,对应一个内核vmlinuz映像。System.map文件是通过nmvmlinux命令生成的。在进行程序设计的时候,会命名变量和函数,在编译以后会生成符号表。Linux内核也会生成符号表,但是Linux工作的时候并不使用这些符号表,而是通过地址来标识变量或者函数的。第二十页,共57页。15.4内核编译系统15.4.1内核编译系统基本架构15.4.2内核顶层Makefile分析15.4.3内核编译文件分析15.4.4目标文件清除机制15.4.5编译辅助程序15.4.6KBuild变量第二十一页,共57页。15.4.1内核编译系统基本架构Linux内核编译系统有5种类型的文件,请参考表。文件类型作

用Makefile顶层Makefile文件.config内核配置文件arch/$(ARCH)/Makefile机器体系Makefile文件scripts/Makefile.*所有内核Makefiles共用规则kbuildMakefiles其他Makefile文件第二十二页,共57页。15.4.2内核顶层Makefile分析内核编译一般会按照7个大步骤执行:(1)配置内核,产生.config配置文件;(2)保存内核版本到include/linux/version.h文件中;(3)建立符号链接到include/asmtoinclude/asm-$(ARCH);(4)更新定义在arch/$(ARCH)/Makefile所有目标对象的前提文件;(5)递归进入init-*

core*

drivers-*

net-*

libs-*中的所有子目录和编译所有的目标对象;(6)链接所有的object文件生成vmlinux文件,并且复制到内核代码根目录下。最开始链接的几个object文件列举在arch/$(ARCH)/Makefile文件的head-y变量中;(7)最后体系Makefile文件定义编译后期处理规则和建立最终的引导映像bootimage,包括创建引导记录,准备initrd映像和相关处理等。第二十三页,共57页。1.设置变量顶层Makefile定义了一些编译内核基本的变量,也是公共用到的变量。LDFLAGS变量LDFLAGS_MODULE变量LDFLAGS_vmlinux变量OBJCOPYFLAGS变量AFLAGS变量CFLAGS变量第二十四页,共57页。2.增加预设置项在开始进入子目录编译之前需要调用prepare规则生成编译需要的前提文件。前提文件是包含汇编常量的头文件。#arch/s390/Makefileprepare:include/asm-$(ARCH)/offsets.h第二十五页,共57页。3.目录表顶层Makefile定义了所有通用目录,arch/$(ARCH)/Makefile文件只需增加体系相关的目录。#arch/sparc64/Makefilecore-y+=arch/sparc64/kernel/libs-y+=arch/sparc64/prom/arch/sparc64/lib/drivers-$(CONFIG_OPROFILE)+=arch/sparc64/oprofile/第二十六页,共57页。4.引导映像Makefile文件定义了编译vmlinux目标文件需要的代码文件,将它们压缩和封装成引导代码,并复制到合适的位置。这包括各种安装命令。如何定义实际的目标对象无法为所有的体系结构提供标准化的方法。处理过程常位于arch/$(ARCH)/下的boot/目录下。第二十七页,共57页。5.编译非内核目标extra-y定义了在当前目录下创建没有在obj-*定义的附加的目标文件。使用extra-y列举目标有两个目的:一个是内核编译系统在命令行中检查变动情况,另一个是向makeclean提供删除的文件列表。#arch/i386/kernel/Makefileextra-y:=head.oinit_task.o第二十八页,共57页。6.编译引导映像命令Kbuild提供了编译内核需要的宏。if_changed是后面命令使用的基础。用法如下:target:source(s)FORCE$(callif_changed,ld/objcopy/gzip)第二十九页,共57页。7.定制编译命令当执行带KBUILD_VERBOSE=0参数的编译命令时,会显示简短的命令提示。如果用户定制的命令需要这种功能需要设置如下两个变量:quiet_cmd_<command>

//存放将被显示的内容cmd_<command>

//被执行的命令第三十页,共57页。8.预处理链接脚本当编译vmlinux映像时将使用arch/$(ARCH)/kernel/vmlinux.lds链接脚本。相同目录下的vmlinux.lds.S文件是这个脚本的预处理的变体。内核编译系统知晓.lds文件并使用规则*lds.S->*lds。#arch/i386/kernel/Makefilealways:=vmlinux.lds#MakefileexportCPPFLAGS_vmlinux.lds+=-P-C-U$(ARCH)第三十一页,共57页。15.4.3内核编译文件分析Linux内核代码使用KBuild作为Makefile的基础架构。Kbuild定义了若干的内置变量。1.目标定义2.内嵌对象-obj-y3.可加载模块-obj-m4.导出符号目标5.库文件-lib-y6.目录递归7.编译标记8.依赖关系9.特殊规则10.$(CC)支持功能第三十二页,共57页。1.目标定义Makefile文件的核心是目标定义。目标定义的主要功能是定义如何编译文件、设置编译选项以及递归子目录的方法等。在使用Kbuild架构的Makefile文件里,最简单的Makefile可以只包含一行配置:obj-y+=foo.o第三十三页,共57页。2.内嵌对象-obj-y$obj-y是用于存放编译生成vmlinux的目标文件的列表,列表的内容由内核编译配置决定。Kbuild编译$(obj-y)列表内的所有文件,之后使用“$(LD)–r”命令把目标文件打包到built-in.o一个文件中。built-in.o文件最终被链接到vmlinux目标文件。第三十四页,共57页。3.可加载模块-obj-m$(obj-m)表示对象文件(objectfiles)编译成可加载的内核模块。一个模块可以通过一个源文件或几个源文件编译而成。Makefile只需简单地把它们加到$(obj-m)。#drivers/isdn/i4l/Makefileobj-$(CONFIG_ISDN_PPP_BSDCOMP)+=isdn_bsdcomp.o第三十五页,共57页。4.导出符号目标在Makefile文件中没有特别导出符号的标记。第三十六页,共57页。5.库文件-lib-yobj-*中的object文件用于模块或built-in.o编译。object文件也可能编译到库文件中--lib.a。所有罗列在lib-y中的object文件都将编译到该目录下的一个单一的库文件中。包含在0bj-y中的object文件如果也列举在lib-y中将不会包含到库文件中,因为它们不能被访问。但lib-m中的object文件将被编译进lib.a库文件。第三十七页,共57页。6.目录递归Makefile文件负责编译当前目录下的目标文件,子目录中的文件由子目录中的Makefile文件负责编译。编译系统将使用obj-y和obj-m自动递归编译各个子目录中文件。如果ext2是一个子目录,fs目录下的Makefile将使用以下赋值语句编译系统编译ext2子目录。例如:#fs/Makefileobj-$(CONFIG_EXT2_FS)+=ext2/第三十八页,共57页。7.编译标记所有的EXTRA_变量只能使用在定义该变量后的Makefile文件中。EXTRA_变量被Makefile文件所有的执行命令语句所使用。$(EXTRA_CFLAGS)是使用$(CC)编译C文件的选项。#drivers/sound/emu10k1/MakefileEXTRA_CFLAGS+=-I$(obj)ifdefDEBUGEXTRA_CFLAGS+=-DEMU10K1_DEBUGendif第三十九页,共57页。8.依赖关系内核编译记录如下依赖关系:所有的前提文件(both*.cand*.h);CONFIG_选项影响到的所有文件;编译目标文件使用的命令行。因此,假如改变$(CC)的一个选项,所有相关的文件都要重新编译。第四十页,共57页。9.特殊规则特殊规则使用在内核编译需要规则定义而没有相应定义的时候,典型的例子如编译时头文件的产生规则。其他例子有体系Makefile编译引导映像的特殊规则。定义特殊规则时将使用到两个变量:$(src)和$(obj)。$(src)是对于Makefile文件目录的相对路径,当使用代码树中的文件时使用该变量$(src)。$(obj)是目标文件目录的相对路径。生成文件使用$(obj)变量。第四十一页,共57页。10.$(CC)支持功能内核可能会用不同版本的$(CC)进行编译,每个版本有不同的性能和选项,内核编译系统提供基本的支持用于验证$(CC)选项。$(CC)通常是gcc编译器,但其他编译器也可以。另外提供了几种与$(CC)有关的功能。cc-optioncc-option-yncc-option-aligncc-version第四十二页,共57页。15.4.4目标文件清除机制"makeclean"命令删除在编译内核生成的大部分文件如主机程序。列举在$(hostprogs-y)、$(hostprogs-m)、$(always)、$(extra-y)和$(targets)中目标文件都将被删除。代码目录数中的"*.[oas]"、"*.ko"文件和一些由编译系统产生的附加文件也将被删除。附加文件可以使用$(clean-files)进行定义。第四十三页,共57页。15.4.5编译辅助程序内核编译系统支持在编译(compliation)阶段编译主机可执行程序。为了使用主机程序需要2个步骤:第1个步骤使用hostprogs-y变量告诉内核编译系统有主机程序可用。第2步给主机程序添加潜在的依赖关系。1.简单辅助程序2.组合辅助程序3.定义共享库4.C++语言使用方法5.辅助程序编译控制选项6.何时建立辅助程序7.使用hostprogs-$(CONFIG_FOO)第四十四页,共57页。1.简单辅助程序在一些情况下需要在主机上编译和运行主机程序。下面这行告诉Kbuild在主机上建立bin2hex程序。例如:hostprogs-y:=bin2hex第四十五页,共57页。2.组合辅助程序主机程序也可以由多个object文件组成。定义组合辅助程序的语法同内核对象的定义方法。$(<executeable>-objs)包含了所有的用于链接最终可执行程序的对象。#scripts/lxdialog/Makefilehostprogs-y:=lxdialoglxdialog-objs:=checklist.olxdialog.o第四十六页,共57页。3.定义共享库扩展名为.so的对象是共享库文件,并且是位置无关的object文件。内核编译系统提供共享库使用支持,但使用方法有限制。在下面例子中libkconfig.so库文件被链接到可执行文件conf中。#scripts/kconfig/Makefilehostprogs-y:=confconf-objs:=conf.olibkconfig.solibkconfig-objs:=expr.otype.o第四十七页,共57页。4.C++语言使用方法内核编译系统提供了对C++主机程序的支持以用于内核配置,但不主张其他方面使用这种方法。#scripts/kconfig/Makefilehostprogs-y:=qconfqconf-cxxobjs:=qconf.o第四十八页,共57页。5.辅助程序编译控制选项当编译主机程序时仍然可以使用$(HOSTCFLAGS)设置编译选项传递给$(HOSTCC)。这些选项将影响所有使用变量HOST_EXTRACFLAG的Makefile创建的主机程序。#scripts/lxdialog/MakefileHOST_EXTRACFLAGS+=

-I/usr/include/ncurses第四十九页,共57页。6.何时建立辅助程序只有当需要时内核编译系统才会编译主机

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论