Ubuntu12.10 内核源码外编译 linux模块--编译驱动模块的基本方法

本文介绍了如何在Ubuntu 12.10上进行Linux内核源码外编译驱动模块,详细阐述了编译驱动模块的基本步骤,包括源码获取、配置、编译和安装等关键环节。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、先编写一个简单的hello模块,hello.c 源码如下:

 1 #ifndef __KERNEL__
 2 #  define __KERNEL__
 3 #endif
 4 #ifndef MODULE
 5 #  define MODULE
 6 #endif
 7 
 8 // 下面的是主要的内容
 9 #include <linux/kernel.h>
10 #include <linux/module.h>
11 #include <linux/init.h>
12 
13 MODULE_LICENSE("GPL");
14 
15 static int year=2012;
16 
17 int hello_init()
18 {
19     printk(KERN_WARNING "Hello kernel, it's %d!\n",year);
20     return 0;
21 }
22 
23 
24 void hello_exit()
25 {
26     printk("Bye, kernel!\n");
27 }
28 
29 // 下面两个为关键的模块函数
30 module_init(hello_init);
31 module_exit(hello_exit);

如果上面的代码看起来不太熟悉,那么需要查看以下相关的书籍,比如《Linux设备驱动程序,第三版》,也就是大名鼎鼎的LDD;

2、老式驱动模块编译方法:

直接写出make规则到makefile文件中,引用内核体系的头文件路径,举例如下:

 1 # The path of kernel source code
 2 INCLUDEDIR = /media/GoldenResources/linux/linux-2.6.30/include
 3 
 4 # Compiler
 5 CC = gcc
 6 
 7 # Options
 8 CFLAGS = -D__KERNEL__ -DMODULE -O -Wall -I$(INCLUDEDIR)
 9 
10 # Target
11 OBJS = hello.o
12 
13 all: $(OBJS)
14 
15 $(OBJS): hello.c
16     $(CC) $(CFLAGS) -c $<
17 
18 install:
19     insmod $(OBJS)
20 
21 uninstall:
22     rmmod hello
23 
24 .PHONY: clean
25 clean:
26     rm -f *.o

这里有我是用的一个linux内核源代码路径:/media/GoldenResources/linux/linux-2.6.30/include ,注意设置到正确的源码路径。

尝试这编译:

$make
gcc -D__KERNEL__ -DMODULE -O -Wall -I/media/GoldenResources/linux/linux-2.6.30/include -c hello.c
In file included from /media/GoldenResources/linux/linux-2.6.30/include/linux/kernel.h:11:0,
                 from hello.c:8:
/media/GoldenResources/linux/linux-2.6.30/include/linux/linkage.h:5:25: fatal error: asm/linkage.h: No such file or directory
compilation terminated.
make: *** [hello.o] Error 1

出现错误: include/linux/linkage.h:5:25: fatal error: asm/linkage.h: No such file or directory , 网上查阅相关资料后,找到不错的说明:

请查看:http://stackoverflow.com/questions/9492559/module-compiling-asm-linkage-h-file-not-found

主要意思是这种编译方法不能很好的解决相关的依赖体系,主要是源于历史原因,linux内核升级很快,越来越复杂,所以建议使用kbuild体系来自动完成;故下面采用了可行的kbuild体系来完成。

3、使用kbuild进行模块编译:

基本方法可以参考: http://www.mjmwired.net/kernel/Documentation/kbuild/modules.txt

核心思想是,通过-C指明系统上的内核体系路径,通过M=指明模块源文件路径,然后自己构造一个makefile文件,从而实现编译过程。

3.1 构建适用于kbuild方法的makefile:

obj-m := hello.o

all :
    $(MAKE) -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules

clean:
    $(MAKE) -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean

开始make:

