как я linux драйвер писал...
От: IID Россия  
Дата: 19.09.16 01:19
Оценка: 7 (4) +3 :))) :))) :))) :))
Драйвер очень незатейливый, называется "привет мир!". 20 строчек кода, включая пустые.

  "hello_world.c"
#include <linux/module.h>
#include <linux/kernel.h>

static int __init hw_init_module(void)
{
   printk(KERN_ALERT "Hello workd 1.\n");
   return 0;
}

static void __exit hw_cleanup_module(void)
{
  printk(KERN_ALERT "Goodbye world 1.\n");
}

module_init(hw_init_module);
module_exit(hw_cleanup_module);

MODULE_LICENSE("WTFPL");
MODULE_AUTHOR("IID, 2016");
MODULE_DESCRIPTION("Some kernel module");


1) Собираю. Хрен там! Просто исходников ядра недостаточно. Надо его предварительно скомпилить. Мол, часть заголовочных файлов генерируется в процессе компиляции. Ребята, вы рыбного супа обожрались ? У меня только printk в драйвере. Я не использую внутренние какие-то структуры. Тем более которые только при билде чудесным образом возникают. Вынесите такие определения нахрен в спец-файл, который будет генерироваться при сборке. Кому надо — пусть подключают после билда ядра. Собираю ядро. Собираю драйвер. Собрался.

2) Пытаюсь загрузить. Не, говорит. versionmagic не та. У тебя "3.4.6 SMP preempt mod_unload ARMv7 ", а надо "3.4.67 SMP preempt mod_unload ARMv7 ". Мрак и ужас. Мой драйвер в целой куче версий работспособен. Что за тупая проверка ? Смотрю где она определяется, делаю #ifndef, определяю у себя в коде.

3) Пытаюсь собрать. Хрен там! При сборке make-ом генерируется еще один файл, hello_world.mod.c, который подключает vermagic.h самостоятельно и чихать хотел на мои определения. Чертыхаюсь, иду и хардкожу vermagic прямо в сорцы ядра. Собираю драйвер. Собрался.

4) Пытаюсь загрузить. Хрен там! "Unknown relocations 3.". Меняю тулчейн 4.9 на более старый 4.4.3. Собираю.

5) Пытаюсь загрузить. Хрен там! Не удалось отрезолвить символ __aeabi_unwind_cpp_pr0. ИМХО в чистом виде косяк тулчена/механизма сборки. Делаю заглушку. Собираю.

6) Пытаюсь загрузить. Аллилуйя! в /proc/kmsg долгожданное приветствие.

7) Выгружаем... Что ? Как это нахер ? Какой еще EBUSY ? Блин, да мой драйвер не делает нихрена. Чем он может быть занят ? Смотрю начинку сисколла delete_module. Единственная разумная причина, по которой так может быть — не отрезолвился символ cleanup_module. Проверяю readelf-ом. Нет, на месте. Рядом с init_module.

8) проверяю на другом устростве. Там ядро 3.4.5 Привычным движением правлю vermagic. Собираю. Загружаю. Любуюсь в kmsg. Выгружаю. ХРЕН! EBUSY.

Потратив час на разбирательства с unload забил болт. Мне проще устройство ребутнуть между итерациями кодирования-запуска. Тупо по времени экономичнее получится.
kalsarikännit
Re: как я linux драйвер писал...
От: Michael7 Россия  
Дата: 19.09.16 09:53
Оценка:
Здравствуйте, IID, Вы писали:


IID>Драйвер очень незатейливый, называется "привет мир!". 20 строчек кода, включая пустые.


Сразу вопрос, а вот это читали? https://www.kernel.org/doc/Documentation/kbuild/modules.txt
Плюс, обычно есть специальная документация для конкретного дистрибутива, например, для Debian как собирать ядро и модули, вписываясь в инфраструктуру deb-пакетов.

