Linux 内核中选用可加载的模块化规划(LKMs,Loadable Kernel Modules),一般情况下编译的Linux 内核是支撑可刺进式模块的,也便是将最基本的中心代码编译在内核中,其他的代码能够挑选在内核中,或许编译为内核的模块文件。常见的驱动程序也是作为内核模块动态加载的。
模块相关指令
lsmod 列出当时体系加载的模块
rmmod 将当时模块卸载
insmod、modprobe 用于加载当时模块。但insmod不会主动处理依存关系,而modprobe能够依据模块间的依存关系以及 /etc/modules.conf 文件中的内容主动刺进模块
mknod 创立相关模块
Linux 体系的设备文件分为三类:块设备文件、字符设备文件和网络设备文件。
· 块设备文件通常指一些需求以块(如512 字节)的方法写入的设备,如IDE 硬盘、SCSI硬盘、光驱等。
· 字符型设备文件通常指能够直接读写,没有缓冲区的设备,如并口、虚拟操控台等。
· 网络设备文件通常是指网络设备拜访的BSD socket接口,如网卡等。
设备号设备号是一个数字,它是设备的标志。就如前面所述,一个设备文件(也便是设备节点)能够经过mknod指令来创立,其间指定了主设备号和次设备号。主设备号标明某一类设备,
一般对应着确认的驱动程序;次设备号一般是用于区别标明不同特色,例如不同的运用方法,不同的方位,不同的操作等,它标志着某个详细的物理设备。高字节为主设备号和底字节为次设备号。例如,在体系中的块设备IDE 硬盘的主设备号是3,而多个IDE 硬盘及其各个分区别别赋予次设备号1、2、3……
Linux 设备驱动程序包括中止处理程序和设备服务子程序两部分
设备服务子程序包括了一切与设备操作相关的处理代码。它从面向用户进程的设备文件体系中承受用户指令,并对设备操控器履行操作。这样,设备驱动程序屏蔽了设备的特殊性,运用户能够像对待文件相同操作设备。
设备操控器需求取得体系服务时有两种方法:查询和中止。由于Linux 下的设备驱动程序是内核的一部分,在设备查询期间体系不能运转其他代码,查询方法的工作效率比较低,所以只要少量设备如软盘驱动程序采纳这种方法,大多设备以中止方法向设备驱动程序宣布输入/输出恳求。
screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.style.cursor=’hand’; this.alt=’Click here to open new window\nCTRL+Mouse wheel to zoom in/out’;} onclick=if(!this.resized) {return true;} else {window.open(this.src);} alt= src=paij20hn5wm.jpg onload=if(this.width>screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.alt=’Click here to open new window\nCTRL+Mouse wheel to zoom in/out’;} border=0>
Linux 中的设备驱动程序有如下特色。
(1)内核代码:设备驱动程序是内核的一部分,假如驱动程序犯错,则或许导致体系溃散。
(2)内核接口:设备驱动程序有必要为内核或许其子体系供给一个规范接口。比方,一个终端驱动程序有必要为内核供给一个文件I/O 接口;一个SCSI设备驱动程序应该为SCSI子体系供给一个SCSI设备接口,一起SCSI子体系也有必要为内核供给文件的I/O 接口及缓冲区。
(3)内核机制和服务:设备驱动程序运用一些规范的内核服务,如内存分配等。
(4)可装载:大多数的Linux 操作体系设备驱动程序都能够在需求时装载进内核,在不需求时从内核中卸载。
(5)可设置:Linux 操作体系设备驱动程序能够集成为内核的一部分,并能够依据需求把其间的某一部分集成到内核中,这只需求在体系编译时进行相应的设置即可。
(6)动态性:在体系启动且各个设备驱动程序初始化后,驱动程序将保护其操控的设备。
假如该设备驱动程序操控的设备不存在也不影响体系的运转,那么此刻的设备驱动程序仅仅多占用了一点体系内存算了。
驱动开发时却没有main 函数,模块在调用insmod指令时被加载,此刻的进口点是init_module函数,通常在该函数中完结设备的注册。相同,模块在调rmmod
函数时被卸载,此刻的进口点是cleanup_module函数,在该函数中完结设备的卸载。在设备完结注册加载之后,用户的应用程序就能够对该设备进行必定的操作,如read、write等,而驱动程序便是用于完结这些操作,在用户应用程序调用相应进口函数时履行相关的操作,init_module进口点函数则不需求完结其他如read、write之类功用。
设备驱动程序的进口点,它是一个在中界说的struct file结构,这是一个内核结构,不会出现在用户空间的程序中,它界说了常见文件I/O 函数的进口。
struct file_operations {
loff_t (*llseek) (struct file *, loff_t, int);
ssize_t (*read) (struct file *filp, char *buff, size_t count, loff_t *offp);
ssize_t (*write) (struct file *filp, const char *buff, size_t count, loff_t *offp);
int (*readdir) (struct file *, void *, filldir_t);
unsigned int (*poll) (struct file *, struct poll_table_struct *);
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 (*flush) (struct file *);
int (*release) (struct inode *, struct file *);
int (*fsync) (struct file *, struct dentry *);
int (*fasync) (int, struct file *, int);
int (*check_media_change) (kdev_t dev);
int (*revalidate) (kdev_t dev);
int (*lock) (struct file *, int, struct file_lock *);
};
每个设备的驱动程序不必定要完结其间一切的函数操作,若不需求界说完结时,则只需将其设为NULL即可。