(495) 925-0049, ITShop интернет-магазин 229-0436, Учебный Центр 925-0049
  Главная страница Карта сайта Контакты
Поиск
Вход
Регистрация
Рассылки сайта
 
 
 
 
 

Драйверы устройств

Источник: rus-linux
Anil Kumar Pugalia; Перевод: Н.Ромоданов

Часть 8: Специальные средства отображения ввода/вывода для аппаратных средств платформы x86

Оригинал: "Device Drivers, Part 8: Accessing x86-Specific I/O-Mapped Hardware"
Автор: Anil Kumar Pugalia
Дата публикации: July 1, 2011
Перевод: Н.Ромоданов
Дата перевода: июнь 2012 г.

В этой статье, которая является частью серии статей о драйверах устройств в Linux, продолжается обсуждение доступа к аппаратным средствам в Linux.

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

Специальные возможности доступа к аппаратным средствам на платформе x86

В отличие от большинства других архитектур, на платформе x86 есть дополнительный механизм доступа к аппаратным средствам - прямое отображение ввода/вывода. Это схема с прямой 16-битной адресацией, в которой для доступа не требуется использовать отображение в виртуальное пространство. Эти адреса называются адресами портов или портами. Поскольку это дополнительный механизм доступа, для него есть дополнительный набор инструкций x86 (на ассемблере/в машинном коде). И да, есть инструкции ввода inb, inw и inl для чтения через порты из устройств, отображающих ввод/вывод, соответственно 8-битовых байтов, 16-разрядных слов и 32-разрядных слов. Для вывода соответственно используются аналогичные инструкции outb, outw и outl. Их эквивалентами на языке C будут следующие функции/макросы (есть в заголовке <asm/io.h>):

u8 inb(unsigned long port);
u16 inw(unsigned long port);
u32 inl(unsigned long port);
void outb(u8 value, unsigned long port);
void outw(u16 value, unsigned long port);
void outl(u32 value, unsigned long port);

Главный вопрос, который может возникнуть, касается того, для каких устройств используется такое отображение ввода/вывода и какие будут адреса портов этих устройств. Ответ довольно прост. В соответствии со стандартом x86, все эти устройства и их отображения должны быть определены заранее. На рис.1 показана часть списка таких отображений, взятых из директория /proc/ioports. Если назвать лишь несколько устройств, то в этом списке есть устройство DMA, таймер и часы реального времени, а кроме того интерфейсы доступа через последовательный и параллельный порты и шину PCI.

Рис.1: Конкретные порты ввода/вывода на платформе x86

Простейшее: последовательный порт на платформе x86

Например, первый последовательный порт ввода/вывода всегда отображается в адреса с 0x3F8 по 0x3FF. Но что это отображение означает? Что нам с ним делать? Как это поможет нам использовать последовательный порт? Вот когда нам нужно обратиться к спецификациям на соответствующее устройство.

Управление последовательным портом осуществляется контроллером последовательного устройства, которое называется UART (Universal Asynchronous Receiver/Transmitter - Универсальный асинхронный приемник/передатчик) или, иногда, USART (Universal Synchronous/Asynchronous Receiver/Transmitter - Универсальный синхронный/асинхронный приемник/передатчик). На ПК обычно используемым устройством UART является устройство PC16550D. Спецификации для этого устройства [PDF] можно загрузить с сайта lddk.esrijan.com в составе самораспаковывающегося пакета [файл BIN] с набором документации по драйверам устройств для Linux.

Вообще говоря, где и как можно найти спецификации для таких устройств? Как правило, поиск в интернете с указанием соответствующего номера устройства должен привести вас к результату. Далее, а как можно узнать номер устройства? Просто ... взглянув на устройство. Если оно находится внутри компьютера, то откройте компьютер и посмотрите на устройство. Да, для того, чтобы писать драйвера устройств, вам, как минимум, придется это делать. Если все уже сделано, то заглянем в спецификации устройства PC16550D UART.

Авторы драйверов устройств должны разбираться в особенностях использования регистров устройства; это именно те регистры, которые им нужно программировать для использования устройства. На странице 14 спецификаций (она также показана на рис.2) приведена таблица для всех двенадцати 8-битных регистров, которые есть в устройстве UART PC16550D.

Рис.2: Регистры устройства UART PC16550D

Каждая из восьми строк таблицы соответствует определенному биту регистра. Кроме того, обратите внимание, что регистровые адреса начинаются с 0 и продолжается до 7. Интересно то, что в спецификациях всегда для регистров указываются смещения, которые нужно затем добавить к базовому адресу устройства для того, чтобы получить фактические адреса регистров.

Кто определяет базовый адрес и откуда его можно получить? Базовый адрес, если он, конечно, не является динамически настраиваемым как в случае с устройствами PCI, как правило, вполне конкретен для карты/платформы. В данном случае, например, для устройства последовательного порта на платформе x86 он задается архитектурой x86 - это именно то, откуда начинается адресация последовательного порта - 0x3F8.

Таким образом, смещения восьми регистров от 0 и до 7 точно отображаются в восемь адресов портов с 0x3F8 по 0x3FF. Таким образом, согласно описанию регистров, это фактические адреса для чтения или записи, через которые можно, для выполнения нужных операций с последовательным портом, читать и писать в соответствующие регистры последовательного порта.

