Howto: Build Linux Kernel Module Against Installed Kernel w/o Full Kernel Source Tree

本文介绍如何仅使用Linux内核头文件来编译特定硬件驱动,如无线网卡或SCSI设备等,而无需编译整个Linux内核。文中详细说明了安装内核头文件的方法,并提供了创建和编译内核模块的具体步骤。

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


依赖内核头文件编译内核模块

Linux Kernel headers

This is essential because if you just want to compile and install driver for new hardware such as Wireless card or SCSI device etc. With following method, you will save the time, as you are not going to compile entire Linux kernel.

Please note that to work with this hack you just need the Linux kernel headers and not the full kernel source tree. Install the linux-kernel-headers package which provides headers from the Linux kernel. These headers are used by the installed headers for GNU glibc and other system libraries as well as compiling modules. Use following command to install kernel headers:
# apt-get install kernel-headers-2.6.xx.xx.xx

Replace xx.xx with your actual running kernel version (e.g. 2.6.8.-2) and architecture name (e.g. 686/em64t/amd64). Use uname -r command to get actual kernel version name. Please note that above command will only install kernel headers and not the entire kernel source-code tree.

A more generic (recommend) and accurate way is as follows:
# apt-get install kernel-headers-$(uname -r)

All you need to do is change Makefile to use current kernel build directory. You can obtain this directory name by typing following command:
$ ls -d /lib/modules/$(uname -r)/build
Sample output:

/lib/modules/2.6.27-7-generic/build

Let, say you have .c source code file called hello.c. Now create a Makefile as follows in the directory containing hello.c program / file:
$ vi Makefile
Append following text:

obj-m := hello.oKDIR := /lib/modules/$(shell uname -r)/buildPWD := $(shell pwd)default: $(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules

Save and close the file. Type the following command to build the hello.ko module:
$ make

To load Linux kernel module type the command:
# modprobe hello

A complete example

Create test directory (you can download following Makefile and .c file here):
$ mkdir ~/test
$ cd ~/test

Create hello.c kernel module file:

#include<linux/module.h>#include<linux/kernel.h> int init_module(void){ printk(KERN_INFO "init_module() called\n"); return 0;} void cleanup_module(void){ printk(KERN_INFO "cleanup_module() called\n");} 

Create a 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) clea

To build kernel module enter:
$ make
Sample output:

make -C /lib/modules/2.6.27-7-generic/build M=/tmp/test2 modulesmake[1]: Entering directory `/usr/src/linux-headers-2.6.27-7-generic' CC [M] /tmp/test2/hello.o Building modules, stage 2. MODPOST 1 modules CC /tmp/test2/hello.mod.o LD [M] /tmp/test2/hello.komake[1]: Leaving directory `/usr/src/linux-headers-2.6.27-7-generic'

Run ls command to see newly build kernel module:
$ ls
Sample output:

hello.c hello.ko hello.mod.c hello.mod.o hello.o Makefile Module.markers modules.order Module.symvers

hello.ko is kernel module file. To see information about module, enter:
$ modinfo hello.ko
Sample output:

filename: hello.kosrcversion: 4F856ABA1F3290D5F81D961depends:vermagic: 2.6.27-7-generic SMP mod_unload modversions 586

To load kernel module, enter:
$ sudo insmod hello.ko
OR
$ sudo modprobe hello
To list installed Linux kernel module, enter:
$ lsmod
$ lsmod | grep hello

To remove hello Linux kernel module, enter:
$ rmmod hello
This module just logs message to a log file called /var/log/messages (/var/log/syslog), enter:
$ tail -f /var/log/messages
Sample output:

