LINUX.ORG.RU

makefile как указать путь к системным файлам

 ,


1

2

Пытаюсь собрать простейший модуль драйвера:

#define MODULE
#define __KERNEL__
#include <module.h>
 
int init_module() 
{
	return 0;
}

void cleanup_module()
{
	return;
}

Makefile:
CC = gcc
objects :=module.o

KERNEL_SOURCE := /usr/src/linux-headers-2.6.32-122-rtai/include/linux/
PWD := $(shell pwd)

module.o: module.c 
	$(CC) -c module.c

all:
	${MAKE} -C ${KERNEL_SOURCE} SUBDIRS=${PWD} modules
ошибка: gcc -c module.c module.c:3:20: error: module.h: No such file or directory
make: *** [module.o] Error 1

Ну а общем то тут видно на чём все это собирается. Как правильно составить makefile. Уже всю голову сломал


Ответ на: комментарий от andreyu

Ну так получше?

Можно конечно указать полный путь к хедеру, но в нём и в других есть вызовы системных файлов, и они тоже не будут определяться

T00T ()
Ответ на: комментарий от T00T

Ну так получше?

Нет, надо заключить код в [code].

А теперь по делу.

Во-первых, ты, похоже, совершенно не понимаешь, как работает make. Прочти мануал по GNU make: https://www.gnu.org/software/make/manual/

Во-вторых, даже если ты не понимаешь, как работает make, ты бы всё равно мог собрать свой модуль, следуя документации. Надо было написать:

obj-m += module.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
А если ты собирал для ядра, которое не установлено, то:
obj-m += module.o

all:
	make -C  /usr/src/linux-2.6.32-122-rtai/ M=$(PWD) modules

clean:
	make -C  /usr/src/linux-2.6.32-122-rtai/ M=$(PWD) clean
где /usr/src/linux-2.6.32-122-rtai — это корень дерева исходников Линукс, а не директория с одними заголовками.

Предупреждаю, что я никогда по-серьёзному программированием ядра Линукс не занимался. Однако я активно пользовался make.

proud_anon ★★★★★ ()
Последнее исправление: proud_anon (всего исправлений: 4)
Ответ на: комментарий от proud_anon

А я вот ни make ни Linux не занимался ранее, только вникаю. Зато я на микроконтроллерах программировал и на плисинах. А вот потребовалось одно такое устройство к Linux прицепить. Вот и мучаюсь. Ну вот так.....

