[转]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,当你调用这个工具后,它的工作基本如下:

  • 在用户空间打开待安装的module
  • 调用query_module()系统调用询问无法落实的符号在内核或其他模块中的地址
  • 链接操作,落实模块中的符号引用
  • 调用create_module()系统调用在内核中创建module数据结构,并申请所需的内核空间
  • 调用init_module()系统调用将链接好的module映像装入内核空间,然后调用模块中的init_module()函数(注意:这里面的两个init_module函数不一样,一个是系统调用,一个是你写在模块里面的函数)

.
内核导出的符号清单可以由下面的命令来查看:

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"所做工作如下:

  • 调用delete_module()系统调用释放模块的module结构,同时释放模块所占的内核空间
  • 调用模块中的cleanup_module()的函数

.

那么,一般情况下,驱动程序会在init_module()和cleanu_module()函数中做些什么呢?

 

  • init_module(): 向内核登记本模块中一些包含着函数指针的数据结构(file_operations)
  • cleanup_module(): 向内核撤销本模块提供的数据结构的登记,使内核在模块拆卸后不至于再企图访问这些数据结构

.

一个字符型驱动的注册函数如下:

#include
 
#inlcude
 
int register_chrdev(unsigned int major, const char *name,
                struct file_operations *fops);
  • major: 设备的主设备号,若为空则系统动态分配
  • name: 设备名
  • fops: 函数指针结构,各个调用的入口
  • 操作成功,设备名出现在/proc/devices文件

至于怎么创建一个有设备名和设备号的文件,可以通过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端口等。

[转]insmod的更多相关文章

  1. insmod模块的几种常见错误

    1. 与内核版本不一致 嵌入式开发时,模块编译时需要制定内核的路径,内核的版本信息会加入到模块文件中,如果目标板上运行的内核与模块中包含的内核版本对不上,加载就会出错,报如下错误:  insmod i ...

  2. linux显示git commit id,同时解决insmod模块时版本不一致导致无法加载问题

    linux内核默认会包含git的commit ID. 而linux的内核在insmod模块时,会对模块和内核本身的版本做严格的校验.在开发产品时,改动内核后,由于commit ID变更,会导致linu ...

  3. insmod过程详解【转】

    转自:http://blog.csdn.net/chrovery/article/details/51088425 转自 http://blog.chinaunix.net/xmlrpc.php?r= ...

  4. First insmod a module

    不得不说网上坑爹的文章比虱子还多,参考这位仁兄调试成功 喜欢C的人却靠着Java产业吃饭,人艰不拆... 对于未知的东西,有个习惯,run success first,then research en ...

  5. 模块在insmod之后无法rmmod问题

    1,首先保证make menuconfig选项配置: [*] Enable loadable module support  ---> [*]   Module unloading 2,在lib ...

  6. linux 命令之 insmod

    man insmod: INSMOD(8) insmod INSMOD(8) NAME insmod - Simple program to insert a module into the Linu ...

  7. insmod module_param 模块参数

    模块参数 引导模块时,可以向它传递参数.要使用模块参数加载模块,这样写: insmod module.ko [param1=value param2=value ...] 为了使用这些参数的值,要在模 ...

  8. linux内核模块相关命令:lsmod,depmod,modprobe,modinfo,insmod,rmmod 使用说明

    加载内核驱动的通常流程: 1.先将.ko文件拷贝到/lib/module/`uname -r`(内核版本号)/kernel/driver/...目录下, 根据具体用途的区别分为net.ide.scsi ...

  9. 解决insmod: error inserting 'hello.ko': -1 Invalid module format

    编译自己的内核模块后,insmod出现error:error inserting 'hello.ko': -1 Invalid module format 出现这种情况的原因是因为Makefile种使 ...

随机推荐

  1. 【SSH 1】SSH框架的基本理解

    导读:在结束了BS之后,接触到的第一个项目算是网上商城了.这次用到了和之前都不一样的框架:SSH.这个项目就和之前学牛腩一样,有着里程碑的意义.当然了,这也就意味着,什么都是新鲜的,接触到的东西,有时 ...

  2. docker学习(二)

    1 镜像 docker使用联合加载技术,一次同时加载多个文件系统,在外面只能看到一个文件系统 docker使用写时复制,每个只读镜像层都是只读的,也永远不会发生变化,建立一个新容器,会构建一个镜像栈, ...

  3. markdown语法学习源码

    __注: 结合markdown官方文档 其中大部分例子和说明文字都摘自官方文档__官方链接:[Markdown: Basics (快速入门)](http://wowubuntu.com/markdow ...

  4. C# Java 3DES加密解密 扩展及修正\0 问题

    注: C#已亲测及做扩展, Java 部分未做验证 /// <summary> /// 3DES加密解密 /// ------------------------------------- ...

  5. JAVA设计模式--State(状态模式)

    状态模式(State Pattern)是设计模式的一种,属于行为模式. 定义(源于Design Pattern):当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类. 状态模式主要 ...

  6. javaSE第二十天

    第二十天    254 1:递归(理解)    254 (1)方法定义中调用方法本身的现象    254 (2)递归的注意事项    255 (3)递归的案例:    255 A:递归求阶乘    2 ...

  7. [leetcode]_Pascal's Triangle

    题目:题目本身不存在问题,生成Pascal三角. 注意: ArrayList的使用: 1.ArrayList申请二维数组. ArrayList<ArrayList<Integer>& ...

  8. .NET程序员爱上网站[整理]

    1.博客园(代码改变世界) http://www.cnblogs.com 2.开源中国社区(开源软件发现.使用和交流平台) http://www.oschina.net 3.CSDN(中国最大的IT社 ...

  9. nginx+php与apache+php性能对比

    测试工具http_load相同的动态页面测试,相同的硬件资源,相同并发,相同请求数量的前提下,nginx+php比apache+php的性能要 差,而且如果请求的压力大于硬件资源的承受能力,nginx ...

  10. PHP数组在HTML之中的应用

    <select name="data[status]" id="" <?php if(in_array($list['status'],array( ...