有时我们在编译好内核后发现自己的网卡驱动没有编译进内核,这时我们应该怎么办呢?是重新把内核编译吗?下面方法是我经过试验,单独编译网卡驱动的方法。不好的地方请大家指出来。
首先要确定自己的网卡型号,可以通过以下三步实现:
1、查看自己网卡的型号
下面以Realtek的网卡驱动为例进行说明
[user@elrepo]$ /sbin/lspci | grep -i Ethernet
04:00.0 Ethernet controller: Realtek Semiconductor Co., Ltd. RTL8111/8168B PCI Express Gigabit Ethernet controller (rev 01)
[user@elrepo]$ /sbin/lspci -n | grep '04:00.0'
04:00.0 0200: 10ec:8168 (rev 01)
Searching for the vendor:device ID pairing of 10ec:8168 shows that kmod-r8168 should work with this Ethernet controller.
3、对应的硬件驱动下载点:http://elrepo.org/linux/elrepo/el5/i386/RPMS/(此处为RPM包的网卡模块,可能需要为内核打补丁,比较麻烦,我试过了,就不介绍了)。
我的机器是联想B450的笔记本,在经过以上三步后,确定了我的网卡模块为atl1e.ko
下面开始介绍如何从内核源码中分离出代码单独进行编译:
1、首先从内核官网:http://www.kernel.org/中下载比较新的2.6内核的源代码,我下载的是stable(稳定版)的linux-2.6.32.59.tar.bz2
2、将下载的源码解压至我的根目录的work文件夹中,找到对应的网卡驱动目录路径为:/work/linux-2.6.32.59/drivers/net/atl1e,将该目录下的所有文件复制到另一个目录中。
[root@localhost atl1e]#cp ./* /home/atl1e (此处复制到我的home目录atl1e文件夹中)
[root@localhost atl1e]#cd /home/atl1e
[root@localhost atl1e]# ls
atl1e_ethtool.c atl1e_hw.c atl1e_main.c Makefile
atl1e.h atl1e_hw.h atl1e_param.c
将其中的Makefile中的内容改为如下:
ifeq ($(KERNELRELEASE),)
KERNELDIR ?=/work/linux-2.6.32.59
PWD := $(shell pwd)
modules:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
modules_install:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules_install
clean:
rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions *.order Module*
.PHONY: modules modules_install clean
else
obj-m := atl1e.o
atl1e-objs := atl1e_main.o atl1e_hw.o atl1e_ethtool.o atl1e_para
m.o (此处解释一下,如果一个目录文件依赖多个文件生成那么就得写成obj-m :=target.o
target-objs := file1.o file2.o …)
endif
接着执行make
[root@localhost atl1e]# make
此时出现如下情况:
make -C /work/linux-2.6.32.59 M=/home/atl1e modules
make[1]: Entering directory `/work/linux-2.6.32.59'
ERROR: Kernel configuration is invalid.
include/linux/autoconf.h or include/config/auto.conf are missing.
Run 'make oldconfig && make prepare' on kernel src to fix it.
WARNING: Symbol version dump /work/linux-2.6.32.59/Module.symvers
is missing; modules will have no dependencies and modversions.
scripts/Makefile.build:44: /home/atl1e/Makefile: 没有那个文件或目录
make[2]: *** 没有规则可以创建目标“/home/atl1e/Makefile”。 停止。
make[1]: *** [_module_/home/atl1e] 错误 2
make[1]: Leaving directory `/work/linux-2.6.32.59'
make: *** [modules] 错误 2
按提示进入到/work/linux-2.6.32.59目录中依次执行make oldconfig ; make prepare命令。
没有报错,再回到刚刚编译的目录中,激动的再次执行make。此时出现如下错误:
make -C /work/linux-2.6.32.59 M=/home/atl1e modules
make[1]: Entering directory `/work/linux-2.6.32.59'
WARNING: Symbol version dump /work/linux-2.6.32.59/Module.symvers
is missing; modules will have no dependencies and modversions.
CC [M] /home/atl1e/atl1e_main.o
CC [M] /home/atl1e/atl1e_hw.o
CC [M] /home/atl1e/atl1e_ethtool.o
CC [M] /home/atl1e/atl1e_param.o
LD [M] /home/atl1e/atl1e.o
Building modules, stage 2.
MODPOST 1 modules
/bin/sh: scripts/mod/modpost: 没有那个文件或目录
make[2]: *** [__modpost] 错误 127
make[1]: *** [modules] 错误 2
make[1]: Leaving directory `/work/linux-2.6.32.59'
make: *** [modules] 错误 2
这是因为在内核源码中没有执行make scripts操作。好吧,再次回到/work/linux-2.6.32.59目录中,执行:make scripts
[root@localhost linux-2.6.32.59]# make scripts
HOSTCC scripts/genksyms/genksyms.o
SHIPPED scripts/genksyms/lex.c
SHIPPED scripts/genksyms/parse.h
SHIPPED scripts/genksyms/keywords.c
HOSTCC scripts/genksyms/lex.o
SHIPPED scripts/genksyms/parse.c
HOSTCC scripts/genksyms/parse.o
HOSTLD scripts/genksyms/genksyms
CC scripts/mod/empty.o
HOSTCC scripts/mod/mk_elfconfig
MKELF scripts/mod/elfconfig.h
HOSTCC scripts/mod/file2alias.o
HOSTCC scripts/mod/modpost.o
HOSTCC scripts/mod/sumversion.o
HOSTLD scripts/mod/modpost
HOSTCC scripts/selinux/mdp/mdp
HOSTCC scripts/kallsyms
HOSTCC scripts/pnmtologo
HOSTCC scripts/conmakehash
此时再回到编译目录执行make后终于生成了atl1e.ko
[root@localhost atl1e]# make
make -C /work/linux-2.6.32.59 M=/home/atl1e modules
make[1]: Entering directory `/work/linux-2.6.32.59'
WARNING: Symbol version dump /work/linux-2.6.32.59/Module.symvers
is missing; modules will have no dependencies and modversions.
CC [M] /home/atl1e/atl1e_main.o
CC [M] /home/atl1e/atl1e_hw.o
CC [M] /home/atl1e/atl1e_ethtool.o
CC [M] /home/atl1e/atl1e_param.o
LD [M] /home/atl1e/atl1e.o
Building modules, stage 2.
MODPOST 1 modules
CC /home/atl1e/atl1e.mod.o
LD [M] /home/atl1e/atl1e.ko
make[1]: Leaving directory `/work/linux-2.6.32.59'
[root@localhost atl1e]# ls
atl1e_ethtool.c atl1e.h atl1e_hw.h atl1e.ko atl1e_main.o atl1e.mod.o atl1e_param.c Makefile Module.symvers
atl1e_ethtool.o atl1e_hw.c atl1e_hw.o atl1e_main.c atl1e.mod.c atl1e.o atl1e_param.o modules.order
3、加载驱动到内核
好了,驱动模块到此已经编译生成了,这比编译一个内核源码要省时间的多吧。下面就将驱动模块加载进内核。
4.模块测试
内核模块编译完成后,就要测试能否正常运行,因为我们已经运行depmod -a,所以直接以modprobe进行模块的加载.
1.加载模块测试
modprobe atl1e.o
注意,不要写完整的名称,.o不需要写.rhinefet就是刚刚编译出来的rhinefet.o.
lsmod
2.设置开机加载摸块
就是编辑/etc/modules.conf
vi /etc/modules.conf
在文件中加入下面一行:
alias eth0 atl1e
3.重新启动,看是否正常启动模块
#reboot
上面我们使用的是rhinefet模块,如果不是这个名称,就请依你的实际情况来修改.接下来就是测试这个网卡是否正常工作.
后记:编译内核步骤:
1、拷贝配置文件
#cp arch/x86/configs/x86_64_defconfig /home/linux-2.6.32.59/.config
#make menuconfig
#make
#make modules_install
#make install