Читать «Linux: Полное руководство» онлайн - страница 402
Денис Николаевич Колисниченко
#define DEV_NAME "device"
// Порты ввода-вывода нашего устройства
#define PORT_START 0x2000 #define PORT_QTY 10
// Память нашего устройства
#define MEM_START 0x20000000
#define MEM_QTY 0x20
// Номер прерывания для нашего устройства
#define IRQ_NUM 9
MODULE_DESCRIPTION("Linux kernel module");
// Старший номер файла устройства
static int Major;
// Структура file_operations - пока пустая,
//но вскоре мы ее напишем
struct file_operations FO;
// Обработчик прерывания
void irq_handler(int irq, void *dev_id,
struct pt_regs *regs) {
return;
}
int init_module() {
// Регистрируем устройство
printk("My module: starting...\n");
Major = register_chrdev(0, DEV_NAME, &F0);
if (Major < 0) {
// Устройство не зарегистрировано
printk("My module: registration failed\n");
return Major;
}
printk("My module: device registered, major number = %d\n",
Major);
// Резервирование портов ввода-вывода
printk("My module: allocating io ports\n");
if (check_region(PORT_START, PORT_QTY)) {
printk("My module; allocation io ports failed\n");
return -EBUSY;
}
request_region(PORT_START, PORT_QTY, DEV_NAME);
printk("My module: io ports allocated\n");
// Резервирование памяти
if (check_mem_region(MEM_START, MEM_QTY)) {
printk("My module: memory allocation failed\n");
release_region(PORT_START, PORT_QTY);
return -EBUSY;
}
request_mem_region(MEM_START, MEM_QTY, DEV_NAME);
printk("My module: memory allocated\n");
// Резервирование прерывания
if (request_irq(IRQ_NUM, irq_handler, 0, DEV_NAME, NULL)) {
printk("My module: IRQ allocation failed\n");
release_mem_region(MEM_START, MEM_QTY);
release_region(PORT_START, PQRT_QTY);
return -EBUSY;
}
printk("My module: IRQ allocated\n");
return 0;
}
void cleanup_module() {
// Освобождаем порты ввода-вывода
release_region(PORT_START, PORT_QTY);
printk("My module; release io ports\n");
// Освобождаем память
release_mem_region(MEM_START, MEM_QTY);
printk("My module: release memory\n");
// Освобождаем прерывание
free_irq(IRQ_NUM, NULL);
printk("My module: release irq\n");
// Отменяем регистрацию устройства
if (unregister_chrdev(Major, DEV_NAME) < 0){
printk("My module: cannot to unregister device\n");
}
printk("My module: device unregistered\n");
return;
}
При загрузке модуля вы увидите следующее сообщение:
My module: device registered, major number = 255
Конечно, кроме этого сообщения будут и другие, но нас они не интересуют. Почему именно это сообщение так важно для нас? В первой части сообщения говорится, что наше устройство успешно зарегистрировано, а во второй сообщается старший номер устройства, который мы будем использовать для создания устройств /dev/device0 и /dev/device1.
Вы не забыли, что нам еще нужно создать два устройства типа device, чтобы программы могли работать с ними? Перейдите в каталог /dev
и от имени суперпользователя выполните команды:
# mknod device с 255 0
# mknod device с 255 1
Здесь 255 — это старший номер устройства (у вас он будет другим), 0 и 1 — младшие номера устройств. После выполнения данных команд будут созданы два файла устройств — /dev/device0
и /dev/device1
.