编译linux 驱动(linux共享内存)
大家好,今天小编来为大家解答编译linux 驱动这个问题,linux共享内存很多人还不知道,现在让我们一起来看看吧!
如何编译一个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下安装编译网卡驱动的方法
安装linux操作系统后发现没有网卡驱动,表现为
system→ Administration→ Network下Hardware列表为空。
以下为安装编译网卡驱动的过程,本人是菜鸟,以下是我从网上找的资料进行整理,并实际操作的过程,仅供借鉴。
一.检测linux系统内核版本和网卡类型,相关命令如下:
uname-r查看linux内核版本(uname-a可显示所有信息)
lsmod设备加载情况
ls/usr/share/hwdata查看硬件设备
lspci查看pci网卡设备 ethernet controller厂商和型号,modprobe********为网卡型号,例如 modprobe RTL8101E,如果出错,说明模块不存在,该型号不识别
我在这一步时查找不到网卡型号,无奈只能由同时采购的其他相同型号预装win7的电脑下查看网卡型号,是个笨办法,嘿嘿……
找到网卡型号后就到驱动之家下载了相应网卡的linux驱动,这些需要根据自己的实际情况下载,不多说了,重点是后面。
二.下载网卡驱动
Intel_e1000e-1.9.5.zip为我下载的所需的网卡驱动,这个在linux下需自己编译.
三.安装网卡驱动
1.检测编译需要用到内核的源代码包和编译程序gcc。所以如果没有的话,要先装。
[root@localhost~]# rpm-qa|grep kernel
kernel-xen-2.6.18-8.el5
kernel-xen-devel-2.6.18-8.el5
kernel-headers-2.6.18-8.el5
[root@localhost~]# rpm-qa|grep gcc
gcc-c++-4.1.1-52.el5
libgcc-4.1.1-52.el5
gcc-4.1.1-52.el5
gcc-gfortran-4.1.1-52.el5
如果缺少kernel-xen-devel-2.6.18-8.el5,可以去安装光盘的/Server/目录下,找到kernel-xen-devel-2.6.18-8.el5.i686.rpm文件安装。
我很幸运,安装的系统中已经安装好了,呵呵。
2.编译安装网卡驱动
将下载的网卡驱动放到/home目录下,解压Intel_e1000e-1.9.5.zip包
unzip Intel_e1000e-1.9.5.zip
进入解压后的目录并编译安装,命令如下:
# cd e1000e-1.9.5/src
# make install
一般情况下解压的目录中会有一个readme文件,里面详细写明了网卡安装的步骤,强烈建议先看readme,安装readme中步骤操作一般不会出现问题。
安装好的文件一般位于如下目录中(kernel version以我的为例)
/lib/modules/2.6.18-194.el5xen/kernel/drivers/net/e1000e/e1000e.ko
insmod e1000e.ko
安装完毕,成功后系统提示网络已连接,说明网卡驱动已经装好,也可以通过检查system→ Administration→ Network下Hardware列表。
备注(以下为网上资料,未实际验证):
如果操作系统启用了支持XEN的内核,“硬件”选项卡里会出现两个网卡,eth0和peth0。
eth0就是映射到peth0的;系统还会自动生成一个xenbr0的网卡;这个网卡是为guestOS做桥接的;vif0.0是指Domain0的第一块网;vif0.1指Domain0的第二块网卡;
如果不准备使用XEN虚拟机;可以在启动时选择没有xen的内核,就不会生成这些额外的网卡了:
步骤一:关闭xend进程,使之不随系统自启动。
1.使用ntsysv命令进入服务管理,关闭xend服务(空格键是选中或者取消)
2.使用chkconfig命令:
[root@localhost~]# chkconfig--level 1 xend off
[root@localhost~]# chkconfig--level 2 xend off
[root@localhost~]# chkconfig--level 3 xend off
[root@localhost~]# chkconfig--level 4 xend off
[root@localhost~]# chkconfig--level 5 xend off
[root@localhost~]# chkconfig--level 6 xend off
检查xend是否都是关闭状态:
[root@localhost~]# chkconfig--list|grep xend
xend 0:关闭 1:关闭 2:关闭 3:关闭 4:关闭 5:关闭 6:关闭
xendomains 0:关闭 1:关闭 2:关闭 3:启用 4:启用 5:启用 6:关闭
修改完毕重启系统。
步骤二:进入系统->管理->网络,已经能看到网卡,可以配置IP和DNS。
然后修改绑定MAC地址:
1.网卡相关的TCP/IP网络配置文件是:/etc/sysconfig/network-scripts/ifcfg-ethx。其中x从0开始,第一个以太网配置文件即:/etc/sysconfig/network-scripts/ifcfg-eth0。使用vi编辑器修改这个文件,也可以修改网卡MAC地址。
把 HWADDR=ff:ff:ff:ff:ff
改为 MACADDR=00:1F:D0:64:9B:B7 MACADDR后面是自己的mac地址
2./etc/sysconfig/networking/profiles/default/ ifcfg-eth0
把 HWADDR=ff:ff:ff:ff:ff
改为 MACADDR=00:1F:D0:64:9B:B7 MACADDR后面是自己的mac地址
重启生效。
怎么将驱动源代码编译进linux系统
一、驱动程序编译进内核的步骤
在 linux内核中增加程序需要完成以下三项工作:
1.将编写的源代码复制到 Linux内核源代码的相应目录;
2.在目录的 Kconfig文件中增加新源代码对应项目的编译配置选项;
3.在目录的 Makefile文件中增加对新源代码的编译条目。
bq27501驱动编译到内核中具体步骤如下:
1.先将驱动代码bq27501文件夹复制到 ti-davinci/drivers/目录下。
确定bq27501驱动模块应在内核源代码树中处于何处。
设备驱动程序存放在内核源码树根目录 drivers/的子目录下,在其内部,设备驱动文件进一步按照类别,类型等有序地组织起来。
a.字符设备存在于 drivers/char/目录下
b.块设备存放在 drivers/block/目录下
c. USB设备则存放在 drivers/usb/目录下。
注意:
(1)此处的文件组织规则并非绝对不变,例如: USB设备也属于字符设备,也可以存放在 drivers/usb/目录下。
(2)在 drivers/char/目录下,在该目录下同时存在大量的 C源代码文件和许多其他目录。所有对于仅仅只有一两个源文件的设备驱动程序,可以直接存放在该目录下,但如果驱动程序包含许多源文件和其他辅助文件,那么可以创建一个新子目录。
(3) bq27501的驱动是属于字符设备驱动类别,虽然驱动相关的文件只有两个,但是为了方面查看,将相关文件放在了bq27501的文件夹中。在drivers/char/目录下增加新的设备过程比较简单,但是在drivers/下直接添加新的设备稍微复杂点。所以下面首先给出在drivers/下添加bq27501驱动的过程,然后再简单说明在drivers/char/目录下添加的过程。
2.在/bq27501下面新建一个Makefile文件。向里面添加代码:
obj-$(CONFIG_BQ27501)+=bq27501.o
此时,构建系统运行就将会进入 bq27501/目录下,并且将bq27501.c编译为 bq27501.o
3.在/bq27501下面新建Kconfig文件。添加代码:
menu"bq27501 driver"
config BQ27501
tristate"BQ27501"
default y
---help---
Say'Y' here, it will be compiled into thekernel; If you choose'M', it will be compiled into a module named asbq27501.ko.
endmenu
注意:help中的文字不能加回车符,否则make menuconfig编译的时候会报错。
4.修改/drivers目录下的Kconfig文件,在endmenu之前添加一条语句‘source drivers/bq27501/Kconfig’对于驱动程序,Kconfig通常和源代码处于同一目录。若建立了一个新的目录,而且也希望 Kconfig文件存在于该目录中的话,那么就必须在一个已存在的 Kconfig文件中将它引入,需要用上面的语句将其挂接在 drivers目录中的Kconfig中。
5.修改/drivers目下Makefile文件,添加‘obj-$(CONFIG_BQ27501)+=bq27501/’。这行编译指令告诉模块构建系统在编译模块时需要进入 bq27501/子目录中。此时的驱动程序的编译取决于一个特殊配置 CONFIG_BQ27501配置选项。
6.修改arch/arm目录下的Kconfig文件,在menu"Device Drivers……endmenu"直接添加语句
source"drivers/bq27501/Kconfig"