RSDT/ru

From KolibriOS wiki
Jump to navigation Jump to search

RSDT (Root System Description Table) эта структура данных (таблица), используется в программном интерфейсе ACPI. Она содержит указатели на все другие таблицы системных дескрипторов (System Description Tables).

Обнаружение RSDT

Чтобы найти таблицу RSDT вы должны в первую очередь обнаружить таблицу RSDP и выполнить её проверку. Поле RsdtAddress (для ACPI версии < 2.0) или XsdtAddress (в противном случае) таблицы RSDP является указателем на соответствующую таблицу.

Проверка RSDT

Необходимо сложить все байты таблицы и сравнить результат с 0.

Структура

RSDT является основной таблицей системных дескрипторов ACPI. Тем не менее существует много других таблиц. Все таблицы можно поделить на две части. Одна (заголовок) является общей для всех таблиц, в то время как другая (данные) является индивидуальной для каждой таблицы. Структура заголовка: <source lang="c"> struct ACPISDTHeader {

 char Signature[4];
 DWORD Length;
 BYTE Revision;
 BYTE Checksum;
 char OEMID[6];
 char OEMTableID[8];
 DWORD OEMRevision;
 DWORD CreatorID;
 DWORD CreatorRevision;

} </source>

В случае, когда используется поле RsdtAddress, структура всей таблицы имеет вид: <source lang="c"> struct RSDT {

 struct ACPISDTHeader h;
 DWORD PointerToOtherSDT[(h.Length - sizeof(h)) / 4];

} </source> В случае, когда используется поле XsdtAddress, структура всей таблицы имеет вид: <source lang="c"> struct XSDT {

 struct ACPISDTHeader h;
 QWORD PointerToOtherSDT[(h.Length - sizeof(h)) / 8];

} </source>

Как использовать

Предположим, что нужно найти таблицу FADT. Так как FADT, является таблицей системных дескрипторов, она имеет заголовок с общей для всех таблиц структурой. Поле Signature должно содержать сигнатуру "FACP". Можно воспользоваться следующим кодом: <source lang="c"> void *findFACP(void *RootSDT) {

 RSDT *rsdt = (RSDT *) RootSDT;
 int n = (rsdt->h.Length - sizeof(rsdt->h)) / 4;
 for (int i = 0; i < n; i++) {
   ACPISDTHeader *h = (ACPISDTHeader *) rsdt->PointerToOtherSDT[i];
   if (!strncmp(h->Signature, "FACP"))
     return (void *) h;
 }
 return NULL;

} </source>

Следующий шаг

Теперь вам необходимо разпарсить все таблицы, на которые указывает RSDP. (Скорее всего вам понадобится только FADT и SSDT)