Да сам давно не собирал модулей, когда-то делал для эксперимента, но не нужно сейчас. Просто навскидку, но эти страдания с номером версий и неотресолвенными символами похожи на то, чего-то не по "фен-шую" для конкретного дистрибутива.
Кстати, за параноидальную проверку версий отвечает само ядро, ее можно отключить (пересобрав его без этого параметра).
Отредактировано 19.09.2016 10:13 Michael7 . Предыдущая версия .
Re: как я linux драйвер писал...
От: kov_serg Россия  
Дата: 19.09.16 10:10
Оценка:
Здравствуйте, IID, Вы писали:

IID>Потратив час на разбирательства с unload забил болт. Мне проще устройство ребутнуть между итерациями кодирования-запуска. Тупо по времени экономичнее получится.

IID>

Я примерно так собирал.
dir=$PWD
mykernel=$dir/linux-3.8.13
mymodule=$dir/mymodule
tcprefix=$dir/ndk-r10d/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-

#make -C $mykernel ARCH=arm CROSS_COMPILE=$tcprefix menuconfig
#nano $mykernel/include/linux/vermagic.h

cd $mymodule

make -C $mykernel ARCH=arm CROSS_COMPILE=$tcprefix SUBDIRS=$PWD modules CFLAGS_MODULE=-fno-pic

cd $dir

Собралось сразу и загружалось, выгружалось без проблем.
Re: как я linux драйвер писал...
От: Слава  
Дата: 19.09.16 10:50
Оценка: 1 (1) :)
Здравствуйте, IID, Вы писали:


IID>Драйвер очень незатейливый, называется "привет мир!". 20 строчек кода, включая пустые.


"И так у них всё" ((с) известный анекдот)
Re[2]: как я linux драйвер писал...
От: IID Россия  
Дата: 19.09.16 12:50
Оценка:
Здравствуйте, kov_serg, Вы писали:

_>Я примерно так собирал.

_>
_>dir=$PWD
_>mykernel=$dir/linux-3.8.13
_>mymodule=$dir/mymodule
_>tcprefix=$dir/ndk-r10d/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-

_>#make -C $mykernel ARCH=arm CROSS_COMPILE=$tcprefix menuconfig
_>#nano $mykernel/include/linux/vermagic.h

_>cd $mymodule

_>make -C $mykernel ARCH=arm CROSS_COMPILE=$tcprefix SUBDIRS=$PWD modules CFLAGS_MODULE=-fno-pic

_>cd $dir
_>

_>Собралось сразу и загружалось, выгружалось без проблем.


У меня ядро постарее. Ровно такой же тулчейн как у тебя генерил несъедобные ему релоки. А unwind символов сгенерил целых два — еще и __aeabi_unwind_cpp_pr1 (это я внутри elf'а подсмотрел, т.к. из-за релоков не грузилось ничего).

В твоём девайсе ядро самосборное или заводское ? Попробуй на заводском версии 3.6 или более старой.

Вот мой make.

obj-m := hw.o
KDIR := ~/work/android/kernel
PWD := $(shell pwd)

#CCPATH := ~/work/ndk/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin
#CCPATH_EXT := $(CCPATH)/arm-linux-androideabi-

CCPATH := ~/work/toolchains/arm-eabi-4.4.3/bin
CCPATH_EXT := $(CCPATH)/arm-eabi-

default:
    $(MAKE) ARCH=arm CROSS_COMPILE=$(CCPATH_EXT) -C $(KDIR) M=$(PWD) modules

clean:
    $(MAKE) -C $(KDIR) M=$(PWD) clean
    rm -rf *.c~
    rm -rf *.h~
    rm -rf *.o
    rm -f modules.order
kalsarikännit
Re: как я linux драйвер писал...
От: T4r4sB Россия  
Дата: 19.09.16 12:54
Оценка:
Здравствуйте, IID, Вы писали:

IID> printk(KERN_ALERT "Hello workd 1.\n");


Runtime error 42: unknown word "workd".
Re[2]: как я linux драйвер писал...
От: IID Россия  
Дата: 19.09.16 12:54
Оценка:
Здравствуйте, Michael7, Вы писали:

M>Плюс, обычно есть специальная документация для конкретного дистрибутива, например, для Debian как собирать ядро и модули, вписываясь в инфраструктуру deb-пакетов.


Мой "дистрибутив" это Android. Нет необходимости вписываться в инфраструктуру пакетов. Нужен драйвер для личного использования, на крайне ограниченном наборе оборудования. Загружаемый руками по insmod.

M>Кстати, за параноидальную проверку версий отвечает само ядро, ее можно отключить (пересобрав его без этого параметра).


Это очевидно. Даже если бы не было параметра проверку всегда можно отпатчить. Но идея искать и пересобирать ядра для нескольких устройств мне не подходит. Я хочу чтобы работало с заводской прошивкой.
kalsarikännit
Re[2]: как я linux драйвер писал...
От: IID Россия  
Дата: 19.09.16 12:56
Оценка: :)))
Здравствуйте, T4r4sB, Вы писали:

