linux内核学习(1)

LKM,可加载内核模块,是这是一种用来动态地向 Linux 内核添加或删除代码的新方法,也是 Linux 内核中为设备驱动程序和文件系统使用的一种流行机制。
如果您曾经重新编译过 Linux 内核,就可能会发现在内核的配置过程中,有很多设备驱动程序和其他内核元素都被编译成了模块。如果一个驱动程序被直接编译到了内核中,那么即使这个驱动程序没有运行,它的代码和静态数据也会占据一部分空间。但是如果这个驱动程序被编译成一个模块,就只有在需要内存并将其加载到内核时才会真正占用内存空间。对于 LKM 来说,我们不会注意到有什么性能方面的差异,因此这对于创建一个适应于自己环境的内核来说是一种功能强大的手段,这样可以根据可用硬件和连接的设备来加载对应的模块。

下面给出了一个hello_world的内核模块
hello_world.c
  1 #include <linux/module.h>
  2 /* Defines the license for this LKM */
  3 MODULE_LICENSE("GPL");
  4 /* Init function called on module entry */
  5 int my_module_init( void )
  6 {
  7   printk(KERN_INFO "Hello world!/n");
  8   return 0;
  9 }
 10 /* Cleanup function called on module exit */
 11 void my_module_cleanup( void )
 12 {
 13   printk(KERN_INFO " Byebye!/n");
 14   return;
 15 }
 16 /* Declare entry and exit functions */
 17 module_init( my_module_init );
 18 module_exit( my_module_cleanup );

line 1定义了模块头(包含了模块的API、类型和宏)
line 2定义了模块的许可证,我们这里定义了GPL,防止会污染到内核。
line 5-9定义了模块的init函数,他会在模块被加载的时候调用,进行一些初始化的工作。
line 11-15定义了模块的cleanup函数,他会在卸载模块的时候调用,用来释放内存和清除模块的痕迹。
两个函数都用到了printk函数,printk函数是kernel的printf函数。
函数printk原型和一些相应的宏在include/linux/kernel.h文件中定义,将内核的信息反馈给控制台、dmesg和syslog后台。
line 17-18声明的模块的入口函数和出口函数这样我们可以根据自己的意愿来对init和cleanup进行命名了,只要最后告诉内核维护函数是这些函数就可以了。

要编译上述的LKM需要有内核的源码的支持,为了方便起见我们编写个Makefile
obj-m += hello+world.o

编译
secularbird@zhuangyao kernel_study $ make -C /usr/src/kernels/2.6.23.1-10.fc7-i686/ SUBDIRS=$PWD modules
make: Entering directory `/usr/src/kernels/2.6.23.1-10.fc7-i686'
  CC [M]  /home/secularbird/Templates/kernel_study/hello_world.o
  Building modules, stage 2.
  MODPOST 1 modules
  CC      /home/secularbird/Templates/kernel_study/hello_world.mod.o
  LD [M]  /home/secularbird/Templates/kernel_study/hello_world.ko
make: Leaving directory `/usr/src/kernels/2.6.23.1-10.fc7-i686'
注意:上面的内核版本要和现运行的版本一致,不然可能通过编译,但是加载模块时会出错。可用命令uname -r来查看你现有的内核的版本。

secularbird@zhuangyao kernel_study $ ls
hello_world.c  hello_world.ko  hello_world.mod.c  hello_world.mod.o  hello_world.o  Makefile  Module.symvers
结果生成了一个hello_world.ko的文件,这个新的命名约定可以帮助将这些内核对象(LKM)与标准对象区分开来。
现在可以加载或卸载这个模块了,然后可以查看它的输出。要加载这个模块,请使用 insmod 命令;反之,要卸载这个模块,请使用 rmmod 命令。lsmod 可以显示当前加载的 LKM。

注意:编译可以不用root进行,但加载要切换到root
root@zhuangyao kernel_study #/sbin/insmod hello_world.ko
root@zhuangyao kernel_study #/sbin/lsmod |grep hello_world
hello_world             5376  0
模块被加载上去了
root@zhuangyao kernel_study #dmesg |tail -5
hello: version magic '2.6.23.1-21.fc7 SMP mod_unload 686 4KSTACKS ' should be '2.6.23.1-10.fc7 SMP mod_unload 686 4KSTACKS '
my_module_init called.  Module is now loaded.
Hello world!
 Byebye!
Hello world!
呵呵,不要被前几行迷惑了,那是我测试时用的,如果你第一次加载成功,你应该会有一个"Hello world!"
卸载模块
root@zhuangyao kernel_study #/sbin/rmmod hello_world
root@zhuangyao kernel_study #dmesg |tail -5
my_module_init called.  Module is now loaded.
Hello world!
 Byebye!
Hello world!

All Right ,We got it now.
 
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

zeloas

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

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

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

打赏作者

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

抵扣说明:

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

余额充值