А вот по поводу первого примера:
make -C /lib/modules/2.6.32-122-rtai/build M=/home/vladimir/Work/driver_o modules
make[1]: Entering directory `/usr/src/linux-headers-2.6.32-122-rtai'
scripts/Makefile.build:44: /home/vladimir/Work/driver_o/Makefile: No such file or directory
make[2]: *** No rule to make target `/home/vladimir/Work/driver_o/Makefile'. Stop.
make[1]: *** [_module_/home/vladimir/Work/driver_o] Error 2
make[1]: Leaving directory `/usr/src/linux-headers-2.6.32-122-rtai' make: *** [all] Error 2

T00T ()
Ответ на: комментарий от E

Ключ компилятора -I

Я не нашёл как это использовать.

Ну сильно не ругайте, яж написал Нубовопрос :). Разбираться в новых вещах не так просто, очень много информации приходиться прорабатывать. Вот я над этим вопросом уже второй день сижу у компа, а там ещё непаханое поле дальше!!!!!

T00T ()
Ответ на: комментарий от T00T

На компе такого нет.

Как нет? Он должен быть в составе исходников ядра.

Слушай, ответь на два вопроса:

  1. Ты собираешь модуль на том же компьютере, где это ядро установлено?
  2. У тебя есть исходник этого ядра? Не одни заголовки, а весь исходник?
proud_anon ★★★★★ ()
Ответ на: комментарий от proud_anon

Я очень мало знаю про Linux но в си вроде разобрался, раньше программировал на pascal а в основном на asme, ну чтоб было понятие о том что я могу знать.

Linux я устанавливаю с диска, устанавливал на этом компе(Хотя материнку может и менял). Образ диска могу найти откуда скачивал. Короче, я сделал PCI-ную железку, написал под неё PCI-target. Ну теперь нужно её к программе прикрутить, в этой программе даже полноценный драйвер писать не надо, там толко нужно описать что делать. Но везде используются библиотеки системные при работе с PCI и дровами. И я не могу собрать всё это. Поэтому хотел попробывать написать простой драйвер для системы по типу
http://www.opennet.ru/base/dev/linux_driver.txt.html.
Но и тут чё то не хочет собитаться.

T00T ()
Ответ на: комментарий от T00T

В общем то я понимаю что такое ядро, что оно собирается, уже много о чём прочитал. Но читать одно, а ручками команды вбивать это другое. Я искал мож кто из знакомых программистов может помочь драйвер написать, но чёт все отмахиваются, а так если разобраться там для знающего человека делов на 1 день. И то если постоянно кофеёк попивать :)

T00T ()
Ответ на: комментарий от T00T

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

T00T ()
Ответ на: комментарий от T00T

Вот что сейчас в Makefile

# Makefile makefile of our first driver
CURRENT = $(shell uname -r)
KDIR = /lib/modules/$(CURRENT)/build
PWD = $(shell pwd)
TARGET1 = module

obj-m := $(TARGET1).o

default: 
	$(MAKE) -C $(KDIR) M=$(PWD) modules

И вот что пишет:
make -C /lib/modules/2.6.32-122-rtai/build M=/home/vladimir/Work/driver_o modules
make[1]: Entering directory `/usr/src/linux-headers-2.6.32-122-rtai'
CC [M] /home/vladimir/Work/driver_o/module.o
/home/vladimir/Work/driver_o/module.c:1:1: warning: «MODULE» redefined
<command-line>: warning: this is the location of the previous definition
/home/vladimir/Work/driver_o/module.c:2:1: warning: «__KERNEL__» redefined
<command-line>: warning: this is the location of the previous definition
/home/vladimir/Work/driver_o/module.c:3:20: error: module.h: No such file or directory
/home/vladimir/Work/driver_o/module.c:6: warning: function declaration isn’t a prototype
/home/vladimir/Work/driver_o/module.c:11: warning: function declaration isn’t a prototype
make[2]: *** [/home/vladimir/Work/driver_o/module.o] Error 1
make[1]: *** [_module_/home/vladimir/Work/driver_o] Error 2
make[1]: Leaving directory `/usr/src/linux-headers-2.6.32-122-rtai'
make: *** [default] Error 2

Файл в той папке где он пишет реально есть вот путь к нему: /usr/src/linux-headers-2.6.32-122-rtai/include/linux/module.h В общем то его и не находит

T00T ()
Ответ на: комментарий от T00T

В общем то всё срослось, походу ищет он в папке
/usr/src/linux-headers-2.6.32-122-rtai/include/
А поэтому нужно писать <linux/module.h>

T00T ()
Ответ на: комментарий от T00T

проверьте, должен быть установлен пакет linux-headers-$(uname -r) или что-то типа kernel-devel

какой дистрибутив используете?

узнать можно примерно так:

cat /etc/os-release
lsb_release -a
cat /etc/issue
IvanR ★★★ ()
Ответ на: комментарий от T00T

А есть кто нибудь у кого опыт написания драйверов, а то есть вопросы. В разных источниках иногда разная информация попадается. Хотелось бы просто общую картину узнать куда копать :)

T00T ()
Ответ на: комментарий от T00T

Linux Device Drivers, Third Edition и та подборка статей, что я выше скидывал, еще можно книгу Олега Цирюлика найти (те статьи им же и написаны), еще есть сайт http://lxr.free-electrons.com/ там удобно искать по ключевым словам, но подобное можно и у себя локально сделать на своем с помощью cscope

IvanR ★★★ ()
Ответ на: комментарий от T00T

Теоретически, простой драйвер для валидного PCI устройства можно написать без добавления единой строчки кода ядра.

Использовать UIO для пробрасывания прерываний:

Чтение-запись в пространство pci можно через /dev/iomem. Информацию о девайсе можно узнать с помощью libpci.

Но Linux Device Drivers лучше почитать.

anonymous ()
Ответ на: комментарий от anonymous

Спасибо за ответы буду дальше разбираться. Вот такой вот вопрос:
Стандартно так, и в примерах: драйвер регистрируется, получает свой MAJOR номер, за ним закрепляется файл в /dev и через функции R/W данные обмениваются с этим файлом. Я вот просто пока не дошёл до того как из пользовательской программы читаются данные из файла устройства. Или как вызываются функции драйвера.
Но вообще хотелось бы сделать так:
1 вариант:
В драйвере описаны функции R/W таким образом что бы при её вызове сообщался указатель переменной или массива пользовательской программы. И данные сразу попадали бы в нужную переменную напрямую.
2 вариант:
Или ещё проще я уже так видел. Драйвер устройства лишь открывает устройство и отображает его адресное пространство в виртуальную память(пользовательскую), и закрывает его. Для общения нужно из драйвера передавать только что устройство открыто и готово передавать данные, ну и соответственно верхний адрес виртуальной памяти. А функции R/W реализована в пользовательской программе *(*u32)var = *(*u32)dev. т.е. просто переместить данные из ячейки устройства в ячейку некой переменной и всё.

Т.е. в общем то стандартный драйвер не нужен(нужно максимальное быстродействие, и соответсвенно ядро реалтайм для этого)
Возможны ли такие варианты??

T00T ()
Ответ на: комментарий от anonymous

си..... блин.

Собираю значит драйвер в принципи всё работает кроме одного.
Помогите правильно записать:

typedef struct {
	void *mem_base;
  	__u32 io_base;
	int len;
	hal_bit_t *digital_in[32];    /* ptrs for digital input pins 0 - 31 */
  	hal_bit_t *digital_out[32];    /* ptrs for digital output pins 0 - 31 */
} to_pci_t;

static to_pci_t *device_data;

.............

device_data->mem_base = ioremap_nocache();

...............

void update_port(void *arg, long period){
	to_pci_t *port;
	__u32 tmp;
	port = arg;

		tmp = readl(port->mem_base);
		printk(KERN_ALERT "to_pci: data: %X\n",tmp);
to_pci_t -структура через которую данные передаются. значение mem_base получается как результат возвращаемый функцией ioremap(.....)
приложение постоянно будет вызывать функцию update_port() в ней мне надо опрашивать устройство.
tmp = readl(port->mem_base); - так реализован опрос. И я в tmp - получаю АДРЕСС ячейки памяти откуда мне надо считать данные. Вопрос как их считать. Всю голову себе сломал уже...... Помогите :)

T00T ()
Ответ на: си..... блин. от T00T

Да забыл, считывать нужно такой же функцией readl()

T00T ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.