标签:
[转]insmod
http://www.cnblogs.com/amaoxiaozhu/archive/2013/03/08/2950002.html
在Linux下,驱动程序是内核的一部分,运行在内核态下,你可以将驱动静态的和内核编译在一起,这样的缺点是内核会比较大,而且如果驱动出错,会 导致整个系统崩溃;也可以以module的方式编译,在需要的时候动态的载入。如果你编译过内核,应该记得在make menuconfig中,选项前面是可以选择和的,就分别表示"编译到内核中"和"编译成模块"。
.
下面介绍下模块,一个简单的“helloworld module”如下所示:
/* hello-1.c - The simplest kernel module. */ #include /* Needed by all modules */ #include /* Needed for KERN_ALERT */ int init_module(void) { printk("<1>Hello world 1.\n"); // A non 0 return means init_module failed; module can‘t be loaded. return 0; } void cleanup_module(void) { printk(KERN_ALERT "Goodbye world 1.\n"); }
其中,init_module函数是加载模块时会被调用的,一般作一些初始化的工作;cleanup_module函数是卸载模块时会被调用的,做一些清理的工作。因为模块是运行在内核态的,你自然不能使用库函数,因此要打印信息,需要使用printk函 数而不是printf函数。另外,你可以使用任意函数名(只要同内核函数名不冲突)来替换init_module和cleanup_module这两个函 数名,但必须使用module_init(初始化函数名),module_exit(卸载时函数名)这两个宏来声明一下,也就是说,下面这个模块和上面的 模块是等价的:
/* hello-1.c - The simplest kernel module. */ #include /* Needed by all modules */ #include /* Needed for KERN_ALERT */ int helloworld(void) { printk("<1>Hello world 1.\n"); // A non 0 return means init_module failed; module can‘t be loaded. return 0; } void goodbyeworld(void) { printk(KERN_ALERT "Goodbye world 1.\n"); } module_init(helloworld); module_exit(goodbyeworld);
.
编译和加载一个模块也很容易:
从上面的图可以看到,我们通过make编译生成一个模块文件".ko"之后,使用"insmod"命令来加载模块,那么“insmod”具体做了什么呢?
.
下面让我们来介绍下insmod这个工具:
insmod是linux下加载模块的工具,路径一般是/sbin/insmod,当你调用这个工具后,它的工作基本如下:
.
内核导出的符号清单可以由下面的命令来查看:
more /proc/k[all]syms c0400000 T _text c0400000 T startup_32 c040007b t default_entry c04000d0 T startup_32_smp c0400152 t checkCPUtype c04001d3 t is486 c04001da t is386 c0400247 t check_x87 c040027a t setup_idt … c06adb25 T printk …
.
从已加载模块中卸载模块使用的是“rmmod”,"rmmod"所做工作如下:
.
.
#include #inlcude int register_chrdev(unsigned int major, const char *name, struct file_operations *fops);
至于怎么创建一个有设备名和设备号的文件,可以通过man mknod获取信息。
.
file_operantions的结构如下:
Linux-2.6.27.25 struct file_operations { struct module *owner; loff_t (*llseek) (struct file *, loff_t, int); ssize_t (*read) (struct file *, char __user *, size_t, loff_t *); ssize_t (*write) (struct file *, const char __user *, size_t, loff_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 (*fsync) (struct file *, struct dentry *, int datasync); …… }
.
此外,初始化部分还负责为设备驱动申请系统资源,如:内存,时钟,中断,I/O端口等。
标签:
原文地址:http://www.cnblogs.com/wansui/p/4233328.html