1、本章内容本章内容pLinux内核体系内核体系结构构p内核引内核引导与与设置置p内核构建内核构建p系系统调用用11.Linux内核体系内核体系结构构22.内核引内核引导与启与启动3BIOS/OFp加加电后后处理器首先理器首先访问通常位于只通常位于只读内存(一般是内存(一般是Flash ROM或或仅仅是是Flash)中的)中的某一地址某一地址。pBIOS(基本(基本输入入输出)是出)是x86系系统加加电后最先运后最先运行的代行的代码。引。引导系系统并并与硬件相关的系与硬件相关的系统初始化初始化代代码。pOpen Firmware是是PPC(PowerPC)系)系统加加电后最先运行的代后最先运行的代
2、码。4BIOS功能功能p自自检及初始化程序;及初始化程序;n自自检,对CPU,640K基本内存,基本内存,1M以上的以上的扩展内存,展内存,ROM,主板,主板,CMOS存存储器等器等进行行测试。n初始化,包括初始化,包括创建中断向量、建中断向量、设置寄存器等。置寄存器等。n引引导程序程序,引,引导DOS或或Linux等操作系等操作系统。p硬件中断硬件中断处理;系理;系统在加在加电引引导机器机器时,要,要读取取CMOS信息,用来初始化机器各个部件的状信息,用来初始化机器各个部件的状态。p程序服程序服务请求;程序服求;程序服务处理程序主要是理程序主要是为应用程用程序和操作系序和操作系统服服务,这些
3、服些服务主要与主要与输入入输出出设备有关,例如有关,例如读磁磁盘、文件、文件输出到打印机等。出到打印机等。5引引导装入程序(装入程序(Boot Loaders)p格式化磁格式化磁盘时,会,会创建主引建主引导记录(MBR),),该记录存存储在引在引导设备的第一个扇区(的第一个扇区(0扇区、扇区、0磁道、磁道、0磁磁头)。包含:)。包含:n一个小程序一个小程序n一一张四入口点的分区表四入口点的分区表n结束束标识符(符(0XAA55),用来做),用来做MBR的有效性的有效性检测。pGRUB(Grand Unified Bootloader),基于,基于x86的引的引导装入程序,用来加装入程序,用来加
4、载Linux。pLILO(Linux Loader)x86中中Linux的加的加载程序。程序。pYaboot是基于是基于PowerPC及其及其OF的引的引导装入程序。装入程序。6pLILO(Linux Loader)已成)已成为所有所有 Linux 发行版的行版的标准准组成部分。成部分。p作作为一个一个较老的老的Linux 引引导加加载程序,它那不断程序,它那不断壮大的壮大的 Linux 社区支持使它能社区支持使它能够随随时间的推移而的推移而发展,并始展,并始终能能够充当一个可用的充当一个可用的现代引代引导加加载程程序。序。LILO7pGNU GRUB(GRand Unified Bootlo
5、ader简称称“GRUB”)是一个来自)是一个来自GNU项目的多操作系目的多操作系统启启动程序。程序。pGRUB允允许用用户可以在可以在计算机内同算机内同时拥有多个操作有多个操作系系统,并在,并在计算机启算机启动时选择希望运行的操作系希望运行的操作系统。pGRUB可用于可用于选择操作系操作系统分区上的不同分区上的不同内核内核,也,也可用于向可用于向这些内核些内核传递启启动参数。参数。GNU GRUB8pGRUB2(GRand Unified Bootloader,Version 2)是)是GRUB的第二版。的第二版。pGRUB目前已目前已经不再不再继续开开发,只是修正存在的,只是修正存在的错误
6、。p官方的官方的说法是法是GRUB的的编码实在太在太烂,以至于没法,以至于没法进行行维护升升级了,所以重新从零开了,所以重新从零开发了新的了新的GRUB2,从此以后原来的从此以后原来的GRUB就叫做就叫做GRUB Legacy了。了。pGRUB2对GRUB2的接口的接口进行了完整地重写,并且行了完整地重写,并且采用了清晰的架构和模采用了清晰的架构和模块化的布局。化的布局。p目前大部分都采用目前大部分都采用GRUB2作作为内核引内核引导管理器。管理器。GRUB29体系体系结构相关的内存初始化构相关的内存初始化pX86和和PowerPC在硬件方面都具有支持在硬件方面都具有支持实寻址和址和虚虚寻址的
7、内存管理特征。址的内存管理特征。pLinux的内存管理依的内存管理依赖于底于底层的硬件的硬件结构。构。p现在在PPC和和x86的代的代码都集中在都集中在init/main.c的的start_kernel()中,位于中,位于与体系与体系结构无关的代构无关的代码段中,段中,调用特定用特定体系体系结构的构的历程来完成内存初始化。程来完成内存初始化。10开始:开始:start_kernel()pInit/main.c中中start-kernel(),执行行进程程0(即超(即超级用用户线程程root thread),),进程程0又又产生生进程程1(即(即init进程),然后程),然后进程程0就就编程程C
8、PU的的空空闲进程。程。pLinux内核只提供了内核只提供了轻量量进程程的支持,限制了更高的支持,限制了更高效的效的线程模型的程模型的实现。目前最流行的。目前最流行的线程机制程机制LinuxThreads所采用的就是所采用的就是线程程-进程程“一一对一一”模型模型,调度交度交给核心,而在用核心,而在用户级实现一个包括一个包括信号信号处理在内的理在内的线程管理机制。程管理机制。113.内核构建内核构建pLinux集成套件包括多种内核,能集成套件包括多种内核,能够处理各种机器。理各种机器。通通过编译内核,内核,选择符合硬件符合硬件类型的型的驱动等,可以等,可以调整整Linux系系统,使其更合理地安
9、装到,使其更合理地安装到计算机中。算机中。p重新重新编译内核以便内核以便实现一些新功能,如将一些新功能,如将Linux系系统设置置为一个一个临时路由器。路由器。p使得全世界内核使得全世界内核设计者提供的各种者提供的各种为改改进性能而性能而设计的内核得到充分利用。的内核得到充分利用。12构建构建Linux内核内核pLinux官方源代官方源代码发布网址:布网址:www.kernel.orgpgzip压缩的的.tar.gz包,包,bzip2压缩的的.tar.bz2。pLinux源代源代码分分为:n与系与系统结构相关的部分构相关的部分n与系与系统结构无关的部分构无关的部分n文档和工具文档和工具13Li
10、nux内核文件内核文件组织结构构p以内核以内核长期期维护的版的版本本3.4.70为例。例。14Linux内核文件内核文件说明明parch:包含了所有和体系:包含了所有和体系结构相关的核心代构相关的核心代码,它的每一个子目它的每一个子目录都代表一种被支持的体系都代表一种被支持的体系结构。构。pinclude:包含:包含编译核心所需要的大部分核心所需要的大部分头文件,文件,与平台无关的与平台无关的头文件放在文件放在include/linux子目子目录中。中。pinit:包含核心的初始化代:包含核心的初始化代码。pmm:包含所有独立于:包含所有独立于CPU体系体系结构的内存管理构的内存管理代代码。p
11、kernel:主要的核心代:主要的核心代码,实现大多数大多数Linux系系统的内核函数,包括的内核函数,包括进程程调度、系度、系统调用等。用等。15Linux内核文件内核文件说明(明(续)pdrivers:系:系统所有的所有的设备驱动程序,每种程序,每种驱动程程序各占用一个子目序各占用一个子目录。p其它:其它:lib放置核心的放置核心的库代代码;net放置核心与网放置核心与网络相关的代相关的代码;lpc包含核心的包含核心的进程程间通信的代通信的代码;fs包含文件系包含文件系统代代码;scripts包含用于配置核心包含用于配置核心的脚本文件。的脚本文件。16Linux内核内核的的makefile
12、文件文件p源代源代码树的每个子目的每个子目录下都有一个下都有一个makefile文件。文件。p在源代在源代码树的根目的根目录下下执行行make,则调用用顶层makefile文件,它定文件,它定义了随后要了随后要输出到其他出到其他makefile的的变量,以及向量,以及向子目子目录中的每个中的每个makefile发出出make调用。用。pScript/makefile.build中定中定义了了makefile向向下下级子目子目录递归并并编译的的规则。17编译内核内核过程程p第第1步,步,预处理理p第第2步,配置内核步,配置内核p第第3步,生成内核步,生成内核p第第4步,安装内核步,安装内核p第第
13、5步,建立模步,建立模块18第第1步,步,预处理理pLinux内核源文件缺省位置:内核源文件缺省位置:/usr/src/linuxp从从Internet下下载最新版本到你最新版本到你创建的主目建的主目录。n如如yanp清除以前清除以前试图建立内核建立内核过程程遗留下的多余文件。留下的多余文件。nMake mrproper19第第2步,配置内核步,配置内核pmake config:手工逐:手工逐项配置配置pmake menuconfig:菜:菜单选项配置配置pmake xconfig:XWindow配置配置p修改配置文件修改配置文件/linux/.confign注意,注意,make mrprop
14、er命令要命令要删除除这个文件,可以从个文件,可以从/linux/arch/i386/defconfig拷拷贝复制一个。复制一个。20第第3步,生成内核步,生成内核p有三步:有三步:n1、make dep:生成相关性:生成相关性n例如:如果激活例如:如果激活“Set Version Information For All Symbols On Modules”选项,那么它,那么它为所建立所建立的模的模块确定其版本信息。确定其版本信息。n2、make clean:清除一些目:清除一些目录中中现有文件,将存有文件,将存储创建的新文件。建的新文件。n3、make bzImage:编译内核本身,花内核
15、本身,花费时间长。对于新内核于新内核规模小,可以使用模小,可以使用make zImage,如果不,如果不确定,最好确定,最好还是使用是使用bzImage。n建立建立/linux/arch/i386/boot/bzImage21第第4步,安装内核步,安装内核p有些集成套件使用有些集成套件使用LILO作作为引引导装入程序。装入程序。n/etc/lilo.conf文件中的文件中的“image”psu命令成命令成为超超级用用户登登录,把,把刚创建的建的bzImage拷拷贝到到/boot中。中。ncp yan/linux/arch/i386/boot/bzImage /boot/vmLinuzn修改修改
16、lilo.conf文件中文件中“image”行。行。n告告诉LILO更新其配置信息更新其配置信息:/sbin/lilo22第第5步,建立模步,建立模块p配置配置Linux内核内核时,可将,可将许多多选项配置配置为模模块而不而不是直接放是直接放进内核。内核。p每个模每个模块可以分可以分别装入和卸装入和卸载。p/linux目目录下下nmake modules:创建在配置建在配置过程中要求的模程中要求的模块,但,但是并不安装。是并不安装。nMake modules_install:将已:将已经完成的模完成的模块拷拷贝到到对应该内核版本的内核版本的/lib/modules/子目子目录中。中。23管理多
17、内核管理多内核p不同的情况使用不同的内核,不同的情况使用不同的内核,lilo.conf文件:文件:delay=15#15-second delay image=/boot/vnlinux label=Linux image=/home/yan/bzImage Label=TestKernel 最后,最后,执行行/sbin/lilo Added Linux*(表示表示Linux标记为缺省内核缺省内核)Added TestKernel(表示添加新内核)(表示添加新内核)244.系系统调用用p每个系每个系统调用都是通用都是通过一个一个单一的入口点多路一的入口点多路传入内核。入内核。eax 寄存器用来
18、寄存器用来标识应当当调用的某个系用的某个系统调用,用,这在在 C 库中做了指定(来自用中做了指定(来自用户空空间应用程序的每个用程序的每个调用)。用)。p当加当加载了系了系统的的 C 库调用索引和参数用索引和参数时,就会,就会调用一个用一个软件中断(件中断(0 x80 中断),它将中断),它将执行行 system_call 函数(通函数(通过中断中断处理程序),理程序),这个函数会按照个函数会按照 eax 内容中的内容中的标识处理所有的系理所有的系统调用。用。p在在经过几个几个简单测试之后,使用之后,使用 system_call_table 和和 eax 中包含的索引来中包含的索引来执行真正的
19、系行真正的系统调用了。从系用了。从系统调用用中返回后,最中返回后,最终执行行 syscall_exit,并,并调用用 resume_userspace 返回用返回用户空空间。然后。然后继续在在 C 库中中执行,它将返回到用行,它将返回到用户应用程序中。用程序中。25 系系统调用的用的实现p系系统调用是操作系用是操作系统向用向用户提供的程序一提供的程序一级的服的服务,用,用户程程序借助于系序借助于系统调用命令向操作系用命令向操作系统提出各种提出各种资源要求和服源要求和服务请求。求。26系统调用处理系系统调用用过程描述程描述 (1)用)用户程序程序调用用C库中的中的API。(2)API里面有里面有
20、软中断中断int 0 x80语句,句,这条指令的条指令的执行会行会让系系统跳跳转到一个到一个预设的内核空的内核空间地址,它指向系地址,它指向系统调用用处理程序,即理程序,即system_call函数,同函数,同时把系把系统调用号放入用号放入eax寄存器中。寄存器中。(3)system_call系系统调用用处理程序是在理程序是在执行系行系统调用服用服务例程之前的一个引例程之前的一个引导过程,程,针对int 0 x80这条指令,面向条指令,面向所有的系所有的系统调用。用。system_call读取取eax寄存器,寄存器,获取系取系统调用号,将其乘以用号,将其乘以4,生成偏移地址,并以,生成偏移地址
21、,并以sys_call_table为基址,基址,转到到执行具体的系行具体的系统调用服用服务例例程。程。27系系统调用用过程描述(程描述(续)(4)系)系统调用服用服务例程将从堆例程将从堆栈里里获取参数并取参数并执行。由于行。由于system_call执行前,会先将参数存放在寄存器中,行前,会先将参数存放在寄存器中,system_call执行行时会首先将会首先将这些寄存器些寄存器压入堆入堆栈。system_call退出后,用退出后,用户可以从寄存器中可以从寄存器中获得(被修改得(被修改过的)参数。的)参数。注意:系注意:系统调用通用通过软中断中断INT 0 x80陷入内核,跳陷入内核,跳转到系到
22、系统调用用处理程序理程序system_call函数,然后函数,然后执行相行相应的的服服务例程。但是由于是代表用例程。但是由于是代表用户进程,所以程,所以这个个执行行过程并程并不属于中断上下文,而是不属于中断上下文,而是进程上下文。因此,系程上下文。因此,系统调用用执行行过程中,可以程中,可以访问用用户进程的程的许多信息,可以被其它多信息,可以被其它进程程抢占,可以休眠。占,可以休眠。28系系统调用用过程描述(程描述(续)(5)系)系统调用完成后,把控制用完成后,把控制权交回到交回到发起起调用的用用的用户进程前,内核会有一次程前,内核会有一次调度。如果度。如果发现有有优先先级更高的更高的进程或程
23、或当前当前进程的程的时间片用完,那么会片用完,那么会选择优先先级更高的更高的进程或重程或重新新选择进程程执行。行。29增加系增加系统调用用p如果用如果用户在在Linux中添加新的系中添加新的系统调用,用,应该遵循几个步遵循几个步骤才能添加成功。才能添加成功。30编写系统调用程序配置新的系统调用编译新内核运行新内核编写程序调用新的系统调用第第1步,添加新的系步,添加新的系统调用函数源代用函数源代码 p第一个任第一个任务是是编写加到内核中的源程序,即将要加写加到内核中的源程序,即将要加到一个内核文件中的一个函数,到一个内核文件中的一个函数,该函数的名称函数的名称应该是新的系是新的系统调用名称前面加
24、上用名称前面加上sys_标志。志。p假假设新加的系新加的系统调用用为mycall(int number),在在/usr/src/Linux/kernel/sys.c文件中添文件中添加源代加源代码,它,它对应的函数名称的函数名称为sys_mycall。31第第2步,步,连接新的系接新的系统调用用p添加新的系添加新的系统调用后,下一个任用后,下一个任务是使是使Linux内核内核的其余部分知道的其余部分知道该程序的存在。程序的存在。为了从已有的内核了从已有的内核程序中增加到新的函数的程序中增加到新的函数的连接,需要接,需要编辑两个文件:两个文件:n/usr/src/Linux/include/asm
25、-i386/unistd.h:该文件中包含了系文件中包含了系统调用清用清单,用来,用来给每个系每个系统调用用分配一个唯一的号分配一个唯一的号码。n/usr/src/Linux/arch/i386/kernel/entry.S:该清清单用来用来对sys_call_table数数组进行初始化。行初始化。该数数组包含指向内核中每个系包含指向内核中每个系统调用的指用的指针。这样就在就在数数组中增加了新的内核函数的指中增加了新的内核函数的指针。32第第3步,重建新的步,重建新的Linux内核内核p为使新的系使新的系统调用生效,需要重建用生效,需要重建Linux的内核。的内核。p这需要以超需要以超级用用户
26、身份登身份登录。p具体方法可以参考内核具体方法可以参考内核编译步步骤。33第第4步,使用新的系步,使用新的系统调用用p在在应用程序中使用新添加的系用程序中使用新添加的系统调用。用。p由于使用了系由于使用了系统调用,用,编译和和执行程序行程序时,用,用户都都应该是超是超级用用户身份。身份。34本章小本章小结p虽然然Linux 内核是一个内核是一个庞大而复大而复杂的操作系的操作系统核核心,但是由于采用子系心,但是由于采用子系统和分和分层的概念,具有很好的概念,具有很好的的扩展性和可展性和可读性。性。pLinux的的优势就在于用就在于用户能能够定制内核,内核定制内核,内核编译可以使得全世界内核可以使得全世界内核设计者提供的各种者提供的各种为改改进性能性能而而设计的内核得到充分利用。的内核得到充分利用。p系系统调用是操作系用是操作系统向用向用户提供的程序一提供的程序一级的服的服务,用用户在在Linux中添加新的系中添加新的系统调用后,需要重新用后,需要重新编译内核、运行新的内核之后才能使用。内核、运行新的内核之后才能使用。35
©2010-2024 宁波自信网络信息技术有限公司 版权所有
客服电话:4008-655-100 投诉/维权电话:4009-655-100