Интернет

Чем отличается интерфейс PCI Express от PCI? PCI-контроллер, что это.

Чем отличается интерфейс PCI Express от PCI? PCI-контроллер, что это.

WiFi модули и другие подобные устройства. Разработку данной шины начала компания Intel в 2002 году. Сейчас разработку новых версий данной шины занимается некоммерческая организация PCI Special Interest Group.

На данный момент шина PCI Express полностью заменила такие устаревшие шины как AGP, PCI и PCI-X. Шина PCI Express размещается в нижней части материнской платы в горизонтальном положении.

PCI Express это шина, которая была разработана на основе шины PCI. Основные отличия между PCI Express и PCI лежат на физическом уровне. В то время как PCI использует общую шину, в PCI Express используется топология типа звезда. Каждое устройство подключается к общему коммутатору отдельным соединением.

Программная модель PCI Express во многом повторяет модель PCI. Поэтому большинство существующих PCI контроллеров могут быть легко доработаны для использования шины PCI Express.

Слоты PCI Express и PCI на материнской плате

Кроме этого, шина PCI Express поддерживает такие новые возможности как:

  • Горячее подключение устройств;
  • Гарантированная скорость обмена данными;
  • Управление потреблением энергии;
  • Контроль целостности передаваемой информации;

Как работает шина PCI Express

Для подключения устройств шина PCI Express использует двунаправленное последовательное соединение. При этом такое соединение может иметь одну (x1) или несколько (x2, x4, x8, x12, x16 и x32) отдельных линий. Чем больше таких линий используется, тем большую скорость передачи данных может обеспечить шина PCI Express. В зависимости от количества поддерживаемых линий размер сорта на материнской плате будет отличаться. Существуют слоты с одной (x1), четырьмя (x4) и шестнадцатью (x16) линиями.

Наглядная демонстрация размеров слота PCI Express

При этом любое PCI Express устройство может работать в любом слоте, если слот имеет такое же или большее количество линий. Это позволяет установить PCI Express карту с разъемом x1 в слот x16 на материнской плате.

Пропускная способность PCI Express зависит от количества линий и версии шины.

В одну/обе стороны в Гбит/с

Количество линий

PCIe 1.0 2/4 4/8 8/16 16/32 24/48 32/64 64/128
PCIe 2.0 4/8 8/16 16/32 32/64 48/96 64/128 128/256
PCIe 3.0 8/16 16/32 32/64 64/128 96/192 128/256 256/512
PCIe 4.0 16/32 32/64 64/128 128/256 192/384 256/512 512/1024

Примеры PCI Express устройств

В первую очередь PCI Express используется для подключения дискретных видеокарт. С момента появления данной шины абсолютно все видеокарты используют именно ее.

Видеокарта GIGABYTE GeForce GTX 770

Однако это далеко не все что умеет шина PCI Express. Ее используют производители других комплектующих.

Звуковая карта SUS Xonar DX

SSD накопитель OCZ Z-Drive R4 Enterprise

MEMR# (MRDC#) - чтение памяти в любой области до 16 Мбайт.

OWS# (SRDY#, NOWS#, ENDXFR) - укорочение текущего цикла по инициативе адресованного устройства.

