Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1253907
  • 博文数量: 254
  • 博客积分: 1586
  • 博客等级: 上尉
  • 技术积分: 2295
  • 用 户 组: 普通用户
  • 注册时间: 2009-01-15 16:38
个人简介

linux学习中

文章分类

全部博文(254)

文章存档

2016年(6)

2015年(2)

2014年(74)

2013年(93)

2012年(12)

2011年(2)

2010年(51)

2009年(14)

分类: LINUX

2013-03-18 09:37:50

7.1-7.2:

1. 可以用nm命令列出模块内使用的函数和全局变量。如:
> nm test.ko
0000003c r __mod_author109
0000000c r __mod_description110
00000000 r __mod_license111
00000074 r __mod_vermagic5
00000068 r __module_depends
00000000 D __this_module
00000000 S bb
00000000 T cleanup_module
00000000 T init_module
         U printk
00000000 t test_exit
00000000 t test_init
00000000 B timer

r:表示符号在“只读”数据区,
D:表示符号在“初始化了的”数据区
S:表示符号在“未初始化”数据区
T:在文本区
U:符号未定义,此符号必须已经编译进内核,否则模块加载或运行不成功
B:在未初始化的数据区,即BSS
Note: 更多定义见:man nm

如果KALLSYMS_ALL开始了,则可以用以下命令显示内核已经存在的符号定义:
> cat /proc/kallsyms |grep "xxx"

2. 模块间可能有依赖关系,其依赖关系存放在下面文件:
> cat /lib/modules/kernel version/modules.dep
/lib/modules/2.6.32/kernel/drivers/video/backlight/backlight.ko:
/lib/modules/2.6.32/kernel/drivers/video/backlight/lcd.ko:
/lib/modules/2.6.32/kernel/drivers/video/backlight/generic_bl.ko: /lib/modules/2.6.32/kernel/drivers/video/backlight/backlight.ko
/lib/modules/2.6.32/kernel/drivers/scsi/scsi_wait_scan.ko:

前面的模块依赖于后面的模块。
模块依赖文件的产生是用depmod命令产生,它产生所有模块以及内核的符号列表,然后分析出依赖关系。

3. modinfo xxx.ko 可以列出模块的一些有用信息
4. 有些模块需要提供更多的信息给内核,如PCI,USB等,这些信息通常用MODULE_ALIAS来提供,这些信息是通过 scripts/mod/file2alias.c脚本来分析产生 .mod.c文件给内核提供信息。

7.3 section
1. 模块的三种状态:
enum module_state
{
MODULE_STATE_LIVE,
MODULE_STATE_COMING,
MODULE_STATE_GOING,
};
LIVE:表示完成了初始化,正常工作状态
COMING:装载期间
GOING:卸载状态
2. 模块的两种依赖关系:
A依赖于B或B引用A。

3.模块的参数:struct list modules_which_use_me, 表示所有引用该模块的模块

4.  struct module_use
{
    struct list_head list;
    struct module *module_which_uses;
}; 表示模块所使用的其它模块。

5. 模块产生的步骤:
A:先把.C文件编译为.o文件
B:编译所有其它的模块文件,并分析其依赖关系,生成.mod.c文件
C:链接生成最终文件(有可能插入了其它模块的信息,因为有依赖关系).

6. module_init为模块的初始化文件
module_exit为模块的退出文件。
如果该模块没有被定义为模块类型,则module_init被放到内核的指定段中,一般为.init.section. 否则module_init为普通文件,否则会被定义为普通文件。init文件会在初始化完成后释放。

7. 模块被加载时必须和内核保持版本的一致,匹配的信息包括:
A:SMP开启与否
B:抢占是否被配置
C:编译器的版本
D:架构特定的要求

8. 插入模块的执行流程:
kernel/module.c
init_module
    |-->load_module
    |-->insert module into kernel list
    |-->mod->init
    |-->free init area

9. 删除模块的流程:
kernel/module.c
delete_module
    |-->find module
    |-->ensure module is not used
    |-->mod->exit
    |-->free_module

7.4
1. 模块有可能在下面两种情况下被自动加载:
A:内核发现需要的函数不可用,会试图加载相应的模块来实现需要的函数
B:新设备加到了支持热插拔的总线,如USB,PCI等

2. 自动加载由request_module函数实现,定义在kernel/kmod.c中,如果内核不支持模块,则该函数定义为空。内核必须在需要加载模块的地方显示调用该函数。

3. request_module实现过程:
kernel/kmod.c
request_module
    |-->Prepare environment for modprobe
    |-->Too many simultaneous calls of request_module? return
    |-->call_usermodehelper
默认会调用/sbin/modprobe用户层程序去加载模块

4. 热拔插会调用/sbin/udevd用户层程序

7.5
1. 为了应对内核版本变化,模块无法加载的问题,模块使用了CRC的机制。即:把模块导出的函数的参数由函数(位于scripts/genksyms/genksym)生成CRC码,并保存在模块文件最后生成的二进制代码段中,加载时内核比较这个CRC,如果不同,说明接口发生了变量,不能加载成功。







阅读(1221) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~