第9章 Linux设备管理.ppt
《第9章 Linux设备管理.ppt》由会员分享,可在线阅读,更多相关《第9章 Linux设备管理.ppt(78页珍藏版)》请在三一办公上搜索。
1、第9章 设备管理与模块机制,Linux设备分类与识别设备转换表设备驱动程序设备注册与注销块设备的请求队列模块机制,Linux的设备管理,在 Linux 系统中,用户通过文件系统与设备接口。利用标准的系统调用可在设备上进行打开、关闭、读取或写入操作。当用户进程发出I/O请求时,系统将请求处理的权限放在文件系统,文件系统通过驱动程序提供的接口将任务下放到驱动程序。驱动程序根据需要,对设备控制器进行操作,设备控制器再去控制设备本身进行I/O操作。驱动程序向文件系统提供的接口屏蔽了设备的物理特性。,用户进程,硬件设备本身,设备控制器,设备驱动程序,文件系统中的设备文件,进程请求设备服务的流程,在内核中
2、设备文件和普通文件的索引节点有区别,可以确认出是硬件设备还是普通文件,确定要访问相应的设备驱动程序还是文件。,Linux系统的设备管理,每个设备都对应文件系统中的一个VFS inode,都有一个设备文件名。在设备文件对应的VFS inode中,i_mode域的值标明了它的类型:S_IFBLK:表示它是一个块设备;S_IFCHR:表示它是一个字符设备;同时,设备文件对应的VFS inode中没有块列表,但却有一个名为i_rdev的域,其中存储着它所标识设备的主、次设备号。内核可以根据该域将设备文件名转化为设备的主、次设备号。,Linux系统的设备管理,每个设备都对应文件系统中的一个索引节点,都有
3、一个设备文件名。应用程序通常可以通过系统调用open()打开设备文件,建立起与目标设备的连接。对设备的使用类似于对文件的存取。设备驱动程序都是系统内核的一部分,它们必须为系统内核或者它们的子系统提供一个标准的接口。设备驱动程序也使用一些标准的内核服务,如内存分配等,设备的分类,字符设备(c)所有能够象字节流一样访问的设备都通过字符设备来实现,通常在/dev/目录下面无需缓冲直接读写设备,通常只允许按顺序访问。如打印机、键盘,终端等。一般要包含open,read,write,close等系统调用的实现块设备(b)通常是指诸如磁盘、内存、Flash等可以容纳文件系统的存储设备。将数据按可寻址的块为
4、单位进行处理,可以随机访问,利用缓冲技术块设备也是通过文件系统来访问网络接口设备通常它指的是硬件设备,但有时也可能是一个软件设备(如回环接口loopback),它们由内核中网络子系统驱动,负责发送和接收数据包。它们的数据传送往往不是面向流的,因此很难将它们映射到一个文件系统的节点上。查看系统中的设备:/proc/devices。查看设备及其类型“ls-l/dev”,主设备号和次设备号,主设备号和次设备号主设备号和次设备号能够唯一地标识一个设备128(V2.0以前),256(V2.0以后)主设备号相同的设备使用相同的驱动程序,次设备号用于区分具体设备的实例动态获取主设备号设备文件 Linux使用
5、设备文件来统一对设备的访问接口,将设备文件放在/dev/目录下设备的命名一般为设备文件名+数字或者字母表示的子类,例如/dev/hda1,/dev/hda2等,/dev/hda 代表系统中的第一个IDE 硬盘,/dev/hdb 代表系统中的第二个 IDE 硬盘;hda1代表第1个分区,hda2代表第2个分区,注意:字符设备与块设备具有独立的编号,例如,块设备(3,0)不同于字符设备(3,0)设备文件通常可以表示一个硬件设备,例如磁盘/dev/hda或硬件设备的某一物理或逻辑分区,例如磁盘分区/dev/hda2或一个虚拟的逻辑设备(不会与任何硬件设备相关联),例如/dev/null代表一个“黑洞
6、”对内核而言,一个设备文件的名字是无关紧要的,关键在于设备文件的类型及其主次设备号,如果一个系统含有两个具有相同主设备号和次设备号的设备文件,而且都是字符设备。当有两个进程想要同时打开这个字符设备时,会发生什么情况?关闭这个设备时又会发生什么情况?当有两个进程想要同时打开这个字符设备时,它将在各自的文件表中增加一次引用计数值。关闭这个设备时可能会发生导致对这个设备是一个无法辨认的状态。从而使这个设备变成一个无用的设备。,设备文件通常包含在/dev目录中一些设备文件的例子,Devfs设备文件,使用主、次设备号标识设备存在局限性在/dev中的大多数设备是不存在的8位长的主次设备号不够用不容易记忆上
7、述原因以及其他的一些因素综合起来,促使了devfs设备文件的产生Linux 2.4以后引入了设备文件系统(devfs)的概念,所有的设备文件作为一个可以挂装的文件系统,这样就可以被文件系统统一管理,从而设备文件就可以挂装到任何需要的地方。一般将主设备建立一个目录,再将具体的子设备文件建立在此目录下。例如,/dev/mtdblock0,Devfs设备文件,有了Devfs设备文件之后,文件系统允许设备驱动程序通过名字而不是主次设备号注册设备,例如所有的磁盘可以放在/dev/disks目录下/dev/hda/dev/disks/disc0/dev/hdb/dev/disks/disc1使用devfs
8、文件系统的I/O驱动程序通过调用devfs_register()注册设备一个注册了的设备文件,自动出现在devfs的虚拟目录下,设备文件的VFS处理,进程访问普通文件时,通过文件系统访问磁盘分区中的数据块当进程访问设备文件时,却可以驱动硬件设备途径:VFS在设备文件打开时使用与设备相关的函数调用替换其缺省的文件操作这些设备相关函数调用对硬件设备进行操作,基本概念,驱动程序使用的2个重要结构struct filestruct file_operations,设备文件:struct file数据结构,Struct fileStruct dentry*f_dentry;/文件对应的目录项结构Stru
9、ct file_operations*f_op;/文件操作的结构指针Unsigned short f_flags;/文件标志,主要进行阻塞/非阻塞型操作时检查Undigned short f_count;Mode_t f_mode;/标识文件的读写权限Loff_t f_pos;当前读写位置Unsigned long f_reada,f_ramax,f_reddb,f_rawin;Struct file*f_next,f_prev;Struct fown_struct f_owner;Int f_error;Unsigned long f_version;Void*private_data;/驱
10、动程序一般将它指向已经分配的数据struct inode*f_inode;,设备文件:i节点,系统所有的设备文件都存放在dev设备子目录下。每一个设备文件也使用唯一的i节点来标识;在i节点中包含设备的主设备号和次设备号,并且和一组文件操作函数的指针相联系。设备文件i节点不指向文件系统中的任何实际的物理块,不占用数据空间,通过这个i节点可以访问相应的设备驱动程序,对设备文件的操作就是直接对设备本身进行相应的操作。,设备文件:操作,文件描述符fd是系统调用与设备驱动程序的接口。在操作时,内核通过fd找到代表该文件的struct file结构,得到打开文件的i节点。在i节点中检查文件类型,如果是设备
11、(块或字符)文件,则从索引节点中提取主设备号和次设备号,再通过主设备号定位块或者字符设备转换表中相应的设备驱动程序。根据用户发出的系统调用的功能,进一步确定应该调用哪一个操作函数,并确定传递的参数。启动该函数。,两个设备转换表,设备转换表是一个数据结构,由它定义了每个设备必须支持的操作入口点,由fops,bdops描述。每个驱动程序提供了这些功能的特定实现,都在其对应数组中占据一个项。块设备转换表(blk_dev)字符设备转换表(chrdevs)这些驱动函数的功能由各个驱动程序具体实现。根据设备的类型和主设备号可以在设备表中找到相应的驱动函数。一旦内核想在某台设备上完成某个动作,它必须首先在转
12、换表中定位该设备的驱动程序,再调用相应的驱动程序函数。设备文件的的主设备号必须与设备驱动程序在登记时申请的主设备号一致,否则用户进程将无法访问到驱动程序。,字符设备转换表(chrdevs),用于注册字符设备的数据结构Struct device_structconst char*name;Struct file_operations*fops;Static struct device_struct chrdevsMAX_CHRDEV;device_struct结构由两项构成:name:指向已登记的设备名称的指针fops:指向设备驱动程序的入口函数:完成指定的设备操作。,字符设备转换表(chrde
13、vs),字符设备初始化时,它的设备驱动将被添加到chrdevs中,从而将其注册到Linux内核中。设备的主设备标识符是固定的。使用主设备号用来对chrdevs数组进行索引。当访问某台设备时,它首先必须在字符转换表中找到该设备的驱动程序,然后控制权转交给设备驱动程序,由设备驱动程序再调用相应的驱动程序函数执行。,字符设备转换表的使用,字符设备转换表(p371),include/linux/fs.hstruct file struct file_operations*f_op;struct file_operations Struct module*owner;loff_t(*llseek)(st
14、ruct file*,loff_t,int);ssize_t(*read)(struct file*,char*,size_t,loff_t*);ssize_t(*write)(struct file*,const char*,size_t,loff_t*);int(*ioctl)(struct inode*,struct file*,unsigned int,unsigned long);int(*mmap)(struct file*,struct vm_area_struct*);int(*open)(struct inode*,struct file*);int(*release)(st
15、ruct inode*,struct file*);int(*fsync)(struct file*,struct dentry*,int datasync);int(*fasync)(int,struct file*,int);,(1)llseek(file,offset,whence):修改文件的读写指针。(2)read(file,buf,count,offset):从设备文件的offset 处开始读出count个字节,然后增加offset的值。(3)write(file,buf,count,offset):从设备文件的offset处写入count个字节,然后增加*offset的值。(4)
16、ioctl(inode,file,cmd,arg):向一个硬件设备发命令,对设备进行控制。(5)mmap(file,vma):将设备空间映射到进程地址空间。(6)open(inode,file):打开并初始化设备。(7)release(inode,file):关闭设备并释放资源。(8)fsync(file,dentry):实现内存与设备之间的同步通信。(9)fasync(file,on):实现内存与设备之间的异步通信。,字符设备的操作:打开文件操作当打开字符设备文件时,使用设备的主标识符来索引chrdevs数组,得到文件操作函数指针。建立起描述此字符设备文件的file结构,使其文件操作指针指向
17、此设备驱动中的文件操作指针集合。这样,所有应用对它进行的文件操作都被映射到此字符设备的文件操作集合上。,字符设备的操作,注册与注销函数:int register_chrdev(unsigned int major,const char*name,struct file_operations*fops):chrdevs表最初为空,注册函数向表中插入一个新项int unregister_chrdev(unsigned int major,const char*name);注:major即设备的主设备号,注册后就是访问数组chrdevs的索引(下标)。例:register_chrdev(6,”lp”
18、,&lp_fops):将并口打印机的相应驱动程序插入到chrdevs表中,字符设备的注册与注销,块设备转换表,fs/block_dev.cstatic struct const char*name;struct block_device_operations*bdops;blk_devsMAX_BLKDEV;,blk_devs结构数组描述了一系列在系统中登记的块设备。内容包括指向已登记的设备名的指针和指向block_device_operations结构的指针。在block_device_operations结构中包含指向有关操作的函数指针。它们由设备驱动程序定义,并分别完成指定的设备操作数组
19、blk_devs也使用主设备号作为索引。,块设备转换表,block_device_operations,struct block_device_operations int(*open)(struct inode*,struct file*);int(*release)(struct inode*,struct file*);int(*ioctl)(struct inode*,struct file*,unsigned,unsigned long);int(*check_media_change)(kdev_t);/检查介质是否已经变化int(*revalidate)(kdev_t);/检查块
20、设备是否持有有效数据;,块设备的注册与管理,注册与注销函数register_blkdev(unsigned int major,const char*name,struct block_device_operations*bdops)int unregister_blkdev(unsigned int major,const char*name),除了文件操作接口外,块设备驱动程序还必须提供缓冲区缓存接口。块设备在内核中的数据结构比字符设备要复杂一些,主要是因为内核为块设备提供缓冲区高速缓存(buffer cache),实际的读写操作由缓冲区缓存协调调用,因此,还需要驱动程序为缓冲区缓存提供接
21、口。,块设备的操作:缓冲区,块设备请求,虽然块设备驱动程序可以一次传送一个单独的数据块,但是内核并不会为磁盘上的每个被访问的数据块都单独执行一次I/O操作,而是试图将几个块合并在一起,并作为一个整体来处理,这样就减少了磁头平均移动时间延迟:块设备发出I/O请求时,将请求放在相应的请求队列中,稍后执行每个块设备都有一个请求队列,一提高磁盘性能的方式对请求进行排序。块设备请求由request结构描述(include/linux/blkdev.h)请求队列:是一个请求描述符的链表,,当系统中有进程发出一个读写块设备的请求时,内核会首先调用block_read()和block_write()对数据缓冲
22、区进行读写。当数据缓冲区不能满足用户进程的一个读写请求或者一个文件需要交换到物理磁盘上时,必须调用块设备的驱动程序来进行实际的数据传输。为此,在Linux中,为完成真正的数据传输请求,又为每一个块设备设计了一个接口blk_dev_structblk_dev_struct结构包含请求过程的地址以及指向请求request数据结构链表的指针,每个代表一个从buffer cache中来让设备进行数据读写的请求。,块设备的操作,每个块设备都有一个blk_dev_struct 结构(块设备驱动程序描述符),所有的blk_dev_struct结构由向量blk_dev集中管理,可以使用主设备号进行索引。str
23、uct blk_dev_struct request_queue_t request_queue;queue_proc*queue;void*data;struct blk_dev_struct blk_devMAX_BLKDEV;blk_dev记录各个设备的请求队列request_queue:请求队列*queue:函数指针,当这个指针非0时,就调用这个函数来找到具体设备的请求队列。*data:辅助queue函数找到特定设备的请求队列,块设备的操作,块设备的操作,在blk_dev_struct中有三个域,驱动程序主要是设置第一个域request_queue中的request_fn参数,该参数是
24、指向相应块设备的I/O操作请求函数的指针。当block_read()和block_write()不能满足I/O操作请求时,内核便调用该设备驱动程序的请求函数request。它可以通过blk_devMAJOR(dev).request_queue.request_fn获得。每个具体设备的请求函数都不同,它们在内核在初始化时被赋值。struct request_queue/include/linux/blkdev.hrequest_fn_proc*request_fn;.,块设备驱动程序数据结构示意图,struct request struct list_head queue;int elevat
25、or_sequence;volatile int rq_status;#define RQ_INACTIVE(-1)#define RQ_ACTIVE1#define RQ_SCSI_BUSY0 xffff#define RQ_SCSI_DONE0 xfffe#define RQ_SCSI_DISCONNECTING0 xffe0kdev_t rq_dev;/*请求所访问的设备*/int cmd;/*要执行的操作READ or WRITE*/int errors;unsigned long sector;/*本次请求要传输的第一个扇区号*/unsigned long nr_sectors;/*
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 第9章 Linux设备管理 Linux 设备管理

链接地址:https://www.31ppt.com/p-2976530.html