第7章 模块(1)

目录

7.1 概述

7.2 使用模块

7.2.1 添加和删除

7.2.2 依赖关系

7.2.3 查询模块信息

7.2.4 自动加载


本专栏文章将有70篇左右,欢迎+关注,查看后续文章。

7.1 概述

模块:

        内核组件,或驱动程序。

内核源码的许可证:

        GNU GPL v2

7.2 使用模块

7.2.1 添加和删除

modutils工具包中有:

        1. rmmod:卸载模块。

        2. insmode:加载单一模块。

        3. modprobe:加载模块及其依赖模块。

模块文件:一种可重定位文件(relocatable)。

可重定位的文件不会引用绝对地址,而是使用相对地址。

因此可重定位的文件能被链接器在内存中的任意地址加载和链接。

静态链接器:ld 命令。

        将编译后的多个目标文件(.o文件)链接成可执行文件或者库文件。

动态链接器:ld.so

        在程序运行时加载共享库到进程的地址空间,并解析程序中的符号引用。

nm 命令:

        作用:查看目标文件的符号表(如函数,全局变量)

使用举例:

# nm test.o

        0000000000000000         T         func

        0000000000000000         B         i

        0000000000000019         T         main

        U         malloc

        0000000000000000         D         z

其中:

T:Text

U:Unresolve。未解决的引用

D:Data

内核如何找到已加载的模块中未定义的函数?

        读取 /proc/kallsyms 内容,其中包括函数及其内存地址。

CONFIG_KALLSYMS_ALL:

        将所有符号信息导出到内核镜像的内核符号表中。

7.2.2 依赖关系

依赖关系:一个模块使用的函数定义在其他模块中。

depmod 命令:(busybox 中的一个命令)

        作用:

                1. 为每个模块都计算依赖关系。

                2. 将依赖关系写入 /lib/modules/3.10.0-uc0/modules.dep

 

modprobe 命令:

        作用:读取 modules.dep 得到模块的依赖关联,并加载模块及其依赖模块。

modules.builtin 文件:

        路径:/lib/modules/3.10.0-uc0/modules.builtin

        内容:

                包含所有编译进内核镜像中的模块名和路径(而非独立模块)。

        使用:

                内核启动时,会读取该文件,自动初始化内置模块。

modules.order文件

        路径:/lib/modules/3.10.0-uc0/modules.order

        内容:

                记录了内核模块的加载顺序。

        使用:内核启动时,读取该文件按照顺序加载模块,可保证依赖关系正确。

System.map:

        包含了内核导出的所有符号。

7.2.3 查询模块信息

modinfo 命令

        来源:modutils工具包。

        作用:查询模块信息。

        原理:读取了模块的.modinfo段,得到模块信息。

使用举例:

# modinfo /lib/modules/3.10.0-uc0/kernel/net/ipv4/ip_gre.ko

        filename:         /lib/modules/3.10.0-uc0/kernel/net/ipv4/ip_gre.ko

        license:           GPL

        alias:               netdev-gretap0

        depends:        gre

        vermagic:       3.10.0-uc0 mod_unload ARMv7

        parm:              log_ecn_error:Log packets received with corrupted ECN

7.2.4 自动加载

模块加载方式分为:

        1. 用户层:modprobe / insmod 命令。

        2. 内核:内核函数 request_module,该函数将调用用户层的 modprobe 命令。

request_module

        -> call_modprobe

                -> call_usermodehelper_setup():

call_usermodehelper_setup():

        作用:内核使用该函数调用用户空间的程序。

当接入USB 存储卡,内核如何知道加载 usb-storage 模块,而不是usb-eth 模块?

        1. 读取USB设备描述符中Class Code(类别),厂商ID等。

        2. 读取模块别名(ALIAS)。

MODULE_ALIAS宏:

        作用:生成模块别名。别名将保存在模块文件 .modinfo 段。

一个模块可同时支持多个别名,如:

        MODULE_ALIAS("ip6t_SNPT");

        MODULE_ALIAS("ip6t_DNPT");

比别名更直观的是设备数据库:

struct    platform_device_id     my_driver_ids[] = {

        {

                .name                 =         "s3c2410-i2c",

                .driver_data         =         TYPE_S3C2410,

        }, {

                .name                 =         "s3c2440-i2c",

                .driver_data         =         TYPE_S3C2440,

        },

};

MODULE_DEVICE_TABLE(platform,my_driver_ids);

        将my_driver_ids导出到用户空间,就可以知道加载设备什么驱动了。

#define   MODULE_DEVICE_TABLE(type,   name) \

extern const struct type##_device_id __mod_##type##__##name##_device_table

        将生成一个对应ELF符号。

scripts/mod/file2alias.c会对PCI/USB等总线来解析设备表,并生成MODULE_ALIAS项。

模块的别名:

        作用:模块自动装载的基础。

有些 bus 的 match 函数可能会比较 alias 和 device->name 是否一致。

  • 13
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

山下小童

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值