文档介绍:L inux – Module Module 可以允许我们动态的改变 kernel , 加载 device driver , 而且它也能缩短我们 driver development 的时间。在 RedHat 里,我们可以执行 sndconfig ,它可以帮我们 config 声卡。 config 完之后如果捉得到你的声卡,那你的声卡马上就可以动了,而且还不用重新激活计算机。这是怎么做到的呢? 就是靠 module 。 module 其实是一般的程序,但是它可以被动态载到 kernel 里成为 kernel 的一部分。载到 kernel 里的 module 它具有跟 kernel 一样的权力,可以 access 任何 kernel 的 data structure 。你听过 kdebug 吗? 它是用来 debug kernel 的。它就是先将它本身的一个 module 载到 kernel 里,而在 user space 的 gdb 就可以经由跟这个 module 沟通, 得知 kernel 里的 data structure 的值, 除此之外, 还可以经由载到 kernel 的 module 去更改 kernel 里 data structure 。我们知道,在写 C 程序的时候,一个程序只能有一个 main 。 Kernel 本身其实也是一个程序,它本身也有个 main ,叫 start_kernel() 。当我们把一个 module 载到 kernel 里的时候, 它会跟 kernel 整合在一起, 成为 kernel 的一部分。请各位想想,那 module 可以有 main 吗? 答案很明显的,是 No 。理由很简单。一个程序只能有一个 main 。在使用 module 时, 有一点要记住的是 module 是处于被动的角色, 它是提供某些功能让别人去使用的。 Kernel 里有一个变量叫 module_list , 每当 user 将一个 module 载到 kernel 里的时候, 这个 module 就会被记录在 module_list 里面。当 kernel 要使用到这个 module 提供的 function 时,它就会去 search 这个 list ,找到 module ,然后再使用其提供的 function 或 variable 。每一个 module 都可以 export 一些 function 或变量来让别人使用。除此之外 module 也可以使用已经载到 kernel 里的 module 提供的 function 。这种情形叫做 module stack 。比方说, module A 用到 module B 的东西, 那在加载 module A 之前必须要先加载 module B。否则 module A 会无法加载。除了 module 会 export 东西之外, kernel 本身也会 export 一些 function 或 variable 。同样的, module 也可以使用 kernel 所 export 出来的东西。由于大家平时都是撰写 user space 的程序, 所以, 当突然去写 module 的时候, 会把平时写程序用的 function 拿到 module 里使用。像是 printf 之类的东西。我要告诉各位的是, module 所使用的 function 或 variable , 要嘛就是自己写在 module 里, 要嘛就是别的 module 提供的,再不就是 kernel 所提供的。你不能使用一般 libc 或 glibc 所提供的 function 。像 printf 之类的东西。这一点可能是各位要多小心的地方。 kernel 本身会 export 出一些 function 或 variable 来让 module 使用,但是,我们不是万能的,我们怎么知道 kernel 又开放哪些东西让我们使用呢? Linux 提供一 mand ,叫 ksyms ,你只要执行 ksyms -a 就可以知道 kernel 或目前载到 kernel 里的 module 提供了那些 function 或 variable 。底下是我的系统的情形: c0216ba0 drive_info_R744aa133 c01e4a44 boot_cpu_data_R660bd466 c01e4ac0 EISA_bus_R7413793a c01e4ac4 MCA_bus_Rf48a2c4c 34 __verify_write_R203afbeb ..... 在 kernel 里,有一个 symbol table 是用来记录 export 出去的 function 或 variable 。除此之外,也