LINUX.ORG.RU

cpumask.h и for_each_cpu_and


0

0

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

#define BITS_PER_LONG 32

#include <linux/module.h>       /* Необходим для любого модуля ядра */
#include <linux/kernel.h>       /* Здесь находится определение KERN_ALERT */

int init_module(void)
{
        printk("<1>Hello world 1.\n");
        return 0;
}

void cleanup_module(void)
{
        printk(KERN_ALERT "Goodbye world 1.\n");
}
$ gcc -I /usr/src/linux/include/ -I /usr/src/linux/arch/x86/include/ -c main.cpp

Вылетает с ошибкой:

/usr/src/linux/include/linux/cpumask.h:586:37: error: «and» may not appear in macro parameter list

То есть ему не нравится эта строчка:

#define for_each_cpu(cpu, mask)			\
	for ((cpu) = 0; (cpu) < 1; (cpu)++, (void)mask)
#define for_each_cpu_and(cpu, mask, and)	\
	for ((cpu) = 0; (cpu) < 1; (cpu)++, (void)mask, (void)and

Как можно решить эту проблему? Необходимо описать макропараметр «and»?

P.S. Компилю под ядро linux-2.6.29.6, но и под linux-2.6.33.2 та же ошибка.

★★

Кажется, вышел из положения - заменил #define for_each_cpu_and(cpu, mask, and) на #define for_each_cpu_and(cpu, mask, and_deb) ну и, соответственно, подставил это значение везде, где оно встречается

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

Но зато другая проблема появилась:

/usr/src/linux/arch/x86/include/asm/bitops.h:59: ошибка: expected initializer before ‘void’

/**
 * set_bit - Atomically set a bit in memory
 * @nr: the bit to set
 * @addr: the address to start counting from
 *
 * This function is atomic and may not be reordered.  See __set_bit()
 * if you do not require the atomic guarantees.
 *
 * Note: there are no guarantees that this function will not be reordered
 * on non x86 architectures, so if you are writing portable code,
 * make sure not to rely on its reordering guarantees.
 *
 * Note that @nr may be almost arbitrarily large; this function is not
 * restricted to acting on a single-word quantity.
 */
static __always_inline void // <-- 59 СТРОКА
set_bit(unsigned int nr, volatile unsigned long *addr)
{
	if (IS_IMMEDIATE(nr)) {
		asm volatile(LOCK_PREFIX "orb %1,%0"
			: CONST_MASK_ADDR(nr, addr)
			: "iq" ((u8)CONST_MASK(nr))
			: "memory");
	} else {
		asm volatile(LOCK_PREFIX "bts %1,%0"
			: BITOP_ADDR(addr) : "Ir" (nr) : "memory");
	}
}
SaBo ★★
() автор топика

напиши Makefile

ifneq ($(KERNELRELEASE),)
obj-m:=main.o
else
KERNELDIR?=/lib/modules/$(shell uname -r)/build
PWD:=$(shell pwd)
default:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
endif

и собирай с помощью make. будет тебе модуль main.ko

и ради бога, не обзывай исходники на С плюсовыми расширениями типа .cpp

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

блин, табы порезало

ifneq ($(KERNELRELEASE),)                              
        obj-m:=m.o                                     
else                                                   
        KERNELDIR?=/lib/modules/$(shell uname -r)/build
        PWD:=$(shell pwd)                              
default:                                               
        $(MAKE) -C $(KERNELDIR) M=$(PWD) modules       
endif                                                  

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

> и ради бога, не обзывай исходники на С плюсовыми расширениями типа .cpp

Может он ядерный модуль на C++ пишет.

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

> и ради бога, не обзывай исходники на С плюсовыми расширениями типа .cpp

В этом вся собака и зарыта.

Может он ядерный модуль на C++ пишет.

Пример из сабжа демонстрирует, что без костылей на плюсах не напишешь :)

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

В этом вся собака и зарыта.

Я так понимаю, достаточно было сделать так:

extern "C" {
#include <linux/module.h>       /* Необходим для любого модуля ядра */ 
#include <linux/kernel.h>       /* Здесь находится определение KERN_ALERT */
}
Dendy ★★★★★
()
Ответ на: комментарий от const86

> В этом вся собака и зарыта.

на такой мелочи - да. но чтобы в дальнейшем не возникали проблемы с отсутствием нужных #define-ов, лучше сразу приучиться использовать ядерную систему сборки, а не изобретать велосипеды

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

> лучше сразу приучиться использовать ядерную систему сборки, а не изобретать велосипеды

Ну это да, к тому же она ещё и проще :)

const86 ★★★★★
()

Адово.

Раз так, то вот мой вклад в кроссплатформенность твоего модуля. Можешь не благодарить!

--- m0.c	2010-04-20 17:25:36.431688484 +0400
+++ m.c	2010-04-20 17:25:58.682688705 +0400
@@ -1,4 +1,10 @@
+#if defined (__i386__)
 #define BITS_PER_LONG 32 
+#elif defined(__x86_64__)
+#define BITS_PER_LONG 64
+#else
+#error "Pipec, neponyatnaya arhitektura..."
+#endif
  
 #include <linux/module.h>       /* Необходим для любого модуля ядра */ 
 #include <linux/kernel.h>       /* Здесь находится определение KERN_ALERT */
ttnl ★★★★★
()
Ответ на: комментарий от ttnl

между прочим, исходник модуля из первого поста вполне себе кроссплатформенен.
просто ТС не осилил google://how+to+compile+linux+kernel+module

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

ananas> и собирай с помощью make. будет тебе модуль main.ko

Не совсем понимаю, его нужно запускать с какими-то ключами? Ибо выдаёт следующее:

$ make
make: Цель `default' не требует выполнения команд.

Dendy> Я так понимаю, достаточно было сделать так

Нужно ли компилятору скармливать какие-то дополнительные ключи? Так как разницы с 'extern «C»' и без 'extern «C»' никакой.

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

Всё, разобрался с ключами. Запустил make вот так:

$ make -C /usr/src/linux SUBDIRS=$PWD modules

А сам makefile переписал так:

ifneq ($(KERNELRELEASE),)
obj-m:=main.o
else
KERNELDIR?=/lib/modules/$(shell uname -r)/build
PWD:=$(shell pwd)
default:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
endif

Благодарю за помощь!

SaBo ★★
() автор топика
Ответ на: комментарий от jtootf

а нужно ли?

Хороший вопрос... Пока нет, но для общего развития было бы интересно знать.

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

> И всё-таки, можно ли писать модули на плюсах?

А что мешает? Только вот rrti у тебя, думаю, не будет

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