zoukankan      html  css  js  c++  java
  • 内核模块管理(转)

    内核与内核模块

    谈完了整个启动的流程,您应该会知道,在整个启动的过程当中,是否能够成功的驱动我们主机的硬件配备, 是内核 (kernel) 的工作!而内核一般都是压缩档,因此在使用内核之前,就得要将他解压缩后, 才能加载主内存当中。

    另外,为了应付日新月异的硬件,目前的内核都是具有『可读取模块化驱动程序』的功能, 亦即是所谓的『 modules (模块化)』的功能啦!所谓的模块化可以将他想成是一个『外挂程序』, 该外挂程序可能由硬件开发厂商提供,也有可能我们的内核本来就支持~不过,较新的硬件, 通常都需要硬件开发商提供驱动程序模块啦!

    那么内核与内核模块放在哪?

    • 内核: /boot/vmlinuz 或 /boot/vmlinuz-version;
    • 内核解压缩所需 RAM Disk: /boot/initrd (/boot/initrd-version);
    • 内核模块: /lib/modules/version/kernel 或 /lib/modules/$(uname -r)/kernel;
    • 内核原始码: /usr/src/linux 或 /usr/src/kernels/ (要安装才会有,默认不安装)

    如果该内核被顺利的加载系统当中了,那么就会有几个资讯纪录下来:

    • 内核版本: /proc/version
    • 系统内核功能: /proc/sys/kernel

    问题来啦,如果我有个新的硬件,偏偏我的操作系统不支持,该怎么办?很简单啊!

    • 重新编译内核,并加入最新的硬件驱动程序原始码;
    • 将该硬件的驱动程序编译成为模块,在启动时加载该模块

    上面第一点还很好理解,反正就是重新编译内核就是了。不过,内核编译很不容易啊!

    depmod

    既然要处理内核模块,自然就得要了解了解我们内核提供的模块之间的相关性啦! 基本上,内核模块的放置处是在 /lib/modules/$(uname -r)/kernel 当中,里面主要还分成几个目录:

    arch    :与硬件平台有关的项目,例如 CPU 的等级等等;
    crypto    :内核所支持的加密的技术,例如 md5 或者是 des 等等;
    drivers    :一些硬件的驱动程序,例如显卡、网络卡、PCI 相关硬件等等;
    fs    :内核所支持的 filesystems ,例如 vfat, reiserfs, nfs 等等;
    lib    :一些函式库;
    net    :与网络有关的各项协议数据,还有防火墙模块 (net/ipv4/netfilter/*) 等等;
    sound    :与音效有关的各项模块;

    如果要我们一个一个的去检查这些模块的主要资讯,然后定义出他们的相依性, 我们可能会疯掉吧!所以说,我们的 Linux 当然会提供一些模块相依性的解决方案罗~ 对啦!那就是检查 /lib/modules/$(uname -r)/modules.dep 这个文件啦!他记录了在内核支持的模块的各项相依性。

    那么这个文件如何创建呢?挺简单!利用 depmod 这个命令就可以达到创建该文件的需求了!

    [root@www ~]# depmod [-Ane]
    选项与参数:
    -A  :不加任何参数时, depmod 会主动的去分析目前内核的模块,并且重新写入
          /lib/modules/$(uname -r)/modules.dep 当中。若加入 -A 参数时,则 depmod
          会去搜寻比 modules.dep 内还要新的模块,如果真找到新模块,才会升级。
    -n  :不写入 modules.dep ,而是将结果输出到萤幕上(standard out);
    -e  :显示出目前已加载的不可运行的模块名称
    
    范例一:若我做好一个网络卡驱动程序,档名为 a.ko,该如何升级内核相依性?
    [root@www ~]# cp a.ko /lib/modules/$(uname -r)/kernel/drivers/net
    [root@www ~]# depmod

    以上面的范例一为例,我们的 Linux kernel 2.6.x 版本的内核模块扩展名一定是 .ko 结尾的, 当你使用 depmod 之后,该程序会跑到模块标准放置目录 /lib/modules/$(uname -r)/kernel , 并依据相关目录的定义将全部的模块捉出来分析,最终才将分析的结果写入 modules.dep 文件中的呐! 这个文件很重要喔!因为他会影响到本章稍后会介绍的 modprobe 命令的应用!

     

    lsmod

    那你到底晓不晓得目前内核加载了多少的模块呢?利用 lsmod 即可!

    [root@www ~]# lsmod
    Module                  Size  Used by
    autofs4                24517  2
    hidp                   23105  2
    ....(中间省略)....
    8139too                28737  0
    8139cp                 26305  0
    mii                     9409  2 8139too,8139cp <==mii 还被 8139cp, 8139too 使用
    ....(中间省略)....
    uhci_hcd               25421  0  <==底下三个是 U盘 相关的模块!
    ohci_hcd               23261  0
    ehci_hcd               33357  0

    使用 lsmod 之后,系统会显示出目前已经存在於内核当中的模块,显示的内容包括有:

    • 模块名称(Module);
    • 模块的大小(size);
    • 此模块是否被其他模块所使用 (Used by)。

    也就是说,模块其实真的有相依性喔!举上表为例, mii 这个模块会被 8139too 所使用。 简单的说,就是『当你要加载 8139too 时,需要先加载 mii 这个模块才可以顺利的加载 8139too』的意思。

    那么除了显示出目前的模块外,我还可以查阅每个模块的资讯吗?举例来说,我们知道 8139too 是螃蟹卡的驱动程序,那么 mii 是什么咚咚?就用 modinfo 来观察吧!

    [root@www ~]# modinfo [-adln] [module_name|filename]
    选项与参数:
    -a  :仅列出作者名称;
    -d  :仅列出该 modules 的说明 (description);
    -l  :仅列出授权 (license);
    -n  :仅列出该模块的详细路径。
    
    范例一:由上个表格当中,请列出 mii 这个模块的相关资讯:
    [root@www ~]# modinfo mii
    filename:       /lib/modules/2.6.18-92.el5/kernel/drivers/net/mii.ko
    license:        GPL
    description:    MII hardware support library
    author:         Jeff Garzik <jgarzik@pobox.com>
    srcversion:     16DCEDEE4B5629C222C352D
    depends:
    vermagic:       2.6.18-92.el5 SMP mod_unload 686 REGPARM 4KSTACKS gcc-4.1
    # 可以看到这个模块的来源,以及该模块的简易说明!(是硬件支持函式库)
    
    范例二:我有一个模块名称为 a.ko ,请问该模块的资讯为?
    [root@www ~]# modinfo a.ko
    ....(省略)....

    事实上,这个 modinfo 除了可以『查阅在内核内的模块』之外,还可以检查『某个模块文件』, 因此,如果你想要知道某个文件代表的意义为何,利用 modinfo 加上完整档名吧! 看看就晓得是啥玩意儿罗!

     

    insmod和rmmod

    好了,如果我想要自行手动加载模块,又该如何是好?有很多方法啦,最简单而且建议的,是使用 modprobe 这个命令来加载模块, 这是因为 modprobe 会主动的去搜寻 modules.dep 的内容,先克服了模块的相依性后, 才决定需要加载的模块有哪些,很方便。至於 insmod 则完全由使用者自行加载一个完整档名的模块, 并不会主动的分析模块相依性啊!

    [root@www ~]# insmod [/full/path/module_name] [parameters]
    
    范例一:请尝试加载 cifs.ko 这个『文件系统』模块
    [root@www ~]# insmod /lib/modules/$(uname -r)/kernel/fs/cifs/cifs.ko
    [root@www ~]# lsmod | grep cifs
    cifs                  212789  0

    他立刻就将该模块加载罗~但是 insmod 后面接的模块必须要是完整的『档名』才行!那如何移除这个模块呢?

    [root@www ~]# rmmod [-fw] module_name
    选项与参数:
    -f  :强制将该模块移除掉,不论是否正被使用;
    -w  :若该模块正被使用,则 rmmod 会等待该模块被使用完毕后,才移除他!
    
    范例一:将刚刚加载的 cifs 模块移除!
    [root@www ~]# rmmod cifs
    
    范例二:请加载 vfat 这个『文件系统』模块
    [root@www ~]# insmod /lib/modules/$(uname -r)/kernel/fs/vfat/vfat.ko
    insmod: error inserting '/lib/modules/2.6.18-92.el5/kernel/fs/vfat/vfat.ko': 
    -1 Unknown symbol in module
    # 无法加载 vfat 这个模块啊!伤脑筋!

     

    modprobe

    使用 insmod 与 rmmod 的问题就是,你必须要自行找到模块的完整档名才行,而且如同上述范例二的结果, 万一模块有相依属性的问题时,你将无法直接加载或移除该模块呢!所以近年来我们都建议直接使用 modprobe 来处理模块加载的问题,这个命令的用法是:

    [root@www ~]# modprobe [-lcfr] module_name
    选项与参数:
    -c  :列出目前系统所有的模块!(更详细的代号对应表)
    -l  :列出目前在 /lib/modules/`uname -r`/kernel 当中的所有模块完整档名;
    -f  :强制加载该模块;
    -r  :类似 rmmod ,就是移除某个模块罗~
    
    范例一:加载 cifs 模块
    [root@www ~]# modprobe cifs
    # 很方便吧!不需要知道完整的模块档名,这是因为该完整档名已经记录到
    # /lib/modules/`uname -r`/modules.dep 当中的缘故啊!如果要移除的话:
    [root@www ~]# modprobe -r cifs

    使用 modprobe 真的是要比 insmod 方便很多!因为他是直接去搜寻 modules.dep 的纪录, 所以罗,当然可以克服模块的相依性问题,而且还不需要知道该模块的详细路径呢!

     

    尝试使用 modprobe 加载 vfat 这个模块,并且观察该模块的相关模块是哪个?

    [root@www ~]# modprobe vfat
    [root@www ~]# lsmod | grep vfat
    vfat                   15809  0
    fat                    51165  1 vfat <==原来就是 fat 这个模块啊!
    
    [root@www ~]# modprobe -r vfat <==测试完移除此模块

     

    内核模块的额外参数配置: /etc/modprobe.conf

    如果您想要修改某些模块的额外参数配置, 就在这个文件内配置吧!我们假设一个案例好了,假设我的网络卡 eth0 是使用 ne , 但是 eth1 同样也使用 ne ,为了避免同一个模块会导致网络卡的错乱, 因此,我可以先找到 eth0 与 eth1 的 I/O 与 IRQ ,假设:

    • eth0 : I/O (0x300) 且 IRQ=5
    • eth1 : I/O (0x320) 且 IRQ=7

    则:

    [root@www ~]# vi /etc/modprobe.conf
    alias eth0 ne
    alias eth1 ne
    options eth0 io=0x300 irq=5
    options eth1 io=0x320 irq=7

    嘿嘿!如此一来,我的 Linux 就不会捉错网络卡的对应罗!因为被我强制指定某个 I/O 咯嘛! ^_^

     

    转自 http://vbird.dic.ksu.edu.tw/linux_basic/0510osloader_2.php

  • 相关阅读:
    Learn Prolog Now 翻译
    Learn Prolog Now 翻译
    Learn Prolog Now 翻译
    Learn Prolog Now 翻译
    Learn Prolog Now 翻译
    Learn Prolog Now 翻译
    Learn Prolog Now 翻译
    Learn Prolog Now 翻译
    Learn Prolog Now 翻译
    Learn Prolog Now 翻译
  • 原文地址:https://www.cnblogs.com/ggjucheng/p/2722929.html
Copyright © 2011-2022 走看看