Nov 5 00:36:36 vivek-desktop kernel: [52488.923000] init_module() calledNov 5 00:36:50 vivek-desktop kernel: [52503.065252] cleanup_module() called
<think>我们正在处理用户的问题:"Kernel module installed but no devices recognized error"。根据引用[1],这个错误通常发生在内核模块安装成功但系统无法识别设备时。我们需要逐步诊断问题。 首先,用户已经执行了sudo ./load_drive.sh,并得到了错误信息。引用[1]建议首先使用`lspci`命令来检查系统是否能检测到设备。 步骤: 1. 运行`lspci`命令,查看设备是否在PCI列表中。 2. 如果设备未出现在`lspci`输出中,可能是硬件连接问题或设备未上电。 3. 如果设备出现在`lspci`输出中,那么可能是驱动没有正确绑定到设备,或者驱动加载时参数不正确。 此外,引用[2]提到了使用Svmap工具枚举SIP设备,但这里的问题可能不是SIP设备,所以这个引用可能不直接相关。不过,我们可以借鉴枚举设备的思想,使用其他工具来检查设备。 其他可能的原因和检查方法: - 检查内核模块是否真的加载:使用`lsmod | grep 模块名`。 - 检查内核日志:使用`dmesg | tail`查看最近的内核消息,可能会有关于设备初始化的错误信息。 - 确认设备ID是否在驱动程序中支持:检查驱动源代码中是否包含该设备的设备ID。 因此,我们给用户的建议步骤: 1. 运行`lspci`,查看设备是否列出。 2. 如果设备列出,记录设备的ID(例如:厂商ID和设备ID)。 3. 使用`lsmod`检查模块是否加载。 4. 使用`dmesg`检查内核日志。 5. 如果设备未列出,检查硬件连接和电源。 如果以上步骤还不能解决问题,可能需要检查驱动代码是否支持该设备,或者重新编译驱动。 注意:用户可能不是PCI设备,可能是USB或其他总线。如果是USB设备,则应该使用`lsusb`。 因此,我们首先需要确定设备类型。用户的问题中没有明确,所以我们可以建议用户先通过`lspci`和`lsusb`来检查设备是否被系统识别。 总结步骤: 步骤1:确定设备类型(PCI/USB等)并使用相应的命令检查。 步骤2:如果系统总线枚举出了设备,则检查驱动是否绑定和设备ID是否匹配。 步骤3:检查内核日志。 如果用户提供了更多信息(如设备类型),我们可以更具体。 由于用户没有提供设备类型,我们给出通用步骤。 此外,引用[1]中提到的错误信息明确指向设备未被识别,所以重点在硬件枚举和驱动绑定。 生成相关问题: 1. 如何检查PCI设备是否被系统识别? 2. 如何查看内核模块加载后的调试信息? 3. 驱动程序中如何添加对新设备的支持?</think>### 内核模块安装后设备未被识别的问题分析 当出现"Kernel module installed correctly, but no devices were recognized"错误时,表示内核模块已成功加载,但系统未能检测到相关硬件设备。以下是逐步排查方案: #### 1. **检查硬件检测状态** ```bash lspci -v # 检查PCI设备列表 lsusb # 检查USB设备列表 ``` - 如果设备未出现在输出中,可能是物理连接问题或设备未上电[^1] - 示例输出中查找设备ID(如 `abcd:1234` 格式的厂商ID:设备ID) #### 2. **验证内核模块加载** ```bash lsmod | grep your_module_name # 检查模块是否加载 dmesg | tail -n 30 # 查看内核日志中的错误信息 ``` - 确认模块加载时无错误提示 - 检查日志中是否有"device not supported"或"failed to probe device"等错误[^1] #### 3. **检查设备ID绑定** ```bash modinfo your_module_name | grep alias # 查看驱动支持的设备ID ``` - 比较输出中的设备ID与`lspci`显示的ID是否匹配 - 若不匹配需修改驱动代码添加设备ID支持 #### 4. **检查用户权限** ```bash groups # 查看当前用户组 ``` - 确保用户拥有访问设备的权限(通常在`dialout`或`plugdev`组) - 临时测试:`sudo chmod 666 /dev/device_node` #### 5. **排查内核兼容性** ```bash uname -a # 查看内核版本 ``` - 确认驱动是否针对当前内核版本编译 - 尝试重新编译:`make clean && make` #### 6. **检查设备树配置(嵌入式系统)** ```bash dtc -I fs /proc/device-tree | grep your_device ``` - ARM架构设备需确认设备树(Device Tree)已正确配置设备节点 > **典型解决方案**:若设备ID未绑定,在驱动源码中添加: > ```c > static const struct pci_device_id my_ids[] = { > { PCI_DEVICE(VENDOR_ID, DEVICE_ID) }, // 添加新行 > { 0, } > }; > MODULE_DEVICE_TABLE(pci, my_ids); > ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值