开源力量学习笔记
下载内核
可以从网站git.kernel.org中找到自己感兴趣的分支
Linus的分支
下载完成后,可以用make localmodconfig来按照现有的kernel编译源代码
开始编译
编译完后安装
然后修改grub2
,默认fedora19第一个就是安装的内核。ubuntu可以用sudo update-grub
重启一下就可以进编译好的
内核了。可以写个内核模块测试一下
linux中底层有一个Kbuild,然后在各层中有kconfig.然后又对应一个Makefile
下面是一个简单的Makefile:
make -C 后面是内核的目录,用``+shell可以获取内容。M应该是内核的源地址。
要使用内核的函数,必须只使用内核的导出函数。不能使用用户空间的任何Lib
-EXPORT_SYMBOL和EXPORT_SYMBOL_GPL
-或者在.h中实现的函数
编译有多个源文件的module
此时main.c文件中还是空的,加点东西试试吧
make后可以用insmod家在编译好的内核模块main.ko,卸载就是rmmod
然后通过dmesg看情况。
更进一步的话,可以再创建一个other.c
然后在main.c中引用,当然我们还需要再改Makefile
-y表示把mian.o和other.o生成test.o
编译多个源文件位于不同目录的module
如果other.o在src的文件目录下呢,那么test-y = main.o src/other.o
指定include.h位置
如果是other.h在include文件夹下,那么同样加上目录
当然如果我们需要使用外部的库文件,文件路径没有那么固定。这时候就可以在Makefile中添加
同时main.c中的#include "include/other.h"可以改成
模块参数
我们可以用modinfo来看模块信息,如:
可以自己编写一个
编译后就看到了
然后我们就可以给模块参数
赋值了
编写和编译一个module之间有依赖的情况
首先把上面的模块变成m1,复制一个m2,删除其中的src ,在m 2中编译会有警告说函数未定义
这时就可以把m1编译出来的Module.symvers复制到m2中,编译就能通过。加载时需要先加载m1模块,再加载m2模块
阅读(632) | 评论(0) | 转发(0) |
<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>
下载内核
可以从网站git.kernel.org中找到自己感兴趣的分支
Linus的分支
- git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
开始编译
- make -j6
- make modules_install
- make install
- cd /boot/grub2
- vim grub.cfg
- echo > main.c
- echo > Makefile
下面是一个简单的Makefile:
- obj-m = main.o
-
- all:
- make -C /lib/modules/`uname -r`/build M=`pwd`
- clean:
- rm -f *.o *.ko *.mod.c modules.order Module.symvers
要使用内核的函数,必须只使用内核的导出函数。不能使用用户空间的任何Lib
-EXPORT_SYMBOL和EXPORT_SYMBOL_GPL
-或者在.h中实现的函数
编译有多个源文件的module
此时main.c文件中还是空的,加点东西试试吧
- #include <linux/module.h>
-
- MODULE_LICENSE("GPL"); //代码的说明
- MODULE_AUTHOR("Chen");
- MODULE_DESCRIPTION("The module is only used for test.");
-
- static __init int minit(void) //如果函数只调用一次的函数可以用__init来修饰,调用完后可以free它
- {
- printk("call %s.\n",__FUNCTION__);
- return 0;
- }
-
- static __exit int mexit(void) //退出的话就可以用__exit修饰
- {
- printk("call %s.\n",__FUNCTION__);
- }
-
- module_init(minit) //内核宏入口
- module_exit(mexit) //内核宏退出
然后通过dmesg看情况。
更进一步的话,可以再创建一个other.c
- #include <linux/module.h>
-
- void other_function(void)
- {
- printk("call %s.\n",__FUNCTION__);
- }
- obj-m = test.o
- test-y = main.o other.o
-
- all:
- make -C /lib/modules/`uname -r`/build M=`pwd`
- clean:
- rm -f *.o *.ko *.mod.c modules.order Module.symvers
编译多个源文件位于不同目录的module
如果other.o在src的文件目录下呢,那么test-y = main.o src/other.o
指定include.h位置
如果是other.h在include文件夹下,那么同样加上目录
- #ifndef __OTHER_H
- #define __OTHER_H
-
- extern void other_function(void);
- #endif
- all:
- make -C /lib/modules/`uname -r`/build EXTRA_CFLAGS=-I$(shell pwd)/include M=`pwd`
- #include <other.h>
我们可以用modinfo来看模块信息,如:
- [chen@localhost linux]$ modinfo ./fs/fuse/fuse.ko
- filename: /home/chen/mygit/linux/./fs/fuse/fuse.ko 表示模块的绝对路径
- alias: devname:fuse alias:别名
- alias: char-major-10-229
- alias: fs-fuseblk
- alias: fs-fuse
- license: GPL 支持GPL协议
- description: Filesystem in Userspace 模块的描述
- author: Miklos Szeredi <miklos@szeredi.hu> 模块作者
- alias: fs-fusectl
- depends: depends:表示fuse.ko模块所依赖的模块
- intree: Y
- vermagic: 3.18.0-rc5 SMP mod_unload vermagic:表示编译时对应的内核版本、硬件平台及GCC版本
- parm: max_user_bgreq:Global limit for the maximum number of backgrounded requests an unprivileged user can set (uint) parm:相对应的调试参数,括号中表示参数的类型如uint
- parm: max_user_congthresh:Global limit for the maximum congestion threshold an unprivileged user can set (uint)
- static unsigned int testpar = 0;
- module_param(testpar, uint, S_IRUGO | S_IWUSR)
- //然后在main函数中加
- printk("testpar = %d.\n", testpar);
- [chen@localhost test]$ modinfo tmain.ko
- filename: /home/chen/mygit/test/tmain.ko
- description: The module is only used for test.
- author: Chen
- license: GPL
- depends:
- vermagic: 3.18.0-rc5 SMP mod_unload
- parm: testpar:uint
- [chen@localhost test]$ insmod tmain.ko
- [chen@localhost test]$ rmmod tmain.ko
- [chen@localhost test]$ insmod tmain.ko testpar=100
- [chen@localhost test]$ dmesg
- [ 7389.378824] testpar = 0. //之前没赋值
- [ 7389.378830] call minit.
- [ 7389.378831] call other_function.
- [ 7509.541034] call mexit.
- [ 7529.539102] testpar = 100. //赋值之后
- [ 7529.539107] call minit.
- [ 7529.539108] call other_function.
首先把上面的模块变成m1,复制一个m2,删除其中的src ,在m 2中编译会有警告说函数未定义
这时就可以把m1编译出来的Module.symvers复制到m2中,编译就能通过。加载时需要先加载m1模块,再加载m2模块
相关热门文章
给主人留下些什么吧!~~
评论热议