Все смещения регистров последовательного порта и все битовые маски регистров определяются в заголовке <linux/serial_reg.h>. Так что вместо того, чтобы жестко кодировать значения, взятые из спецификаций, можно вместо этого воспользоваться соответствующими макросами. Эти макросы используются в коде, который приводится ниже; также используется следующее определение:

#define SERIAL_PORT_BASE 0x3F8

Операции с регистрами устройств:

В качестве итога изучения спецификаций PC16550D UART ниже приводится несколько примеров операций чтения и записи с регистрами последовательного порта.

Чтение и запись в "Line Control Register(LCR)":

u8 val;
 
val = inb(SERIAL_PORT_BASE + UART_LCR /* 3 */);
outb(val, SERIAL_PORT_BASE + UART_LCR /* 3 */);

Установка и сброс бита "Divisor Latch Access Bit (DLAB)" в LCR:

u8 val;
 
val = inb(SERIAL_PORT_BASE + UART_LCR /* 3 */);
 
/* Setting DLAB */
val /= UART_LCR_DLAB /* 0x80 */;
outb(val, SERIAL_PORT_BASE + UART_LCR /* 3 */);
 
/* Clearing DLAB */
val &= ~UART_LCR_DLAB /* 0x80 */;
outb(val, SERIAL_PORT_BASE + UART_LCR /* 3 */);

Чтение и запись в "Divisor Latch"

u8 dlab;
u16 val;
dlab = inb(SERIAL_PORT_BASE + UART_LCR);
dlab /= UART_LCR_DLAB; // Setting DLAB to access Divisor Latch
outb(dlab, SERIAL_PORT_BASE + UART_LCR);
 
val = inw(SERIAL_PORT_BASE + UART_DLL /* 0 */);
outw(val, SERIAL_PORT_BASE + UART_DLL /* 0 */);

Мигающий светодиод

Чтобы получить реальный опыт работы с низкоуровневым доступом к устройствам и драйверами устройств в Linux, лучше всего воспользоваться комплектом разработки драйверов устройств для Linux - Linux device driver kit (LDDK), который уже ранее упоминался. Но для того, чтобы просто попробовать низкоуровневый доступ, можно воспользоваться мигающим светодиодом, а именно, сделайте следующее:

Подключите светодиод (LED) через резистор 330 Ом между контактом 3 (Tx) и контактом 5 (Gnd) к разъему DB9 вашего компьютера.

Подавайте и отключайте сигнал в цепи передачи (Tx) с интервалом в 500 мс; для этого с помощью команды insmod blink_led.ko загрузите драйвер blink_led, а затем с помощью команды rmmod blink_led выгрузите драйвер.

Файл драйвера blink_led.ko можно создать из файла исходного кода blink_led.c; запустите для этого команду make и воспользуйтесь обычным для драйвера файлом Makefile. Ниже приводится полный текст файла blink_led.c:

#include <linux/module.h>
#include <linux/version.h>
#include <linux/types.h>
#include <linux/delay.h>
#include <asm/io.h>
 
#include <linux/serial_reg.h>
 
#define SERIAL_PORT_BASE 0x3F8
 
int __init init_module()
{
    int i;
    u8 data;
 
    data = inb(SERIAL_PORT_BASE + UART_LCR);
    for (i = 0; i < 5; i++)
    {
        /* Pulling the Tx line low */
        data /= UART_LCR_SBC;
        outb(data, SERIAL_PORT_BASE + UART_LCR);
        msleep(500);
        /* Defaulting the Tx line high */
        data &= ~UART_LCR_SBC;
        outb(data, SERIAL_PORT_BASE + UART_LCR);
        msleep(500);
    }
    return 0;
}
 
void __exit cleanup_module()
{
}
 
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Anil Kumar Pugalia ");
MODULE_DESCRIPTION("Blinking LED Hack");

Что дальше

Возможно, вы задавали вопрос, почему в этой статье нет ни слова о Светлане? Она проспала все занятия. Читайте следующую статью, если хотите узнать, почему она проспала.

Ссылки по теме


 Распечатать »
 Правила публикации »
  Написать редактору 
 Рекомендовать » Дата публикации: 15.06.2012 
 

Магазин программного обеспечения   WWW.ITSHOP.RU
Microsoft 365 Business Standard (corporate)
Microsoft Office 365 Персональный 32-bit/x64. 1 ПК/MAC + 1 Планшет + 1 Телефон. Все языки. Подписка на 1 год.
Microsoft 365 Apps for business (corporate)
Microsoft Windows Professional 10, Электронный ключ
Microsoft 365 Business Basic (corporate)
 
Другие предложения...
 
Курсы обучения   WWW.ITSHOP.RU
 
Другие предложения...
 
Магазин сертификационных экзаменов   WWW.ITSHOP.RU
 
Другие предложения...
 
3D Принтеры | 3D Печать   WWW.ITSHOP.RU
 
Другие предложения...
 
Новости по теме
 
Рассылки Subscribe.ru
Информационные технологии: CASE, RAD, ERP, OLAP
Безопасность компьютерных сетей и защита информации
Новости ITShop.ru - ПО, книги, документация, курсы обучения
CASE-технологии
Программирование на Microsoft Access
Мир OLAP и Business Intelligence: новости, статьи, обзоры
Программирование на Visual Basic/Visual Studio и ASP/ASP.NET
 
Статьи по теме
 
Новинки каталога Download
 
Исходники
 
Документация
 
 



    
rambler's top100 Rambler's Top100