IID>> printk(KERN_ALERT "Hello workd 1.\n");


TB>Runtime error 42: unknown word "workd".


У тебя тулчейн совсем старый. Должен быть warning 1488.
kalsarikännit
Re[2]: как я linux драйвер писал...
От: T4r4sB Россия  
Дата: 19.09.16 12:56
Оценка: +1 :))) :)))
Здравствуйте, kov_serg, Вы писали:

_>Я примерно так собирал.


Это что за язык? Его тоже отдельно зубрить надо? Одной сишки недостаточно?
Re[3]: как я linux драйвер писал...
От: consign  
Дата: 19.09.16 13:19
Оценка: :)
Здравствуйте, IID, Вы писали:

IID>Должен быть warning 1488.


А кричать "зиг хайль" перед компиляцией надо?
Re[4]: как я linux драйвер писал...
От: IID Россия  
Дата: 19.09.16 13:23
Оценка: :)
Здравствуйте, consign, Вы писали:

C>А кричать "зиг хайль" перед компиляцией надо?


Достаточно маленькой, карманной зигулечки.
kalsarikännit
Re: как я linux драйвер писал...
От: DreamMaker  
Дата: 19.09.16 19:49
Оценка: +2 :))) :))) :))) :))) :))) :)))
Здравствуйте, IID, Вы писали:


IID>Драйвер очень незатейливый, называется "привет мир!". 20 строчек кода, включая пустые.


человек, опустившийся до юникса, должен страдать. это нормально.
In P=NP we trust.
Re: как я linux драйвер писал...
От: Cyberax Марс  
Дата: 20.09.16 04:24
Оценка: :)))
Здравствуйте, IID, Вы писали:

IID>Драйвер очень незатейливый, называется "привет мир!". 20 строчек кода, включая пустые.

Ну а почитать доку — слабо? Для сборки нужна точно версия работающего ядра, с точностью до patchlevel'а. При разработке на нормальной системе (Debian, RedHat) для этого достаточно поставить пакет заголовков из менеджера пакетов.

Если требуется сборка под Андроид, то начинается секс. Пакетного менеджера там нет и нужно искать исходники ядра, из которых собираются заголовки и дальше всё прекрасно строится.
Sapienti sat!
Re[3]: как я linux драйвер писал...
От: kov_serg Россия  
Дата: 20.09.16 06:53
Оценка:
Здравствуйте, T4r4sB, Вы писали:

TB>Здравствуйте, kov_serg, Вы писали:


_>>Я примерно так собирал.


TB>Это что за язык? Его тоже отдельно зубрить надо? Одной сишки недостаточно?

Это bash
Re[2]: как я linux драйвер писал...
От: IID Россия  
Дата: 20.09.16 15:20
Оценка:
Здравствуйте, Cyberax, Вы писали:

C>Для сборки нужна точно версия работающего ядра, с точностью до patchlevel'а.


Спокуха квакуха! Болото будет наше!

