Энциклопедия разработчика модулей ядра Linux - [10]

Шрифт
Интервал

, выполнять оба действия или ни одно из них. Функция ioctl вызывается с тремя параметрами: описатель файла соответствующий файлу устройства, ioctl номер, и параметра, который имеет тип long, так что Вы можете использовать приведение, чтобы передать что-нибудь.[5]

Ioctl номер кодирует главный номер устройства, тип ioctl команды и тип параметра. Этот ioctl номер обычно создается макрообращением (_IO, _IOR, _IOW или _IOWR: в зависимости от типа) в файле заголовка. Этот файл заголовка должен быть присоединен командой #include программой, которая использует ioctl и модулем (так что они могут генерировать соответствующие ioctl). В примере ниже, файл заголовка chardev.h и программа, которая использует это ioctl.c.

Если Вы хотите использовать ioctl в ваших собственных модулях, самое лучшее получить официальное ioctl назначение, так, если Вы случайно получаете ioctl кого-то другого вы будете знать, что что-то неправильно. Для большего количества информации, проконсультируйтесь в файле `Documentation/ioctl-number.txt' дерева исходников ядра.

chardev.c 

>/* chardev.c

>*

>* Create an input/output character device

>*/

>/* Copyright (C) 1998-99 by Ori Pomerantz */


>/* The necessary header files */

>/* Standard in kernel modules */

>#include /* We're doing kernel work */

>#include /* Specifically, a module */


>/* Deal with CONFIG_MODVERSIONS */

>#if CONFIG_MODVERSIONS==1

>#define MODVERSIONS

>#include

>#endif


>/* For character devices */

>/* The character device definitions are here */

>#include


>/* A wrapper which does next to nothing at

>* at present, but may help for compatibility

>* with future versions of Linux */

>#include


>/* Our own ioctl numbers */

>#include "chardev.h"


>/* In 2.2.3 /usr/include/linux/version.h includes a

>* macro for this, but 2.0.35 doesn't - so I add it

>* here if necessary. */

>#ifndef KERNEL_VERSION

>#define KERNEL_VERSION(a,b,c) ((a)*65536+(b)*256+(c))

>#endif


>#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)

>#include /* for get_user and put_user */

>#endif


>#define SUCCESS 0


>/* Device Declarations ******************************** */

>/* The name for our device, as it will appear in /proc/devices */

>#define DEVICE_NAME "char_dev"


>/* The maximum length of the message for the device */

>#define BUF_LEN 80


>/* Is the device open right now? Used to prevent concurent access into the same device */

>static int Device_Open = 0;


>/* The message the device will give when asked */

>static char Message[BUF_LEN];


>/* How far did the process reading the message get?

>* Useful if the message is larger than the size of the

>* buffer we get to fill in device_read. */

>static char *Message_Ptr;


>/* This function is called whenever a process attempts to open the device file */

>static int device_open(struct inode *inode, struct file *file) {

>#ifdef DEBUG

> printk("device_open(%p)\n", file);

>#endif

> /* We don't want to talk to two processes at the  same time */

> if (Device_Open) return -EBUSY;

> /* If this was a process, we would have had to be

> * more careful here, because one process might have

> * checked Device_Open right before the other one

> * tried to increment it. However, we're in the

> * kernel, so we're protected against context switches.

> *

> * This is NOT the right attitude to take, because we

> * might be running on an SMP box, but we'll deal with

> * SMP in a later chapter. */

> Device_Open++;

> /* Initialize the message */

> Message_Ptr = Message;

> MOD_INC_USE_COUNT;

> return SUCCESS;

>}


>/* This function is called when a process closes the

>* device file. It doesn't have a return value because

>* it cannot fail. Regardless of what else happens, you

>* should always be able to close a device (in 2.0, a 2.2

>* device file could be impossible to close). */

>#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)

>static int device_release(struct inode *inode, struct file *file)

>#else

>static void device_release(struct inode *inode, struct file *file)

>#endif

>{

>#ifdef DEBUG

> printk("device_release(%p,%p)\n", inode, file);

>#endif

> /* We're now ready for our next caller */

> Device_Open--;

> MOD_DEC_USE_COUNT;

>#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)

> return 0;

>#endif

>}


>/* This function is called whenever a process which

>* has already opened the device file attempts to read from it. */

>#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)

>static ssize_t device_read(

> struct file *file,

> char *buffer, /* The buffer to fill with the data */

> size_t length, /* The length of the buffer */

> loff_t *offset) /* offset to the file */

>#else

>static int device_read(

> struct inode *inode, struct file *file,

> char *buffer, /* The buffer to fill with the data */

> int length) /* The length of the buffer (mustn't write beyond that!) */

>#endif

>{

> /* Number of bytes actually written to the buffer */

> int bytes_read = 0;

>#ifdef DEBUG

> printk("device_read(%p,%p,%d)\n", file, buffer, length);

>#endif

> /* If we're at the end of the message, return 0 (which signifies end of file) */

> if (*Message_Ptr == 0) return 0;

> /* Actually put the data into the buffer */


Рекомендуем почитать
Графика DirectX в Delphi

В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.


Вторая жизнь старых компьютеров

Сейчас во многих школах, институтах и других учебных заведениях можно встретить компьютеры старого парка, уже отслужившие свое как морально, так и физически. На таких компьютерах можно изучать разве что Dos, что далеко от реалий сегодняшнего дня. К тому же у большинства, как правило, жесткий диск уже в нерабочем состоянии. Но и выбросить жалко, а новых никто не дает. Различные спонсоры, меценаты, бывает, подарят компьютер (один) и радуются, как дети. Спасибо, конечно, большое, но проблемы, как вы понимаете, этот компьютер в общем не решает, даже наоборот, усугубляет, работать на старых уже как-то не хочется, теперь просто есть с чем сравнивать.


DirectX 8. Начинаем работу с DirectX Graphics

В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.


Симуляция частичной специализации

В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.


Обработка событий в С++

В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.


Питон — модули, пакеты, классы, экземпляры

Python - объектно-ориентированный язык сверхвысокого уровня. Python, в отличии от Java, не требует исключительно объектной ориентированности, но классы в Python так просто изучить и так удобно использовать, что даже новые и неискушенные пользователи быстро переходят на ОО-подход.