欢迎来到乐乐文库,课件爱好者! | 帮助中心 精品ppt课件,ppt课件精品!
乐乐文库,课件爱好者
首页 乐乐文库,课件爱好者 > 资源分类 > PPT文档下载

03LINUX内核引导启动程序.ppt

  • 资源大小:855.00KB        全文页数:28页
  • 资源格式: PPT        下载权限:游客/注册会员/VIP会员    下载费用:15金币 【人民币15元】
游客快捷下载 游客一键下载
会员登录下载
下载资源需要15金币 【人民币15元】

邮箱/手机:
温馨提示:

支付成功后,系统会根据您填写的邮箱或者手机号作为您下次登录的用户名和密码(如填写的是手机,那登陆用户名和密码就是手机号),方便下次登录下载和查询订单;
特别说明:
请自助下载,系统不会自动发送文件的哦;
支付方式: 支付宝   
验证码:   换一换

 
友情提示
2、本站资源不支持迅雷下载,请使用浏览器直接下载(不支持QQ浏览器)
3、本站资源下载后的文档和图纸-无水印,预览文档经过压缩,下载后原文更清晰   

03LINUX内核引导启动程序.ppt

LINUX内核引导程序,武汉大学计算机学院 郑鹏 Emailpzheng51163.com,LINUX系统初始化1,1.当PC启动时,Intel系列的CPU首先进入的是实模式,并开始执行位于地址0xFFFF0处的代码(只用于实模式高地址位忽略,也就是ROM-BIOS起始位置的代码。BIOS先进行一系列的系统自检,然后初始化位于地址0的中断向量表。最后BIOS将启动盘的第一个扇区,也就是bootsect.S,装入到0x7C0031K处,并开始执行此处的代码。,LINUX系统初始化2,2.当bootsect.S开始运行时,将自己装入到绝对地址0x90000 576K处,再将其后的2k字节代码boot/setup.s装入到地址0x90200处,最后将核心的其余部分(system 模块)装入到0x10000。当系统装入时,会显示Loading...信息。 装入完成后,控制转向另一个实模式下的汇编语言代码boot/setup.S。 因为当时system 模块的长度不会超过0x80000 字节大小(即512KB),所以它不会覆盖在0x90000处开始的bootsect 和setup 模块。随后将system 模块移动到内存起始处,这样system 模块中代码的地址也即等于实际的物理地址。便于对内核代码和数据的操作。,LINUX系统初始化3,3.Setup部分首先设置一些系统的硬件设备,然后将核心从0x10000处移至0x1000处。这时系统转入保护模式,开始执行位于0x1000处的代码。,LINUX系统初始化4,4.接下来是内核的解压缩。0x1000处的代码来自于文件zBoot/head.S,它用来初始化寄存器和调用decompress_kernel程序。decompress_kernel程序由zBoot/inflate.c, zBoot/unzip.c 和zBoot/misc.c组成。解压缩后的数据被装入到了0x100000处,这也是Linux不能在内存小于2M的环境下运行的主要原因。 5.解压后的代码在0x1010000处开始执行,紧接着所有的32位的设置都将完成 IDT、GDT和LDT将被装入,处理器初始化完毕,设置好内存页面,最终调用start_kernel过程。这大概是整个内核中最为复杂的部分。,LINUX系统初始化5,6.start_kernel程序用于初始化系统内核的各个部分,包括 设置内存边界,调用paging_init初始化内存页面。 初始化陷阱,中断通道和调度。 对命令行进行语法分析。 初始化设备驱动程序和磁盘缓冲区。 校对延迟循环。 7.最后,系统核心转向move_to_user_mode,以便创建初始化进程(init)。此后,进程0开始进入无限循环。,LINUX系统初始化6,启动引导时内核在内存中的位置和移动后的位置情况,bootsect.s 程序,功能描述 bootsect.s 代码是磁盘引导块程序,驻留在磁盘的第一个扇区中引导扇区,0 磁道柱面,0 磁头,第1 个扇区。在PC 机加电ROM BIOS 自检后,引导扇区由BIOS 加载到内存0x7C00 处,然后将自己移动到内存0x90000 处。该程序的主要作用是首先将setup 模块(由setup.s 编译成)从磁盘加载到内存,紧接着bootsect 的后面位置(0x90200),然后利用BIOS 中断0x13取磁盘参数表中当前启动引导盘的参数,接着在屏幕上显示“Loading system...”字符串。再者将system 模块从磁盘上加载到内存0x10000 开始的地方。随后确定根文件系统的设备号,若没有指定,则根据所保存的引导盘的每磁道扇区数判别出盘的类型和种类(是1.44M A 盘)并保存其设备号于root_dev引导块的0x508 地址处,最后长跳转到setup 程序的开始处(0x90200)执行setup 程序。,setup.s 程序,功能描述 setup 程序的作用主要是利用ROM BIOS 中断读取机器系统数据,并将这些数据保存到0x90000 开始的位置(覆盖掉了bootsect 程序所在的地方)。内核相关程序使用这些参数将。 然后setup 程序将system 模块从0x10000-0x8ffff(当时认为内核系统模块system 的长度不会超过此值512KB)整块向下移动到内存绝对地址0x00000 处。接下来加载中断描述符表寄存器idtr和全局描述符表寄存器gdtr,开启A20 地址线,重新设置两个中断控制芯片8259A,将硬件中断号重新设置为0x20 - 0x2f。最后设置CPU 的控制寄存器CR0(也称机器状态字),从而进入32 位保护模式运行,并跳转到位于system模块最前面部分的head.s 程序继续运行。 为了能让head.s 在32位保护模式下运行,在本程序中临时设置了中断描述符表idt和全局描述符表gdt,并在gdt 中设置了当前内核代码段的描述符和数据段的描述符。在下面的head.s 程序中会根据内核的需要重新设置这些描述符表。,setup.s 程序,在setup.s 程序执行结束后,系统模块system 被移动到物理地址0x0000 开始处,而从0x90000 处则存放了内核将会使用的一些系统基本参数。 此时临时全局表中有三个描述符,第一个是(NULL)不用,另外两个分别是代码段描述符和数据段描述符。它们都指向系统模块的起始处,也即物理地址0x0000 处。这样当setup.s 中执行最后一条指令 jmp 0,8 (第193 行)时,就会跳到head.s 程序开始处继续执行下去。这条指令中的8是段选择符,用来指定所需使用的描述符项,此处是指gdt 中的代码段描述符。0是描述符项指定的代码段中的偏移值。,setup.s 程序,setup.s 程序结束后内存中程序示意图,head.s 程序,head.s 程序在被编译后,会被连接成system 模块的最前面开始部分,这也就是为什么称其为头部head程序的原因。从这里开始,内核完全都是在保护模式下运行了。head.s 汇编程序与前面的语法格式不同,它采用的是ATT 的汇编语言格式,并且需要使用GNU 的gas 和gld2进行编译连接。因此请注意代码中赋值的方向是从左到右。,head.s 程序,这段程序实际上处于内存绝对地址0 处开始的地方。首先是加载各个数据段寄存器,重新设置中断描述符表idt,共256 项,并使各个表项均指向一个只报错误的哑中断程序。然后重新设置全局描述符表gdt。接着使用物理地址0 与1M 开始处的内容相比较的方法,检测A20 地址线是否已真的开启(如果没有开启,则在访问高于1Mb 物理内存地址时CPU 实际只会访问(IP MOD 1Mb)地址处的内容),如果检测下来发现没有开启,则进入死循环。然后程序测试PC 机是否含有数学协处理器芯片(80287、80387 或其兼容芯片),并在控制寄存器CR0 中设置相应的标志位。接着设置管理内存的分页处理机制,将页目录表放在绝对物理地址0 开始处(也是本程序所处的物理内存位置,因此这段程序将被覆盖掉),紧随后面放置共可寻址16MB 内存的4 个页表,并分别设置它们的表项。最后利用返回指令将预先放置在堆栈中的/init/main.c 程序的入口地址弹出,去运行main程序。,head.s 程序,head.s 程序执行结束后,已经正式完成了内存页目录和页表的设置,并重新设置了内核实际使用的中断描述符表idt 和全局描述符表gdt。另外还为软盘驱动程序开辟了1KB 字节的缓冲区。,head.s 程序,system 模块在内存中的映像示意图,Intel 32 位保护运行机制,CPU 在实模式运行方式时,段寄存器用来放置一个内存段地址(比如0x9000),而此时在该段内可以寻址64KB 的内存。但当进入保护模式运行方式时,此时段寄存器中放置的并不是内存中的某个地址值,而是指定描述符表中某个描述符项相对于该描述符表基址的一个偏移量。在这个8 字节的描述符中含有该段线性地址的‘段’基址和段的长度,以及其它一些描述该段特征的比特位。因此此时所寻址的内存位置是这个段基址加上当前执行代码指针eip 的值。而当前描述符表的基地址则保存在描述符表寄存器中,如全局描述符表寄存器gdtr、中断门描述符表寄存器idtr,加载这些表寄存器须使用专用指令lgdt 或lidt。当然,此时所寻址的实际物理内存地址,还需要经过内存页面处理管理机制进行变换后才能得到。 简而言之,32 位保护模式下的内存寻址需要经过描述符表中的描述符和内存页管理来确定。,Intel 32 位保护运行机制,针对不同的使用方面,描述符表分为三种 全局描述符表(GDT) 中断描述符表(IDT) 局部描述符表(LDT) 当CPU 运行在保护模式下,某一时刻GDT 和IDT 分别只能有一个,分别由寄存器GDTR和IDTR 指定它们的表基址。局部表可以有0-8191 个,其基址由当前LDTR 寄存器的内容指定,是使用GDT 中某个描述符来加载的,也即LDT 也是由GDT 中的描述符来指定。但是在某一时刻同样也只有其中的一个被认为是活动的。一般对于每个任务(进程)使用一个LDT。在运行时,程序可以使用GDT 中的描述符以及当前任务的LDT 中的描述符。,Intel 32 位保护运行机制,中断描述符表IDT 的结构与GDT 类似,在Linux 内核中它正好位于GDT 表的后面。共含有256 项8字节的描述符。但每个描述符项的格式与GDT 的不同,其中存放着相应中断过程的偏移值(0-1,6-7 字节)、所处段的选择符值(2-3 字节)和一些标志(4-5 字节)。,Intel 32 位保护运行机制,Linux 内核中所使用的描述符表在内存中的示意图,系统运行,初始化进程开始执行/etc/init、/bin/init 或/sbin/init中的一个之后,系统内核就不再对程序进行直接控制了。之后系统内核的作用主要是给进程提供系统调用,以及提供异步中断事件的处理。多任务机制已经建立起来,并开始处理多个用户的登录和fork创建的进程。,内核提供的各种系统调用,进程的基本概念和系统的基本数据结构 从系统内核的角度看来,一个进程仅仅是进程控制表(process table)中的一项。进程控制表中的每一项都是一个task_struct 结构,而task_struct 结构本身是在include/linux/sched.h中定义的。在task_struct结构中存储各种低级和高级的信息,包括从一些硬件设备的寄存器拷贝到进程的工作目录的链接点。 进程控制表既是一个数组,又是一个双向链表,同时又是一个树。其物理实现是一个包括多个指针的静态数组。此数组的长度保存在include/linux/tasks.h 定义的常量NR_TASKS中,其缺省值为128,数组中的结构则保存在系统预留的内存页中。链表是由next_task 和prev_task两个指针实现的,而树的实现则比较复杂。,内核提供的各种系统调用,进程的基本概念和系统的基本数据结构 系统启动后,内核通常作为某一个进程的代表。一个指向task_struct的全局指针变量current用来记录正在运行的进程。变量current只能由kernel/sched.c中的进程调度改变。当系统需要查看所有的进程时,则调用for_each_task,这将比系统搜索数组的速度要快得多。 某一个进程只能运行在用户方式(user mode)或内核方式(kernel mode)下。用户程序运行在用户方式下,而系统调用运行在内核方式下。在这两种方式下所用的堆栈不一样用户方式下用的是一般的堆栈,而内核方式下用的是固定大小的堆栈(一般为一个内存页的大小)。,内核提供的各种系统调用,创建进程 Linux系统使用系统调用fork来创建一个进程,使用exit 来结束进程。fork和exit的源程序保存在kernel/fork.c and kernel/exit.c中。fork的主要任务是初始化要创建进程的数据结构,其主要的步骤有 1)申请一个空闲的页面来保存task_struct。 2)查找一个空的进程槽(find_empty_process)。 3)为kernel_stack_page申请另一个空闲的内存页作为堆栈。 4)将父进程的LDT表拷贝给子进程。 5)复制父进程的内存映射信息。 6)管理文件描述符和链接点。,内核提供的各种系统调用,撤消进程 撤消一个进程可能稍微复杂些,因为撤消子进程必须通知父进程。另外,使用kill也可以结束一个进程。sys_kill、sys_wait和sys_exit都保存在文件exit.c中。,内核提供的各种系统调用,执行程序 使用fork创建一个进程后,程序的两个拷贝都在运行。通常一个拷贝使用exec调用另一个拷贝。系统调用exec负责定位可执行文件的二进制代码,并负责装入和运行。 Linux系统中的exec通过使用linux_binfmt结构支持多种二进制格式。每种二进制格式都代表可执行代码和链接库。linux_binfmt结构种包含两个指针,一个指向装入可执行代码的函数,另一个指向装入链接库的函数。 Unix系统提供给程序员6种调用exec 的方法。其中的5种是作为库函数实现,而sys_execve是由系统内核实现的。它执行一个十分简单的任务装入可执行文件的文件头,并试图执行它。如果文件的头两个字节是 ,那么它就调用在文件第一行中所指定的解释器,否则,它将逐个尝试注册的二进制格式。,存取文件系统,文件系统是Unix系统最基本的资源。最初的Unix系统一般都只支持一种单一类型的文件系统,在这种情况下,文件系统的结构深入到整个系统内核中。而现在的系统大多都在系统内核和文件系统之间提供一个标准的接口,这样不同文件结构之间的数据可以十分方便地交换。Linux也在系统内核和文件系统之间提供了一种叫做VFS(virtual file system)的标准接口。 这样,文件系统的代码就分成了两部分上层用于处理系统内核的各种表格和数据结构;而下层用来实现文件系统本身的函数,并通过VFS来调用。这些函数主要包括,存取文件系统,管理缓冲区 buffer.c。 响应系统调用fcntl 和ioctlfcntl.c and ioctl.c。 将管道和文件输入/输出映射到索引节点和缓冲区fifo.c, pipe.c。 锁定和不锁定文件和记录locks.c。 映射名字到索引节点namei.c, open.c。 实现select函数select.c。 提供各种信息stat.c。 挂接和卸载文件系统super.c。 调用可执行代码和转存核心exec.c。 装入各种二进制格式bin_fmt*.c。,存取文件系统,VFS接口则由一系列相对高级的操作组成,这些操作由和文件系统无关的代码调用,并且由不同的文件系统执行。其中最主要的结构有inode_operations 和file_operations。 file_system_type是系统内核中指向真正文件系统的结构。每挂接一次文件系统,都将使用file_system_type组成的数组。file_system_type组成的数组嵌入到了fs/filesystems.c中。相关文件系统的read_super函数负责填充super_block结构。,

注意事项

本文(03LINUX内核引导启动程序.ppt)为本站会员(w89153)主动上传,乐乐文库,课件爱好者仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知乐乐文库,课件爱好者(发送邮件至1748365562@qq.com或直接QQ联系客服),我们立即给予删除!

温馨提示:如果因为网速或其他原因下载失败请重新下载,重复下载不扣分。

关于我们 - 网站声明 - 网站地图 - 资源地图 - 友情链接 - 网站客服客服 - 联系我们

站长联系QQ:1748365562
工信部备案号: 鄂ICP备17024083号                 公安局备案号:42118102000213

收起
展开