专注于互联网--专注于架构

最新标签
网站地图
文章索引
Rss订阅

首页 »Linux » 编译2.6内核:Linux 2.6内核的编译步骤及模块动态加载 »正文

编译2.6内核:Linux 2.6内核的编译步骤及模块动态加载

来源: 发布时间:星期四, 2009年2月12日 浏览:94次 评论:0


  本文是基于2.6内核也建议各位可以先看Linux内核设计和实现(第 2版)作为个基础知识铺垫当然从实战角度来看只要按着以下步骤去做也应该可以实现成功编译内核及加载模块

  个人用Linux版本为:Debian GNU/Linux内核版本为:2.6.20-1-686.

  第Linux内核源代码即构建LDD3(Linux Device Drivers 3rd)上面所说内核树

  如过安装Linux系统中已经自带了源代码应该在/usr/src目录下如果该目录为空则需要自己手动源代码代码思路方法和链接很多也可以在CU上通过去下载不过下载内核版本最好和所运行Linux系统内核版本当然也可以比Linux系统内核版本低但高话应该不行(个人尚未实战)

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

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

  # apt-cache search -source

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

  # apt-get linux-source-2.6.20

  下载完成后安装在/usr/src下文件名为:linux-source-2.6.20.tar.bz2,是个压缩包解压缩既可以得到整个内核源代码:

  # tar jxvf linux-source-2.6.20.tar.bz2

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

  注:该目录会因内核版本区别而区别各位动手实战朋友只需知道自己源代码所在具体位置即可

  第 2步:配置及编译内核

  进入/usr/src/linux——source-2.6.20目录下可以看到Makefile文件它包含了整个内核树编译信息该文件最上面 4行是有关内核版本信息对于整个Makefile可以不用做修改采用默认就可以了

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

  make menuconfig是基于界面内核配置思路方法make xconfig应该是基于QT库还有make gcofig也是基于图形配置思路方法应该是需要GTK环境make oldcofig就是对内核树原有.config文件进行配置下即可

  其实内核配置部分主要是保证内核启动模块可动态加载配置默认配置里面应该已经包含了这样内容因此我用是make oldconfig.

  在内核源码目录下执行:

  # make

  # make bzImage

  其中个make也可以不执行直接make bzImage这个过程可能要持续个小时左右因此是对整个内核重新编译了执行结束后可以看到在当前目录下生成了个新文件: vmlinux, 其属性为-rwxr-xr-x

  然后执行:

  # make modules

  # make modules_

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

  执行结束的后会在/lib/modules下生成新目录/lib/modules/2.6.20/ 在随后编译模块文件时要用到这个路径下build目录至此内核编译完成可以重启下系统

  第 3步:编写模块文件及Makefile

  以LDD3上hello.c为例:

//hello.c # <linux/init.h> # <linux/module.h> MODULE_LICENSE("Dual BSD/GPL"); hello_init(void) { prk(KERN_ALERT "Hello, world\n"); 0; } void hello_exit(void) { prk(KERN_ALERT"Goodbye, cruel world\n"); } module_init(hello_init); module_exit(hello_exit);





  Makefile文件内容为:

obj-m := hello.o KERNELDIR := /lib/modules/2.6.20/build PWD := $(shell pwd) modules: $(MAKE) -C $(KERNELDIR) M=$(PWD) modules modules_: $(MAKE) -C $(KERNELDIR) M=$(PWD) modules_ clean: rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions





  其中,hello.c和Makefile文件应该位于同个目录下,可以放在/home下,我两个文件都位于/home/david/.

  第 4步:编译和装载模块

  在文件所处目录下,执行:

  debian:/home/david # make

  然后查看该目录下有哪些文件生成:

debian:/home/david # ls -l 总计 28 drwxr-xr-x 2 david david 4096 2007-02-07 17:49 Desktop -rw-r--r-- 1 david david 462 2007-07-20 13:42 hello.c -rw-r--r-- 1 root root 2432 2007-07-20 13:55 hello.ko -rw-r--r-- 1 root root 607 2007-07-20 13:55 hello.mod.c -rw-r--r-- 1 root root 1968 2007-07-20 13:55 hello.mod.o -rw-r--r-- 1 root root 1140 2007-07-20 13:55 hello.o -rw-r--r-- 1 david david 267 2007-07-20 13:48 Makefile -rw-r--r-- 1 root root 0 2007-07-05 14:11 Module.symvers











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

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

  debian:/home/david # insmod hello.ko

  查看模块是否加载进内核:

  debian:/home/david # lsmod

  Module Size Used by

  hello 1344 0

  nfs 219468 0

  nfsd 202224 17

  …… ……

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

  卸载模块:

  debian:/home/david # rmmod hello

  同样可以通过lsmod来查看该模块是否被卸载.

  这里有两个问题,其就是prk输出问题.LDD3上也说,在加载和卸载模块时候都会有信息输出在屏幕上,如果在下通过终端仿真器(我们常用虚拟机算是种),则在屏幕上看不到任何输出.我同时在虚拟机和和物理机都运行了该模块,均未看到有"Hello, world"(加载模块时prk输出)或"Goodby, cruel world"(卸载模块时prk输出). 这个不知道是我操作系统发行版原因还是系统配置问题,请了解这个问题朋友指点下.

  其 2,书上讲到如果屏幕上看不到信息,可能输出在某个日志文件里面了,并说可能在/var/log/messages文件中.并且看到网上很多网友也说是输出到这个文件里面.我不知道有没有发现输出在其他日志文件里,不过我这个信息输出在/var/log/syslog里面.在加载和卸载完该模块后, 执行命令:

  debian:/home/david # cat /var/log/syslog | grep world

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

  Jul 20 14:15:29 localhost kernel: Hello, world

  Jul 20 14:15:34 localhost kernel: Goodbye, cruel world

  这就是prk应该输出信息.

  这里有另外个思路方法,可以实现prk信息输出在屏幕上,即更改prk输出优先级.例子中优先级为:KERN_ALERT,优先级为<1>,如果将优先级改为KERN_EMERG即<0>,则可以看到屏幕输出信息.

  修改思路方法只是修改下hello.c中两句prk内容,修改后hello.c如下:

# <linux/init.h> # <linux/module.h> MODULE_LICENSE("Dual BSD/GPL"); hello_init(void) { prk(KERN_EMERG "Hello, world\n"); /*改动部分*/ 0; } void hello_exit(void) { prk(KERN_EMERG"Goodbye, cruel world\n"); /*改动部分*/ } module_init(hello_init); module_exit(hello_exit);



  同样思路方法编译生成模块,再次用insmod和rmmod,则在屏幕上看到输出信息为:

debian:/home/david# insmod hello.ko debian:/home/david# Message from syslogd@localhost at Fri Jul 20 14:27:32 2007 ... localhost kernel: Hello, world debian:/home/david# rmmod hello debian:/home/david# Message from syslogd@localhost at Fri Jul 20 14:27:42 2007 ... localhost kernel: Goodbye, cruel world debian:/home/david



  但是,是否能够将prk优先级改为KERN_EMERG值得商榷.在Linux Kernel Development中,对该优先级描述为: An emergency condition; the system is probably dead.

  以上就是整个2.6内核编译步骤以及模块动态加载思路方法.理解和解释有误地方,也请各位浏览本文朋友指点,也希望能和对内核和驱动感兴趣朋友交流



0

相关文章

读者评论

发表评论

  • 昵称:
  • 内容: