linux模块编译(ubuntu怎么编译)

大家好,今天来为大家解答linux模块编译这个问题的一些问题点,包括ubuntu怎么编译也一样很多人还不知道,因此呢,今天就来为大家分析分析,现在让我们一起来看看吧!如果解决了您的问题,还望您关注下本站哦,谢谢~

linux内核编译过程中选项为m的模块是单独编译的对吗

对的

inux内核模块编译

为了清晰的编译Linux内核,内核编译系统使用Kbuild规则对编译的过程以及依赖进行规约。在内核模块的编译中,为了保持与内核源码的兼容以及传递编译链接选项给GCC,也使用Kbuild规则。

内核模块的源代码可以在内核源码树中,也可以在内核源码树外,当使用Kbuild时,两种情况的编译方式也大致相似。一般的内核模块在开发时,都是放在源码树外的。

本文主要是针对源码树外部的内核模块的编译。为了屏蔽内核模块编译的复杂性,开发人员需要编写额外的Makefile,最终让编译内核模块就像编译普通的应用程序一样,敲入”make”就行了。本文后面就给了一个实例。

编译外部模块

在编译外部模块之前,需要首先准备好当前内核的配置以及内核头文件,同时,当前内核的modules enable选项应该开启(编译内核时指定)。

命令行选项

使用如下命令编译外部模块:

make–C<kernerl_src_dir>M=<ext_module_path>

其中-C表明make要调用<kernel_src_dir>下的Makefile,该Makefile就是内核的Makefile,M为该Makefile的参数,指定外部模块源码的路径。当Makefile接收到M参数时,就默认编译外部模块。

例如,当前目录下存放一个外部模块的源码,其编译命令如下:

make–C/lib/modules/`uname-r`/buildM=`pwd`

其中uname–r获取当前运行内核的版本,pwd为当前源码路径,将其展开之后为:

make–C/lib/modules/ 2.6.42.9/buildM=/home/user/hello

其中/lib/modules/ 2.6.42.9/build是指向内核源码目录的符号链接。

编译完成之后,要安装驱动时,调用如下命令:

make–C/lib/modules/`uname-r`/buildM=`pwd` modules_install

编译目标

modules

编译外部模块,默认目标就是modules

modules_install

安装编译成功了的外部模块,默认的安装目录为/lib/modules/<kernel_release>/extra/,前缀可以同过INSTALL_MOD_PATH指定。

如何编译一个linux下的驱动模块

本文记录我的第一个Linux设备驱动程序的编译过程。遇到问题的解决方法。

环境:2.4.18-14的内核,Linux内核源码:2.4.18。

Linux内核源码路径:/usr/src/linux(这个源码是从kernel.org网站download的2.4.18版本)

按照《linux设备驱动开发详解》一书中的步骤实现经典例子"hello,world!"的例子。

具体步骤如下:

=============================================

1.源码如下:

/*

* hello.c-- the example of printf"hello world!" in the screen of driver program

*/

#include<linux/init.h>

#include<linux/module.h>

MODULE_LICENSE("Dual BSD/GPL");/* declare the license of the module,it is necessary*/

static int hello_init(void)

{

printk(KERN_ALERT"Hello World enter!\n");

return 0;

}

static int hello_exit(void)

{

printk(KERN_ALERT"Hello world exit!\n");

}

module_init(hello_init);/* load the module*/

module_exit(hello_exit);/* unload the module*/

进入目录:

[root@Alex_linux/]#cd/work/jiakun_test/moduletest

[root@Alex_linux moduletest]# vi hello.c

然后拷入上面书上的源码。

2.编译代码:

1>.首先我在2.4内核的虚拟机上进行编译,编译过程如下:

[root@Alex_linux moduletest]#gcc-D__KERNEL__-I/usr/src/linux-DMODULE-Wall-O2-c-o hello.o hello.c

其中-I选项指定内河源码,也就是内核源码树路径。编译结果:

hello.c:1:22: net/sock.h: No such file or directory

hello.c: In function `hello_init':

hello.c:6: warning: implicit declaration of function `printk'

hello.c:6: `KERN_ALERT' undeclared(first use in this function)

hello.c:6:(Each undeclared identifier is reported only once

hello.c:6: for each function it appears in.)

hello.c:6: parse error before string constant

hello.c: In function `hello_exit':

hello.c:11: `KERN_ALERT' undeclared(first use in this function)

hello.c:11: parse error before string constant

hello.c: At top level:

hello.c:13: warning: type defaults to `int' in declaration of `module_init'

hello.c:13: warning: parameter names(without types) in function declaration

hello.c:13: warning: data definition has no type or storage class

hello.c:14: warning: type defaults to `int' in declaration of `module_exit'

hello.c:14: warning: parameter names(without types) in function declaration

hello.c:14: warning: data definition has no type or storage class

在网上查询有网友提示没有引入kernel.h

解决:vi hello.c

在第一行加入:#include<linux/kernel.h>

再次编译仍然报KERN_ALERT没有声明

修改编译条件-I,再次编译:

[root@Alex_linux moduletest]#gcc-D__KERNEL__-I/usr/src/linux-DMODULE-Wall-O2-c-o hello.o hello.c

[root@Alex_linux moduletest]#ls

hello.c hello.o Makefile

[root@Alex_linux moduletest]#

2>.接着我尝试在2.6内核的虚拟机上进行编译

编译过程如下:

[root@JiaKun moduletest]# ls

hello.c makefile

[root@JiaKun moduletest]# vi hello.c

[root@JiaKun moduletest]# make

make-C/mylinux/kernel/2.4.18-rmk7 M=/home/alex/test/moduletest modules

make:***/mylinux/kernel/2.4.18-rmk7: No such file or directory. Stop.