MASTER* (MASTER 16#) - запрос от устройства, использующего 16-битный канал DMA на управление шиной. При получении подтверждения DACK Bus-Master может захватить шину.

В шине EISA на дополнительных контактах слотов (недоступных картам ISA) располагается расширение шин данных и адреса до 32 бит, а также набор сигналов, обеспечивающих передачу данных в синхронном режиме с возможностью пакетных циклов.

6.2. Шина PCI

PCI (Peripheral Component Interconnect) local bus - шина соединения периферийных компонентов является основной шиной расширения современных компьютеров. Она разрабатывалась в расчете на Pentium, но хорошо сочеталась и с процессорами 486. Сейчас PCI является четко стандартизованной высокопроизводительной и надежной шиной расширения. Первая версия PCI 1.0 появилась в 1992 г. В PCI 2.0 (1993 г.) введена спецификация коннекторов и карт расширения. В версии 2.1 (1995 г.) введена частота 66 МГц. В настоящее время действует спецификация PCI 2.2 (декабрь 1998 г.), которая уточняет и разъясняет некоторые положения предшествующей версии 2.1. Данное описание основано на тексте стандарта «PCI Local Bus Specification. Revision 2.2» от 17.12.1998, опубликованного организацией PCI SIG (Special Interest Group).

Поначалу шина PCI вводилась как пристройка (mezzanine bus) к системам с основной шиной ISA, став позже центральной шиной: она соединяется с системной шиной процессора высокопроизводительным мостом («северным»), входящим в состав чипсета системной платы. Остальные шины расширения ввода-вывода (ISA/EISA или МСА), а также локальная ISA-подобная шина X-BUS и интерфейс LPC, к которым подключаются микросхемы системной платы (ROM BIOS, контроллеры прерываний, клавиатуры, DMA, портов СОМ и LPT, НГМД и прочие «мелочи»), подключаются к шине PCI через «южный» мост. В современных системных платах с хабовой архитектурой шину PCI Отодвинули на периферию, не ущемляя ее в мощности канала связи с процессором и памятью, но и не нагружая транзитным трафиком устройств других шин.

Шина является синхронной - фиксация всех сигналов выполняется по положительному перепаду (срронту) сигнала CLK. Номинальной частотой синхронизации считается 33 МГц, при необходимости частота может быть понижена (на машинах с процессором 486 использовали частоты 20-33 МГц). Во многих случаях частоту успешно разгоняют и до 41,5 МГц (половина типовой частоты системной шины 83 МГц). Начиная с версии 2.1 допускается повышение частоты до 66 МГц при согласии всех устройств на шине. Номинальная разрядность шины данных - 32 бита, спецификация определяет и расширение разрядности до 64 бит. При частоте шины 33 МГц теоретическая пропускная способность достигает 132 Мбайт/с для 32-битной шины и 264 Мбайт/с для 64-битной; при частоте синхронизации 66 МГц - 264 и 528 соответственно. Однако эти пиковые значения достигаются лишь во время передачи пакета, а из-за протокольных накладных расходов реальная средняя суммарная.(для всех задат-чиков) пропускная способность шины оказывается ниже.

С устройствами PCI процессор может взаимодействовать командами обращения к памяти и портам ввода-вывода, адресованным к областям, выделенным каждому такому устройству при конфигурировании. Устройства могут вырабатывать запросы маскируемых и немаскируемых прерываний. Понятия каналов DMA для шины PCI нет, но агент шины может сам выступать в роли зада"тчика, поддерживая высокопроизводительный обмен с памятью (и не только), не занимая ресурсов

центрального процессора. Таким образом, к примеру, может быть реализован обмен в режиме DMA с устройствами AT А, подключенными к контролеру PCI IDE (см. п. 9.2.1). Спецификация PCI требует от устройств способности перемещать все занимаемые ресурсы в пределах доступного пространства адресации. Это позволяет обеспечивать бесконфликтное распределение ресурсов для многих устройств (функций). Для управления устройствами рекомендуется вместо портов ввода-вывода по возможности использовать ячейки памяти. Одно и то же функциональное устройство может быть сконфигурировано по-разному, отображая свои регистры либо на пространство памяти, либо на пространство ввода-вывода. Драйвер может определить текущую настройку, прочитав содержимое регистра базового адреса устройства, - признаком пространства ввода-вывода будет единичное значение бита 0 (см. п. 6.2.12). Драйвер также может определить и номер запроса прерывания, который используется устройством.

6.2.1. Адресация устройств PCI

Для шины PCI принята иерархия понятий адресации: шина, устройство, функция. Эти понятия фигурируют только при обращении к регистрам конфигурационного пространства (см. п. 6.2.12). К этим регистрам обращаются на этапе конфигурирования - переучета обнаруженных устройств, выделения им непересекающихся ресурсов (областей памяти и пространства ввода-вывода) и назначения номеров аппаратных прерываний. При дальнейшей регулярной работе устройства будут отзываться на обращения по назначенным им адресам памяти и ввода-вывода, доведенным до сведения связанных с ними модулей ПО. Эти адреса принимаются с шины AD в начале каждой транзакции. Для доступа к конфигурационному пространству используются отдельные линии IDSEL Устройством PCI называется микросхема или карта расширения, подключенная к одной из шин PCI и использующая для идентификации выделенную ей линию IDSEL, принадлежащую этой шине. Устройство может быть многофункциональным, то есть состоять из множества (от 1 до 8) так называемых функций. Каждой функции отводится конфигурационное пространство в 256 байт (см. п. 6.2.12). Многофункциональные устройства должны отзываться только на конфигурационные циклы с номерами функций, для которых имеется конфигурационное пространство. При этом функция с номером 0 должна быть обязательно, номера остальных функций назначаются разработчиком устройства произвольно (в диапазоне 1-7). Простые (однофункциональные) устройства, в зависимости от реализации, могут отзываться либо на любой номер функции, либо только на номер функции 0.

Шина PCI - набор сигнальных линий (см. п. 6.2.2), непосредственно соединяющих интерфейсные выводы группы устройств (слотов, микросхем на системной плате). В системе может присутствовать несколько шин PCI, соединенных мостами PCI (см. п. 6,2.10). Мосты электрически отделяют интерфейсные сигналы одной шины от другой, соединяя их логически; главный мост соединяет главную шину с ядром системы (процессором и памятью). Каждая шина имеет свой номер шины (PCI bus number). Шины нумеруются последовательно; главная шина имеет нулевой номер.

С точки зрения конфигурирования, минимальной адресуемой единицей этой иерархии является функция; ее полный адрес состоит из трех частей: номера шины, номера устройства и номера функции. Короткая форма идентификации вида РСЮ:1:2 (например, в сообщениях ОС Unix) означает функцию 2 устройства 1, подключенного к главной (0) шине PCI.

В шине PCI принята географическая адресация - номер устройства определяется местом его подключения. Номер устройства (device number или dev) определяется той линией шины AD, к которой подключена линия сигнала IDSEL данного слота: kADU - devO(MOCT),AD12-devl,...AD31 -dev20. В соседних слотах PCI, как правило,

задействуются соседние номера устройств; их нумерация определяется разработчиком системной платы (или пассивной кросс-платы в промышленных компьютерах). Часто для

слотов используются убывающие номера устройств, начиная с 20. Группы соседних слотов могут подключаться к разным шинам; на каждой шине PCI нумерация устройств независимая (могут быть и устройства с совпадающими номерами dev, но разными номерами шин). Устройства PCI, интегрированные в системную плату, используют ту же систему адресации. Их номера «запаяны намертво», в то время как адреса карт расширения можно изменять перестановкой их в разные слоты. Одна карта PCI может содержать только одно устройство шины, к которой она подключается, поскольку ей в слоте выделяется только одна линия IDSEL Если на карте размещают несколько устройств (например, 4-портовая карта Ethernet), то на ней приходится устанавливать мост

Тоже устройство PCI, к которому и обращаются по линии IDSEL, выделенной данной карте. Этот мост организует на карте дополнительную шину PCI, к которой можно подключить множество устройств.

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

Разобраться с нумерацией устройств и полученных ими линий прерываний на конкретной плате можно просто: устанавливать одну карту PCI поочередно в каждый из слотов (отключая питание) и смотреть на сообщения об обнаруженных устройствах PCI, выводимых на дисплей в конце теста POST. В этих сообщениях будут фигурировать и устройства PCI, установленные непосредственно на системной плате (и не отключенные параметрами CMOS Setup).

Но чтобы не было иллюзий простоты и прозрачности, отметим, что «особо умные» операционные системы (Windows) не довольствуются полученными назначениями номеров прерывании и изменяют их по своему усмотрению (что никак не может отразиться на разделяемости линий).

6.2.2. Протокол шины PCI

В каждой транзакции (обмене по шине) участвуют два устройства - инициатор (initiator) обмена, он же ведущее (master) устройство, и целевое (target) устройство (ЦУ), оно жеведомое (slave). Шина PCI все транзакции трактует как пакетные: каждая транзакция начинается фазой адреса, за которой может следовать одна или несколько фаз данных. Состав и назначение интерфейсных сигналов шины приведены в табл. 6.11.

Таблица 6.11. Сигналы шины PCI

Назначение

Address/Data - мультиплексированная шина адреса/данных. В начале транзакции передается адрес, в

последующихтактах-данные

Command/Byte Enable - команда/разрешение обращения к байтам. Команда, определяющаятипочередного

циклашины, задаетсячетырехбитнымкодомв фазе адреса

Кадр. Введением сигнала отмечается начало транзакции (фаза адреса), снятие сигналауказываетнато, что

последующийциклпередачиданныхявляетсяпоследнимвтранзакции

Device Select - устройство выбрано (ответ ЦУ на адресованную к нему транзакцию)

Initiator Ready - готовность ведущего устройства к обмену данными

Target Ready - готовность ЦУ к обмену данными

ЗапросЦУкведущемуустройствунаостановкутекущейтранзакции

Сигнал захвата шины для обеспечения целостного выполнения операции. Используетсямостом, которомудля

выполненияоднойоперациитребуетсявыполнить несколько транзакций PCI

Request - запрос от ведущего устройства на захват шины

Grant - предоставление ведущему устройству управления шиной

Parity - общий бит паритета для линий AD и С/ВЕ#

PRSNT# Present - индикаторы присутствия платы, кодирующие запрос потребляемой мощности. Накарте расширенияоднаилидвелиниииндикаторовсоединяютсяс шиной GND, что воспринимается системной платой

Reset - сброс всех регистров в начальное состояние

Initialization Device Select - выбор устройства в циклах конфигурационного

считыванияизаписи

System Error - системная ошибка. Ошибка паритета адреса данных в специальном циклеилииная

катастрофическаяошибка, обнаруженнаяустройством. Активизируется любым устройством PCI и вызывает

Request 64 bit - запрос на 64-битный обмен. Сигнал вводится 64-битным

инициатором, по времени он совпадает с сигналом FRAME*. Во время окончания сброса (сигналом

RST*) сигнализирует 64-битному устройству о том, что оно подключенок64-битнойшине. Если64-б.итное

устройствонеобнаружитэтогосигнала, онодолжнопереконфигурироватьсяна32-битныйрежим, отключив

буферныесхемыстаршихбайтов

Подтверждение64-битногообмена. Сигналвводится64-битнымЦУ, опознавшимсвой адрес, одновременно с

DEVSEL*. Отсутствие этого подтверждения заставитинициаторвыполнятьобменс32-битнойразрядностью

INTA#, INTB*, Interrupt А, В, С, D - линии запросов прерывания, чувствительность к уровню, INTC#, INTD* активный уровень - низкий, что допускает разделяемость (совместное использование)линий

Назначение

Snoop Done - сигнал завершенности цикла слежения для текущей транзакции. Низкийуровеньуказываетна

незавершенностьцикласлежениязакогерентностьюпамятиикэша. Необязательныйсигнал, используетсятолько

устройствамишиныскэшируемойпамятью

Snoop Backoff - попадание текущего обращения к памяти абонента шины

вмодифицированнуюстрокукэша. Необязательныйсигнал, используетсятолькоабонентамишиныскэшируемой

памятьюприалгоритмеобратнойзаписи

Test Clock - синхронизация тестового интерфейса JTAG

Test Data Input - входные данные тестового интерфейса JTAG

Test Data Output - выходные данные тестового интерфейса JTAG

Test Mode Select - выбор режима для тестового интерфейса JTAG

Test Logic Reset - сброс тестовой логики

В каждый момент времени шиной может управлять только одно ведущее устройство, получившее на это право от арбитра. Каждое ведущее устройство имеет пару сигналов - REQ# для запроса на управление шиной и GNT* для подтверждения предоставления управления шиной. Устройство может начинать транзакцию (устанавливать сигнал FRAME*) только при активном полученном сигнале GNT*. Снятие сигнала GNT* не позволяет устройству начать следующую транзакцию, а при определенных условиях (см. ниже) заставляет прекратить начатую транзакцию. Арбитражем запросов на использование шины занимается специальный узел, входящий в чипсет системной платы. Схема приоритетов (фиксированный, циклический, комбинированный) определяется программированием арбитра.

Для адреса и данных используются общие мультиплексированные линии AD. Четыре мультиплексированные линии С/ВЕ обеспечивают кодирование команд в фазе адреса и разрешения байт в фазе данных. В начале транзакции ведущее устройство активизирует сигнал FRAME*, по шине AD передает целевой адрес, а по линиям С/ВЕ# - информацию

о типе транзакции (команде). Адресованное ЦУ отзывается сигналом DEVSEL*. Ведущее устройство указывает на свою готовность к обмену данными сигналом IRDY#, эта готовность может быть выставлена и раньше получения DEVSEL*. Когда к обмену данными будет готово и ЦУ, оно установит сигнал TRDY*. Данные по шине AD передаются только при одновременном наличии сигналов IRDY# и TRDY*. С помощью этих сигналов ведущее устройство и ЦУ согласуют свои скорости, вводя такты ожидания. На рис. 6.7 приведена временная диаграмма обмена, в которой и ведущее устройство, и ЦУ вводят такты ожидания. Если бы они оба ввели сигналы готовности в конце фазы адреса и не снимали их до конца обмена, то в каждом такте после фазы адреса передавались бы по 32 бита данных, что обеспечило бы выход на предельную производительность обмена.

Количество фаз данных в пакете явно не указывается, но перед последней фазой данных ведущее устройство при введенном сигнале IRDY* снимает сигнал FRAME*. В одиночных транзакциях сигнал FRAME* активен лишь один такт. Если устройство не поддерживает пакетные транзакции в ведомом режиме, то оно должно потребовать прекращения пакетной транзакции во время первой фазы данных (введя сигнал STOP* одновременно с TRDY*). В ответ на это ведущее устройство завершит данную транзакцию и продолжит обмен последующей транзакцией с новым значением адреса. После последней фазы данных ведущее устройство снимает сигнал IRDY#, и шина переходит в состояние покоя (PCI Idle) - оба сигнала FRAME* и IRDY# находятся в пассивном состоянии. Инициатор может начать следующую транзакцию и без такта покоя, введя FRAME* одновременно со снятием IRDY#. Такие быстрые смежные транзакции (Fast Back-to-Back) могут быть обращены как к одному, так и к разным ЦУ. Первый тип поддерживается всеми устройствами PCI, выступающими в роли ЦУ. На поддержку второго типа (она необязательна) указывает бит 7 регистра состояния (см. п. 6.2.12). Инициатору разрешают (если он умеет) использовать быстрые смежные транзакции с разными устройствами (битом 9 регистра команд), только если все агенты шины допускают быстрые обращения.

Рис. 6.7. Цикл обмена на шине PCI

Шина позволяет уменьшить мощность (ток), потребляемую устройствами, ценой снижения производительности, применяя пошаговое переключение линий AD и PAR (address/data stepping). Здесь возможны два варианта.

катора действительной информации (FRAME# в фазе адреса, IRDY# или TRDY# вфазеданных). Заэтинесколькотактовсигналы«доползут» дотребуемогозначения применьшем токе.

Дискретный шаг (diskrete stepping) - нормальные формирователи срабатывают не все сразу, а группами (например, побайтно), в каждом такте по группе. При этом снижаются броски тока, поскольку одновременно переключается меньше формирователей.

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

В качестве минимальной базы для работы с PCI-устройствами будем использовать ядро, поддерживающее спецификацию Multiboot. Так удастся избежать необходимости писать собственный загрузочный сектор и загрузчик (loader). Кроме того, этот вопрос и так отлично освещен в интернете. В качестве загрузчика будет выступать GRUB. Грузиться мы будем с флэшки, так как с нее удобно загружать и виртуальную, и реальную машину. В качестве виртуальной машины будем использовать QEMU. В качестве реальной машины должна выступать машина с обычным BIOS-ом (не UEFI), поддерживающим загрузку с USB-HDD (обычно присутствует опция Legacy USB support). Для работы понадобятся Ubuntu Linux со следующими программами: expect, qemu, grub (их можно легко установить при помощи команды sudo apt-get install). Используемый gcc должен компилировать 32х битный код.

Рассмотрим первый шаг – создание ядра, поддерживающего спецификацию Multiboot. В случае использования GRUB-а в качестве загрузчика ядро будет создаваться из 3-х файлов:
Kernel.c – основной файл с кодом нашей программы и процедурой main();
Loader.s – содержит заголовок мультизагрузчика для GRUB;
Linker.ld – скрипт компоновщика ld, в котором в частности указывается, по какому адресу будет располагаться ядро.

Содержимое Linker.ld:

ENTRY (loader) SECTIONS { . = 0x00100000; .text ALIGN (0x1000) : { *(.text) } .rodata ALIGN (0x1000) : { *(.rodata*) } .data ALIGN (0x1000) : { *(.data) } .bss: { sbss = .; *(COMMON) *(.bss) ebss = .; } }

Скрипт компоновщика указывает, как слинковать уже скомпилированные объектные файлы. В первой строчке указано, что точкой входа в нашем ядре будет адрес с меткой «loader». Далее в скрипте указано, что начиная с адреса 0x00100000 (1Мб) будет располагаться секция text. Секции rodata, data и bss выровнены по 0x1000 (4Кб) и располагаются после секции text.

Содержимое Loader.s:

Global loader .set FLAGS, 0x0 .set MAGIC, 0x1BADB002 .set CHECKSUM, -(MAGIC + FLAGS) .align 4 .long MAGIC .long FLAGS .long CHECKSUM # reserve initial kernel stack space .set STACKSIZE, 0x4000 .lcomm stack, STACKSIZE .comm mbd, 4 .comm magic, 4 loader: movl $(stack + STACKSIZE), %esp movl %eax, magic movl %ebx, mbd call kmain cli hang: hlt jmp hang

GRUB после загрузки образа ядра с диска ищет в первых 8Кб загруженного образа сигнатуру 0x1BADB002. Сигнатура является первым полем заголовка мультизагрузки. Сам заголовок выглядит следующим образом:

Offset Type Field Name Note
0 u32 magic required
4 u32 flags required
8 u32 checksum required
12 u32 header_addr if flags is set
16 u32 load_addr if flags is set
20 u32 load_end_addr if flags is set
24 u32 bss_end_addr if flags is set
28 u32 entry_addr if flags is set
32 u32 mode_type if flags is set
36 u32 width if flags is set
40 u32 height if flags is set
44 u32 depth if flags is set

Заголовок должен включать в себя минимум 3 поля – magic, flag, checksum. Поле magic является сигнатурой и, как уже было сказано выше, всегда равно 0x1BADB002. Поле flag содержит дополнительные требования к состоянию машины на момент передачи управления ОС. В зависимости от значения этого поля может меняться набор полей в структуре Multiboot Information. Указатель на структуру Multiboot Information содержит регистр EBX в момент передачи управления загружаемому ядру. В нашем случае поле flag имеет значение 0, и заголовок мультизагрузки состоит только из 3-ех полей.

На момент передачи управления ядру процессор работает в защищенном режиме с выключенной страничной адресацией. Обработка прерываний от устройств отключена. GRUB не формирует стек для загружаемого ядра, и это первое что должна сделать операционная система. В нашем случае под стек выделяется 16Кб. Последней выполненной ассемблерной инструкцией будет инструкция call kmain, которая передает управление коду на C, а именно функции void kmain(void).

Содержимое kernel.c:

#include "printf.h" #include "screen.h" void kmain(void) { clear_screen(); printf(" -- Kernel started! -- n"); }

Пока здесь нет ничего интересного. С точки зрения загрузки в нем не должно присутствовать ничего специфичного, только точка входа для кода на С. Для вывода на экран была добавлена реализация функции printf, найденная на просторах Интернета, и несколько функций для работы с видеопамятью, таких как putchar, clear_screen.

Для сборки ядра будет использоваться следующий простой makefile:

CC = gcc CFLAGS = -Wall -nostdlib -fno-builtin -nostartfiles -nodefaultlibs LD = ld OBJFILES = loader.o printf.o screen.o pci.o kernel.o start: all cp ./kernel.bin ./flash/boot/grub/ expect ./grub_install.exp qemu /dev/sdb all: kernel.bin .s.o: as -o $@ $< .c.o: $(CC) $(CFLAGS) -o $@ -c $< kernel.bin: $(OBJFILES) $(LD) -T linker.ld -o $@ $^ clean: rm $(OBJFILES) kernel.bin

Теперь у нас есть ядро, которое можно загрузить. Пора проверить, что оно действительно загружается. Установим GRUB на флешку и скажем ему загружать наше ядро при старте. Для этого нужно выполнить следующие шаги:

1. Создать раздел на флешке, отформатировать его в файловую систему, поддерживаемую GRUB-ом (в нашем случае это файловая система FAT32). Мы воспользовались утилитой Disk Utility из комплекта Ubuntu, которая позволила создать раздел:

2. Примонтировать флешку и создать каталог /boot/grub/. Скопировать в него из /usr/lib файлы stage1, stage2, fat_stage1_5. Создать текстовый файл menu.lst в директории /boot/grub/ и записать в него

Timeout 5 default 0 title start_kernel root (hd0,0) kernel /boot/grub/kernel.bin

Для установки GRUB-а на флешку используется expect-скрипт в файле grub_install.exp. Его содержимое:

Log_user 0 spawn grub expect "grub> " send "root (hd1,0)r" expect "grub> " send "setup (hd1)r" expect "grub> " send "quitr" exit 0

В конкретном случае возможны другие номера дисков и названия устройств. В конечном итоге компиляция и запуск виртуальной машины должны выполняться командой make start. Эта команда из makefile выполнит установку GRUB на флэшку с использованием скрипта grub_install.exp, а затем запустит виртуальную машину QEMU с нашей программой. Поскольку все загружается с реальной флэшки, то с нее можно загрузить не только виртуальную машину QEMU, но и реальный компьютер.

Запущенная виртуальная машина QEMU с нашей программой выглядит следующим образом:


Теперь займемся основной задачей – перечисление всех имеющихся на компьютере PCI-устройств. PCI – это основная шина с устройствами на компьютере. В нее помимо обычных устройств, которые вставляются во всем известные слоты на материнской плате, также подключены устройства, вшитые в саму материнскую плату (так называемые On-board devices), а так же ряд контроллеров (например, USB) и мостов на другие шины (например, PCI-ISA bridge). Таким образом, PCI – это основная шина на компьютере, с которой начинается опрос всех его устройств.

С каждым PCI-устройством связана структура из 256-ти байт (PCI Configuration Space), в которой располагаются его настройки. Конфигурация устройства в конечном итоге сводится к записи и чтению данных из этой структуры. Для всех PCI-устройств чтение и запись данных происходит через 2 порта ввода-вывода:
0xcf8 - конфигурационный порт, в который записывается PCI-адрес;
0xcfc - порт данных, через который происходит чтение и запись данных по указанному в конфигурационном порту PCI-адресу.

При чтении данных из PCI Configuration Space можно получить информацию об устройстве, а записывая туда данные устройство можно настроить.

PCI-адрес представляет собой следующую 32-х битную структуру:

Бит 31 Биты 30 – 24 Биты 23 – 16 Биты 15 – 11 Биты 10 – 8 Биты 7 – 2 Биты 1 – 0
Всегда 1 Зарезервировано Номер шины Номер устройства Номер функции Номер регистра Всегда 0

Номер шины вместе с номером устройства идентифицируют физическое устройство на компьютере. Физическое устройство может включать в себя несколько логических, которые идентифицируются номером функции (например, плата видео захвата с контроллером Wi-Fi будет иметь, по крайней мере, две функции).

PCI Configuration Space условно разбита на регистры по 4 байта. Номер регистра, к которому происходит обращение, хранится с 2го по 7й биты в 32-х битном PCI-адресе. Поля структуры PCI Configuration Space, описывающей PCI-устройство, зависят от его типа. Но для всех типов устройств первые 4 регистра структуры содержат следующие поля:

Номер регистра Биты 31 - 24 Биты 23 – 16 Биты 15 – 8 Биты 7 – 0
0 Device ID Vendor ID
1 Status Command
2 Class code Subclass Prog IF Revision ID
3 BIST Header type Latency Timer Cache Line Size

Class code – описывает тип (класс) устройства с точки зрения функций, которые устройство выполняет (сетевой адаптер, видео карта и т.д.);
Vendor ID – идентификатор производителя устройства (у каждого производителя устройств в мире есть один или несколько таких уникальных идентификаторов). Эти номера выдаются международной организацией PCI SIG;
Device ID уникальный идентификатор устройства (уникален для заданного Vendor ID). Их нумерацию определяет сам производитель.

По полям DeviceID (сокращенно DEV) и VendorID (сокращенно VEN) определяется драйвер, соответствующий этому устройству. Иногда для этого используется еще дополнительный идентификатор RevisionID (сокращенно REV). Другими словами, Windows, обнаруживая новое устройство в компьютере, использует числа VEN, DEV и REV для поиска соответствующих им драйверов у себя на диске или в Интернете, используя сервера Microsoft. Также эти номера можно встретить в диспетчере устройств:

Рассмотрим код, реализующий самый простой способ получения списка имеющихся на компьютере PCI-устройств:

Int ReadPCIDevHeader(u32 bus, u32 dev, u32 func, PCIDevHeader *p_pciDevice) { int i; if (p_pciDevice == 0) return 1; for (i = 0; i < sizeof(p_pciDevice->header)/sizeof(p_pciDevice->header); i++) ReadConfig32(bus, dev, func, i, &p_pciDevice->header[i]); if (p_pciDevice->option.vendorID == 0x0000 || p_pciDevice->option.vendorID == 0xffff || p_pciDevice->option.deviceID == 0xffff) return 1; return 0; } void kmain(void) { int bus; int dev; clear_screen(); printf(" -- Kernel started! -- n"); for (bus = 0; bus < PCI_MAX_BUSES; bus++) for (dev = 0; dev < PCI_MAX_DEVICES; dev++) { u32 func = 0; PCIDevHeader pci_device; if (ReadPCIDevHeader(bus, dev, func, &pci_device)) continue; PrintPCIDevHeader(bus, dev, func, &pci_device); if (pci_device.option.headerType & PCI_HEADERTYPE_MULTIFUNC) { for (func = 1; func < PCI_MAX_FUNCTIONS; func++) { if (ReadPCIDevHeader(bus, dev, func, &pci_device)) continue; PrintPCIDevHeader(bus, dev, func, &pci_device); } } } }

В данном коде происходит полный перебор номеров шин и номеров устройств в адресе, по которому происходит чтение. Если поле Header type содержит флаг PCI_HEADERTYPE_MULTIFUNC, то данное физическое устройство реализует несколько логических устройств, и при поиске PCI-устройств в адресе, записываемом в конфигурационный порт, нужно перебирать номер функции. Если VendorID имеет некорректное значение, то устройства с таким номером на этой шине нет. На Qemu этот код выводит следующий результат:


0x8086 – это VendorID оборудования компании Intel. DeviceID, равный 0x7000, соответствует устройству PIIX3 PCI-to-ISA Bridge. Загрузимся с получившейся флешки в VmWare Workstation 9.0. Список PCI-устройств оказался значительно длиннее и выглядит следующим образом:


Вот так выглядит поиск PCI-устройств в системе. Это действие выполняется во всех современных операционных системах, работающих на компьютерах IBM PC. Следующим шагом в работе операционной системы является поиск драйверов и конфигурирование найденных устройств, а это уже происходит уникальным образом для каждого устройства в отдельности.

Здравствуйте. Хотим рассказать как решить проблему при установке драйвера PCI контроллера.
Недавно к нам принесли ноутбук Asus, после установки драйвера выяснилось, что драйвер работает не корректно.

Необходимо было установить операционную систему Windows 7. После установки операционной системы были установлены последовательно, как положено с перезагрузкой, все драйвера. Драйвера устанавливались с официального сайта asus.

Обнаружилась такая проблема. Драйвер для устройства Trusted Execution Engine Interface работает не корректно. Обновление драйвера результатов не дало, все осталось без изменений.

Было решено удалить драйвера для этого устройства полностью. После удаления и перезагрузки система показала, что нет драйверов для — PCI контроллер шифрации/дешифрации.

Коротко PCI контроллер это универсальная шина для подключения различных устройств, стали искать решение проблемы в этом направлении.

Как решить эту проблему:

Первый вариант решения этой проблемы, выставить в настройках BIOS в разделе Advanced параметр OS Selection, операционную систему, ту которую устанавливаете, в нашем случае windows 7. Если этой опции нет то необходимо обновить BIOS.

Затем там же в BIOS функцию Boot Option UEFI ставим Disabled, отключаем ее. Теперь устанавливаем операционную систему с вашего носителя DVD или USB не имеет значения.

После установки операционной системы устанавливаем драйвера кроме драйвера Intel(R) Trusted Execution Engine Interface.

Затем устанавливаем обновление для Windows 7 — Kernel-Mode Driver Framework version 1.11 update for Windows 7, это обновление еще имеет имя KB2685811 в центре обновлений.

Скачать его можно с официального сайта microsoft
или у нас с яндекс диска, версия для х64 , версия для х86 .

Затем устанавливаем драйвера для Intel(R) Trusted Execution Engine Interface или PCI устройство шифрации/дешифрации.

Как сделали мы.

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

Приветствую вас, дорогие читатели.

После переустановки операционной системы некоторые пользователи (в том числе и я) встречались с ситуацией, когда в «Диспетчере устройств» показывает, что необходим драйвер PCI-устройства для Windows 7. И чаще всего такое встречается на ноутбуках, хоть и на ПК также можно увидеть проблему. В некоторых случаях можно заметить определенные негативные моменты в работе устройства, проявляющиеся скоростью обработки информации, «паузами», а иногда и «остановками». В статье я постараюсь рассказать, как справиться с недугом.

Сразу нужно сказать, что PCI-устройство не имеет конкретного назначения. Эта маркировка указывает на шину, с помощью которой подключается компонент. Само по себе оборудование может иметь разное назначение – модем, сетевая карта, cardreader и многое другое. А потому решить так сразу проблему не всегда удастся.

Установка определенных драйверов ( )

Узнать, какой именно драйвер необходимо искать, можно несколькими способами. Для начала необходимо попасть в «», а затем в «».

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

Так, например, необходимо найти драйвер PCI-контроллер Simple Communications. Это означает, что на компьютере не найдено специального интерфейса между хостом и микропрограммой Management Engine от Intel.

Еще одной популярной проблемой считается наличие ошибки в Nvidia nforce PCI Management. Она указывает на недуг с программным обеспечением чипсета. Для решения нужно зайти на официальный сайт и найти соответствующее ПО. Важно разыскать именно подходящее обеспечение (должны совпадать версии Windows, разрядность и даже выпуск БИОСа). Далее вы можете просто обновить драйвер или установить, если его не было. Иногда требуется перезагрузка.

Поиск по ID ( )

Иногда случаются ситуации, когда вы не можете так сразу определить, какое именно оборудование не работает. Кроме того, не помогает маркировка в «Диспетчере устройств ». Что же делать в таком случае?

Чтобы для Windows 7 найти нужное программное обеспечение, нужно проделать несколько движений:


Кстати, этот способ подходит и для устройств PCI Windows XP. Лучше всего искать на проверенных сайтах, чтобы ненароком себе не установить вирус.