linux26内核的编译步骤及模块的动态加载内核源码学习linux论坛.docx

上传人:b****5 文档编号:28385284 上传时间:2023-07-10 格式:DOCX 页数:7 大小:18.44KB
下载 相关 举报
linux26内核的编译步骤及模块的动态加载内核源码学习linux论坛.docx_第1页
第1页 / 共7页
linux26内核的编译步骤及模块的动态加载内核源码学习linux论坛.docx_第2页
第2页 / 共7页
linux26内核的编译步骤及模块的动态加载内核源码学习linux论坛.docx_第3页
第3页 / 共7页
linux26内核的编译步骤及模块的动态加载内核源码学习linux论坛.docx_第4页
第4页 / 共7页
linux26内核的编译步骤及模块的动态加载内核源码学习linux论坛.docx_第5页
第5页 / 共7页
点击查看更多>>
下载资源
资源描述

linux26内核的编译步骤及模块的动态加载内核源码学习linux论坛.docx

《linux26内核的编译步骤及模块的动态加载内核源码学习linux论坛.docx》由会员分享,可在线阅读,更多相关《linux26内核的编译步骤及模块的动态加载内核源码学习linux论坛.docx(7页珍藏版)》请在冰豆网上搜索。

linux26内核的编译步骤及模块的动态加载内核源码学习linux论坛.docx

linux26内核的编译步骤及模块的动态加载内核源码学习linux论坛

[原创]linux2.6内核的编译步骤及模块的动态加载-内核源码学习-linux论坛

05年本科毕业设计做的是Linux下驱动的剖析,当时就买了一本《Linux设备驱动程序(第二版)》,但是没有实现将最简单的helloworld程

序编译成模块,加载到kernel里。

不过,现在自己确实打算做一款芯片的Linux的驱动,因此,又开始看了《Linux设备驱动程序》这本书,不过已

经是第三版了。

第二版讲的是2.4的内核,第三版讲的是2.6的内核。

两个内核版本之间关于编译内核以及加载模块的方法都有所变化。

本文是基于2.6的内核,也建议各位可以先看一下《Linux内核设计与实现(第二版)》作为一个基础知识的铺垫。

当然,从实践角度来看,只要按着以下的步骤去做也应该可以实现成功编译内核及加载模块。

个人用的Linux版本为:

DebianGNU/Linux,内核版本为:

2.6.20-1-686.第一步,下载Linux内核的源代码,即构建LDD3(LinuxDeviceDrivers3rd)上面所说的内核树。

如过安装的Linux系统中已经自带了源代码的话,应该在/usr/src目录下。

如果该目录为空的话,则需要自己手动下载源代码。

下载代码的方法和链接很多,也可以在CU上通过

Debian下可以很方便的通过Debian源下载:

首先查找一下可下载的内核源代码:

#apt-cachesearchlinux-source

其中显示的有:

linux-source-2.6.20,没有和我的内核版本完全匹配,不过也没关系,直接下载就可以了:

#apt-getinstalllinux-source-2.6.20

下载完成后,安装在/usr/src下,文件名为:

linux-source-2.6.20.tar.bz2,是一个压缩包,解压缩既可以得到整个内核的源代码:

#tarjxvflinux-source-2.6.20.tar.bz2

解压后生成一个新的目录/usr/src/linux--source-2.6.20,所有的源代码都在该目录下。

注:

该目录会因内核版本的不同而不同,各位动手实践的朋友只需知道自己的源代码所在的具体位置即可。

第二步:

配置及编译内核。

进入/usr/src/linux--source-2.6.20目录下,可以看到Makefile文件,它包含了整个内核树编译信息。

该文件最上面四行是关于内核版本的信息。

对于整个Makefile可以不用做修改,采用默认的就可以了。

一般情况下,需要先用命令诸如"makemenuconfig","makexconfig"或者"makeoldcofig"对内核进行配置,这几个都是对内核进行配置的命令,只是它们运行的环境不一样,执行一下这几个命令中的任何一个即可对内核进行配置:

makemenuconfig是基于界面的内核配置方法,makexconfig应该是基于QT库的,还有makegcofig也是基于图形的配置方法,应该是需要GTK的环境,makeoldcofig就是对内核树原有的.config文件进行配置一下即可。

其实内核的配置部分,主要是保证内核启动模块可动态加载的配置,默认配置里面应该已经包含了这样的内容,因此,我用的是makeoldconfig.内核的详细配置请见另外一位网友的帖子,这里给出链接:

#make

#makebzImage

其中,第一个make也可以不执行,直接makebzImage。

这个过程可能要持续一个小时左右,因此是对整个内核重新编译了。

执行结束后,可以看到在当前目录下生成了一个新的文件:

vmlinux,其属性为-rwxr-xr-x。

然后执行:

#makemodules

#makemodules_install

对内核的所有模块进行编译和安装。

执行结束之后,会在/lib/modules下生成新的目录/lib/modules/2.6.20/。

在随后的编译模块文件时,要用到这个路径下的build目录。

至此,内核编译完成。

可以重启一下系统。

第三步:

编写模块文件及Makefile

以LDD3上的hello.c为例:

//hello.c

#include<linux/init.h>

#include<linux/module.h>

MODULE_LICENSE("DualBSD/GPL");staticinthello_init(void)

