Сборка модулей ядра из дерева, depmod - и зачем перезагружаться? - PullRequest
2 голосов
/ 26 октября 2010

Я работал с пользовательской программой writeread.c (именуемой здесь ), используя драйвер ftdi_sio Linux.

Я работал со стандартным ftdi_sio, который поставляется с Ubuntu Lucid, который я использую, а затем, в качестве проверки работоспособности, решил пересобрать ftdi_sio из исходного кода. Я не хотел загружать весь исходный код ядра, поэтому я выбрал так называемое «построение модулей вне дерева»:

... что означает, что вы можете установить только пакеты linux-headers-* (вместо того, чтобы установить весь linux-source-*) - и соответствующий источник модуля ядра - для сборки модуля ядра.

Итак, я в основном получил следующие файлы в папке:

и run make - и ftdi_sio.ko объекты ядра компилируются, что также может быть insmod -ed без проблем.

Проблема теперь здесь - пока я работаю на низких скоростях (115200 бит / с), нет видимой разницы между: загрузкой драйвера 'vanilla' ( с использованием sudo modprobe ftdi_sio); и загрузка нового встроенного драйвера ( с использованием sudo modprobe usbserial; sudo insmod /path/to/ftdi_sio.ko) - в отношении производительности программы пользователя (writeread.c).

Однако, если я попытаюсь сделать то же самое на скорости 2000000 бит / с, то драйвер 'vanilla' будет работать нормально - тогда как драйвер сборки вызовет segfault программы userland (writeread.c). В частности, этот segfault произошел при free() -ing ресурсах памяти - потому что драйвер в конечном итоге будет читать больше байтов из петлевого соединения, чем он сам записал бы! Тем не менее, это само по себе не так важно для этого обсуждения, потому что я наконец-то нашел способ заставить работать встроенную ftdi_sio ( Edit: только что заметил, что аналогичная процедура также приведена в External Linux kernel Зависимости модуля R # 2238581 - Переполнение стека ):

$ 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 и перезагружаться после каждой время сборки драйвера - что, я думаю, было бы утомительно :) Итак, было бы неплохо иметь возможность перестроить модуль ядра и использовать его в одном сеансе - без перезагрузки.

Ну, заранее спасибо за любые ответы,

Ура !!

Makefile:

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

1 Ответ

4 голосов
/ 27 октября 2010

Короче говоря, нет, я не вижу ничего плохого в последовательности, которую вы делаете, или почему это может вызвать такое поведение.

Тот факт, что ядро ​​позволяет вставлять только что построенный модуль, в основном означает, что вы собрали его правильно, и он также вставлен правильно, поэтому нет никаких несовпадений версий или чего-либо еще.

Я предполагаю, что когда вы запускаете тест на скорости 2000000 бит / с, вы сначала тестировали драйвер vanilla, а затем новый драйвер? Таким образом, я предполагаю, что драйвер не очищает что-то правильно, поэтому при повторном запуске теста (с новым драйвером) вы видите ошибку сегмента. Но, как я уже сказал, это предположение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...