linux内核完全注释(课件)第六章_第1页
linux内核完全注释(课件)第六章_第2页
linux内核完全注释(课件)第六章_第3页
linux内核完全注释(课件)第六章_第4页
linux内核完全注释(课件)第六章_第5页
已阅读5页,还剩50页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

Linux操作系统内核分析湘潭大学信息工程学院Linux操作系统内核分析湘潭大学信息工程学院1讲课内容设备管理简介硬盘驱动虚拟盘驱动讲课内容设备管理简介2块设备的操作方式P132图6-2块设备的操作方式P132图6-23设备管理模块读处理过程进程向缓冲区模块提出读块(2扇区)请求。缓冲区模块检查该块是否已经被缓冲。如果已经被缓冲,则直接返回缓冲的块;否则,向设备管理模块提出读请求。设备管理模块接受请求。如果设备不忙,则向设备发送命令;否则,把请求插入到设备的请求队列中。缓冲区模块挂起进程。设备控制器从设备中读入数据到自己的缓冲区中,并产生中断。设备中断处理程序把数据从控制器缓冲区读到内存缓冲区,然后唤醒进程。P248第267设备管理模块读处理过程进程向缓冲区模块提出读块(2扇区)请求4设备管理模块写处理过程缓冲区模块决定要回写被缓冲的块。如果该块是脏的,向设备管理模块提出写请求。设备管理模块接受请求。如果设备不忙,则向设备发送命令和数据;否则,把请求插入到设备的请求队列中。缓冲区模块挂起进程。设备控制器把数据写入到设备并产生中断。设备中断处理程序唤醒进程。设备管理模块写处理过程缓冲区模块决定要回写被缓冲的块。如果该5低级读写流程根据缓冲区头创建一个请求队列中没有请求把请求插入到设备的请求队列中向设备发送命令是否说明设备空闲低级读写流程根据缓冲区头队列中没有请求把请求插入到设向设备发6设备号设备是通过主设备号和次设备号(两者构成了物理设备号)来进行区分的主设备号:区分不同类型的设备(P131表6-2)次设备号:区分相同类型设备中的个体逻辑设备号用于区分不同的设备,逻辑设备号=主设备号<<8+次设备号#defineMAJOR(a)(((unsigned)(a))>>8)#defineMINOR(a)((a)&0xff)P395第33、34行逻辑设备号设备号设备是通过主设备号和次设备号(两者构成了物理设备号)来7块设备请求项structrequest{ intdev; //逻辑设备号,-1表示是自由的请求项 intcmd;//命令(P395第26—29) interrors;//如果超过MAX_ERRORS,要重置设备 unsignedlongsector;//要读或写的开始扇区 unsignedlongnr_sectors;//要读或写的数量 char*buffer;//数据缓冲区指针 structtask_struct*waiting;//等待请求完成的进程队列 structbuffer_head*bh;//缓冲区头指针 structrequest*next;//同一设备的下一个请求项};P131或P134第23行块设备请求项structrequest{P131或P138块设备请求项数组为方便查找空闲请求项,建立了请求项数组。 structrequestrequest[NR_REQUEST];//定义在ll_rw_blk.c(P150第21行)

