Pull to refresh

Как написать свой первый Linux device driver. Часть 3

Reading time3 min
Views17K
Добрый вечер, хаброчитатели!

В предыдущих статьях (один, два) мы определили понятие символьного устройства и написали простейший пример символьного драйвера. Последняя часть посвещена проверки его работоспособности. На Хабре уже есть примеры как можно протестировать драйвер, например: тык.

Я попытаюсь рассмотреть данный вопрос чуть подробнее, надеюсь, вам понравится.



Пожалуйста, если у вас есть мысли, что можно добавить/исправить, то жду ваших комментариев или писем в ЛС, спасибо.

Сборка модуля ядра


Для того чтобы собрать наш модуль, нам понадобится написать маленький Makefile. Прочитать, что такое Makefile, можно тут: раз, два, три. Также я писал как-то пример Makefile для студентов, можно посомтреть тут: клик.

Если вкратце, то Makefile это набор инструкций для программы make, а make это утилита, автоматизирующая процесс преобразования файлов из одной формы в другую. После беглого знакомства с Makefile можно посмотреть на код:

Makefile:

obj-m += fake.o

all:
        make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules

clean:
        make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean

Давайте взгялнем на команду:

make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules

Она начинается со смены каталога (в моем случае на: /lib/modules/4.4.0-93-generic/build), в этом каталоге находятся исходные тексты ядра, а также Makefile, который утилита make прочитает. Переменная M, позволяет указать где находится наш проект и вернуться назад, по указанному в нем пути. Т.е на самом деле мы используем другой Makefile, чтобы выполнить сборку нашего модуля.

Пишем в командной строке make и получаем вывод:

make -C /lib/modules/4.4.0-93-generic/build M=/home/alexey/Desktop/drivers/character modules
make[1]: Entering directory '/usr/src/linux-headers-4.4.0-93-generic'
  CC [M]  /home/alexey/Desktop/drivers/character/fake.o
  Building modules, stage 2.
  MODPOST 1 modules
  CC      /home/alexey/Desktop/drivers/character/fake.mod.o
  LD [M]  /home/alexey/Desktop/drivers/character/fake.ko
make[1]: Leaving directory '/usr/src/linux-headers-4.4.0-93-generic'

После сборки, на выходе получился скомпилированный модуль fake.ko. Его то мы и будем загружать с помощью команды insmod.

Далее нужно выполнить следующую последовательность действий:

  1. Загрузить модуль в ядро
    Выполнить: sudo insmod fake.ko
  2. Проверить, с помощью команды dmesg, ожидаемый вывод модуля
    Пример: scull: register device major = 243 minor = 0
  3. Создать файл нашего устройства в файловой системе
    Пример: sudo mknod /dev/scull c 243 0
  4. Изменить права доступа
    Пример: sudo chmod 777 /dev/scull

Осталось дело за малым, пишем маленькую программу, которая позволит просто считывать/записывать данные.

#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>

#define DEVICE "/dev/scull"
#define BUFF_SIZE 100

int main()
{
        int fd;
        char ch, write_buf[BUFF_SIZE], read_buf[BUFF_SIZE];

        fd = open(DEVICE, O_RDWR);

        if (!fd)
                return -1;

        printf("r - read, w - write\n");
        scanf("%c", &ch);

        switch (ch) {
                case 'w':
                        printf("enter data: ");
                        scanf(" %[^\n]", write_buf);
                        write(fd, write_buf, sizeof(write_buf));
                        break;
                case 'r':
                        read(fd, read_buf, sizeof(read_buf));
                        printf("scull: %s\n", read_buf);
                        break;
        }

        return 0;
}

Проверка работоспособности:

  1. Компилируем: gcc test.c -o test
  2. Вызываем исполняемый файл: ./test
  3. Записываем в устройство: Hello world!
  4. Повторно вызываем исполняемый файл: ./test
  5. Считываем данные: scull: Hello world!

На этом тестирование простого символьного драйвера завершено, теперь вы можете придумать новый функционал, реализовать и выполнить проерку самостоятельно:)

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

P.S. Если вы нашли неточности в статье, буду ждать ваших сообщений, спасибо!
Tags:
Hubs:
Total votes 32: ↑30 and ↓2+28
Comments2

Articles