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

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

> /* If there's an error, report it */

> if (ret < 0) printk("Error in module_unregister_chrdev: %d\n", ret);

>}

chardev.h 

>/* chardev.h - the header file with the ioctl definitions.

>*

>* The declarations here have to be in a header file,

>* because they need to be known both to the kernel

>* module (in chardev.c) and the process calling ioctl (ioctl.c)

>*/

>#ifndef CHARDEV_H

>#define CHARDEV_H #


>include

>/* The major device number. We can't rely on dynamic

>* registration any more, because ioctls need to know it. */

>#define MAJOR_NUM 100


>/* Set the message of the device driver */

>#define IOCTL_SET_MSG _IOR(MAJOR_NUM, 0, char *)

>/* _IOR means that we're creating an ioctl command

>* number for passing information from a user process

>* to the kernel module.

>*

>* The first arguments, MAJOR_NUM, is the major device

>* number we're using.

>*

>* The second argument is the number of the command

>* (there could be several with different meanings).

>*

>* The third argument is the type we want to get from

>* the process to the kernel. */


>/* Get the message of the device driver */

>#define IOCTL_GET_MSG _IOR(MAJOR_NUM, 1, char *)

>/* This IOCTL is used for output, to get the message

>* of the device driver. However, we still need the

>* buffer to place the message in to be input,

>* as it is allocated by the process. */


>/* Get the n'th byte of the message */

>#define IOCTL_GET_NTH_BYTE _IOWR(MAJOR_NUM, 2, int)

>/* The IOCTL is used for both input and output. It

>* receives from the user a number, n, and returns Message[n]. */


>/* The name of the device file */

>#define DEVICE_FILE_NAME "char_dev"

>#endif  

ioctl.c 

>/* ioctl.c - the process to use ioctl's to control the

>* kernel module

>*

>* Until now we could have used cat for input and

>* output. But now we need to do ioctl's, which require

>* writing our own process. */

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


>/* device specifics, such as ioctl numbers and the major device file. */

>#include "chardev.h"

>#include /* open */

>#include /* exit */

>#include /* ioctl */


>/* Functions for the ioctl calls */

>ioctl_set_msg(int file_desc, char *message) {

> int ret_val;

> ret_val = ioctl(file_desc, IOCTL_SET_MSG, message);

> if (ret_val < 0) {

>  printf("ioctl_set_msg failed:%d\n", ret_val);

>  exit(-1);

> }

>}


>ioctl_get_msg(int file_desc) {

> int ret_val;

> char message[100];

> /* Warning - this is dangerous because we don't tell

> * the kernel how far it's allowed to write, so it

> * might overflow the buffer. In a real production

> * program, we would have used two ioctls - one to tell

> * the kernel the buffer length and another to give

> * it the buffer to fill */

> ret_val = ioctl(file_desc, IOCTL_GET_MSG, message);

> if (ret_val < 0) {

>  printf("ioctl_get_msg failed:%d\n", ret_val);

>  exit(-1);

> }

> printf("get_msg message:%s\n", message);

>}


>ioctl_get_nth_byte(int file_desc) {

> int i;

> char c;

> printf("get_nth_byte message:");

> i = 0;

> while (c != 0) {

>  c = ioctl(file_desc, IOCTL_GET_NTH_BYTE, i++);

>  if (c < 0) {

>   printf("ioctl_get_nth_byte failed at the %d'th byte:\n", i);

>   exit(-1);

>  }

>  putchar(c);

> }

> putchar('\n');

>}


>/* Main - Call the ioctl functions */

>main() {

> int file_desc, ret_val;

> char *msg = "Message passed by ioctl\n";

> file_desc = open(DEVICE_FILE_NAME, 0);

> if (file_desc < 0) {

>  printf("Can't open device file: %s\n", DEVICE_FILE_NAME);

>  exit(-1);

> }

> ioctl_get_nth_byte(file_desc);

> ioctl_get_msg(file_desc);

> ioctl_set_msg(file_desc, msg);

> close(file_desc);

>}

Загрузочные параметры

Во многих из предыдущих примеров, мы жестко задавали какие-либо параметры в модуле. Это идет против правил Unix и Linux, философия которых такова, что программа должна быть гибкой, чтобы пользователь мог ее настраивать.

Способ сообщить программе или модулю что-либо до запуска это параметры командной строки. В случае ядерных модулей, мы не получаем argc и argv. Вместо этого, мы получаем кое-что лучше. Мы можем определять глобальные переменные в модуле, и insmod заполнит их для нас.

В этом ядерном модуле мы определяем две таких переменных: str1 и str2. Все, что Вы должны делать это скомпилировать модуль и затем выполнить insmod str1=xxx str2=yyy. При вызове init_module str1 укажет на строку `xxx' и str2 на строку `yyy'.

В версии 2.0 не имеется никакого контроля соответствия типов аргументов[6]. Если первый символ str1 или str2 является цифрой, ядро заполнит переменную значением целого числа, а не указателем на строку. В реальной ситуации Вы должны проверять это.

С другой стороны, в версии 2.2 Вы используете макрокоманду MACRO_PARM , чтобы сообщить insmod, что Вы ожидаете параметры, их имена и их типы. Это решает проблему типа и позволяет модулям получать строки, которые начинаются с цифры.

param.c

>/* param.c

>*

>* Receive command line parameters at module installation

>*/

>/* 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 */


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

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


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

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


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

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


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

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


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

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


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

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