make:*** [modules] Error 2

[root@JiaKun moduletest]# vi makefile

[root@JiaKun moduletest]# make

make-C/usr/src/kernels/2.6.18-53.el5-i686 M=/home/alex/test/moduletest modules

make[1]: Entering directory `/usr/src/kernels/2.6.18-53.el5-i686'

scripts/Makefile.build:17:/home/alex/test/moduletest/Makefile: No such file or directory

make[2]:*** No rule to make target `/home/alex/test/moduletest/Makefile'. Stop.

make[1]:*** [_module_/home/alex/test/moduletest] Error 2

make[1]: Leaving directory `/usr/src/kernels/2.6.18-53.el5-i686'

make:*** [modules] Error 2

[root@JiaKun moduletest]# mv makefile Makefile

[root@JiaKun moduletest]# make

make-C/usr/src/kernels/2.6.18-53.el5-i686 M=/home/alex/test/moduletest modules

make[1]: Entering directory `/usr/src/kernels/2.6.18-53.el5-i686'

CC [M]/home/alex/test/moduletest/hello.o

Building modules, stage 2.

MODPOST

CC/home/alex/test/moduletest/hello.mod.o

LD [M]/home/alex/test/moduletest/hello.ko

make[1]: Leaving directory `/usr/src/kernels/2.6.18-53.el5-i686'

[root@JiaKun moduletest]# ls

hello.c hello.ko hello.mod.c hello.mod.o hello.o Makefile Module.symvers

3.执行代码,加载驱动模块:

2.4内核加载模块:

insmod./hello.o

但是此时并没有输出printk打印的信息。但是可以在/var/log/messages中看到打印的信息,这是由于KERN_ALERT优先级不够高。这里

需要修改为:KERN_EMERG。再次编译,加载模块即可以看到结果

2.6内核加载模块:

[root@JiaKun moduletest]# insmod hello.ko

[root@JiaKun moduletest]#

Message from syslogd@ at Sat Jul 26 19:52:44 2008...

JiaKun kernel: Hello, world

有的朋友可能会出现insmod命令找不到的错误,这可能有下面几个原因:

<1>你的系统没有安装module-init-tools工具,关于此问题,只需安装即可,但是一般装完系统是有这个命令的。

<2>环境变量没有添加导致不能使用该命令。使用echo$PATH即可查看PATH环境变量,发现没有/sbin这个路径,所以你当然不能使用insmod这个命令了。解决的方法很简单,只需在命令行输入:

PATH="$PATH:/sbin"即可添加。(insmod在/sbin这个目录下,你可以使用whereis insmod查看)。

<3> insmod这个命令需要在root权限下才能使用。

加载完成后你可以输入lsmod查看hello这个模块哦。

4.卸载驱动模块:rmmod hello.

加载模块后就可在屏幕上看到如下信息:Hello world enter.

卸载时就可在屏幕上看到如下信息:hello world exit.

[root@JiaKun moduletest]# rmmod hello.ko

[root@JiaKun moduletest]#

Message from syslogd@ at Sat Jul 26 19:52:58 2008...

JiaKun kernel: Goodbye, cruel world

另外,如果有多个文件,则按下列方式编写Makefile文件(file1.c、file2.c):

obj-m:= modulename.o

module-objs:= file1.o file2.o

linux lsmod命令详解

linux系统下lsmod命令是什么呢?下面是lsmod命令的具体内容:

1、lsmod命令简介:

lsmod全称是listmodules,是一个小程序,用来显示文件、proc/modules的信息,也就是显示当前内核模块装载的模块。

2、语法:

lsmod

3、补充说明:

执行lsmod指令,会列出所有已载入系统的模块。Linux操作系统的核心具有模块化的特性,应此在编译核心时,务须把全部的功能都放入核心。您可以将这些功能编译成一个个单独的模块,待需要时再分别载入。

4、其它常见信息查看方法:

查看CPU信息: cat/proc/cpuinfo

查看板卡信息:cat/proc/pci

查看PCI信息: lspci

比如 lspci|grep Ethernet查看网卡型号

查看内存信息:cat/proc/meminfo

查看USB设备: cat/proc/bus/usb/devices

查看键盘和鼠标:cat/proc/bus/input/devices

查看系统硬盘信息和使用情况:fdisk disk- l df

查看各设备的中断请求(IRQ): cat/proc/interrupts

查看系统体系结构:uname-a

dmidecode查看硬件信息,包括bios、cpu、内存等信息

dmesg| more查看硬件信息

对于“/proc”中文件可使用文件查看命令浏览其内容,文件中包含系统特定信息:

Cpuinfo主机CPU信息

Dma主机DMA通道信息

Filesystems文件系统信息

Interrupts主机中断信息

Ioprots主机I/O端口号信息

Meninfo主机内存信息

Version Linux内存版本信息(编译内核的编译器版本)

举例:

[root@LinServ-1~]# lsmod

Module Size Used by

ipv6 272801 15

xfrm_nalgo 13381 1 ipv6

crypto_api 12609 1 xfrm_nalgo

ip_conntrack_ftp 11569 0

xt_limit 6721 2

xt_state 6209 2

ip_conntrack 53665 2 ip_conntrack_ftp,xt_state

nfnetlink 10713 1 ip_conntrack

第1列:表示模块的名称。

第2列:表示模块的大小。

第3列:表示依赖模块的个数。

第4列:表示依赖模块的内容。

通常在使用lsmod命令时,都会采用类似lsmod|grep-i ext3这样的命令来查询当前系统是否加载了某些模块。

通常会配合grep来查看指定模块是否已经加载,若没有加载,先确认模块是否已经安装,安装完成后可以用modprobe来加载。

阅读剩余
THE END