$make
make -C /lib/modules/3.5.0-17-generic/build M=/media/GoldenResources/arm/ARM高级班/内核第一天/实验代码/HelloWorld/hello modules
make[1]: Entering directory `/usr/src/linux-headers-3.5.0-17-generic'
scripts/Makefile.build:44: /media/GoldenResources/arm/ARM高级班/内核第一天/实验代码/HelloWorld/hello/Makefile: No such file or directory
make[2]: *** No rule to make target `/media/GoldenResources/arm/ARM高级班/内核第一天/实验代码/HelloWorld/hello/Makefile'.  Stop.
make[1]: *** [_module_/media/GoldenResources/arm/ARM高级班/内核第一天/实验代码/HelloWorld/hello] Error 2
make[1]: Leaving directory `/usr/src/linux-headers-3.5.0-17-generic'
make: *** [all] Error 2

自动使用了当前运行中的内核,构建对应的模块,但是提示找不到Makefile,而该目录下的文件为makefile,所以尝试修改名字:

$mv makefile  Makefile

特别注意,要使用Makefile才行!不能时makefile;

修改后,编译成功:

$make
make -C /lib/modules/3.5.0-17-generic/build M=/media/GoldenResources/arm/ARM高级班/内核第一天/实验代码/HelloWorld/hello modules
make[1]: Entering directory `/usr/src/linux-headers-3.5.0-17-generic'
  Building modules, stage 2.
  MODPOST 1 modules  # 说明成功编译了一个模块
make[1]: Leaving directory `/usr/src/linux-headers-3.5.0-17-generic'

3.2 加载和删除内核模块:

$sudo insmod ./hello.ko #加载
$sudo rmmod hello       #删除

并没有看到源代码中的输出信息,查看系统相应日志即可:

$tail /var/log/kern.log   # 注意ubuntu下的日志路径
Oct 23 22:22:22 qunengrong-Studio-1450 kernel: [43021.773888] Hello kernel, it's 2012!
Oct 23 22:22:37 qunengrong-Studio-1450 kernel: [43037.092339] Bye, kernel!

至此,我们已经可以成功编译和加载内核模块了;

4、额外成就,要注意模块与内核版本的匹配:

假设我直接使用另一个内核体系进行构建,比如3.5.0-15-generic,但是当前系统运行的为3.5.0-17-generic的内核,则加载时报错,如下:

$make -C /lib/modules/3.5.0-15-generic/build M=`pwd` modules
make: Entering directory `/usr/src/linux-headers-3.5.0-15-generic'
  CC [M]  /media/GoldenResources/arm/ARM高级班/内核第一天/实验代码/HelloWorld/hello/hello.o
/media/GoldenResources/arm/ARM高级班/内核第一天/实验代码/HelloWorld/hello/hello.c:16:5: warning: function declaration isn’t a prototype
/media/GoldenResources/arm/ARM高级班/内核第一天/实验代码/HelloWorld/hello/hello.c:23:6: warning: function declaration isn’t a prototype
  Building modules, stage 2.
  MODPOST 1 modules
  CC      /media/GoldenResources/arm/ARM高级班/内核第一天/实验代码/HelloWorld/hello/hello.mod.o
  LD [M]  /media/GoldenResources/arm/ARM高级班/内核第一天/实验代码/HelloWorld/hello/hello.ko
