В Linux есть функция трассировки вызовов. Я предлагаю вам проследить запрос ввода-вывода.
Предупреждение: следующее было написано мной, не зная истинных подробностей.
В основном вам нужно использовать PCI API для связи с дисковым устройством для настройки прямого доступа к памяти, потому что вы не хотите читать блоки диска (или кадры Ethernet) по одному байту за раз. Таким образом, вы сообщаете аппаратному обеспечению, что некоторая область памяти (начиная с адреса X и длиной N байтов) является областью DMA. Вы также настраиваете кэширование памяти, чтобы знать, что данные в этой области ОЗУ могут изменяться без записи ЦП в нее, поэтому даже если вы являетесь однопроцессором, они изменчивы.
Предположим, что аппаратное обеспечение поддерживает только одну транзакцию DMA одновременно. Затем вы передаете команды типа «прочитать 512-байтовый номер сектора X (т. Е. Байты X << 9 - ((X + 1) << 9) -1 диска)) и поместить его в область DMA. сделано, запустить прерывание ". Контроллер диска делает свое дело (у него есть процессор ARM и все остальное), через PCI соединяется с концентратором северного моста и через него с оперативной памятью, минуя процессор. Когда запись завершена (или с ошибками), прерывание срабатывает. Пока это происходит, вы ждете (ну, ядро запускает другие процессы, пока ваш процесс спит). Спустя миллионы циклов ЦП (10 мс - это вечность для чипа 2 ГГц), прерывание срабатывает. ОС уведомляется, что чтение было завершено. ОС может видеть данные в оперативной памяти. Затем он либо копирует его в память пользовательского процесса, либо находится на общей странице, и пользовательский процесс может прочитать его оттуда. Пользовательский процесс возобновляется (ну, ставится в очередь, готовая к запуску, и в конце концов запускается, когда планировщик чувствует себя так). </p>
Записывает работу путем копирования данных в пространство DMA и передачи команды «записать данные из области DMA в сектор номер X на диске и запустить прерывание по завершении». Затем диск может запустить прерывание по окончании записи или сразу после считывания данных из ОЗУ, и в этом случае fsync действительно не работает, а ваша база данных и файловая система повреждены из-за сбоя питания.
Кэш блоков ОС работает на целых страницах памяти объемом 4 КБ, поэтому он читает 8 секторов за раз, но идея та же. Новые диски имеют собственный API, который работает с 4KB секторами , но идея та же. USB отличается от PCI, но идея та же. Различное высокопроизводительное оборудование имеет продуманные API-интерфейсы для ускорения всего этого, имеет несколько транзакций в полете одновременно и различные средства управления их заказами.
Сетевые интерфейсы, которые разгружают TCP / IP, вероятно, имеют API вокруг пакетов вместо кадров Ethernet, поскольку сетевая карта понимает заголовок TCP / IP.
Блочные устройства, которые действительно являются сетевыми устройствами, где-то скрывают перевод (часть аппаратного обеспечения, часть встроенного программного обеспечения, часть программного обеспечения).
В Linux для моего оборудования, я думаю, это выглядит так:
Когда модуль sata_piix загружен , он сообщает ОС идентификаторы устройств PCI устройств, которые он поддерживает, и обратные вызовы, которые должна использовать ОС, все описаны в структуре. Общий код топологии PCI ОС обнаруживает устройство с идентификатором 8086: 27c0, ICH7 и находит его в таблице драйверов , поэтому ОС решает, что это правильный драйвер для данного оборудования. В этой таблице драйвер обнаружит, что он должен рассматривать это устройство как устройство SATA ICH6 , позже. Поскольку драйвер сообщает, что поддерживает устройство, ОС регистрирует устройство с драйвером.
Оттуда выделены области управления устройства и подготовлено . DMA настроен . Управление шиной PCI включено (это позволяет контроллеру самостоятельно инициировать передачу данных PCI в ОЗУ (когда у него есть данные) вместо ожидания, пока ЦП инициирует передачу) , Установлены обработчики прерываний .
Код является общим и поддерживает многие поколения оборудования в хронологическом порядке:
- PIO
- Single / Multi-word DMA
- UDMA
- SATA
- AHCI
Так что трудно читать.Трассировка сделает это намного проще.