nixp.ru v3.0

17 октября 2017,
вторник,
16:25:29 MSK

DevOps с компанией «Флант»
anonymous написал 14 апреля 2006 года в 16:35 (391 просмотр) Ведет себя неопределенно; открыл 1814 темы в форуме, оставил 5575 комментариев на сайте.

Возникла проблема написания своего драйвера для символьного устройства.

При загрузке драйвера выдается сообщение:

insmod: error inserting 'mydrv.ko’: -1 Unknown symbol in module

Сообщения при компиляции:

make -C /lib/modules/2.6.9-1.667asp/build M=/home/Nikolai modules

make[1]: Entering directory `/lib/modules/2.6.9-1.667asp/build'

Building modules, stage 2.

MODPOST

* Warning: «mydrv_minor» [/home/Nikolai/mydrv.ko] undefined!

* Warning: «mydrv_major» [/home/Nikolai/mydrv.ko] undefined!

make[1]: Leaving directory `/lib/modules/2.6.9-1.667asp/build'

Я чтото не доопределил или напутал с определение переменных….. Подскажите:

Исходный текст заголовочного файла mydirect.h:

#define mydrv_major 0;

#define mydrv_minor;

Исходный текст модуля mydrv.c:

#include

#include

#include

#include

#include

#include

#include

#include

MODULE_LICENSE(«DUAL BSD/GPL»);

MODULE_AUTHOR («Dorofeev Nikolai Viktorovich»);

MODULE_SUPPORTED_DEVICE («ADC card»);

extern mydrv_major;

extern mydrv_minor;

int dev;

int result;

int mydrv_nr_devs;

static int __init my_init(void)

{

if (mydrv_major)

{dev=MKDEV(mydrv_major,mydrv_minor);

result=register_chrdev_region(dev,mydrv_nr_devs,«mydrv»);

}else

{result=alloc_chrdev_region(&dev,mydrv_minor,mydrv_nr_devs,«mydrv»);

mydrv_major=MAJOR(dev);

}

if (result<0)

{printk(KERN_WARNING «mydrv: can’t get major %d\n»,mydrv_major);

return result;

}

printk(KERN_ALERT «Govno\n»);

return 0;

};

static int my_detect(unsigned int port, unsigned int range)

{

int err;

if ((err=check_region(port,range))<0) return err;

request_region(port,range,«skull»);

return 0;

}

static void __exit my_cleanup(void)

{

result=unregister_chrdev(dev,mydrv_nr_devs);

if (result<0)

{printk(KERN_WARNING «mydrv: can’t unregister dev\n»);

return result;

}

printk(KERN_ALERT «Da\n»);

};

module_init(my_init);

module_exit(my_cleanup);

Исходный текст makefile:

ifneq ($(KERNELRELEASE),)

obj-m := mydrv.o

else

KERNELDIR ?= /lib/modules/$(shell uname -r)/build

PWD := $(shell pwd)

default:

$(MAKE) -C $(KERNELDIR) M=$(PWD) modules

endif

Исходный текст скрипта загрузки модуля mydrv_load:

#!/bin/sh

module=«mydrv»

device=«ADC»

mode=«664»

# invoke insmod with all arguments we were passed

# and use a pathname, as newer modutils don’t look in . by default

/sbin/insmod -f ./$module.ko $* || exit 1

# remove stale nodes

rm -f /dev/${device}[0]

major=$(awk «\\$2==\»$module\» {print \\$1}» /proc/devices)

mknod /dev/${device}0 c $major 0

# give appropriate group/permissions, and change the group.

# Not all distributions have staff; some have «wheel» instead.

group=«staff»

grep -q '^staff:' /etc/group || group=«wheel»

chgrp $group /dev/${device}[0]

chmod $mode /dev/${device}[0]

Заранее, благодарен!!!

rgo

у меня начинает складываться ощущение, что не стоит тебе пока заниматься драйверами. Вот ты сказал

extern mydrv_major;

extern mydrv_minor;


то есть объяснил компилятору, что эти символы лежат где-то ещё. Но ты их хоть куда-нибудь положил?

И ещё поясни, нафига ты привёл здесь содержимое файла mydirect.h

Совет, в Makefile первой строчкой:

CFLAGS=-Wall


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

Ещё совет, читай доки про C. Много. Пиши программы на C. Ещё больше. А потом берись за написание дров. kernel panic — это очень утомительная вещь, она просто достаёт необходимостью ребута. А уж этот неотъемлимый запуск fsck, при старте системы… Ограничь себя хоть на полгода user-space программами: сэкономив время на этих ребутах и fsck дальше продвинешься в изучении расположения C-specific граблей и не очень граблей.