#defineNR_REQUEST 32//定义在blk.h(P134第15行)块设备请求项数组为方便查找空闲请求项,建立了请求项数组。9块设备结构每个块设备都有自己的独立的请求队列。为方便管理队列,建立了块设备结构。 structblk_dev_struct{ void(*request_fn)(void);//设备独有的请求处理函数指针 structrequest*current_request; //请求队列头指针}; //blk.h(P134第45行或P130)块设备结构每个块设备都有自己的独立的请求队列。为方便管理队列10块设备结构Linux支持多种块设备,为所有这些块设备结构建立了一个数组,数组下标就是设备的主设备号。structblk_dev_structblk_dev[NR_BLK_DEV]//P151第32行#defineNR_BLK_DEV 7块设备结构Linux支持多种块设备,为所有这些块设备结构建立11数据结构间的关系P132图6-1数据结构间的关系P132图6-112设备管理模块接口设备管理模块文件管理模块(缓冲区)ll_rw_block中断管理模块hd_interruptfloppy_interrupt初始化模块blk_dev_inithd_initfloppy_initsetup设备管理模块接口设备管理模块文件管理模块ll_rw_bloc13初始化voidblk_dev_init(void)//定义在ll_rw_blk.c(P153第157行)作用:完成请求项数组的初始化voidhd_init(void)//定义在hd.c(P146第343行)voidfloppy_init(void)//定义在floppy.c(P168第457行)longrd_init(longmem_start,intlength)//定义在ramdisk.c(P155第52行)初始化voidblk_dev_init(void)14低级读写操作voidll_rw_block(intrw,structbuffer_head*bh)//定义在ll_rw_blk.c(P153第145行)作用:完成低级读写操作参数:rw——读写命令 bh——缓冲区头指针低级读写操作voidll_rw_block15电梯算法磁头朝一个方向运动来满足该方向上最近的请求。当该方向上所有的请求都处理完之后,则反方向来处理其它请求。例如:磁头正在第5柱面处理请求,磁头向内运动,其后有5个请求到达,分别是第7、2、6、1、8柱面上的请求。则处理顺序是:567821电梯算法磁头朝一个方向运动来满足该方向上最近的请求。当该方向16电梯算法在一般情况下,所有请求都能获得合适的处理。但是,在极端情况下仍然会造成饿死现象。例如:上例中,如果不断的有第5柱面之后的处理请求,则第1、2柱面的处理请求会饿死。电梯算法在一般情况下,所有请求都能获得合适的处理。但是,在极17电梯算法改进 57572

5

672567

1

2567128对于请求Q,如果队列中存在A1和A2,1、满足A1<Q<A2,则把Q插入到A1和A2中2、满足Q<A2<A1,则把Q插入到A1和A2中3、否则插入到队列最后电梯算法改进对于请求Q,如果队列中存在A1和A2,18IN_ORDER#defineIN_ORDER(s1,s2)((s1)->cmd<(s2)->cmd||((s1)->cmd==(s2)->cmd&&((s1)->dev<(s2)->dev||((s1)->dev==(s2)->dev&&(s1)->sector<(s2)->sector))))P134第40行read、write、reada、writea宏可以简单理解为s1<s2是否为真IN_ORDER#defineIN_ORDER(s1,s219add_request(IN_ORDER(tmp,req)||!IN_ORDER(tmp,tmp->next)&&IN_ORDER(req,tmp->next)IN_ORDER(tmp,req)&&IN_ORDER(req,tmp->next)||!IN_ORDER(tmp,tmp->next)&&IN_ORDER(req,tmp->next)tmp<req<req->nextreq<tmp->next<tmpadd_request(IN_ORDER(tmp,req)20ll_rw_block根据缓冲区头创建一个请求队列中没有请求把请求插入到设备的请求队列中向设备发送命令是否说明设备空闲make_requestP150图6-4ll_rw_block根据缓冲区头队列中没有请求把请求插入到21讲课内容设备管理简介硬盘驱动虚拟盘驱动讲课内容设备管理简介22硬盘分类按照接口分,硬盘可以分为

IDE(ATA)硬盘 SCSI硬盘 FC硬盘 SATA硬盘

