Ответ 1
В более старых архитектурах доступ к периферии осуществлялся через отдельный механизм доступа к памяти с помощью специальных инструкций ввода-вывода. На x86 были (и все еще есть!) Инструкции "in" и "out" для передачи байтов между CPU и периферией. Периферийным устройствам были предоставлены адреса, например 0x80 для клавиатуры. Упрощая многое, выполнение "в 0x80" будет читать байт от контроллера клавиатуры до регистра процессора "AL".
В современных архитектурах периферийные устройства получают доступ к памяти аналогично памяти: через сопоставленные адреса памяти на шине. Вы не должны думать о шине как способе доступа к памяти. Это больше способ адресовать отдельные периферийные устройства, память которых (RAM/DDR) - это всего лишь один тип. Например, у вас может быть 2 ГБ ОЗУ по адресам 0x00000000..0x7fffffff. После этого у вас может быть видеокарта размером 0x80000000..0x80001fff. Контроллер шины (PCIe или что-то еще) знает, какие диапазоны адресов идут на периферию.
Память обычно отличается тем, что ее можно кэшировать, поэтому отдельные чтения/записи в память, как правило, не переходят непосредственно на отдельные чтения/записи в чипы RAM. Периферийные устройства отмечены как специальные - доступ к ЦП должен выходить на периферию точно так же, как указано в вашей программе.
Язык, с которым вы разговариваете с периферийными устройствами, в значительной степени зависит от устройства. Основная тема заключается в том, что периферийное устройство отображается где-то в памяти (например, 0x80000000 для нескольких KB, как указано выше), с отдельным битом состояния и действиями, управляемыми разными словами (обычно 32 или 64 бит). Мифический пример последовательного порта на 0x80000000:
- Напишите 32-битное слово "A" на 0x80000000, выставляя символ "A" в своем выходном FIFO.
- Введите 32-битное слово 0x1 в 0x80000004, которое сообщает последовательному порту отправить свою очередь.
Опять же, полностью составлен только для примера, но реальный последовательный порт (uart) не так уж и отличается.
Проблема в том, что на самом деле вы не увидите какой-либо из вышеперечисленных макетов памяти в современной ОС из-за виртуальной памяти. Адреса, указанные выше, будут называться "адреса физической памяти" (или адреса шины) - фактические адреса, которые выходят на шину. Процессор вместо этого видит адреса виртуальной памяти. Отдельные периферийные устройства должны быть отображены в виртуальное адресное пространство. Это довольно сложно объяснить и, вероятно, лучше всего в другом вопросе, но дело в том, что вряд ли вы получите доступ к периферии своим фактическим физическим адресом в современной ОС.