Вход/Регистрация
Энциклопедия разработчика модулей ядра Linux
вернуться

Померанц Ори

Шрифт:

/* Deal with CONFIG_MODVERSIONS */

#if CONFIG_MODVERSIONS==1

#define MODVERSIONS

#include <linux/modversions.h>

#endif

/* For character devices */

#include <linux/fs.h> /* The character device definitions are here */

#include <linux/wrapper.h> /* A wrapper which does next to nothing at present, but may help for compatibility with future versions of Linux */

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

/* Conditional compilation. LINUX_VERSION_CODE is the code (as per KERNEL_VERSION) of this version. */

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

#include <asm/uaccess.h> /* for 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 from 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) {

 static int counter = 0;

#ifdef DEBUG

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

#endif

/* This is how you get the minor device number in case you have more than one physical device using the driver. */

 printk("Device: %d.%d\n", inode->i_rdev >> 8, inode->i_rdev & 0xFF);

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

 *

 * In the case of processes, the danger would be

 * that one process might have check Device_Open

 * and then be replaced by the schedualer by another

 * process which runs this function. Then, when the

 * first process was back on the CPU, it would assume

 * the device is still not open.

 *

 * However, Linux guarantees that a process won't be

 * replaced while it is running in kernel context.

 *

 * In the case of SMP, one CPU might increment

 * Device_Open while another CPU is here, right after

 * the check. However, in version 2.0 of the

 * kernel this is not a problem because there's a lock

 * to guarantee only one CPU will be kernel module at

 * the same time. This is bad in terms of

 * performance, so version 2.2 changed it.

 * Unfortunately, I don't have access to an SMP box

 * to check how it works with SMP. */

  • Читать дальше
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

Подпишитесь на рассылку: