




已阅读5页,还剩17页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
操作系统课程设计第1页目目录录概述概述.1一一.课设分析的具体内容课设分析的具体内容.3二二.分析的具体目标分析的具体目标.4三三BOOOTSECT.S源代码分析基础源代码分析基础.51磁盘参数.52BIOS的INT13H调用.53根文件系统的命名方式及设备号的计算.74.串传输指令.7四各模块源代码的分析四各模块源代码的分析.81.BOOTSECT将自身从目前段位置0X07C0移到0X9000处.92.将SETUP模块读到0X90200开始处.93.获得磁盘驱动参数.104.显示LOADINGSYSTEM.115.将系统模块加载到0X10000处.126.检查要使用哪个根文件系统设备.127.保存设备号,并跳转到0X9020:0000处.14分析研究体会分析研究体会.17自我评价自我评价.20参考文献参考文献.21操作系统课程设计第2页概述概述Linux作为一个优秀的操作系统,其原因之一应归属于开放的内核源代码。说起内核源代码,我们不得不存着敬畏的心理。它在Linux中的地位好像心脏在我们身体中的地位一样重要,它是整个操作系统的灵魂。因此要更好的了解Linux,分析他的源代码是非常必要的。在这次课程设计中我选择分析的是Linux0.11的Boot.s的引导块源代码分析。首先我们粗略的看一下计算机内开机过程:通电后,CPU完成自检和初始化,设置寄存器内的初值,而后执行第一条指令。该指令的地址是CS16+IP,即0 xFFFF0,该地址是BIOS的入口地址。BIOS对整个机器系统完成自检后,将有关系统配置的基本信息记录在内存的BIOS数据区中,然后把引导盘的第一个扇区读入内存的0 x7C00处。转到该处,把控制权交给引导程序,最后引导程序把操作系统读入内存中,并把控制权交给操作系统内核。我们再来看看引导启动程序目录Boot。Boot目录中含有三个汇编语言文件,是内核源代码中最先被编译的程序。这3个程序完成的主要功能是当计算机加电时引导内核启动,将内核代码加载到内存中,并做一些进入32位保护运行方式前的系统初始化工作。其中bootsect.s和setup.s程序需要使用as86软件来编译,使用的是as86的汇编语言格式(与微软的类似),而head.s需要用GNUas来编译,使用的是AT&T格式的汇编语言。我主要研究的是Boot.s的引导块源代码分析。所以对setup.s和操作系统课程设计第3页head.s不做详细解释。Setup.s程序主要是读取机器的硬件配置参数,并把内核模块System移动到适当的内存位置。Head.s程序被编译连接到System的最前部分,主要进行硬件设备的探测设置和内存管理页面的初始化设置工作。Bootsect.s代码是磁盘引导块程序,驻留在磁盘的第一个扇区中(引导扇区,0磁道(柱面),0磁头,第1个扇区)。在PC机加电ROMBIOS自检后,引导扇区由BIOS加载到内存0 x7c00处,然后将自己移到内存0 x9000处。该程序的主要作用是首先将setup模块从磁盘加载到内存,紧接着bootsect的后面位置(0 x9200),然后利用BIOS中断0 x13取磁盘参数中当前启动引导盘的参数,接着在屏幕上显示”Loadingsystem.”字符串,再者将system模块从磁盘上加载到内存ox1000开始地方。随后确定根文件系统的设备号。若设备指定,则根据所保存的引导盘的磁道扇区数判别出盘的类型和种类并保存起设备号于root_dev(引导块的0 x508地址处)。最后长跳转到setup程序开始处(0 x90200)执行setup程序。一一.课设分析的具体内容课设分析的具体内容由于Linux内核是一种单内核模式的系统。因此,内核中的所有程序都有密切的联系,他们之间的依赖和调用关系非常密切。所以我们先来看看源代码的目录结构,从目录结构中我们就可以看到我所分析的源代码所处的位置了(图转第2页)。我所分析的则是linuxboot下的bootsect.s汇编源程序。Bootsect.s程序是磁盘引导块程序,编译后会驻留在磁盘的第一操作系统课程设计第4页个扇区。在PC加电ROMBIOS自检后,将被BIOS加载到内存0 x7c00处进行执行。图1.1Linux源代码的目录结构二二.分析的具体目标分析的具体目标通过分析一个早期的Linux内核,加深对操作系统各个组成模块具体实现机制的理解,同时也为今后从事底层的研究开发增加一些实践经验。通过对bootsect.s的分析,进一步了解Linux的启动过程,明白计算机从开始加电后做了什么?进一步认识引导程序,通过BIOS读磁盘扇区的方法以及BIOS的中断处理。同时也可以巩固汇编的一些知识和80 x86的系统结构,熟悉源代码的目录结构,了解文件从哪里调用,明白系统在加电后进入实操作系统课程设计第5页模式后内存的分布情况等。三三Boootsect.s源代码分析基础源代码分析基础11磁盘参数磁盘参数我们在研究磁盘参数方面主要考虑这三部分CHS(CylinderHeadSector).即磁头数(Heads)、柱面数(Cylinders)、扇区数(Sectors).其中:磁头数(Heads)表示磁盘总共有几个磁头也就是有几面盘片最大为255(用8个二进制位存储);柱面数(Cylinders)表示磁盘每一面盘片上有几条磁道最大为1023(用10个二进制位存储);扇区数(Sectors)表示每一条磁道上有几个扇区最大为63(用6个二进制位存储);每个扇区一般是512个字节(理论上讲这不是必须的,但好象都取此值)。据此,磁盘最大容量为:2551023635121048576=8024MB(1M=1048576Bytes)在CHS寻址方式中磁头柱面扇区的取值范围分别为0到Heads-10到Cylinders-11到Sectors(注意是从1开始)。22BIOSBIOS的的IntInt13H13H调用调用BIOS的13H中断功能是专门用来管理磁盘的。中断13H功操作系统课程设计第6页能每次处理的磁盘数据是若干个扇区,调用前要求用户给出访问的第1个扇区所在的磁盘物理地址(磁道号、扇区号、磁头号)和访问的扇区数。功能入口参数出口参数(AH)=0磁盘复位(AH)=1读磁盘状态(AL)=状态字节(AH)=2读指定扇区(DH)=面号(01)(DL)=驱动器号(03)(CH)=磁道号(039)(CL)=扇区号(19)(AL)=扇区数(18)(ES:BX)=数据缓冲区地址读成功:(AH)=0(AL)=读出的扇区数读失败:(AH)=出错代码(AH)=3写指定扇区同上写成功:(AL)=写入的扇区数,其余同上磁盘驱动程序13H(AH)=4检查指定扇区同上,(ES:BX)不设置成功:(AL)=检查的扇区数,其余同上操作系统课程设计第7页(AH)=5对指定磁道格式化(ES:BX)=磁道地址同(AH)=4的出口参数33根文件系统的命名方式及设备号的计算根文件系统的命名方式及设备号的计算Linux老式硬盘命名方式,具体值含义如下:设备号=主设备号256+次设备号(主设备号:1内存,2磁盘,3硬盘,4ttyx5tty,6并行口,7非命名管道)0 x300devhd0代表整个第1个硬盘0 x301devhd1第1个盘的第1个分区0 x302devhd2第1个盘的第2个分区0 x303devhd3第1个盘的第3个分区0 x304devhd4第1个盘的第4个分区0 x305devhd5代表整个第2个硬盘0 x306devhd6第2个盘的第1个分区其它的依次类推。在Linux中软驱的主设备号是2,次设备号=type4+nrnr为03分别对应软驱ABC或D,type是软驱的类型(2-1.2M或7-1.44M等)。因为74+0=28,所以devps0(228)指的是1.44MA驱动器,其设备号是0 x021C同理devat0(28)指的是1.2MA驱动器,其设备号是0 x0208.操作系统课程设计第8页4.4.串传输指令串传输指令MOVSBMOVSW执行的操作:字节:(ES:DI)指向数据缓冲区;如果出错则CF标志位置位。对应程序流程图如下:操作系统课程设计第11页置磁头号,驱动器号为0置磁道号为0,开始扇区为2置地址为Initseg段中的0 x0200处置读磁盘扇区到内存的0 x0200处,需要读出的扇区数为4调用13H号中断CF=0Y跳入OK_load_setup继续执行置0 x0000-dx0 x0000-ax调用13H号中断N图4.2将setup读到0 x90200处3.3.获得磁盘驱动参数获得磁盘驱动参数其相应代码请参见Linux内核完全注释的P54页的代码注释,对应代码的8390行。对应于OK_load_setup程序段用于取磁盘驱动器参数,尤其是每道的扇区数量。取磁盘驱动器参数INT13H调用格式和返回信息如下:AH=0 x08DL=驱动器号(如果是硬盘位7为1)返回信息:如果出错则CF置位,并且AH=状态码AH=0AL=0;BL=驱动器类型(ATPS2)操作系统课程设计第12页CH=最大磁道号的低8位;CL=每磁道最大扇区数(05位),最大磁道号高2位(67)DH=最大的磁道数;DL=驱动器数量ES:DI-软驱磁盘参数表置驱动器号为0置AH=0 x08调用13H号中断置最大磁道号的低8位为0保存每磁道扇区数将ES重新置回0 x9000图4.3读磁盘驱动参数4.4.显示显示LoadingLoadingsystem.system.其相应代码请参见Linux内核完全注释的P54页的代码注释,对应代码的94102行。对应流程图如下:操作系统课程设计第13页读光标位置置页号为0调用10H号中断置共要显示的字符个数为24指向要显示的字符串写字符串并移动光标调用10H号中断图4.4显示Loadingsystem5.5.将系统模块加载到将系统模块加载到0 x100000 x10000处处其相应代码请参见Linux内核完全注释的P54页的代码注释,对应代码的107110行。对应流程图如下:置ES=存放system的段地址读磁盘上system模块,ES为输入模块参数关闭驱动马达,这样就可以知道驱动器的状态了图4.5将system加载到0 x10000处6.6.检查要使用哪个根文件系统设备检查要使用哪个根文件系统设备上一步之后,我们要检查使用哪个根文件系统设备(简称根设备)。如果已指定了设备(!=0)就直接使用给定的设备。否则就需要根据BIOS报告的每磁道扇区数来确定到底使用devPS0(2,28),还是devat0(28).操作系统课程设计第14页上面一行中两个设备文件的含义:在Linux中软驱的主设备号是2,次设备号=type4+nrnr为03分别对应软驱ABC或D,type是软驱的类型(2-1.2M或7-1.44M等)。因为74+0=28,所以devps0(228)指的是1.44MA驱动器,其设备号是0 x021C同理devat0(28)指的是1.2MA驱动器,其设备号是0 x0208.其相应代码请参见Linux内核完全注释的P5455页的代码注释,对应代码的117128行。对应流程图如下:将根设备号-ax比较ax是否等于0N转入root_defined继续执行Y取保存的每磁道扇区数将devat0的设备驱动号0 x0208-ax比较bx是否等于15Y将devat0的设备驱动号0 x021c-ax比较bx是否等于18NY死机N操作系统课程设计第15页图4.6确定根文件系统设备7.7.保存设备号,并跳转到保存设备号,并跳转到0 x9020:00000 x9020:0000处处其相应代码请参见Linux内核完全注释的P55页的代码注释,对应代码的131139行。即Root_defined:segcsMovroot_devax将检查过的设备号保存起来Jmpi0setupseg跳转到0 x9020:0000(setup.s程序开始处)综上所述,bootsect.s主要要完成的工作就是按上面的7个步骤来执行的,对应的整体流程图如下:操作系统课程设计第16页开始定义了6个全局表识符初始化setup程序的扇区数,bootsect的原始地址,bootsect移动到的地址,setup程序的开始地址等信息将源地址置为ds:si=0 x07c0:0 x0000目的地址es:di=0 x9000:0 x0000Bootsect.s的程序长度256字-cx移动1个字Cx=0YN将dses和ss都置为0 x9000将堆栈指向0 x9000:0 xff00处给出被访问的第1扇区所在的磁盘物理地址和访问的扇区数调用13H中断获得磁盘驱动器的参数显示Loadingsystem.将system模块加载到0 x1000处检查是否已指定了设备?Y保存检查过的设备号跳转到0 x9000:0000setup.s程序的开始处判断磁道扇区数是否为15NY判断磁道扇区数是否为18NY开始N图4.7boosect.s整体流程图在整个过程中内存的变化属最大了,理清内存的变化也是我们分析的重点。从PC电源加电后进入实模式,这时候内存大小为1MB.下图为从加电开始到Bootsect.s执行结束内存的变化:(具体的一些操作系统课程设计第17页内存移动的原因在分析研究体会中做了解释)PC加电从0 xFFFF0开始执行代码(ROMBIOS中的地址)在物理地址0处开始初始化中断向量(共1KB大小)将Bootsect.s读入到内存绝对地址0 x7c00处Bootsect.s将自己从0 x7c00移到0 x90000将setup.s程序加载到0 x90200处将system模块加载到0 x10000处跳到0 x90200处继续执行setup.s程序图4.8从开机到执行完Bootsect.s后内存变化图因此,我们可以看一下,在计算机初始化时,1MB的物理内存的大致安排情况:低端640KB为基本内存(RAM)所以当加载Bootsect.s后,执行过程中程序的移动和加载都在这个范围内;A0000HBFFFFH保留给显示卡的显存使用(ROM);C0000HFFFFFH保留给BIOS(biosrom)使用,这样就可以解释加电后的开始执行的地址为0 xFFFF0了。0 x000000 x00400共1KB大小为BIOS中断向量表,这是由初始执行的BIOS程序初始化到RAM中的。最后,我们来看看开机初始化时,对堆栈的使用。当bootsect.s代码被ROMBIOS引导加载到物理内存0 x7c00处时,操作系统课程设计第18页并没有设置堆栈段,当然程序也没有使用堆栈,直到bootsect被移动到0 x90000处时,才把堆栈段寄存器SS设置为0 x9000堆栈指针ESP寄存器设置为0 xFF00,也即堆栈顶端在0 x9000:0 xFF00处,参见bootbootsect.s第61,62行。这就是系统初始化时临时使用的堆栈。分析研究体会分析研究体会这次,我们分析的Linux0.11源代码,因为以前都没怎么分析过,所以选择从开始进行分析,于是选了Bootsect.s引导块程序进行分析。Bootsect.s中的程序需要使用as86软件来编译,使用的是as86的汇编语言格式(与微软的类似),总共大小为512字节。所涉及的语言仅汇编一种,没有C语言。对于汇编语言我们在大二上学期就已经学了,再加之这个学期刚学完单片机,对于这部分代码要看懂他还是没问题。一开始在有点汇编基础上加之源代码又有注释,觉得看起来还挺顺的,好像没花多长时间就看完了。后来再具体分析阶段,开始对每个模块进行分析画流程图时,问题慢慢就出来了。在第一部分中就遇到了repmovw这两句到底是怎么用的呀,只知道大概就是循环执行256次,画流程图时就出现了到底循环哪部分,还有这源地址和目的地址有什么用呀。后来翻书才明白原来这是串传输指令,把SI所指向的源串一个字传送到DI所指向的目的串中,同时按照DF修改SI和DI。当该指令与REP联用时,就可以将bootsect.s从0 x07c0处移到0 x9000处了。操作系统课程设计第19页在汇编程序上的问题还有就是Int13H号调用,具体的入口参数,出口参数,及干什么用的不清楚。总不明白在load_setup为什么要调用两次中断,第一次,当然知道是使setup模块从第2个扇区开始读到0 x90200开始处,即调用中断的目的是读磁盘扇区到内存,第二个调用在没翻书前就太清楚了。后面翻书后才比较清楚了,第二次调用原来是磁盘复位。同样在显示LoadingSystem同样有Int10H号中断也不太清楚,看书后才明白了。小问题解决了,就还存在一个整体上的问题,那个bootsect.s程序干吗要移来移去,内存地址开始处为什么不从0开始呢,等地址问题,有些搞不清楚,后面通过查阅资料终于能理清一些思路了。PC电源打开后,进入实模式,并从0 xffff0开始自动执行程序代码。这个地址通常是ROMBIOS中的地址,将执行某些系统检测,并在物理地址0处开始初始化中断向量,此后,他将可启动的设备的第一个扇区读入内存绝对地址0 x7c00处,并跳转到这个地址。计算机初始化启动时,CPU默认是在实模式下开始寻址和执行指令的。这时候1MB的物理内存是这样安排的:低端640KB被称为基本内存(RAM)而A0000HBFFFFH要保留给显卡的显存使用的(ROM),C0000FFFFFH则被保留给BIOS(biosrom)使用,其中系统BIOS一般占用最后的62KB或更多一点的空间,显示卡BIOS一般在C0000HC7FFFH处,IDE控制器的BIOS在C8000HCBFFFH.但这并不意味着BIOS中断向量表也在ROM中,这是由初始执行的BIOS程序初始化到RAM中的(从物理地址00000H开始的1KB)。操作系统课程设计第20页这两段使我明白了原来bootsect.s不是一开机就有了的,原来是通过ROMBIOS将bootsect.s读入到内存中的,之后才有bootsect.s的执行,在此期间他还要初始化中断向量。中断向量占据着物理地址的低1KB字节,所以bootsect.s也不能读到0开始的位置。那为什么地址要移来移去呢,BIOS加电后,会将boot加载到7c00H上,这是不能改变的,而如果加载到这个地方,会让system加载时很尴尬,所以,要将引导程序向后移动。移动代码本身的原因通常是因为内存地址重复。比如MBR会把自己从0 x7c00移动到别处,是因为后面的分区引导记录也会被装载到0 x7c00处,如果不移动,将会导致代码被覆盖的情况发生,倘若代码被覆盖,就不能被CPU正常执行。还有一中情况是为了节省内存。我想我们这里移动代码的原因还是第一种情况吧,第二种情况是后面的将System又移动到00000H处的,这不是我所研究的范围。至于前面说的会让system加载很尴尬,我想也可能是因为后面要将system移到00000H处的原因吧。这个我不能确定,因为后面的程序我还没看。大问题总算解决了还有些小问题,如一会儿又是设备驱动器号一会儿又是设备号,真是都快搞晕了。查了一下,好像是说调用BIOS的0 x13中断,DL中设置的入口参数是驱动器号,设备驱动器号是BIOS设置好的,例如:00表示磁盘,80表示硬盘,而设备号是LINUX系统编号。还有要知道根文件系统设备。哦,好像明白了点是不是要加载System,system在文件系统下面,所以要知道根文件系统设备。启
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
评论
0/150
提交评论