make: Leaving directory `/usr/src/linux-headers-3.5.0-15-generic'

$sudo insmod ./hello.ko  # 版本不一致报错
insmod: error inserting './hello.ko': -1 Invalid module format

由此可见,使用自动构建带来的方便,将该通用Makefile分享如下:

obj-m := name.o

all :
    $(MAKE) -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules

clean:
    $(MAKE) -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean

<think>好的,我现在需要帮用户解决在Ubuntu系统下安装Realtek RTL8188CUS无线网卡驱动的问题。首先,我得回忆一下用户提供的引用内容,看看有没有相关的步骤。根据引用[3]和[4],用户提到需要编译安装驱动,并且可能需要屏蔽系统自带的驱动。 首先,用户可能需要先安装必要的编译工具,比如build-essential和linux-headers。这是常见的步骤,因为在编译内核模块时这些工具是必须的。然后,用户需要下载正确的驱动源码。引用[2]和[4]提到了Realtek官方的驱动包,可能需要从官网下载或者特定的版本。 接下来,解压源码包并进入目录,给install.sh执行权限。不过根据引用[4],用户可能在编译过程中遇到os_intfs.c的错误,需要修改该文件或者替换代码。这时候需要指导用户如何修改文件,或者替换成正确的代码版本。此,还需要注意驱动包是否需要重新打包,因为install.sh可能每次都会解压原始tar.gz文件,覆盖之前的修改。 然后,安装过程中可能需要屏蔽自带的rtl8192cu驱动,如引用[3]所述,编辑blacklist.conf文件,添加blacklist rtl8192cu,并修改/etc/modules加入新驱动模块。安装完成后需要重启或者手动卸载旧驱动,加载新驱动。 还要注意,不同Ubuntu版本可能有不同的兼容性问题。比如引用[1]提到Ubuntu 14.04的驱动问题,而引用[3]是在12.10下的解决方法。用户可能使用的是较新的Ubuntu版本,可能需要调整步骤,比如内核版本差异导致编译错误。 最后,确保用户按照步骤操作后,能够正确加载新驱动,并通过ifconfig或iwconfig检查无线网卡状态。如果还有问题,可能需要检查日志或尝试其他版本的驱动。 现在需要将这些步骤整理成清晰的中文回答,分步骤说明,确保用户能逐步操作。同时,根据用户提供的引用,正确标注引用来源。还要生成相关问题,可能涉及驱动安装的常见问题、编译错误的解决、驱动冲突处理等。</think>### 如何在 Ubuntu 上安装 Realtek RTL8188CUS 无线网卡驱动 #### **步骤说明** 1. **安装编译依赖** 打开终端,执行以下命令安装编译工具和内核头文件: ```bash sudo apt-get update sudo apt-get install build-essential linux-headers-$(uname -r) ``` 2. **下载驱动源码** Realtek RTL8188CUS 的官方驱动可从 GitHub 或 Realtek 官网获取。例如使用以下命令下载并解压: ```bash wget https://github.com/lwfinger/rtl8188eu/archive/refs/heads/master.zip unzip master.zip && cd rtl8188eu-master ``` 3. **屏蔽系统自带驱动** 为避免驱动冲突,需屏蔽 Ubuntu 自带的 `rtl8192cu` 驱动。编辑黑名单配置文件: ```bash sudo nano /etc/modprobe.d/blacklist.conf ``` 添加以下内容并保存: ```conf blacklist rtl8192cu ``` 接着修改 `/etc/modules` 文件,添加新驱动模块: ```bash echo "8192cu" | sudo tee -a /etc/modules ``` [^3] 4. **编译并安装驱动** 进入驱动源码目录,赋予安装脚本权限并执行: ```bash sudo chmod +x install.sh sudo ./install.sh ``` 若编译报错(如 `os_intfs.c` 错误),需手动修改源码文件 `driver/rtl8188C_8192C_usb_linux_v4.0.2_9000.20130911/os_dep/linux/os_intfs.c`,或替换为修复后的代码[^4]。 5. **重启系统或重新加载驱动** 重启 Ubuntu 或手动卸载旧驱动并加载新驱动: ```bash sudo rmmod rtl8192cu sudo modprobe 8192cu ``` 6. **验证驱动状态** 使用以下命令检查无线网卡是否被识别: ```bash iwconfig ``` 若出现无线接口(如 `wlan0`),则表示驱动安装成功[^2]。 --- ### **注意事项** - **内核兼容性**:部分驱动版本可能不兼容较新内核,可尝试更换驱动源码分支或调整编译参数[^1]。 - **固件更新**:若仍无法连接网络,需检查无线网卡固件是否需要更新(通过 `dmesg | grep firmware` 排查)。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值