Здравствуйте!
Столкнулся с такой проблемой. Пишу свой второй модуль ядра. Решил кое-какие функции вынести в отдельный файл. Основной модуль называется hello.c, библиотечный файл — debug.c и заголовочный файл - debug.h. Однако при попытке компиляции получаю такой вывод:
make -C /lib/modules/2.6.28-11-generic/build M=/home/kostik/progs/kernel/modul02 modulesmake[1]: Вход в каталог `/usr/src/linux-headers-2.6.28-11-generic'
CC [M] /home/kostik/progs/kernel/modul02/debug.o
/home/kostik/progs/kernel/modul02/debug.c:4: предупреждение: ‘write_to_tty’ определена, но нигде не используется
CC [M] /home/kostik/progs/kernel/modul02/hello.o
/home/kostik/progs/kernel/modul02/debug.h:9: предупреждение: ‘write_to_tty’ используется, но нигде не определена
Building modules, stage 2.
MODPOST 2 modules
WARNING: "write_to_tty" [/home/kostik/progs/kernel/modul02/hello.ko] undefined!
CC /home/kostik/progs/kernel/modul02/debug.mod.o
LD [M] /home/kostik/progs/kernel/modul02/debug.ko
CC /home/kostik/progs/kernel/modul02/hello.mod.o
LD [M] /home/kostik/progs/kernel/modul02/hello.ko
make[1]: Выход из каталога `/usr/src/linux-headers-2.6.28-11-generic'
При попытке установить модуль получаю сообщение:
insmod: error inserting './hello.ko': -1 Unknown symbol in module
Т.е. компилятор не может найти функцию write_to_tty(). write_to_tty() - единственная функция, определенная в debug.h. Видимо, я неправильно создал Makefile. Поискал по имеющейся документации, но нигде не нашел, как же нужно поступать, если модуль использует самодельные библиотеки. Файлы проекта привожу ниже. Подскажите, как правильно оформить такой проект?
файл hello.c
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/miscdevice.h>
#include <linux/module.h>
#include <asm/uaccess.h>
#include "debug.h"static ssize_t hello_read(struct file *file, char *buf, size_t count, loff_t *ppos)
{
char hello_str[] = "Hello, world!\n";
int len = strlen(hello_str);
write_to_tty("3 hello write");
if(count < len)
{
return -EINVAL;
}
if(*ppos != 0)
{
return 0;
}
if(copy_to_user(buf, hello_str, len))
{
return -EINVAL;
}
*ppos = len;
return len;
}static const struct file_operations hello_fops =
{
.owner = THIS_MODULE,
.read = hello_read
};static struct miscdevice hello_dev =
{
MISC_DYNAMIC_MINOR,
"hello",
&hello_fops
};static int __init hello_init(void)
{
int ret;
ret = misc_register(&hello_dev);
if(ret)
{
printk("error!\n");
write_to_tty("error!");
}
return ret;
}static void __exit hello_exit(void)
{
misc_deregister(&hello_dev);
}
module_init(hello_init);
module_exit(hello_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Mak");
MODULE_DESCRIPTION("\"Hello, world!\" minimal module");
MODULE_VERSION("dev");файл debug.c
#include "debug.h"
static int write_to_tty(char *text)
{
struct tty_struct *curr_tty;
curr_tty = current->signal->tty;
if (curr_tty != NULL)
{
((curr_tty->driver->ops)->write)(curr_tty, text, strlen(text));
((curr_tty->driver->ops)->write) (curr_tty, "\xD\xA", 2);
}
return 0;
}файл debug.h
#include <linux/kernel.h>
#include <linux/tty.h>
#include <linux/sched.h>static int write_to_tty(char *text);
#define DEBUD_START
Makefile:
obj-m := debug.o hello.o
KDIR := /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
default:
$(MAKE) -C $(KDIR) M=$(PWD) modules
>Makefile:
>obj-m := debug.o hello.oЗдесь должно быть что-то вроде:
obj-m := my_module.o
my_module-objs := debug.o hello.o
>KDIR := /lib/modules/$(shell uname -r)/build
>PWD := $(shell pwd)
>default:
> $(MAKE) -C $(KDIR) M=$(PWD) modules
>>Makefile:
>>obj-m := debug.o hello.o
>
>Здесь должно быть что-то вроде:obj-m := my_module.o
>my_module-objs := debug.o hello.o
>>KDIR := /lib/modules/$(shell uname -r)/build
>>PWD := $(shell pwd)
>>default:
>> $(MAKE) -C $(KDIR) M=$(PWD) modulesЕсли сделать дословно как у Вас, то make ругается так:
make -C /lib/modules/2.6.28-11-generic/build M=/home/kostik/progs/kernel/modul02 modules
make[1]: Вход в каталог `/usr/src/linux-headers-2.6.28-11-generic'
make[2]: *** Нет правила для сборки цели `/home/kostik/progs/kernel/modul02/my_module.c', требуемой для `/home/kostik/progs/kernel/modul02/my_module.o'. Останов.
make[1]: *** [_module_/home/kostik/progs/kernel/modul02] Ошибка 2
make[1]: Выход из каталога `/usr/src/linux-headers-2.6.28-11-generic'
make: *** [default] Ошибка 2
т.е. не находит my_module.c, которого естественно нет.
Я попробовал сделать так:
obj-m := hello.o
hello-obj := debug.o
KDIR := /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
default:
$(MAKE) -C $(KDIR) M=$(PWD) modules
и опять получил:
make -C /lib/modules/2.6.28-11-generic/build M=/home/kostik/progs/kernel/modul02 modules
make[1]: Вход в каталог `/usr/src/linux-headers-2.6.28-11-generic'
CC [M] /home/kostik/progs/kernel/modul02/hello.o
/home/kostik/progs/kernel/modul02/debug.h:9: предупреждение: ‘write_to_tty’ используется, но нигде не определена
Building modules, stage 2.
MODPOST 1 modules
WARNING: "write_to_tty" [/home/kostik/progs/kernel/modul02/hello.ko] undefined!
CC /home/kostik/progs/kernel/modul02/hello.mod.o
LD [M] /home/kostik/progs/kernel/modul02/hello.ko
make[1]: Выход из каталога `/usr/src/linux-headers-2.6.28-11-generic'
Вы точно написали так же?
>>obj-m := my_module.o
>>my_module-objs := debug.o hello.o
>obj-m := hello.o
>hello-obj := debug.oПотому что в вашем коде написано hello-obj, в то время как в моём my_module-objs (с 's' на конце).
P.S. Я сам-то уже не помню, как там что пишется - давно драйверами не занимался. Код взял из работающего проекта. С той лишь разницей, что у меня там obj-m += ..., но там в одном проекте несколько драйверов.
>/home/kostik/progs/kernel/modul02/debug.c:4: предупреждение: ‘write_to_tty’ определена, но нигде не используется
>
>/home/kostik/progs/kernel/modul02/debug.h:9: предупреждение: ‘write_to_tty’ используется, но нигде не определена
>static int write_to_tty(char *text);
>static и extern перепутали?
Вот, нашёл (собственно, с помощью$ grep -r '\-obj' /usr/src/linux.../Documentation/
Documentation/kbuild/makefiles.txt - там всё написано, как что делать.
>Вот, нашёл (собственно, с помощью$ grep -r '\-obj' /usr/src/linux.../Documentation/
>Documentation/kbuild/makefiles.txt - там всё написано, как что делать.За ссылку отдельное спасибо - буду разбираться :-)
Большое спасибо!
Оба совета следовало применить одновременно:
1) я действительно написал my_module-obj:=debug.o hello.o вместо my_module-objs:=debug.o hello.o;
2) кроме этого в debug.h нужно было поставить спецификатор extern вместо static.
Все вместе помогло, а по-отдельности не работает :-)))