Ubuntu 下编译的第一个内核模块
今天终于弄出了第一个模块,很高兴,我辛辛苦苦弄了几乎两天,遇到太多问题了。
错误的开始
最初,我从网上下载了kernel-2.6.31,然后开始编译安装这个内核。假设下载后的包放在了$HOME/Software/linux-kernel-2.6.31.tar.bz2
过了好久好久,差不多两个小时,内核编译好了,在arch/x86/boot/下有个bzImage文件,现在编译需要的模块
make modules_install会将编译的模块安装到目录/lib/modules/2.6.31/下,所以需要root权限,现在可以安装这个内核了,因为内核模块需要特定的版本支持才能插入内核中,所以开发基于这个内核版本的模块时,需要运行这个内核。
然后在/boot/grub/grub.cfg中添加一个menuentry,不过我不知道,为什么我添加后,启动时却没有显示出来,难道只能在/etc/grub.d/中修改?但是我修复被windows7覆盖的grub也是直接在/boot/grub/grub.cfg中修改的,都能生效!现在先不管这个问题。最后重启后我是手动启动的内核,在启动菜单时,按下C键,获得一个grub shell
这里是你的/boot分区,如果没有单独分区,这是/分区,注意:grub2中的分区号从1开始,也就是(hd0,7)表示/dev/sda7。
这里的root=/dev/sda7表示/分区,注意和前面的root命令区别
启动内核后,如果你没有安装模块,将会发现不正常,一定要确保前面执行了$sudo make modules_install
正确的hello world
我照着书上写了一个hello world模块,假设位于$HOME/Kernel_module/hello/下,如下
然后,编写一个Makefile,内容如下:
然后使用如下命令编译
编译会成功,插入模块
提示invalid module format 这种情况重复了好多次,就是不明白为什么不能插入内核。
正确的做法
最后,经过多次折磨后,我直接使用Ubuntu系统上的内核来编译模块。注意,这时候要运行ubuntu自带的内核,如2.6.31-17-generic 使用如下命令来编译
编译成功后,插入模块
没有提示任何东西,表示成功了,但是为什么没有输出”hello from hello world”?,如果你在字符终端而不是终端模拟器下运行的话,就会输出,因为在终端模拟器下时会把内核消息输出到日志文件/var/log/kern.log中。
如果上面编译失败,如modpost不存在,那么需要首先编译这些脚本