硬盘分类按照接口分,硬盘可以分为23硬盘内部结构硬盘内部结构24硬盘参数表在setup.s中,Linux通过BIOS调用读取了硬盘的参数,并保存在物理地址0x90080处(第1块硬盘)和物理地址0x90090处(第2块硬盘)。(参见P44表3-3)硬盘参数表在setup.s中,Linux通过BIOS调用读取25硬盘参数表位移大小说明0x002B柱面数0x021B磁头数0x032BAT硬盘为00x052B写前预补偿柱面号*40x071BAT硬盘为00x081B控制字节位0未用位4未用位1保留(0)位5有坏区图则置1位2允许复位位6禁止ECC重试位3若磁头数大于8则为1,否则为0位7禁止访问重试0x091BAT硬盘为00x0A1BAT硬盘为00x0B1BAT硬盘为00x0C2B磁头着陆柱面号0x0E1B每磁道扇区数0x0F1B保留硬盘参数表位移大小说明0x002B柱面数0x021B磁头数026硬盘结构structhd_i_struct{ inthead,sect,cyl,wpcom,lzone,ctl;};//定义在hd.c(P139第45行)硬盘结构structhd_i_struct27硬盘分区表一个硬盘最多可以分为4个区,每个分区用一个整数标识(次设备号) 0对应第一个硬盘 1、2、3、4对应第一个硬盘的四个分区 5对应第二个硬盘 6、7、8、9对应第二个硬盘的四个分区硬盘分区表一个硬盘最多可以分为4个区,每个分区用一个整数标识28硬盘逻辑设备号逻辑设备号主设备号次设备号说明0x30030第一块硬盘0x3011第一块硬盘的第一个分区0x3022第一块硬盘的第二个分区0x3033第一块硬盘的第三个分区0x3044第一块硬盘的第四个分区0x3055第二块硬盘0x3066第二块硬盘的第一个分区0x3077第二块硬盘的第二个分区0x3088第二块硬盘的第三个分区0x3099第二块硬盘的第四个分区硬盘逻辑设备号逻辑设备号主设备号次设备号说明0x30030第29硬盘分区表引导程序第1分区表项第2分区表项第3分区表项第4分区表项0x55AA主引导记录分区表引导标志开始磁头号开始扇区号开始柱面号分区类型结束磁头号结束扇区号结束柱面号起始物理扇区号分区扇区数量参见P149表6-80x1BE硬盘分区表引导程序第1分区表项第2分区表项第3分区表项第4分30分区数据结构structpartition{ unsignedcharboot_ind; unsignedcharhead; unsignedcharsector; unsignedcharcyl; unsignedcharsys_ind; unsignedcharend_head; unsignedcharend_sector; unsignedcharend_cyl; unsignedintstart_sect; /*startingsectorcountingfrom0*/ unsignedintnr_sects; /*nrofsectorsinpartition*/};参见Hdreg.h(P400第52行)分区数据结构structpartition{参见Hdre31硬盘分区结构staticstructhd_struct{ longstart_sect; longnr_sects;}hd[5*MAX_HD]={{0,0},};//定义在hd.c(P140第56行)硬盘分区结构staticstructhd_struct32硬盘初始化intsys_setup(void*BIOS)//定义在hd.c(P140第71行)作用:通过读BIOS调用的结果来设置硬盘数据结 构。参数:BIOS——保存硬盘数据的内存块地址该函数在main.c的init函数中(P66第172行)被调用硬盘初始化intsys_setup(void*BIOS33硬盘初始化voidhd_init(void)

