it-roy-ru.com

ошибка insmod: вставка './hello.ko': -1 Неверный формат модуля "

Я только что сделал мой первый модуль драйвера, модуль hello world, следующий за LDD3. Однако, к сожалению, столкнулся с этой ошибкой:

insmod: error inserting './hello.ko': -1 Invalid module format.

Я делаю это на Ubuntu 11.04 и моей среде:

$ uname -r
2.6.38-8-generic

Я получаю исходный код ядра следующим образом:

Sudo apt-cache search linux-source
linux-source - Linux kernel source with Ubuntu patches
linux-source-2.6.38 - Linux kernel source for version 2.6.38 with Ubuntu patches
$Sudo apt-get install linux-source-2.6.38

мой/usr/src:

$ls /usr/src/
linux-headers-2.6.38-8          linux-source-2.6.38          vboxguest-5.0.10
linux-headers-2.6.38-8-generic  linux-source-2.6.38.tar.bz2

а потом я собираю ядро

$Sudo cp /boot/config-2.6.38-8-generic ./.config
$Sudo make menuconfig -- load the .config file
$make
$make modules

а затем я собираю свой модуль ядра

$make -C /usr/src/linux-source-2.6.38/linux-source-2.6.38 M=`pwd` modules

с Makefile:

obj-m := hello.o

и, наконец, когда я вставляю модуль:

$Sudo insmod hello_world.ko
insmod: error inserting 'hello_world.ko': -1 Invalid module format

что я нашел в dmesg:

hello: disagrees about version of symbol module_layout

Так в чем проблема?

Я также заметил, что linux-header is -2.26.38-generic и версия исходного кода -2.26.38, это проблема? но я действительно не нашел пакет linux-source-2.26.38-generic в сети.

обновление статуса: Я обнаружил, что файл/lib/moduels/$ (name -r)/build/Makefile указывает мою работающую версию ядра:

VERSION = 2
PATCHLEVEL = 6
SUBLEVEL = 38
EXTRAVERSION = .2

Поэтому я скачиваю linux-2.6.38.2 и компилирую, но все равно та же ошибка.

Я также обнаружил, что в/boot/config есть строка - $ (uname -r):

CONFIG_VERSION_SIGNATURE="Ubuntu 2.6.38-8.42-generic 2.6.38.2"

Кто-нибудь знает, что это значит? Я не вижу его в файле конфигурации ядра, которое я собираю.

7
roMoon

Ядро, из которого вы собираете модуль ядра и в который вы вставляете модуль, должно быть той же версии. Если вы не хотите позаботиться об этом, вы можете использовать следующий Makefile.

obj−m += hello−world.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

Теперь вы можете собрать и попробовать вставить модуль.

Я предлагаю вам стать root, если это возможно, до этой строки 

$ Sudo cp /boot/config-2.6.38-8-generic ./.config

$su
#cp /boot/config-2.6.38-8-generic ./.config
#insmod hello_world.ko

В качестве альтернативы вы также можете использовать следующий файл make

TARGET  := hello-world
WARN    := -W -Wall -Wstrict-prototypes -Wmissing-prototypes
INCLUDE := -isystem /lib/modules/`uname -r`/build/include
CFLAGS  := -O2 -DMODULE -D__KERNEL__ ${WARN} ${INCLUDE}
CC      := gcc-3.0

${TARGET}.o: ${TARGET}.c

.PHONY: clean

clean:
    rm -rf ${TARGET}.o
5
Punit Vara

Попробуйте использовать кросс-компиляцию. Пожалуйста, посмотрите на код ниже для файла make. Помните об отступах, иначе вы можете получить ошибку, такую ​​как отсутствующий разделитель. Стоп

obj-m += hello_.o #это имя должно быть именем вашего .c файла. Я просто использую привет например

Я предлагаю лучший подход через кросс-компиляцию

Создайте переменную для хранения имени каталога, в котором находится каталог ядра Linux. В моем примере измените значение «PATH_TO_LINUX_KERNEL_DIRECTORY» на значение реального пути Пример ~/linux Вам действительно нужно сделать это, чтобы файл make знал, где найти arm-linux-gnueabi- Без этого вы, скорее всего, столкнетесь с проблемами arm-linux-gnueabi-

KDIR := PATH_TO_LINUX_KERNEL_DIRECTORY

all:
    make Arch=arm CROSS_COMPILE=arm-linux-gnueabi- -C $(KDIR) M=$(Shell pwd) modules

clean:
    make -C $(KDIR) M=$(Shell pwd) clean
0
rocksyne