Там, где задействована операционная система, программы не общаются с драйверами устройств, по крайней мере, напрямую. Программы обращаются к абстракциям, которые, без их ведома, в конечном итоге в конечном итоге обращаются к драйверам устройств посредством одного или нескольких уровней абстракции.
Я собираюсь пропустить сложности современных операционных систем и использовать в качестве примера микрокомпьютерную операционную систему CP / M , разработанную 45 лет назад. CP / M был слоеный пирог с тремя слоями:
Программа. Верхний слой - это программа, которая делает что-то полезное (обработка текста, игра Space Invaders), выполняя вычисления и ввод / вывод. Допустим, в какой-то момент программа хочет отобразить букву «А», чтобы пользователь мог ее увидеть. CP / M предоставляет абстракцию, известную как консоль , где пользователь, взаимодействующий с программой, должен искать. Обычный способ отправить персонажа - несколько инструкций по сборке:
LD C,2 ; Load 2 into register C
LD E,65 ; Load the ASCII code for 'A' into register E
CALL 5 ; Call CP/M's routine for getting things done
(Если вы не знакомы с ними, регистры можно рассматривать как переменные, которые живут в процессоре.) Мы расскажем о том, что такое магические числа 2
и 5
о чем идет речь, через минуту. Вывод здесь заключается в том, что все, что знает программа, это то, что есть консоль и есть способ записи в нее. Он не знает и не заботится ни о чем, кроме этого. Это первая из двух абстракций, которые CP / M использует для ввода / вывода.
БДОС . Адрес, который 5
вызывает программа, является точкой входа для следующего уровня, Базовой Дисковой Операционной Системы или BDOS . BDOS предоставляет целый ряд пронумерованных функций , которые похожи на заказ по номеру из меню ресторана. Вы говорите, что хотите вывод на консоль, загружая C
регистр с номером функции ( 2
для вывода на консоль) и E
регистр с символом, который нужно отправить. Вывод на консоль - очень простая операция, и BDOS на самом деле не имеет с ней ничего общего, кроме вызова следующего уровня.
BIOS. BIOS, или Basic Input / Output System - это уровень, на котором живет весь аппаратный код. В современных системах это будет считаться набором драйверов устройств. Как и BDOS, BIOS обеспечивает вызовы для стандартного набора очень примитивных операций, которые BDOS использует для своей деятельности. Одна из этих операций называетсяCONOUT
, который заботится о том, чтобы получить символ, который программа просила записать двумя слоями выше, на любое аппаратное обеспечение, которое это делает. (В отличие от ПК, в то время вещи не были однородными. У всех систем были разные способы сделать это.) Вывод на консоль - это простой проход для BDOS, но выполнение чего-то более сложного, такого как создание файла на диске, может потребовать многих BIOS вызывает манипулирование носителем. Опять же, поскольку BIOS имеет стандартный абстрактный интерфейс, BDOS всегда знает, как получить то, что хочет, и ему все равно, как это делает BIOS.
Вы, наверное, удивляетесь, почему вместо одной есть две абстракции (программа в BDOS и BDOS в BIOS). Ответ заключается в том, что CP / M и его BDOS могут предоставляться производителям компьютеров в двоичном виде, они будут писать собственный BIOS с драйверами устройств для своего оборудования, соединять их вместе и отправлять как ОС для своих систем. Это было большим делом, потому что BDOS поддерживалась одной организацией и, следовательно, всегда была известной величиной для пользовательских программ, что позволяло запускать одни и те же приложения на очень широком (на тот момент) разнообразном оборудовании. Вот почему существуют операционные системы, и мы не просто пишем программы, которые напрямую работают с оборудованием .
Все, что я здесь описал, относится и к современным операционным системам. Unix, например, абстрагирует все как файлы. Это дает программирует одинаковый набор системных вызовов ( open()
, write()
, close()
и т.д.) , чтобы сообщить , является ли это диск или последовательный порт. Набор решений и абстракций намного сложнее, но все же в конечном итоге он сводится к выбору того, какой код драйвера устройства должен быть запущен на нижнем уровне для выполнения операции.