P146第343硬盘初始化voidhd_init(void)34硬盘操作的过程向硬盘发送控制字节等待控制器处于空闲状态等待控制器处于准备状态向控制器数据端口和命令端口发送参数和命令等待中断中断发生时检测处理结果(读状态控制器),并做其它处理参见P149上硬盘操作的过程向硬盘发送控制字节参见P149上35硬盘控制器端口I/O端口从端口读向端口写0x1f0数据寄存器,512B0x1f1错误寄存器(参见表6-4)写前预补偿寄存器0x1f2扇区数寄存器0x1f3扇区号寄存器0x1f4柱面号寄存器0x1f5柱面号寄存器0x1f6驱动器/磁头寄存器(101dhhhhd=驱动器号,h=磁头号)0x1f7状态寄存器(参见表6-5)命令寄存器(参见表6-6)0x3f6控制字节寄存器P146表6-3硬盘控制器端口I/O端口从端口读向端口写0x1f0数据寄存器36向硬盘控制器发送命令staticvoidhd_out( unsignedintdrive,//硬盘号(0或1) unsignedintnsect,//扇区数量 unsignedintsect,//开始扇区 unsignedinthead,//磁头号 unsignedintcyl,//柱面号 unsignedintcmd,//命令(P148表6-6) void(*intr_addr)(void))//中断实施的操作//定义在hd.c(P143第180行),参考P148表6-7向硬盘控制器发送命令staticvoidhd_out(37中断操作对于不同的命令,在中断中实施的操作也不同。Linux使用一个函数指针来记录要实施的操作。#defineDEVICE_INTRdo_hd //定义在blk.h(P135第81行) #ifdefDEVICE_INTR void(*DEVICE_INTR)(void)=NULL; #endif //定义在blk.h(P135第96行)中断操作对于不同的命令,在中断中实施的操作也不同。Linux38对硬盘的操作读硬盘写硬盘对硬盘的操作读硬盘39读硬盘操作系统硬盘控制器发送命令发送中断发送中断READY=1从硬盘读数据从硬盘读数据从控制器的数据端口读数据从控制器的数据端口读数据读硬盘操作系统硬盘控制器发送命令发送中断发送中断READY=40写硬盘操作系统硬盘控制器发送命令DRQ=1发送中断发送中断READY=1写数据到硬盘写数据到硬盘向控制器的数据端口写数据向控制器的数据端口写数据写硬盘操作系统硬盘控制器发送命令DRQ=1发送中断发送中断R41硬盘请求处理函数voiddo_hd_request(void)//定义在hd.c(P145第294行)作用:处理对于硬盘的请求硬盘请求处理函数voiddo_hd_request(voi42逻辑扇区号到CHS的转换在request中保存的是要读扇区的逻辑扇区号,需要转换为磁道号(Cylinder)、磁头号(Head)和扇区号(Sector)扇区是从0磁头0磁道1扇区开始编号(逻辑扇区号0)的,编完后再从1磁头0磁道1扇区开始编号。这样,把0磁道的扇区编完,再编1磁道。即按照磁道、磁头、扇区的顺序进行编号。逻辑扇区号到CHS的转换在request中保存的是要读扇区的43逻辑扇区号到CHS的转换0磁道0磁头0磁道1磁头0柱面1柱面逻辑扇区号=C*(磁头数*每磁道扇区数)+H*每磁道扇区数+S-1=(C*磁头数+H)*每磁道扇区数+S-1S=(逻辑扇区号mod每磁道扇区数)+1H=逻辑扇区号/每磁道扇区数mod磁头数C=逻辑扇区号/每磁道扇区数/磁头数逻辑扇区号到CHS的转换0磁道0磁头0磁道1磁头0柱面1柱面44逻辑扇区号到CHS的转换divl操作数把edx:eax组成的值除以操作数,商放在eax中,余数放在edx中edx=0;eax=逻辑扇区号结果block=逻辑扇区号/每磁道扇区数sec=逻辑扇区号%每磁道扇区数edx=0;eax=逻辑扇区号/每磁道扇区数结果cyl=逻辑扇区号/每磁道扇区数/磁头数head=逻辑扇区号/每磁道扇区数%磁头数逻辑扇区号到CHS的转换divl操作数45硬盘中断voidhd_interrupt(void);//定义在System_call.S(P89第221行)硬盘中断voidhd_interrupt(void);46讲课内容设备管理简介硬盘驱动虚拟盘驱动讲课内容设备管理简介47根文件系统Linux引导启动时,默认使用的文件系统是根文件系统。其中一般都包括这样一些子目录:

/etc:含有一些系统配置文件 /dev:含有设备特殊文件 /usr:存放库函数、手册和其它一些文件 /usr/bin:存放执行程序 /bin:存放执行程序 /var:存放系统运行时可变的数据或者是日志根文件系统Linux引导启动时,默认使用的文件系统是根文件系48集成盘通常我们使用软盘启动Linux0.11系统时需要两张盘:一张是内核引导启动盘,一张是基本的根文件系统盘。这样必须使用两张盘才能引导启动系统来正常运行一个基本的Linux系统,并且在运行过程中

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

最新文档

评论

0/150

提交评论