第05章 嵌入式Linux 的内核

上传人:油** 文档编号:240715812 上传时间:2024-05-02 格式:PPT 页数:87 大小:1.50MB
返回 下载 相关 举报
第05章 嵌入式Linux 的内核_第1页
第1页 / 共87页
第05章 嵌入式Linux 的内核_第2页
第2页 / 共87页
第05章 嵌入式Linux 的内核_第3页
第3页 / 共87页
点击查看更多>>
资源描述
第第0505章章 嵌入式嵌入式Linux Linux 的的内核内核5.1 Linux 内核概述o5.1.1 Linux 内核和功能结构o5.1.2 Linux 内核源代码布局o5.1.3 内核的移植25.1.1 Linux 内核和功能结构o内核(kernel)是操作系统的内部核心程序,它向外部提供了对计算机系统资源进行请求和管理的调用接口和服务 3内核o可以将操作系统的代码分成两部分:n内核所在的地址空间称为内核空间;n而在内核以外,剩下的程序统称为外部管理程序,它们大部分是对外围设备的管理和界面操作,外部管理程序与用户进程所占据的地址空间称为外部空间。o通常,一个程序会跨越两个空间。n当执行到内核空间的一段代码时,称程序处于内核态n当程序执行到外部空间代码时,称程序处于用户态。45.1.1 Linux 内核和功能结构o常见的OS内核有两个模式:n微内核(micro-kernel)n单一内核(Monolithic kernel)5微内核o在微内核结构中,操作系统的内核只需要提供最基本,最核心的一部分操作(比如创建和删除任务,内存管理,中断管理等)o其他的管理程序(如文件系统,网络协议栈等)则尽可能地放在内核以外。这些外部程序可以独立运行,并对应用程序提供操作系统服务,服务之间使用进程间通信机制(IPC)进行交互。只在需要内核的协助时,才通过一套接口对内核发出调用请求。6微内核优点o使操作系统具有良好的灵活性。使得操作系统内部结构变得简单清晰。o在内核以外的外部程序分别独立运行,其间并不互相关联。这样,可以对这些程序分别进行维护和拆装,只要遵循已经规定好的界面,就不会对其他程序有任何干扰。这使得程序代码在维护上十分方便,体现了面向对象软件的结构特征。7微内核的不足o首先,程序代码之间的相互隔离,使得整个系统丧失了许多优化的机会;o其次,部分资源浪费在外部进程之间的通信上(进程间通信的开销要比直接的函数调用大),这样,微内核结构在效率上必然低于传统的单一内核结构,这些效率损失将作为结构精简的代价。o总体上说,在当前的硬件条件下,微内核在效率上的损失小于其在结构上获得的效益,故而选取微内核成为操作系统的一大潮流。85.1.1 Linux 内核和功能结构oLinux内核属于单一内核n参与Linux系统开发的程序员大多数为世界各地的黑客们。比起结构的清晰,他们更加注重功能的强大和高效率的代码。n他们将大量的精力花在优化代码上,而这样的全局性优化必然以损失结构精炼作为代价,导致Linux中的每个部件都不能被轻易拆出,否则必然破坏整体效率。9Linux内核o虽然Linux是一个单一内核操作系统,但它与传统的单一内核UNIX操作系统不同。n在普通单一内核系统中,所有内核代码都是被静态编译和链接的。n而在Linux中,可以动态装入和卸载内核中的部分代码。Linux中将这样的代码段称做模块(module),并对模块给予了强有力的支持。在Linux中,可以在需要时自动装入和卸载模块。105.1.1 Linux 内核和功能结构oLinux内核的结构115.1.1 Linux 内核和功能结构oLinux 内核主要由5 个模块构成,它们分别是:n进程调度模块:控制进程对CPU 资源的使用 n内存管理模块:确保所有进程能够安全地共享机器主内存区;虚拟内存管理 n文件系统模块:支持对外部设备的驱动和存储 n进程间通信模块:支持多种进程间的信息交换方式 n网络接口模块:提供对多种网络通信标准的访问并支持许多网络硬件 12内核模块之间的依赖关系 13内核模块之间的依赖关系 o所有的模块都与进程调度模块存在依赖关系。因为它们都需要依靠进程调度程序来挂起(暂停)或重新运行它们的进程。通常,一个模块会在等待硬件操作期间被挂起,而在操作完成后才可继续运行。14内核模块之间的依赖关系o进程调度子系统需要使用内存管理器来调整一特定进程所使用的物理内存空间。o进程间通信子系统则需要依靠内存管理器来支持共享内存通信机制。o虚拟文件系统也会使用网络接口来支持网络文件系统(NFS),同样也能使用内存管理子系统来提供内存虚拟盘(ramdisk)设备。o而内存管理子系统也会使用文件系统来支持内存数据块的交换操作。155.1.2 Linux 内核源代码布局o安装的时候,如果选择了Kernel Develop,则会在/usr/scr/linux下找到源代码o根据各个目录的名字,可以容易猜出各个目录里面的文件的功能165.1.2 Linux 内核源代码布局oDocumentation oarch odrivers ofs oinclude oinit oipc olib omm onet o175.1.2 Linux 内核源代码布局185.1.2 Linux 内核源代码布局195.1.2 Linux 内核源代码布局20补充:Linux操作系统的启动oBoot Loader 把操作系统的代码调入内存后,会把控制权交给操作系统,由操作系统的启动程序来完成剩下的工作。21Linux操作系统启动的步骤o(1)把控制权交给Setup.S这段程序o(2)进入保护模式,同时把控制权交给Head.So(3)Head.S调用/init/main.C中的start_kernel函数,启动程序从start_kernel()函数继续执行o(4)建立init进程22进入操作系统(1)Setup.So首先,Setup.S对已经调入内存的操作系统代码进行检查,如果没错,它会通过BIOS中断获取内存容量,硬盘等信息(实模式)o准备让CPU进入保护模式 a.先屏蔽中断信号 b.调用指令lidt和lgdt,对中断向量表寄存器IDTR进行初始化 c.对8259中断控制器进行编程 d.协处理器重新定位 完成这几件事后,Setup.S设置保护模式的标志,重取指令,再用一条跳转指令jmpi 0 x100000,KERNEL_CS。进入保护模式下的启动阶段,控制权交给Head.S.23进入操作系统(2)Head.So也要先做屏蔽中断一类的工作o然后对中断向量表做一定的处理oBoot Loader读入内存的启动参数和命令行参数,Head.S把它们保存在empty_zero_page页中o检查CPU类型o对协处理器进行检查 o页初始化,调用setup_paging这个子函数 o因为已进入保护模式,段机制的多任务属性体现 24进入操作系统(3)main.c中的初始化oHead.S调用/init/main.c中的start_kernel函数,把控制权交给它,这个函数是整个操作系统初始化的最重要的函数,一旦它执行完,整个操作系统的初始化也就完成了。25进入操作系统(3)main.c中的初始化o计算机在执行start_kernel前以进入了保护模式,使处理器完全进入了全面执行操作系统代码的状态。o但直到目前为止,这都是针对处理器的。而一旦start_kernel开始执行,Linux内核就一步步展现。oStart_kernel执行后,就可以以一个用户的身份登陆和使用Linux了26进入操作系统(3)main.c中的初始化main.c中其他较为重要的函数如下:oSetup_arch()最基本硬件的初始化oPaging_init()线性地址空间映射oTrap_init()中断向量表初始化oInt_IRQ与中断有关的初始化oSched_init()进程调度初始化oConsole_init()对中断的初始化o对文件系统的初始化oInode_initI()i节点管理机制初始化oName_cache_init()目录缓存机制初始化oBuffer_init()块缓存机制初始化27进入操作系统(3)main.c中的初始化o启动到了目前这种状态,只剩下运行/etc下的启动配置文件。o这时初始化程序并没有完成操作系统各个部分的初始化,更关键的文件系统的安装还没有涉及,这是在init进程建立后完成的。就是start_kernel()最后部分内容。28进入操作系统(4)建立init进程oLinux要建立的第一个进程是init进程o启动所需的Shell脚本文件 a.Linux系统启动所必须的 b.用户登陆后自己设定的 系统启动所必须的脚本存放在系统默认的配置文件目录/etc下。首先调用的是/etc/inittab.295.1.3 内核的移植oLinux移植:n就是把Linux操作系统针对具体的目标平台做必要改写之后,安装到该目标平台,使其正确地运行起来,即把内核从一种硬件平台转移到另外一种硬件平台上运行。这个概念目前在嵌入式开发领域讲的比较多。o对于嵌入式Linux系统来说,有各种体系结构的处理器和硬件平台,并且用户需要根据需求自己定制硬件板。只要硬件平台有些变化,即使非常小,可能也需要做一些移植工作。305.1.3 内核的移植o内核移植工作主要是修改跟硬件平台相关的代码,一般不涉及Linux内核通用的程序。移植的难度也取决于两种硬件平台的差异。nLinux针对于特定的硬件平台的软件包叫做BSP(Board Support Package)。o目前Linux内核的社区已经对常见的硬件平台做了很多工作,移植工作已经简单了n通常都可以找到相同处理器的参考板,并且可以获取到Linux内核源代码。31移植的准备工作o选择参考板,获取到Linux内核源代码:四点原则o分析内核代码,弄清楚哪些设备有驱动程序,哪些还没有。o确信Linux对参考板的支持情况,配置编译Linux内核,在目标板上运行测试。n可能最新的Linux内核版本支持的最好,但是也可能需要在老内核版本上打补丁。o分析平台相关的部分代码实现;分析内核编译组织方式;分析内核启动的初始化程序;分析驱动程序的实现。32移植过程的基本内容o获取某一版本的Linux内核源码,根据具体目标平台对源码进行必要的改写(主要是修改体系结构相关部分)o然后添加一些外设的驱动,打造一款适合需要的目标平台(可以是嵌入式便携设备也可以是其它体系结构的PC机)的新操作系统,对该系统进行针对具体目标平台的交叉编译,生成一个内核映象文件o最后通过一些手段把该映象文件烧写(安装)到目标平台中。o通常,对Linux源码的改写工作难度较大,它要求不仅对Linux内核结构要非常熟悉,还要求对目标平台的硬件结构要非常熟悉,同时还要求对相关版本的汇编语言较熟悉,因为与体系结构相关的部分源码往往是用汇编写的。所以这部分工作一般由目标平台提供商来完成。开发者所要做的就是从目标平台提供商的网站上下载相关版本Linux内核的补丁(Patch)。把它打到Linux内核上,再进行交叉编译就行。33第五章 Linux内核5.1 Linux 内核概述5.2 Linux 内核模块简介5.3 Linux 的编译和定制5.4 Linux 系统调用举例345.2 Linux 内核模块简介o5.2.1 进程管理模块o5.2.2 存储管理模块355.2.1 进程管理模块o多进程是一个简单的思想(如下图):n一个进程一直运行,直到它必须等待,通常是等待一些系统资源,等拥有了资源,它才可以继续运行。n在一个单进程的系统,比如 DOS,CPU 被简单地设为空闲,这样等待的时间就会被浪费。n在一个多进程的系统中,同一时刻许多进程在内存中。当一个进程必须等待时,操作系统将剥夺这个进程对CPU的使用权,并将它交给另一个合适的进程。365.2.1 进程管理模块o进程的切换:n当一个进程被剥夺了CPU,而系统转向去运行另外一个进程的时候,就发生了上下文切换,或者叫做进程切换。负责完成新的进程选择和进程切换的代码就是调度程序 375.2.1 进程管理模块o态的切换和上下文切换(书)n 385.2.1 进程管理模块oLinux的进程状态39task_structoLinux中,每一个进程用一个task_struct的数据结构来表示,用来管理系统中的进程。o当一个新的进程被创建后,从系统内存中分配一个新的task_struct,并增加到task的链表中。o为了更容易查找,用current指针指向当前运行的进程。40task_structotask_struct结构有个成员state表示进程当前的运行状态,已定义的状态如下:(include/linux/sched.h中)n#define TASK_RUNNING0n#define TASK_INTERRUPTIBLE1n#define TASK_UNINTERRUPTIBLE2n#define TASK_ZOMBIE4n#define TASK_STOPPED841进程的家庭关系o在Linux系统中,没有一个进程是和其他进程完全无关的。o系统中的所有进程,除了初始的进程之外,都有一个父进程。新进程不是创建的,而是拷贝,或者说从前一个进程克隆的(cloned)。o在每一个进程的task_struct 中都有指向它的父进程和兄弟进程(拥有相同的父进程的进程)以及它的子进程的的指针。o在Linux系统中,用户可以用pstree 命令看到正在运行的进程的家庭关系。425.2.1 进程管理模块oLinux将进程的创建与目标程序的执行分成两步。n第一步是从已经存在的“父进程”中复制出一个“子进程”,该子进程拥有自己的task_struct结构和系统空间堆栈,但与父进程共享其它所有资源。o两个系统调用:fork和clone n第二步是目标程序的执行。Linux为此提供了一个系统调用execve,让一个进程执行以文件形式存在的一个可执行程序的映像。435.2.1 进程管理模块o创建了子进程后,父进程有两种选择。n一是不受阻的(non-blocking)方式,也称为“异步”方式,即父进程继续走自己的路,与子进程分道扬镳。这种情况下如果子进程先于父进程结束,则内核会向父进程发一个信号告知子进程已经结束。n二是受阻的(blocking)方式,也称为“同步”方式,即父进程停下来进入睡眠状态,等待子进程结束,然后父进程再继续运行。Linux为此提供了两个系统调用,wait4和wait3。两个系统调用基本相同,wait4等待某个特定的子进程结束,而wait3则等待任何一个子进程结束。445.2.2 存储管理模块oLinux的虚拟地址空间olinux的存储管理由两个部分组成:n第一个是物理内存的管理n第二个是虚拟存储器的管理,主要是进程虚拟地址空间的管理455.2.2 存储管理模块o有了虚拟存储器,程序员在编写程序的时候,就可以不用考虑内存的实际大小和程序的具体运行位置了,这个时候,他所使用的地址被称为了逻辑地址,或者虚拟地址,而所对应的物理地址,指的是程序真正运行的时候所占用的地址。o从逻辑地址到物理地址的转换是需要操作系统内核和CPU的硬件部件MMU共同配合来完成的,如下MMU的功能说明图 存储模块的硬件基础46逻辑地址到物理地址的转换 475.2.2 存储管理模块o80386把线性地址空间划分成4K字节的页面,每个页面可以被映射至物理存储空间中任意一块4K字节大小的区间。o在段式存管中,连续的逻辑地址经过映射后在线性地址空间还是连续的。o但是在页式存管中,连续的线性地址经过映射后在物理空间却不一定连续(其灵活性也在于此)。48分页机制地址转换495.2.2 存储管理模块oLinux的存储管理模块 50内存映射 o当一个映像执行时,执行映像的内容必须放在进程的虚拟地址空间中。对于执行映像连接到的任意共享库,情况也是一样。执行文件实际并没有放到物理内存,而只是被连接到进程的虚拟内存。这样,只要运行程序引用了映像的部分,这部分映像就从执行文件中加载到内存中。这种映像和进程虚拟地址空间的连接叫做内存映射。51mm_structo进程的虚拟内存用mm_struct 数据结构表示。它包括当前执行的映像的信息(例如 bash)和指向一组 vm_area_struct 结构的指针。o每一个 vm_area_struct 的数据结构都描述了内存区域的起始、进程对于内存区域的访问权限和对于这段内存的操作。o这些操作是一组例程,用于管理这段虚拟内存。例如其中一种虚拟内存操作就是当进程试图访问这段虚拟内存时,如果发现(通过 page fault)内存不在物理内存中,所必须执行的正确操作,这个操作叫做nopage 操作。Linux 请求把执行映像的页加载到内存中的时候用到 nopage 操作。52vm_area_structo当一个执行映像映射到进程的虚拟地址空间时,产生一组 vm_area_struct 数据结构。每一个vm_area_struct 结构表示执行映像的一部分:执行代码、初始化数据(变量)、未初始化数据等等。Linux 支持一系列标准的虚拟内存操作,当 vm_area_struct 数据结构创建时,一组正确的虚拟内存操作就和它们关联在一起。o只要执行映像映射到进程的虚拟内存中,它就可以开始运行。因为只有映像的最开始的部分是放在物理内存中,很快就会访问到还没有放在物理内存的虚拟空间区。当进程访问没有有效页表条目的虚拟地址的时候,处理器向 Linux 报告 page fault。Page fault 描述了发生 page fault 的虚拟地址和内存访问类型。53Linux的虚拟地址空间的映射o从页的分配角度来说。虚拟地址中的页的类型有下面三个类型:如图所示:n未分配:n已分配了的、但是没有缓存的n已分配的且被缓存的 54第五章 Linux内核5.1 Linux 内核概述5.2 Linux 内核模块简介5.3 Linux 的编译和定制5.4 Linux 系统调用举例555.3 Linux 的编译和定制o8.3.1 Linux 内核编译概述o8.3.2 编译内核前的准备工作o8.3.3 编译内核第一步:配置内核o8.3.4 编译内核第二步:编译内核o8.3.5 编译内核后生成的文件565.3.1 Linux 内核编译概述o如果用户想要使用内核的一些新特性,或想根据自己的系统量身定制一个更高效或更稳定的内核,就需要重新编译内核。o编译内核包含两大项内容:n第一步:配置内核n第二步:编译内核。575.3.2 编译内核前的准备工作o编译内核前先要了解自己系统的硬件配置情况,比如CPU的类型、主板芯片、显卡和声卡的型号以及其他相关参数等。o也要了解现有内核的版本号nuname-a nLinux localhost localdomain 2.4.20-8#1 Thu Mar 13 17:54:28 EST 2003 i686 i686 i386 GNU/Linux 585.3.2 编译内核前的准备工作o把下载好的打包的内核解开。压缩的内核、补丁和解开的源代码总共要占70M 左右的硬盘空间;用root 登录,解开的源代码应该在/usr/src/Linux 2.4.20-8 下面:n#tar zxvf Linux 2.4.20-8.tar.gz 或者n#gzip t Linux 2.4.20-8.tar.gz n#tar x Linux 2.4.20-8.tar 595.3.3 编译内核第一步:配置内核o在开始配置内核之前,首先需要通过下面的命令清除所有的临时文件、中间件和配置文件。对于一个刚从网上下载的内核来说,它肯定是干净的,这么做只会多此一举。但是这是一个良好习惯,而且不会有坏结果。n#make mrproper 605.3.3 编译内核第一步:配置内核omake menuconfig:一个文本模式、简单的菜单模式的配置界面615.3.3 编译内核第一步:配置内核omake xconfig:基于Tcl/Tk的X图形配置界面 625.3.3 编译内核第一步:配置内核o根据自己的需要,进行各个选择和子选项的配置。对每一个内核选项,可以有三个选择:不包括(N),build-in(Y),和模块化支持(M)。635.3.4 编译内核第二步:编译内核o编译内核的软件环境是kbuild系统,它泛指构建一个完整并能够运行的Linux内核所需要的一切资源。这些资源包括构建程序、脚本、中间件、配置文件和Makefile。o编译过程:在/usr/src/linux下依次输入以下命令(功能请参考书上描述)nmake depnmake cleannmake bzImagenmake installnmake modulesnmake modules_install645.3.5 编译内核后生成的文件1.vmlinuz ovmlinuz是可引导的、压缩的内核。“vm”代表“Virtual Memory”。ovmlinuz的建立有两种方式:n一是编译内核时通过“make zImage”创建,然后通过:“cp/usr/src/linux-2.4/arch/i386/linux/boot/zImage/boot/vmlinuz”产生。zImage适用于小内核的情况,它的存在是为了向后的兼容性。n二是内核编译时通过命令make bzImage创建,然后通过:“cp/usr/src/linux-2.4/arch/i386/linux/boot/bzImage/boot/vmlinuz”产生。bzImage是压缩的内核映像,需要注意,bzImage不是用bzip2压缩的,bzImage中的bz容易引起误解,bz表示“big zImage”。bzImage中的b是“big”意思。65vmlinuzozImage(vmlinuz)和bzImage(vmlinuz)都是用gzip压缩的。它们不仅是一个压缩文件,而且在这两个文件的开头部分内嵌有gzip解压缩代码。所以不能用gunzip 或 gzip dc解包vmlinuz。o内核文件中包含一个微型的gzip用于解压缩内核并引导它。两者的不同之处在于,老的zImage解压缩内核到低端内存(第一个640K),bzImage解压缩内核到高端内存(1M以上)。如果内核比较小,那么可以采用zImage 或bzImage之一,两种方式引导的系统运行时是相同的。大的内核采用bzImage,不能采用zImage。ovmlinux是未压缩的内核,vmlinuz是vmlinux的压缩文件。665.3.5 编译内核后生成的文件o2.initrd-x.x.x.img ninitrd-x.x.x.img是用gzip压缩的文件。ninitrd是“initial ramdisk”的简写。initrd一般被用来临时引导硬件驱动到实际内核vmlinuz,使其能够接管并继续引导的状态。ninitrd实现加载一些模块和安装文件系统等功能。initrd映象文件是使用mkinitrd创建的。675.3.5 编译内核后生成的文件o3.System.mapn是一个特定内核的内核符号表,是由“nm vmlinux”产生的n在进行程序设计时,会命名一些变量名或函数名之类的符号。Linux内核是一个很复杂的代码块,有许多的全局符号。nLinux内核不使用符号名,而是通过变量或函数的地址来识别变量或函数名。比如不是使用size_t BytesRead这样的符号,而是像c0343f20这样引用这个变量。n对于使用计算机的人来说,更喜欢使用那些像size_t BytesRead这样的名字,而不喜欢像c0343f20这样的名字。内核主要是用c写的,所以编译器/连接器允许我们编码时使用符号名,当内核运行时使用地址。68System.mapo在有的情况下,我们需要知道符号的地址,或者需要知道地址对应的符号。这由符号表来完成,符号表是所有符号连同它们的地址的列表。Linux 符号表使用到2个文件:n/proc/ksyms nSystem.map o/proc/ksyms是一个“proc file”,在内核引导时创建。实际上,它并不真正的是一个文件,它只不过是内核数据的表示,却给人们是一个磁盘文件的假象,这从它的文件大小是0可以看出来。o而System.map是存在于你的文件系统上的实际文件。当你编译一个新内核时,各个符号名的地址要发生变化,老的System.map具有的是错误的符号信息。每次内核编译时产生一个新的System.map,你应当用新的System.map来取代老的System.map。o虽然内核本身并不真正使用System.map,但其它程序比如klogd、lsof和ps等软件需要一个正确的System.map。69第五章 Linux内核5.1 Linux 内核概述5.2 Linux 内核模块简介5.3 Linux 的编译和定制5.4 Linux 系统调用举例705.4 Linux 系统调用举例o5.4.1 Linux系统调用介绍o5.4.2 给内核增加新的系统调用的实例715.4.1 Linux系统调用介绍oAPI函数与系统调用既有区别又有联系。nAPI是用于某种特定目的的函数,供应用程序调用,而系统调用供应用程序直接进入系统空间。n系统包含了一些供应用程序调用的API函数库,其中的一些仅用于提供系统调用,因此每个系统调用都与一个API函数相对应,反之则不成立 n大多数系统调用的返回值是一个整数,通常返回1表示系统调用失败,返回非负数表示函数执行成功。n系统调用虽然是为应用程序主动进入系统空间而设置,但在内核的开发中也可以使用某些系统调用(如open,read,write等函数)725.4.1 Linux系统调用介绍o系统调用的功能图n应用程序和系统调用及其内核实现之间的层次关系 735.4.2 给内核增加新的系统调用的实例o需要实际操作完成o需要理解每一个修改点的含义和作用74系统调用o与系统调用相关的源程序文件包括以下这些:narch/i386/boot/bootsect.Snarch/i386/Kernel/setup.Snarch/i386/boot/compressed/head.Snarch/i386/kernel/head.S ninit/arch/i386/kernel/arch/i386/kernel/entry.Snarch/i386/kernel/irq.hninclude/asm-386/unistd.h o当然,这只是涉及到的几个主要文件。而事实上,增加系统调用真正要修改文件只有include/asm-386/unistd.h 和arch/i386/kernel/entry.S两个 751 修改kernel/sys.c文件 o在Red Hat 9.0的/usr/src/linux-2.4.20-8/kernel/sys.c文件中增加一个新的自定义系统调用函数:asmlinkage long sys_testsyscall(int num)return num;762 修改include/asm-i386/unistd.h文件 o在unix系统标准头文件/usr/src/linux/include/asm-i386/unistd.h 的末尾,增加一行。o该文件中包含了系统调用清单,用来给每个系统调用分配一个唯一的号码。文件中每一行的格式如下:#define _NR_name NNNo需要说明的是:具体的数值要看读者所采用的内核版本而定,一般都是在系统已有的编号的基础上加1。n#define _NR_testsyscall 259773 修改arch/i386/kernel/entry.S文件 o在/usr/src/linux/arch/i386/kernel/entry.S的文件末尾增加一行o该文件中有类似如下的清单:.long SYMBOL_NAME()该清单用来对sys_call_table数组进行初始化。该数组包含指向内核中每个系统调用的指针。这样就在数组中增加了新的内核函数的指针。o下面这行代码导出了上面新添加的系统调用函数。n.long SYMBOL_NAME(sys_testsyscall)784 编译内核o正确的编译过程大致如下:nmake mrpropernmake xconfigo增加initrd.img的support o如果是在VMWare下,一般默认的硬盘都是SCSI的,所以,需要把SCSI Support选中,并在其Low SCSI 选项中,把BusLogic Support选中。然后进行新内核的编译:nmake depnmake bzImagenmake modulesnmake modules_installnmake install 795.启动内核o内核编译成功后,需要修改BootLoader来启动这个新的内核,以lilo为例,修改后的lilo.conf如下所示:805.启动内核oreboot,下面就会出现linux-2.4.20-8custom的一个内核启动选项,就是刚刚新编译生成的。816.测试新增系统调用 o#include#include int errno;_syscall1(long,testsyscall,int,num);main()printf(“%dn”,testsyscall(10011);82o编辑完成后,保存。编译a.c程序,gcc I/usr/src/linux-2.4.20-8/include a.c,生成a.out。执行./a.out后,出现下面的结果 83讨论o如果硬件平台没有MMU,对操作系统会有什么影响?84作业o1.完成Linux内核的Struct task的代码浏览o2.完成嵌入式Linux内核的编译o3.完成嵌入式Linux内核的API的增加实验85End of Chapter 586
展开阅读全文
相关资源
相关搜索

最新文档


当前位置:首页 > 图纸专区 > 课件教案


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!