内核模块下载和编译、安装

来源:互联网 发布:软件外包开发 编辑:程序博客网 时间:2024/05/22 02:05
开源力量学习笔记
下载内核

可以从网站git.kernel.org中找到自己感兴趣的分支

Linus的分支
  1. git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
下载完成后,可以用make localmodconfig来按照现有的kernel编译源代码

开始编译
  1. make -j6
编译完后安装
  1. make modules_install
  2. make install
然后修改grub2,默认fedora19第一个就是安装的内核。ubuntu可以用sudo update-grub
  1. cd /boot/grub2
  2. vim grub.cfg
重启一下就可以进编译好的内核了。可以写个内核模块测试一下
  1. echo > main.c
  2. echo > Makefile
linux中底层有一个Kbuild,然后在各层中有kconfig.然后又对应一个Makefile
下面是一个简单的Makefile:
  1. obj-m = main.o

  2. all:
  3.         make -C /lib/modules/`uname -r`/build M=`pwd`
  4. clean:
  5.         rm -f *.o *.ko *.mod.c modules.order Module.symvers
make -C 后面是内核的目录,用``+shell可以获取内容。M应该是内核的源地址。

要使用内核的函数,必须只使用内核的导出函数。不能使用用户空间的任何Lib
-EXPORT_SYMBOL和EXPORT_SYMBOL_GPL
-或者在.h中实现的函数
编译有多个源文件的module
此时main.c文件中还是空的,加点东西试试吧
  1. #include <linux/module.h>

  2. MODULE_LICENSE("GPL");    //代码的说明
  3. MODULE_AUTHOR("Chen");
  4. MODULE_DESCRIPTION("The module is only used for test.");

  5. static __init int minit(void)    //如果函数只调用一次的函数可以用__init来修饰,调用完后可以free它
  6. {
  7.     printk("call %s.\n",__FUNCTION__);
  8.     return 0;
  9. }

  10. static __exit int mexit(void)    //退出的话就可以用__exit修饰
  11. {
  12.     printk("call %s.\n",__FUNCTION__);
  13. }

  14. module_init(minit)    //内核宏入口
  15. module_exit(mexit)    //内核宏退出
make后可以用insmod家在编译好的内核模块main.ko,卸载就是rmmod
然后通过dmesg看情况。

更进一步的话,可以再创建一个other.c
  1. #include <linux/module.h>

  2. void other_function(void)
  3. {
  4.     printk("call %s.\n",__FUNCTION__);
  5. }
然后在main.c中引用,当然我们还需要再改Makefile
  1. obj-m = test.o
  2. test-y = main.o other.o

  3. all:
  4.     make -C /lib/modules/`uname -r`/build M=`pwd`
  5. clean:
  6.     rm -f *.o *.ko *.mod.c modules.order Module.symvers
-y表示把mian.o和other.o生成test.o
编译多个源文件位于不同目录的module
如果other.o在src的文件目录下呢,那么test-y = main.o src/other.o
指定include.h位置
如果是other.h在include文件夹下,那么同样加上目录
  1. #ifndef __OTHER_H
  2. #define __OTHER_H

  3. extern void other_function(void);
  4. #endif
当然如果我们需要使用外部的库文件,文件路径没有那么固定。这时候就可以在Makefile中添加
  1. all:
  2.     make -C /lib/modules/`uname -r`/build EXTRA_CFLAGS=-I$(shell pwd)/include M=`pwd`
同时main.c中的#include "include/other.h"可以改成
  1. #include <other.h>
模块参数
我们可以用modinfo来看模块信息,如:
  1. [chen@localhost linux]$ modinfo ./fs/fuse/fuse.ko
  2. filename: /home/chen/mygit/linux/./fs/fuse/fuse.ko     表示模块的绝对路径
  3. alias: devname:fuse                                    alias:别名
  4. alias: char-major-10-229
  5. alias: fs-fuseblk
  6. alias: fs-fuse
  7. license: GPL                                           支持GPL协议
  8. description: Filesystem in Userspace                   模块的描述
  9. author: Miklos Szeredi <miklos@szeredi.hu>             模块作者
  10. alias: fs-fusectl
  11. depends:                                               depends:表示fuse.ko模块所依赖的模块
  12. intree: Y
  13. vermagic: 3.18.0-rc5 SMP mod_unload                    vermagic:表示编译时对应的内核版本、硬件平台及GCC版本
  14. parm: max_user_bgreq:Global limit for the maximum number of backgrounded requests an unprivileged user can set (uint)    parm:相对应的调试参数,括号中表示参数的类型如uint
  15. parm: max_user_congthresh:Global limit for the maximum congestion threshold an unprivileged user can set (uint)
可以自己编写一个
  1. static unsigned int testpar = 0;
  2. module_param(testpar, uint, S_IRUGO | S_IWUSR)
  3. //然后在main函数中加
  4.     printk("testpar = %d.\n", testpar);
编译后就看到了
  1. [chen@localhost test]$ modinfo tmain.ko
  2. filename: /home/chen/mygit/test/tmain.ko
  3. description: The module is only used for test.
  4. author: Chen
  5. license: GPL
  6. depends:
  7. vermagic: 3.18.0-rc5 SMP mod_unload
  8. parm: testpar:uint
然后我们就可以给模块参数赋值了
  1. [chen@localhost test]$ insmod tmain.ko
  2. [chen@localhost test]$ rmmod tmain.ko
  3. [chen@localhost test]$ insmod tmain.ko testpar=100
  4. [chen@localhost test]$ dmesg
  5. [ 7389.378824] testpar = 0.                    //之前没赋值
  6. [ 7389.378830] call minit.
  7. [ 7389.378831] call other_function.
  8. [ 7509.541034] call mexit.
  9. [ 7529.539102] testpar = 100.                   //赋值之后
  10. [ 7529.539107] call minit.
  11. [ 7529.539108] call other_function.
编写和编译一个module之间有依赖的情况
首先把上面的模块变成m1,复制一个m2,删除其中的src,在m2中编译会有警告说函数未定义
这时就可以把m1编译出来的Module.symvers复制到m2中,编译就能通过。加载时需要先加载m1模块,再加载m2模块




<script>window._bd_share_config={"common":{"bdSnsKey":{},"bdText":"","bdMini":"2","bdMiniList":false,"bdPic":"","bdStyle":"0","bdSize":"16"},"share":{}};with(document)0[(getElementsByTagName('head')[0]||body).appendChild(createElement('script')).src='http://bdimg.share.baidu.com/static/api/js/share.js?v=89860593.js?cdnversion='+~(-new Date()/36e5)];</script>
阅读(632) | 评论(0) | 转发(0) |
0

上一篇:linux实用技巧:你该使用ctags查找源码了

下一篇:3.18内核的sk_buff

相关热门文章
  • c++防止隐藏的拷贝构造...
  • Linux内核模块LKM编译-自制Mak...
  • 关于内核模块的挂载后的最终虚...
  • 关于内核模块挂载出现“no sym...
  • 存在依赖关系的内核模块的编译...
  • linux 常见服务端口
  • xmanager 2.0 for linux配置
  • 【ROOTFS搭建】busybox的httpd...
  • openwrt中luci学习笔记
  • 什么是shell
  • linux dhcp peizhi roc
  • 关于Unix文件的软链接
  • 求教这个命令什么意思,我是新...
  • sed -e "/grep/d" 是什么意思...
  • 谁能够帮我解决LINUX 2.6 10...
给主人留下些什么吧!~~
原创粉丝点击