设备管理与模块机制 基本概念 传统方式的设备注册与管理 devfs注册与管理 块设备的请求队列 网络设备 模块机制 Linux Device module
Linux Device & Module 1 设备管理与模块机制 基本概念 传统方式的设备注册与管理 devfs注册与管理 块设备的请求队列 网络设备 模块机制
基本概念 字符设备、块设备、网络设备 字符设备以字节为单位进行数据处理,通常只允许按顺序访问 块设备将数据按可寻址的块为单位进行处理,可以随机访问,利用缓冲技术 网络设备是一类特殊的设备,每块网卡有名字但没有设备文件与之对应 查看系统中的设备:/proc/ devices 主设备号和次设备号 major number:相同的设备使用相同的驱动程序 minor number:用来区分具体设备的实例 查看设备及其类型“ls-l/dev 设备文件系统defs /dev目录过于庞大,很多设备文件没有对应系统中的设备 dev根据系统中的实际设备构建设备文件,并按目录存放,如/ dev/disk, /dev/pts Linux Device module 2
Linux Device & Module 2 基本概念 字符设备、块设备、网络设备 字符设备以字节为单位进行数据处理,通常只允许按顺序访问 块设备将数据按可寻址的块为单位进行处理,可以随机访问,利用缓冲技术 网络设备是一类特殊的设备,每块网卡有名字但没有设备文件与之对应 查看系统中的设备:/proc/devices 主设备号和次设备号 major number:相同的设备使用相同的驱动程序 minor number:用来区分具体设备的实例 查看设备及其类型“ls -l /dev” 设备文件系统devfs /dev目录过于庞大,很多设备文件没有对应系统中的设备 devfs根据系统中的实际设备构建设备文件,并按目录存放,如/dev/disk, /dev/pts
基本概念 I/O请求 用户空间 返回进程继续 设备驱动程 ISR ret from sys call 设备 系统调用 内核空间 Linux Device module 3
Linux Device & Module 3 基本概念 用户空间 内核空间 I/O请求 设备驱动程序 设 备 ISR 系统调用 ret_from_sys_call 返回,进程继续
基本概念 用户程序调用 Fd=fopen("/dev/hda"O RDWR,op: read(buff, fd, size write(fd, buff, sife) close(fd) Virtual file system Generic file reado Generic_file_ write 块设备文件 建立设备 #mknod dev/ dev name type major number minor number Linux Device module
Linux Device & Module 4 基本概念 用户程序调用 Fd=fopen(“/dev/hda”,O_RDWR,0); read(buff,fd,size) write(fd,buff,size) close(fd) Virtual file system Generic_file_read() Generic_file_write() 块设备文件 建立设备: #mknod /dev/dev_name type major_number minor_number
VFS中的文件 include/linux/fs h struct file i struct file operations * f op struct file operations i loff t(*llseek )(struct file*, loff t, int) ssize t read)(struct file *, char*, size t, loff t*; ssize t write(struct file a, const char s, 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) } Linux Device module
Linux Device & Module 5 VFS中的文件 include/linux/fs.h struct file { …… struct file_operations *f_op; }; struct file_operations { 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,oset, whence):修改文件的读写指针 (2)read(fle, buf, count, offset):从设备文件的oiet处开始读出 count个字 节,然后增加* offset的值。 3)wite(file,buf; count, offset):从设备文件的ofet处写入 count个字节, 然后增加* offset的值。 (4) ioctl( inode,fle,cmd,arg):向一个硬件设备发命令,对设备进行控制 (5)mmap(fle,vma):将设备空间映射到进程地址空间 (6) open(inode,fle):打开并初始化设备。 (7) release( inode,file):关闭设备并释放资源 (8) fsync(file, dentry):实现内存与设备之间的同步通信。 (9) fasync(file,on):实现内存与设备之间的异步通信。 Linux Device module 6
Linux Device & Module 6 (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 file operations* fops static struct device struct chrdevs MAX Chrdevi 注册与注销函数: int register chrdevlunsigned int major, const char name, struct file operations*fops int unregister chrdevlunsigned int major, const char* name) 注:maor即设备的主设备号,注册后就是访问数组 chrdevs 的索引(下标) Linux Device module 7
Linux Device & Module 7 fs/devices.c struct device_struct { const char * name; struct file_operations * fops; }; static struct device_struct chrdevs[MAX_CHRDEV]; 注册与注销函数: int register_chrdev(unsigned int major, const char * name, struct file_operations *fops) int unregister_chrdev(unsigned int major, const char * name); 注:major即设备的主设备号,注册后就是访问数组chrdevs 的索引(下标)。 字符设备的注册与管理
PCI设备(驱动实现见word文档) Pc总线0 C总线1 上 下 游游 ::::RAM Pc|PC桥 Pc|桥 CPU 以太网卡 PCH-ISA桥 显卡 多功能Jo控制器 sA总线 Linux内核启动时会对所有PCI设备进行扫描、登录和分配资源等初始化 操作,建立起系统中所有PCI设备的拓扑结构 √此后当内核欲初始化某设备时,调用 module init加载该设备的驱动程 序 Linux Device module 8
Linux Device & Module 8 PCI设备(驱动实现见word文档) ✓Linux内核启动时会对所有PCI设备进行扫描、登录和分配资源等初始化 操作,建立起系统中所有PCI设备的拓扑结构 ✓此后当内核欲初始化某设备时,调用module_init加载该设备的驱动程 序
块设备 fs/block dev.c static struct const char name struct block device operations *bops blkdevsMAX blkdevi Linux Device module 9
Linux Device & Module 9 块设备 fs/block_dev.c static struct { const char *name; struct block_device_operations *bdops; } blkdevs[MAX_BLKDEV];
块设备注册 fs/block dev. c register blkdev(unsigned int major, const char name, struct block device operations*bops int unregister blkdev unsigned int major const char name) Linux Device module
Linux Device & Module 10 块设备注册 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)