资源预览内容
第1页 / 共27页
第2页 / 共27页
第3页 / 共27页
第4页 / 共27页
第5页 / 共27页
第6页 / 共27页
第7页 / 共27页
第8页 / 共27页
第9页 / 共27页
第10页 / 共27页
亲,该文档总共27页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述
设备管理与模块机制,基本概念 传统方式的设备注册与管理 devfs注册与管理 块设备的请求队列 网络设备 模块机制,中英文日报导航站,基本概念,字符设备、块设备、网络设备 字符设备以字节为单位进行数据处理,通常只允许按顺序访问 块设备将数据按可寻址的块为单位进行处理,可以随机访问,利用缓冲技术 网络设备是一类特殊的设备,每块网卡有名字但没有设备文件与之对应 查看系统中的设备:/proc/devices 主设备号和次设备号 major number:相同的设备使用相同的驱动程序 minor number:用来区分具体设备的实例 查看设备及其类型“ls -l /dev” 设备文件系统devfs /dev目录过于庞大,很多设备文件没有对应系统中的设备 devfs根据系统中的实际设备构建设备文件,并按目录存放,如/dev/disk,/dev/pts,中英文日报导航站,基本概念,中英文日报导航站,基本概念,建立设备: #mknod /dev/dev_name type major_number minor_number,中英文日报导航站,VFS中的文件,include/linux/fs.h struct file struct *f_op; ; struct loff_t (*llseek)(struct 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) (struct 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) 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):实现内存与设备之间的异步通信。,中英文日报导航站,fs/devices.c struct device_struct const char * name; struct * fops; ; static struct device_struct chrdevsMAX_CHRDEV; 注册与注销函数: int register_chrdev(unsigned int major, const char * name, struct *fops) int unregister_chrdev(unsigned int major, const char * name); 注:major即设备的主设备号,注册后就是访问数组chrdevs的索引(下标)。,字符设备的注册与管理,中英文日报导航站,PCI设备(驱动实现见word文档),Linux内核启动时会对所有PCI设备进行扫描、登录和分配资源等初始化操作,建立起系统中所有PCI设备的拓扑结构 此后当内核欲初始化某设备时,调用module_init加载该设备的驱动程序,中英文日报导航站,块设备,fs/block_dev.c static struct const char *name; struct block_device_operations *bdops; blkdevsMAX_BLKDEV;,中英文日报导航站,块设备注册,fs/block_dev.c register_blkdev(unsigned int major,const char *name, struct block_device_operations *bdops) int unregister_blkdev(unsigned int major, const char * name),中英文日报导航站,块设备的操作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); struct module *owner; ;,中英文日报导航站,block_device_operations并不能完全提供结构中的所必需的主要函数(例如read、write),所以内核实际上是采用def_blk_fops变量对相关的变量进行了赋值: struct def_blk_fops ; 除了open、release等函数利用了设备注册时提供的block_device_operations结构中的成员变量之外,其他函数都是采用所有块设备通用的操作函数(def_blk_fops),块设备的缺省操作def_blk_fops,中英文日报导航站,fs/block_dev.c struct def_blk_fops = open:blkdev_open,release:blkdev_close,llseek:block_llseek,read:generic_,write:generic_,mmap:generic_,fsync:block_fsync,ioctl:blkdev_ioctl, ;,块设备的缺省操作def_blk_fops,中英文日报导航站,block_read与block_write等函数是设备相关的 块设备注册时一个重要的任务就是提供这个设备相关的操作函数给内核,中英文日报导航站,devfs注册与管理,fs/devfs/base.c register_chrdev()停止使用,改为devfs_register_chrdev() register_blkdev()停止使用,改为devfs_register_blkdev() int devfs_register_chrdev (unsigned int major, const char *name, struct *fops) int devfs_register_blkdev (unsigned int major, const char *name, struct block_device_operations *bdops) int devfs_unregister_chrdev (unsigned int major, const char *name) int devfs_unregister_blkdev (unsigned int major, const char *name),中英文日报导航站,块设备的请求队列,当系统对块设备进行读操作时,仅仅是通过块设备通用的读操作函数block_read( ),将这一个请求发送给对应的设备,并保存在该设备的操作请求队列(request queue)中。然后调用这个块设备的底层处理函数,对请求队列中的操作请求进行逐一的执行 struct blk_dev_struct /*include/linux/blkdev.h*/ request_queue_t request_queue; queue_proc *queue; void *data; ; struct blk_dev_struct blk_devMAX_BLKDEV;,中英文日报导航站,block_read()流程,中英文日报导航站,Linux网络协议栈,中英文日报导航站,重要的数据结构,以socket文件描述符作为参数,系统调用从用户空间切换到内核空间,从而进入到BSD Socket层的操作。操作的对象是socket结构,每一个这样的结构对应的是一个网络连接 通过网络地址族的不同来判断是否应该进入到INET Socket层;这一层的数据存放在msghdr结构的变量中 在INET Socket层中,分成面向连接和面向无连接两种类型,区分TCP和UDP协议。在这一层中的操作对象是sock类型的数据,而数据存放在sk_buff结构中,中英文日报导航站,模块机制(Module),Linux的单块结构(monolithic)使得其可扩展性较差 模块机制(Linux Kernel Module,LKM)提高了linux内核的可扩展性 利用linux源码编译生成内核时,如某功能允许“m”选项(其他为“y”, “ n”),说明可以以模块形式存在 多数设备驱动程序以模块的方式挂接到内核 系统启动时已将若干模块挂入了内核 用户只要有权限,就可以编写模块挂入内核 模块的缺点:增加了内核管理代价,中英文日报导航站,模块的设计,Every LKM consists of two basic functions (minimum) : int init_module(void) /*used for all initialization stuff*/ . void cleanup_module(void) /*used for a clean shutdown*/ . 安装模块命令 # insmod module.o #modprobe module.o 卸载模块命令 # rmmod module.o 查询系统中已装入的模块 #lsmod,中英文日报导航站,模块的设计,例子 hello.c #define MODULE #include int init_module(void) printk(Hello, worldn); return 0; void cleanup_module(void) printk(Goodbye cruel worldn); 编译模块 # gcc c hello.c DMODULE D_KERNEL_ -DLINUX -Wall O2 -I/usr/src/linux-2.4/include 安装、卸载模块 # insmod hello.o Hello world # rmmod hello Goodbye cruel world,中英文日报导航站,模块设计注意事项,模块设计与应用程序设计 模块是装入内核的,
收藏 下载该资源
网站客服QQ:2055934822
金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号