LXF78:Драйвер сетевого устройства – своими руками
Seafox (обсуждение | вклад) (Новая: ''Часть 1. Не нашли, как включить нужную функцию в make menuconfig? Не беда – '''Игорь Тимошенко''' расскажет, как ...) |
Версия 21:49, 19 марта 2008
|
|
|
Часть 1. Не нашли, как включить нужную функцию в make menuconfig? Не беда – Игорь Тимошенко расскажет, как написать драйвер самостоятельно!
Содержание |
Эта статья предназначена для тех, кто желает приобрести начальные знания, позволяющие самостоятельно создавать драйверы сетевых устройств, работающих в среде ОС Linux. Не так давно у меня самого возникла такая задача, и я обнаружил явный недостаток информации по этой теме. В доступной литературе на русском языке подробно описаны все драйвера, кроме сетевых. В англоязычной библии на все времена «Linux Device Drivers» (http://www.oreilly.com/catalog/linuxdrive3) есть всё, но понимания этого «всего» можно достичь, пройдя не самый простой путь. Отчаянные метания по форумам привели меня к неутешительному выводу, что интересующихся этим вопросом несколько больше, чем что-то понимающих в нём. Итак, в результате многочисленных проб и ошибок, я получил некоторое количество полезных знаний и драйвер, который сейчас успешно использую дома для подключения второго компьютера к Интернету. Простота получившейся программы натолкнула меня на мысль, что путь, который я прошёл, мог бы быть гораздо короче и куда менее извилист, если бы в начале мне удалось прочитать статью, которую я сейчас вам и предлагаю.
Не смотря на то, что по ходу изложения, я постараюсь сделать необходимые разъяснения и ссылки, для успешного и правильного понимания материала статьи, читателю понадобятся некоторые начальные познания. Прежде всего – знакомство с языком программирования C, кроме того, я полагаю, что читатель представляет, как работают компьютерные сети, уже работал в ОС Linux и знает, что такое «модуль ядра».
Все примеры, приведённые в статье – рабочие, и представляют собой необходимые начальные этапы того самого пути, который нужно пройти, чтобы научиться создавать драйверы различных сетевых устройств. Я использовал дистрибутив Mandrake 10.1 с ядром 2.6.8.1-12mdk. Для других версий ядра, возможно, понадобится внести некоторые незначительные изменения в исходные тексты.
Чтобы иметь возможность компилировать модули ядра, после обычной установки дистрибутива, нужно дополнительно установить исходные тексты вашей версии ядра в каталог usr/src. В моём дистрибутиве это пришлось сделать вручную, потому, что даже при выборе расширенного варианта установки и указании на необходимость включения в неё исходных текстов, в нужном каталоге у меня оказались только дремучие исходники ядра 2.4. Нужные исходные тексты находятся на третьем диске дистрибутива в папке /media/main3/ в виде rpm-пакета: kernel-source-2.6-2.6.8.1-12mdk.i586.rpm. Их можно установить с помощью команды:
rpm -ivh ./ kernel-source-2.6-2.6.8.1-12mdk.i586.rpm.
Установку следует производить в консольном режиме из каталога, содержащего пакет, в режиме суперпользователя.
Перед началом работы советую создать свой рабочий каталог /home/user/<что-нибудь>, в котором будут находиться ваши исход ные тексты и поместить туда Makefile, взятый мной из примера, предлагаемого средой разработки KDevelop, слегка модифицированный, для обеспечения его работоспособности (ох уж эти особенности свободно распространяемых программ!):
TARGET = myname OBJS = myname.o MDIR = drivers/misc EXTRA_CFLAGS = -DEXPORT_SYMTAB CURRENT = $(shell uname -r) KDIR = /lib/modules/$(CURRENT)/build PWD = $(shell pwd) DEST = /lib/modules/$(CURRENT)/kernel/$(MDIR) obj-m := $(TARGET).o default: make -C $(KDIR) SUBDIRS=$(PWD) modules $(TARGET).o: $(OBJS) $(LD) $(LD_RFLAG) -r -o $@ $(OBJS) ifneq (,$(findstring 2.4.,$(CURRENT))) install: su -c «cp -v $(TARGET).o $(DEST) && /sbin/depmod -a» else install: su -c «cp -v $(TARGET).ko $(DEST) && /sbin/depmod -a» endif clean: -rm -f *.o *.ko .*.cmd .*.flags *.mod.c -include $(KDIR)/Rules.make
Чтобы приспособить этот файл под свои нужды, замените myname на имя вашего модуля. Сборка осуществляется командой make.
Добро пожаловать в мир хакеров Linux!
Для начала, создадим простейший модуль ядра, который будет регистрироваться в системе и сообщать об этом миру доступными ему средствами: «Hello world!». Это необходимый шаг: надо же уважать традиции! Кроме этого, он позволяет удостовериться в работоспособности инструментов (компилятора, компоновщика, ...), корректности make-файлов и правильности установки исходных текстов Linux. Кстати, корифеи от ядра настоятельно рекомендуют разрабатывать и отлаживать модули в текстовой консоли. Вызов printk (речь о котором пойдет ниже) не работает с графическими терминалами типа xterm, поэтому единственным способом понять, что происходит, остается просмотр файлов журнала, а это не всегда удобно. В общем, вооружайтесь люби-