Любопытство вне абстракций: как выполняется байт-код? как работают драйверы устройств? - PullRequest
8 голосов
/ 17 мая 2010

Все, что я видел на * nix, было набором абстракций от аппаратного обеспечения, но мне любопытно, как работает аппаратное обеспечение.
Я запрограммировал на ассемблере, но это всего лишь набор абстракций.

Как процессор понимает коды операций сборки (как байт-код)?
Как работают драйверы устройств (с объяснением на более низком уровне (абстракции))?

Ответы [ 4 ]

3 голосов
/ 22 мая 2010

Драйверы устройств образуют интерфейс между API-интерфейсом устройства операционной системы и реальными аппаратными регистрами.

Модель API устройства linux является продолжением более широкой концепции linux, согласно которой все является файлом и что приложение может выполнить все, что ему нужно, с помощью open (), read (), write (), ioctl (), и закрыть () интерфейс. Под капотом есть процедура install (), но ОС решает, когда ее вызвать.

Другая сторона медали аппаратная. Процессор осуществляет доступ к регистрам устройства либо с помощью специальных инструкций ввода / вывода, либо с помощью обычных обращений к памяти в специальных местах памяти, которые подключены к оборудованию. Хотя аппаратные регистры могут действовать как память, они могут делать то, что не может память. Довольно часто запись в один из регистров устройства может изменять значения некоторых других его регистров и, в сущности, может изменяться или изменяться в результате электрической активности в подключенном оборудовании.

Драйверы устройств устраняют этот пробел. Поскольку возможности для типов устройств практически не ограничены, трудно обобщить, как отображаются функции, за исключением нескольких пунктов. Процедура install () запускается во время запуска системы, настраивает регистры для правильной работы, обычно это включает настройку службы обработки прерываний и обработку; подпрограмма open () дает приложению логическое соединение с устройством; обычно делается попытка заставить read () и write () перемещать данные каким-либо разумным способом, хотя иногда вы видите, что они реализованы как no-ops; и настройки устройства «на лету» обрабатываются через ioctl (). И, конечно же, основная задача close () - отменить работу open (), уделяя особое внимание освобождению любых системных ресурсов, захваченных open ().

Ну, во всяком случае, это ориентированный на Linux. Модель Windows, по крайней мере та, с которой я знаком (вероятно, датирована), имеет тенденцию предлагать библиотеки вызовов функций для конкретных устройств.

2 голосов
/ 22 мая 2010

«Искусство сборки» - хорошая, но отчасти устаревшая книга с объяснениями практически обо всем аппаратном и низком уровне. Вы должны прочитать его.

Он легально доступен онлайн и в печатной форме.

Книга, онлайн

На Амазонке

РЕДАКТИРОВАТЬ: Commenter Samoz упоминает новое издание, так что теперь, вероятно, оно в курсе!

2 голосов
/ 17 мая 2010

Устройства имеют «прерывание», которое сигнализирует о том, что они хотят внимания процессора.

Драйверы устройств имеют «подпрограмму обработки прерываний» - код, который выполняется при возникновении прерывания на этом устройстве.

Драйверы устройств затем считывают или записывают данные в низкоуровневой форме, которая сопоставляется с устройством - обычно либо символы, либо блоки данных. Более высокие уровни драйвера устройства управляют упаковкой, распаковкой, буферизацией и преобразованием данных более низкого уровня в данные более высокого уровня, например, строки текстовых символов.

Довольно просто по своей сути, но очень быстро усложняется, когда вы добавляете несколько устройств, нескольких пользователей, отслеживает состояние для обоих и множество других абстракций, таких как файловая система, поверх базового блочно-ориентированного устройства I / вывода.

1 голос
/ 17 мая 2010

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

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

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

Драйверы ядра Linux

Обратите внимание, что большая часть этого написана на C, а не на ассемблере. Не существует строгого требования использовать язык ассемблера для написания драйверов устройств, при условии, что у вас есть доступные инструкции для взаимодействия с оборудованием (что верно для C, но может не соответствовать некоторым языкам более высокого уровня).

...