Киньте, пожалуйста, работающий пример самого простецкого драйвера в сорцах. Когда-то делал драйвер для ISAшного символьного устройства.
Тут - труба. Задумал написать I2C мастер без обработчика прерываний. Все делаю в виртуальном RHEL4. В единственном C-файле функции работы с TWI закомментарил, оставил пока только загрузку-выгрузку модуля.
При "СС=gcc" драйвер компилится, но не загружается, ошибка "Invalid module format". Я перекомпилял с "CC=arm-none-linux-gnueabi-gcc", при попытке запуска на сабжевой борде - то же самое...
Вот Makefile, переделанный мною из своего ISAшного:
А вот мейк, переделанный из образца для Nandflash:
Ошибка insmod говорит о том, что модуль был скомпилен для другой платформы? Но где-то какой-то вариант должен был установиться нормально :-). Что я делаю не так ?
Все, прощу прощения. Просто я не в курсе, что для ядра 2.6 правила мейкфайлов для ядра перелопатили полностью, гады, и теперь никаких там CFLAGS, -DMODULE и пр. заклинаний. Нашел пример Makefile, загрузка-выгрузка работает.
Теперь можно и HW-функции прикручивать. Как заработает - выложу, авось поможет начинающим :-).
Модули ядра работают только под x86, на плате insmod'иться отказываются. Посмотрел я cmd-файлы, построенные kbuild'ом, и увидел, что там обычный gcc и 'elf_i386'. Т.е. оно и не должно там работать. Так как же дать понять, что надо компилить под ARM? Если ключей CCFLAGS и LDFLAGS нету.
Я пробовал писать "make CROSS_COMPILE=arm-none-linux-gnueabi-" , но тогда вылезают ерроры. Я залез в исходники драйвера AT91_mci - там, кроме этих cmd-файлов, генерируемых в ходе make, нигде не упоминаются линкер и компилер. Что такое Kconfig и зачем, неясно, в инетовских мануалах толком не нашел.
Дайте, плз, простой примерчик модуля ядра с комментарием: как указать, что используется не простой gcc/ld.
GSM_power_driver не предлагать, он вообще непонятный!
А то плата лежит, а я бьюсь как рыба об лед .
В общем случае собирать как-то так:
make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi-
Вы пытаетесь собрать модули отдельно от ядра ? Или что ?
make (синоним make all) - собирает все и модули тоже... make modules собирает только модули, в общем все как обычно, НО не забывайте указывать таргет-архитектуру (ARCH) и префикс кросс-компилятора (CROSS_COMPILE)... никаких проблем с модулями не замечал...
Вот так можно этот модуль ядра собрать (стандартный для 2.6 ядра "make modules" с доп. опциями):
В директории /home/repman/Build/AT91SAM9260-SK/src/linux-2.6.27.10_SK лежит откомпиленное ядро, на котором этот модуль будет работать.
В /home/repman/Build/AT91SAM9260-SK/src/adc_driver/ лежит исходник драйвера, здесь же получим *.ko
Как видите, с форматом все ок:
p.s. в CROSS_COMPILE ставьте СВОЙ префикс, если он отличается от моего...
Установка модуля - может быть специфична для конкретного дистрибутива... На примере Fedora8-ARM:
1. Копируем at91adc.ko на плату в /lib/modules/2.6.27.10/misc каким-либо способом, я это делаю через ssh. Если директории нет - создаем, версия ядра должна быть Вашей (uname -r), depmod подскажет. Верия ядра на плате должна ТОЧНО совпадать с версией ядра с которой собирался наш драйвер, иначе Вас ждет облом.
2. Запускаем depmod, чем создаем служебные файлы системы модулей в /lib/modules/2.6.27.10/, в /lib/modules/2.6.27.10/modules.dep - видим, что наш драйвер найден системой.
3. Стартуем драйвер:
Ошибок нет - драйвер запущен.
4. Смотрим /proc/devices, ищем наш драйвер, запоминаем № устройства. (у меня 252).
5. Создаем ссылки на устройство в /dev (драйвер почему-то создавался для обслуживания только 2 каналов, хотя в SAM их 4... ну, что есть)
mknod /dev/adc0 c 252 0
mknod /dev/adc1 c 252 1
Имеем 2 канала ADC, можем работать... для проверки можно получить на экран результат ввода ADC в виде мусороподобного дампа, который меняется от прикосновения пальцем ко входам ADC на гребенке:
cat /dev/adc0
p.s. автозапуск модуля при старте ОС - отдельная история, специфичная для дистрибутива Linux, как вариант, можно использовать прилагаемый по ссылке выше shell script, который просто повторяет пп 2-5...
Вот спасибо за ценную инфу! Попробую.
У мну 6-летний опыт работы с 8 и 16-битными контроллерами, а вот в Linux программил только на десктопе. Планов громадьё: драйвер опроса кнопок с использованием PIT почти доделал, на очереди драйвер к индикатору Winstar WG12864 с сырцами, портированными с ASMа MCS-51. Не хватает только опыта портирования под другую архитектуру...
В инетовских форумах мне с ключом ARCH встречалось и linux_arm, и armle, и пр. В embedded VC++ с PocketPC SDK, кстати, компилить под ARM архипросто - только выбрать в списке девайс "ARMv4".
На вируталке я просто давал команду insmod прямо из каталога проекта и потом командой dmesg | tail убеждался, что драйвер подхвачен, и символьный драйвер установлен.
В принципе везде аналогично - только insmod может ругнуться что файл не найден, а если задать его с путем, то проблем не будет - можете хранить где хотите.
Вообще для AT91SAM9260 наиболее точно:
arch=armv5tej
tune=arm926ejs
Компилятор понимает эти параметры, НО не все программы имеют оптимизированные версии для сборки... поэтому можно использовать архитектуры вверх с уменьшением конкретики до первого совпадения... armv5te, armv5t, armv5, armv4, arm... НО следует иметь ввиду, что любые обобщения приводят к деградации быстродействия.
В отношении к сборке ядра допустимые архитектуры = просто именам поддиректориев в arch... Вот его содержимое для 2.6.28:
Самое близкое - arm
Где хранить модули - дело сугубо личное... Однако, если Вы имеете уже сложившийся дистрибутив, в котором несколько разных утилит, программ, скриптов и т.п. предполагают, что модули лежат ИМЕННО ТУТ и ИМЕННО ТАК, то логично придерживаться принятых правил... иначе, просто, не сможете в нем работать...
Программы вообще не должны заботиться об этом - это дело компилятора - использовать какой-либо набор инструкций, кроме, естественно, использования инлайн ассемблерных вставок или например оптимизированного хранении данных для использования simd инструкций. И не нужно путать опции компилятора (arch=armv5tej) с переменными окружения через которые сообщают архитектуру при кросскомпиляции ядра (make ARCH=arm).