Я уже написал утилитку с магией GUID. Которая делает холостой прогруз драйвера, выясняет желаемую ядром vermagic, подглядывая в /proc/kmsg. После чего патчит её в файле и уже грузит окончательно. Всё будет сухо и комфортно.
kalsarikännit
Re[3]: как я linux драйвер писал...
От: andrey.desman  
Дата: 20.09.16 16:26
Оценка:
Здравствуйте, IID, Вы писали:

C>>Для сборки нужна точно версия работающего ядра, с точностью до patchlevel'а.

IID>Спокуха квакуха! Болото будет наше!

А в NDK разве нет нужных заголовков?

IID>Я уже написал утилитку с магией GUID. Которая делает холостой прогруз драйвера, выясняет желаемую ядром vermagic, подглядывая в /proc/kmsg. После чего патчит её в файле и уже грузит окончательно. Всё будет сухо и комфортно.


А modprobe -f не спасает, что ли?
Re[4]: как я linux драйвер писал...
От: Michael7 Россия  
Дата: 20.09.16 18:28
Оценка:
Здравствуйте, andrey.desman, Вы писали:

AD>А modprobe -f не спасает, что ли?


Кстати, да

-f, --force Force module insertion or removal.
implies --force-modversions and
--force-vermagic

--force-modversion Ignore module's version
--force-vermagic Ignore module's version magic


Хотя это андроид, там невесть как оно может работать.
Отредактировано 20.09.2016 18:28 Michael7 . Предыдущая версия .
Re[4]: как я linux драйвер писал...
От: kov_serg Россия  
Дата: 20.09.16 19:15
Оценка:
Здравствуйте, andrey.desman, Вы писали:

AD>Здравствуйте, IID, Вы писали:


C>>>Для сборки нужна точно версия работающего ядра, с точностью до patchlevel'а.

IID>>Спокуха квакуха! Болото будет наше!

AD>А в NDK разве нет нужных заголовков?

Нет там вообще ядра. Его надо отдельно качать и конфигурить под конкретное устройство с его ядром.

IID>>Я уже написал утилитку с магией GUID. Которая делает холостой прогруз драйвера, выясняет желаемую ядром vermagic, подглядывая в /proc/kmsg. После чего патчит её в файле и уже грузит окончательно. Всё будет сухо и комфортно.

Светлая мысль. Только могут быть не совместимые ядра. Например кол-во параметров разное.

AD>А modprobe -f не спасает, что ли?

Нет не спасает.
Re[5]: как я linux драйвер писал...
От: IID Россия  
Дата: 20.09.16 22:36
Оценка: 1 (1)
Здравствуйте, kov_serg, Вы писали:

AD>>А modprobe -f не спасает, что ли?

_>Нет не спасает.

Я дополню почему.
1) modprobe в andoroid toolbox отсутствует. Есть только insmod и rmmod. А начиная с версии marchmallow и их убрали.
2) insmod использует сисколл init_module, а не finit_module, имеющий флаг MODULE_INIT_IGNORE_VERMAGIC
3) этот замечательный сисколл отсуствует в ядре 3.4.6 Когда он точно появился мне трудно сказать. В 3.10 он уже есть. Находил табличку соответствия версий ядра версиям ОС, в ней говорится что 3.10 соответствует Android 4.4 Однако у меня есть как минимум одно фабричное опровержение в виде аппарата ZTE. В котором KitKat соседствует с ядром 3.4
kalsarikännit
Re[2]: как я linux драйвер писал...
От: kov_serg Россия  
Дата: 21.09.16 06:57
Оценка:
Здравствуйте, DreamMaker, Вы писали:

DM>Здравствуйте, IID, Вы писали:



IID>>Драйвер очень незатейливый, называется "привет мир!". 20 строчек кода, включая пустые.


DM>человек, опустившийся до юникса, должен страдать. это нормально.

То-то я смотрю что обладатели win10 и iphone7 наслаждаются нововведениями.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.