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

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

> while (length && *Message_Ptr) {

>  /* Because the buffer is in the user data segment,

>  * not the kernel data segment, assignment wouldn't

>  * work. Instead, we have to use put_user which

>  * copies data from the kernel data segment to the

>  * user data segment. */

>  put_user(*(Message_Ptr++), buffer++);

>  length--;

>  bytes_read++;

> }

>#ifdef DEBUG

> printk("Read %d bytes, %d left\n", bytes_read, length);

>#endif

> /* Read functions are supposed to return the number

> * of bytes actually inserted into the buffer */

> return bytes_read;

>}


>/* This function is called when somebody tries to write into our device file. */

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

>static ssize_t device_write(struct file *file, const char *buffer, size_t length, loff_t *offset)

>#else

>static int device_write(struct inode *inode, struct file *file, const char *buffer, int length)

>#endif

>{

> int i;

>#ifdef DEBUG

> printk("device_write(%p,%s,%d)", file, buffer, length);

>#endif

> for(i=0; i

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

>  get_user(Message[i], buffer+i);

>#else

>  Message[i] = get_user(buffer+i);

>#endif

> Message_Ptr = Message;

> /* Again, return the number of input characters used */

> return i;

>}


>/* This function is called whenever a process tries to

>* do an ioctl on our device file. We get two extra

>* parameters (additional to the inode and file

>* structures, which all device functions get): the number

>* of the ioctl called and the parameter given to the ioctl function.

>*

>* If the ioctl is write or read/write (meaning output

>* is returned to the calling process), the ioctl call

>* returns the output of this function. */

>int device_ioctl(struct inode *inode, struct file *file,

> unsigned int ioctl_num, /* The number of the ioctl */

> unsigned long ioctl_param) /* The parameter to it */

>{

> int i;

> char *temp;

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

> char ch;

>#endif

> /* Switch according to the ioctl called */

> switch (ioctl_num) {

> case IOCTL_SET_MSG:

>  /* Receive a pointer to a message (in user space)

>  * and set that to be the device's message. */

>  /* Get the parameter given to ioctl by the process */

>  temp = (char*)ioctl_param;

>  /* Find the length of the message */

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

>  get_user(ch, temp);

>  for (i=0; ch && i

>#else

>  for (i=0; get_user(temp) && i

>#endif

>  /* Don't reinvent the wheel - call device_write */

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

>  device_write(file, (char*)ioctl_param, i, 0);

>#else

>  device_write(inode, file, (char*)ioctl_param, i);

>#endif

>  break;

> case IOCTL_GET_MSG:

>  /* Give the current message to the calling

>  * process - the parameter we got is a pointer, fill it. */

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

>  i = device_read(file, (char*)ioctl_param, 99, 0);

>#else

>  i = device_read(inode, file, (char*)ioctl_param, 99);

>#endif

>  /* Warning - we assume here the buffer length is

>  * 100. If it's less than that we might overflow

>  * the buffer, causing the process to core dump.

>  *

>  * The reason we only allow up to 99 characters is

>  * that the NULL which terminates the string also needs room. */

>  /* Put a zero at the end of the buffer, so it will be properly terminated */

>  put_user('\0', (char*)ioctl_param+i);

>  break;

> case IOCTL_GET_NTH_BYTE:

>  /* This ioctl is both input (ioctl_param) and

>  * output (the return value of this function) */

>  return Message[ioctl_param];

>  break;

> }

> return SUCCESS;

>}


>/* Module Declarations *************************** */

>/* This structure will hold the functions to be called

>* when a process does something to the device we

>* created. Since a pointer to this structure is kept in

>* the devices table, it can't be local to

>* init_module. NULL is for unimplemented functions. */

>struct file_operations Fops = {

> NULL, /* seek */

> device_read,

> device_write,

> NULL, /* readdir */

> NULL, /* select */

> device_ioctl, /* ioctl */

> NULL, /* mmap */

> device_open,

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

> NULL, /* flush */

>#endif

> device_release /* a.k.a. close */

>};


>/* Initialize the module - Register the character device */

>int init_module() {

> int ret_val;

> /* Register the character device (atleast try) */

> ret_val = module_register_chrdev(MAJOR_NUM, DEVICE_NAME, &Fops);

> /* Negative values signify an error */

> if (ret_val < 0) {

>  printk("%s failed with %d\n", "Sorry, registering the character device ", ret_val);

>  return ret_val;

> }

> printk("%s The major device number is %d.\n", "Registeration is a success", MAJOR_NUM);

> printk("If you want to talk to the device driver,\n");

> printk ("you'll have to create a device file. \n");

> printk ("We suggest you use:\n");

> printk ("mknod %s c %d 0\n", DEVICE_FILE_NAME, MAJOR_NUM);

> printk ("The device file name is important, because\n");

> printk ("the ioctl program assumes that's the\n");

> printk ("file you'll use.\n");

> return 0;

>}


>/* Cleanup - unregister the appropriate file from /proc */

>void cleanup_module() {

> int ret;

> /* Unregister the device */

> ret = module_unregister_chrdev(MAJOR_NUM, DEVICE_NAME);


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

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


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

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


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

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


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

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


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

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


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

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