【问题标题】:Building out-of-tree kernel modules, depmod - and, why reboot?构建树外内核模块,depmod - 为什么要重新启动?
【发布时间】:2011-04-30 19:59:00
【问题描述】:

我一直在使用writeread.c(称为here)的用户级程序,使用ftdi_sio Linux 驱动程序。

我曾使用我使用的 Ubuntu Lucid 附带的默认 ftdi_sio - 然后,作为健全性检查,我决定从源代码重建 ftdi_sio。我不想下载整个内核源代码,所以我选择了所谓的“构建树外模块”:

... 这意味着您只能安装 linux-headers-* 软件包(而不是安装整个 linux-source-*) - 以及相应的内核模块源 - 才能构建内核模块。

所以,我基本上在一个文件夹中得到了以下文件:

然后运行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


    【解决方案1】:

    简而言之,不,我看不出您正在执行的序列有什么问题,或者为什么会导致这种行为。

    内核允许插入新构建的模块基本上意味着你已经正确构建它并且它也正确插入,所以没有版本不匹配或任何东西。

    我猜当您以 2000000 bps 运行测试时,您首先测试了 vanilla 驱动程序,然后是新驱动程序?所以我的猜测是驱动程序没有正确清理某些东西,所以当你再次运行测试(使用新驱动程序)时,你会看到一个段错误。但就像我说的,这是一个猜测。

    【讨论】:

    • 感谢@mpe 的回复!首先,感谢您评估步骤顺序。回复:“您首先测试了原版驱动程序,然后测试了新驱动程序?” - 是的,我做了。另外,我以前没有想过,但我认为“驱动程序没有正确清理某些东西”很有意义 - 我会尝试仔细研究一下,并且如果我发现任何有趣的事情,请报告。再次感谢 - 干杯!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多