{

printk(KERN_ALERT"Hello,world\n");

return0;

}staticvoidhello_exit(void)

{

printk(KERN_ALERT"Goodbye,cruelworld\n");

}module_init(hello_init);

module_exit(hello_exit);Makefile文件的内容为:

obj-m:

=hello.o

KERNELDIR:

=/lib/modules/2.6.20/build

PWD:

=$(shellpwd)modules:

$(MAKE)-C$(KERNELDIR)M=$(PWD)modulesmodules_install:

$(MAKE)-C$(KERNELDIR)M=$(PWD)modules_installclean:

rm-rf*.o*~core.depend.*.cmd*.ko*.mod.c.tmp_versions其中,hello.c和Makefile文件应该位于同一个目录下,可以放在/home下,我的两个文件都位于/home/david/.第四步:

编译和装载模块在文件所处的目录下,执行:

debian:

/home/david#make然后查看该目录下有哪些文件生成:

debian:

/home/david#ls-l

总计28

drwxr-xr-x2daviddavid40962007-02-0717:

49Desktop

-rw-r--r--1daviddavid4622007-07-2013:

42hello.c

-rw-r--r--1rootroot24322007-07-2013:

55hello.ko

-rw-r--r--1rootroot6072007-07-2013:

55hello.mod.c

-rw-r--r--1rootroot19682007-07-2013:

55hello.mod.o

-rw-r--r--1rootroot11402007-07-2013:

55hello.o

-rw-r--r--1daviddavid2672007-07-2013:

48Makefile

-rw-r--r--1rootroot02007-07-0514:

11Module.symvers可见,已经生成模块文件hello.ko.

然后,就可以加载该模块:

debian:

/home/david#insmodhello.ko查看模块是否加载进内核:

debian:

/home/david#lsmod

ModuleSizeUsedby

hello13440

nfs2194680

nfsd20222417

......其中Module名为hello的即为我们所加载的模块.卸载模块:

debian:

/home/david#rmmodhello同样可以通过lsmod来查看该模块是否被卸载.这里有两个问题,其一就是printk()输出的问题.LDD3上也说,在加载和卸载模块的时候都会有信息输出在屏幕上,如果通过终端仿真器(,则在屏幕

上看不到任何输出.我同时在虚拟机和和物理机都运行了该模块,均未看到有"Hello,

world"(加载模块时printk的输出)或"Goodby,cruelworld"(卸载模块时printk的输出).

这个不知道是我操作系统发行版的原因还是系统配置的问题,请了解这个问题的朋友指点一下.其二,书上讲到如果屏幕上看不到信息,可能输出在某个日志文件里面了,并说可能在/var/log/messages文件中.并且看到网上很多网友也说是

输出到这个文件里面.我不知道有没有发现输出在其他日志文件里的,不过我的这个信息输出在/var/log/syslog里面.在加载和卸载完该模块后,

执行命令:

debian:

/home/david#cat/var/log/syslog|grepworld

可以看到有两行内容.当然,也可以不用grepworld,应该会出现在最后两行.Jul2014:

15:

29localhostkernel:

Hello,world

Jul2014:

15:

34localhostkernel:

Goodbye,cruelworld这就是printk应该输出的信息.这里有另外一个方法,可以实现printk的信息输出在屏幕上,即更改printk输出的优先级.例子中的优先级为:

KERN_ALERT,优先级为<1>,如果将优先级改为KERN_EMERG即<0>,则可以看到屏幕的输出信息.

修改的方法只是修改一下hello.c中两句printk()的内容,修改后的hello.c如下:

#include<linux/init.h>

#include<linux/module.h>

MODULE_LICENSE("DualBSD/GPL");staticinthello_init(void)

{

printk(KERN_EMERG"Hello,world\n");/*改动部分*/

return0;

}staticvoidhello_exit(void)

{

printk(KERN_EMERG"Goodbye,cruelworld\n");/*改动部分*/

}module_init(hello_init);

module_exit(hello_exit);同样的方法编译生成模块,再次用insmod和rmmod,则在屏幕上看到的输出信息为:

debian:

/home/david#insmodhello.ko

debian:

/home/david#

Messagefromsyslogd@localhostatFriJul2014:

27:

322007...

localhostkernel:

Hello,worlddebian:

/home/david#rmmodhello

debian:

/home/david#

Messagefromsyslogd@localhostatFriJul2014:

27:

422007...

localhostkernel:

Goodbye,cruelworlddebian:

/home/david

但是,是否能够将printk()的优先级改为KERN_EMERG值得商榷.因为在LinuxKernel

Development中,对该优先级的描述为:

Anemergencycondition;thesystemisprobably

dead.以上就是整个2.6内核编译步骤以及模块动态加载的方法.理解和解释有误的地方,也请各位浏览本文的朋友指点,也希望能和对内核和驱动感兴趣的朋友交流.本文也参考了一位网友博客上一篇关于编译2.6内核的文章,这里给出链接:

交流一下。

LDD3书中所说的看不到输出指的是在终端仿真器,就是我们平时在X-Window下用的终端,譬如我用的时Gnome-Terminal,在

这种情况下看不到屏幕的输出。

而我上面的例程正是在终端下运行的。

当时没想到切换到控制台Console运行一下试试。

今天在控制台运行了,发现无论是在

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > IT计算机 > 计算机硬件及网络

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1