【发布时间】:2011-04-30 19:59:00
【问题描述】:
我一直在使用writeread.c(称为here)的用户级程序,使用ftdi_sio Linux 驱动程序。
我曾使用我使用的 Ubuntu Lucid 附带的默认 ftdi_sio - 然后,作为健全性检查,我决定从源代码重建 ftdi_sio。我不想下载整个内核源代码,所以我选择了所谓的“构建树外模块”:
- Howto: Build Linux Kernel Module Against Installed Kernel w/o Full Kernel Source Tree
- Debian Linux Kernel Handbook - Common kernel-related tasks: Building out-of-tree kernel modules
- Building a custom kernel - FedoraProject: Building Only Kernel Modules (Out Of Tree Modules)
... 这意味着您只能安装 linux-headers-* 软件包(而不是安装整个 linux-source-*) - 以及相应的内核模块源 - 才能构建内核模块。
所以,我基本上在一个文件夹中得到了以下文件:
- ftdi_sio.c
- ftdi_sio.h
- ftdi_sio_ids.h
- Makefile(包含在下面)
然后运行make - 和ftdi_sio.ko 内核对象编译,也可以insmod-ed 没有问题。
现在问题出在这里 - 只要我以低速 (115200 bps) 工作,没有明显区别:加载“vanilla”驱动程序(使用 sudo modprobe ftdi_sio );并加载新构建的驱动程序(使用sudo modprobe usbserial; sudo insmod /path/to/ftdi_sio.ko)——关于用户态程序的性能(writeread.c)。
但是,如果我以 2000000 bps 的速度尝试相同的操作,那么“vanilla”驱动程序可以正常工作 - 而构建驱动程序会导致用户空间程序 (writeread.c) 出现 segfault。特别是,这个段错误发生在free()-ing 内存资源上 - 因为驱动程序最终会从环回连接中读取 更多 个字节,而不是它自己会写入!然而,这本身与本次讨论无关,因为我终于找到了一种让构建的ftdi_sio 工作的方法(编辑:刚刚注意到External Linux kernel module dependencies R#2238581 - Stack Overflow 中也给出了类似的过程):
$ sudo modprobe -r ftdi_sio # remove 'vanilla' driver from memory
...
# build the driver
$ cd /path/to/ftdi_sio_2.6.32/
$ make clean && make
# check vanilla version
$ ls -la /lib/modules/2.6.32-25-generic/kernel/drivers/usb/serial/ftdi_sio.ko
-rw-r--r-- 1 root root 102396 2010-10-17 01:47 /lib/modules/2.6.32-25-generic/kernel/drivers/usb/serial/ftdi_sio.ko
# (re)move the 'vanilla' kernel object
$ sudo mv /lib/modules/2.6.32-25-generic/kernel/drivers/usb/serial/ftdi_sio.ko ~/Desktop/ftdi_sio_orig.ko
# symlink our built version, as if it is the 'vanilla' one
$ sudo ln -s /path/to/ftdi_sio_2.6.32/ftdi_sio.ko /lib/modules/2.6.32-25-generic/kernel/drivers/usb/serial/
# check
$ ls -la /lib/modules/2.6.32-25-generic/kernel/drivers/usb/serial/ftdi_sio.ko
lrwxrwxrwx 1 root root 57 2010-10-26 12:49 /lib/modules/2.6.32-25-generic/kernel/drivers/usb/serial/ftdi_sio.ko -> /path/to/ftdi_sio_2.6.32/ftdi_sio.ko
# call depmod
$ sudo depmod
# !! plug in USB at this point, built driver autoloads;
# however, running `writeread.c` will segfault!
# !! REBOOT at this point
# after reboot:
# !! plug in USB at this point, built driver autoloads;
# and `writeread.c` runs without segfault
所以,我的问题是:谁能向我解释一下,为什么 - 即使在运行 depmod 之后 - 我仍然必须重新启动,才能拥有内置的驱动程序正确的行为?换句话说:我可以调用任何其他命令(可能在depmod 之后),以便驱动程序在加载时正常工作, 无需重新启动?
我问的原因是,我怀疑每次重新编译内核模块时,符号表都会改变 - 所以为了确保它正常工作,我必须运行 depmod 并在每次重新编译后重新启动构建驱动程序的时间 - 我认为这有点乏味:) 所以,能够重建内核模块并在同一个会话中使用它会很好 - 无需重新启动。
好的,提前感谢您的任何回答,
干杯!!
生成文件:
CONFIG_MODULE_FORCE_UNLOAD=y
# flags passed to gcc for compilation - -v:verbose, -H:show include files
# KBUILD_CFLAGS += -v
# for debugging make itself, use --debug=i in make command for targets
# debug build:
EXTRA_CFLAGS=-g -O0
KVERSION = $(shell uname -r)
obj-m += ftdi_sio.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
【问题讨论】:
标签: linux-kernel