资源预览内容
第1页 / 共28页
第2页 / 共28页
第3页 / 共28页
第4页 / 共28页
第5页 / 共28页
第6页 / 共28页
第7页 / 共28页
第8页 / 共28页
第9页 / 共28页
第10页 / 共28页
亲,该文档总共28页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述
第4章 解析Linux内核 内核是操作系统的核心,通常说的Linux是指Linux操 作系统的内核,是一组系统管理软件的集合。Linux内核是 目前最流行的开源操作系统之一,由于其代码的高度开放性 ,越来越多的人参与到Linux内核的研究和开发中。Linux 内核的功能也在不断提高,性能在不断改进。操作系统内核 是软件开发领域比较深的技术点,需要结合软硬件知识才能 深入理解。本章由浅入深讲解Linux内核,带领读者进入嵌 入式开发比较深入的领域,主要内容如下: 如何获取Linux内核代码 Linux内核功能解析 Linux内核代码布局 Linux内核镜像结构 4.1 基本知识 Linux内核是Linux操作系统不可缺少的组成部分,但 是内核本身不是操作系统。许多Linux操作系统发行商如 RedHat、Debian等都采用Linux内核,然后加入用户需要 的工具软件和程序库,最终构成一个完整的操作系统。嵌入 式Linux系统是运行在嵌入式硬件系统上的Linux操作系统 ,每个嵌入式Linux系统都包括了必要的工具软件和程序库 。 4.1.1 什么是Linux内核 内核是操作系统的核心部分,为应用程序提供安全访问 硬件资源的功能。直接操作计算机硬件是很复杂的,内核通过 硬件抽象的方法屏蔽了硬件的复杂性和多样性。通过硬件抽象 的方法,内核向应用程序提供了统一和简洁的接口,应用程序 设计复杂程度降低。实际上,内核可以被看做是一个系统资源 管理器,内核管理计算机系统中所有的软件和硬件资源。 应用程序可以直接运行在计算机硬件上而无需内核的支 持,从这个角度看,内核不是必要的。在早期的计算机系统中 ,由于系统资源的局限,通常采用直接在硬件上运行应用程序 的办法。运行应用程序需要一些辅助程序,如程序加载器、调 试器等。随着计算机性能的不断提高,硬件和软件源都变得复 杂,需要一个统一管理的程序,操作系统的概念也逐渐建立起 来。 4.1.2 Linux内核版本 Linux内核版本号采用两个“.”分割的三个数字来标示, 形式为“X.Y.Z”。其中,X是主要版本号,Y是次要版本号, Z代表补丁版本号。奇数代表不稳定的版本;偶数代表稳定 的版本。“稳定”和“不稳定”是相对的,如Linux内核1.1.0相 对于1.0.0来说是“不稳定”版本,但是与1.1.1对比是“稳定” 版本。在Linux内核开发过程中,“不稳定”版本通常是在原 有版本基础上增加了新的功能或者新的特性。 4.1.3 如何获取Linux内核代码 在PC上,一般的Linux发行版都提供了内核代码。嵌 入式系统没有固定的发行版,需要用户自己获取内核代码。 Linux内核代码的官方站点是http:/www.kernel.org,该站 点提供了2.4和2.6所有版本的代码和补丁,用户可以打开该 地址找到和自己所在物理位置就进的站点,下载自己需要的 内核版本代码。高版本Linux内核代码文件比较大,对于国 内的用户推荐使用ftp方式下载,或者使用断点续传工具下 载,具体情况可根据读者自身的网络情况选择。 下载Linux内核代码后,会得到一个类似“linux- 2.6.xx.tar.gz”或者“linux-2.6.xx-tar.bz2”形式的压缩文件, “xx”代表版本号。在Linux系统上,通常把这个文件存放在 /usr/src目录下,便于以后使用。 4.1.4 编译内核 学习Linux内核最好的开始是编译一次Linux内核代码 ,通过配置Linux内核可以对内核代码有一个初步的了解。 本节介绍一下在PC机上如何编译生成2.6版本的内核目标文 件,试验中讲移植Linux部分会讲解如何交叉编译用于ARM 体系结构的Linux内核。 与2.4版本相比,2.6版本内核代码编译相对较容易。内 核编译主要分成配置和编译两部分,其中配置是关键,许多 问题都是出在配置环节。Linux内核编译配置提供多种方式 : make config : make menuconfig : make xconfig : make oldconfig : 4.2 Linux内核的子系统 内核是操作系统的核心。Linux内核提供很多基本功能 ,如虚拟内存、多任务、共享库、需求加载、共享写时拷贝 (Copy-On-Write)以及网络功能等。增加各种不同功能导 致内核代码不断增加。Linux内核把不同功能分成不同的子 系统的方法,通过一种整体的结构把各种功能集合在一起, 提高了工作效率。同时还提供动态加载模块的方式,为动态 修改内核功能提供了灵活性。 4.2.1 系统调用接口 4.2.1 系统调用接口 系统调用是Linux内核提供的,用户空间无法直接使用系 统调用。在用户进程使用系统调用必须跨越应用程序和内核的 界限。Linux内核向用户提供了统一的系统调用接口,但是在 不同处理器上系统调用的方法各不相同。Linux内核提供了大 量的系统调用,本节从系统调用的基本原理出发讲解Linux系 统调用的方法。 4.2.2 进程管理子系统 当一个用户进程被加载后,会进入就绪态,被加入到就 绪态队列,CPU时间轮转到就绪态队列后,切换到进程的 代码,进程被执行,当进程的时间片到了以后被换出。如果 进程发生I/O操作也会提前被换出,并且存放到等待队列, 当I/O请求返回后,进程又被放入就绪队列。 Linux系统对进程队列的管理设计了若干不同的方法, 主要的目的是提高进程调度的稳定性。 4.2.3 内存管理子系统 内存是计算机的重要资源,也是内核的的重要部分。使 用虚拟内存技术的计算机,内存管理的硬件按照分页方式管 理内存。分页方式是把计算机系统的物理内存按照相同大小 等分,每个内存分片称作内存页,通常内存页大小是4KB。 Linux内核的内存管理子系统管理虚拟内存与物理内存之间 的映射关系,以及系统可用内存空间。 内存管理要管理的不仅是4KB缓冲区。Linux提供了对 4KB缓冲区的抽象,例如slab分配器。这种内存管理模式使 用4KB缓冲区为基数,然后从中分配结构,并跟踪内存页使 用情况,比如哪些内存页是满的,哪些页面没有完全使用, 哪些页面为空。这样就允许该模式根据系统需要来动态调整 内存使用。 4.2.4 虚拟文件系统 虚拟文件系统,即VFS(Virtual File System)是 Linux内核中的一个软件抽象层。它通过一些数据结构及其 方法向实际的文件系统如ext2,vfat等提供接口机制。通过 使用同一套文件 I/O 系统调用即可对Linux中的任意文件进 行操作而无需考虑其所在的具体文件系统格式;更进一步, 文件操作可以在不同文件系统之间进行。 4.2.4 虚拟文件系统 4.2.5 网络堆栈 Linux系统下编写网络应用程序,使用socket通过 TCP/IP协议与其他机器通信,和前面介绍的内核子系统相似 ,socket相关的函数也是通过内核的子系统完成的,担当这 部分任务的是内核的网络子系统,一些资料里也把这部分代 码称为“网络堆栈”。 Linux内核提供了优秀的网络处理能力和功能,这与网 络堆栈代码的设计思想是分不开的,Linux的网络堆栈部分 沿袭了传统的层次结构,网络数据从用户进程到达实际的网 络设备需要四个层次。 4.2.5 网络堆栈 4.2.6 设备驱动 Linux内核对设备按照主设备号和从设备号的方法访问, 主设备号描述控制设备的驱动程序,从设备号区分同一个驱动 程序的不同设备。也就是说,主设备号和设备驱动程序对应, 代表某一类型的设备,从设备号和具体设备对应,代表同一类 的设备编号。如使用IDE接口的两个硬盘,主设备号都相同, 但是从设备号不同。Linux提供了mknod命令创建设备驱动程 序的描述文件,后面设备驱动相关章节具体讲解。Linux内核 这种主从设备号的分类方法可以很好的管理设备。 4.2.7 依赖体系结构的代码 Linux内核支持众多体系结构,内核把与设备无关的代 码放在arch目录,对应的头文件放在include/asm-目录下。这样的划分代码结构清晰,同时提高了代码的 复用率。在arch目录里,每个子目录对应一种体系结构,存 放这种体系结构对应的代码,如果代码较多会单独建立一个 目录,例如arch/arm目录下,有一个kernel目录,存放的是 kernel目录中在arm体系结构上特有的函数或者实现方法; 在arch/i386目录存放了Intel X86体系结构的代码,不仅有 kernel目录,而且还有多个目录,例如mm目录包含了x86 体系上内存管理的实现方法,math-emu包含了x86体系上 浮点数模拟的实现等。读者在阅读内核代码的时候可以从一 个体系结构代码入手,对不同体系结构移植代码的主要工作 是arch里面的代码。 4.3 Linux内核代码的工程结构 随着Linux内核功能的不断增加,内核代码也在飞速增 长,目前2.6版本的内核代码早已达到数百万行。如此庞大 的代码量,不仅给学习带来困难,对代码的维护也是一个不 小的挑战,幸好Linux内核开发人员早就考虑到了这一点, 使得Linux内核代码组织有序,本节重点讲述Linux内核代 码的结构。 4.3.1 源代码目录布局 4.1.3节讲述了如何获取到Linux内核代码,通常会存放 在/usr/src目录下,如果是2.6版本的内核解压后会得到例如 linux-2.6.xx类型的目录,这个目录下存放的就是Linux内 核代码。进入内核代码目录,查看文件列表,会看到许多的 目录和文件,如果读者的系统有tree这个命令或者脚本,可 以查看到Linux内核代码的文件数,那会是一个很庞大的结 构。好在Linux内核代码的工程组织是很好的,对于不同版 本的内核,在工程组织上是基本一致的,有的仅是功能上的 差别。 4.3.2 几个重要的Linux内核文件 当用户编译一个Linux内核代码后,会生成几个文件: vmlinuz,initrd.img,以及System.map,如果读者配置过 grub引导管理器程序,会在/boot目录下看到这几个文件。 1vmlinuz文件 2initrd文件 3System.map文件 4.4 内核编译系统 Linux内核代码的复杂,需要一个强大的工程管理系统 ,幸好GNU提供了Makefile机制,此外,内核的开发者们还 提供了KBuild机制。通过Makefile和KBuild的结合,可以 出色的管理Linux内核代码。Linux内核的编译系统和代码 结构是紧密联系的,了解内核编译系统对分析内核代码和编 译内核都有帮助作用。 4.4.1 内核编译系统基本架构 Linux内核编译系统有5种类型的文件。 文件类型作用 Makefile顶层Makefile文件 .config内核配置文件 arch/$(ARCH)/Makefile机器体系Makefile文件 scripts/Makefile.*所有内核Makefiles共用规则 kbuild Makefiles其它Makefile文件 4.4.2 内核顶层Makefile分析 编译内核代码的时候,顶层Makefile文件在开始编译子 目录下的代码之前,设置编译环境和需要用到的变量。顶层 Makefile文件包含通用部分,arch/$(ARCH) /Makefile包含 该体系架构所需的设置。因此arch/$(ARCH)/Makefile会设 置一些变量和少量的目标。 1设置变量 2增加预设置项 3目录表 4引导映像 5编译非内核目标 6编译引导映像命令 7定制编译命令 8预处理连接脚本 4.4.3 内核编译文件分析 Linux内核代码使用KBuild作为Makefile的基础架构。 Kbuild定义了若干的内置变量,本节介绍Kbuild的主要内置 变量和常用方法。 1目标定义 2内嵌对象 - obj-y 3可加载模块 - obj-m 4导出符号目标 5库文件 - lib-y 6目录递归 7编译标记 8依赖
网站客服QQ:2055934822
金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号