RSDT/ru

From KolibriOS wiki
Revision as of 14:50, 24 June 2010 by Asper (talk | contribs) (New page)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
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. Тем не менее существует много других таблиц. Все таблицы можно поделить на две части. Одна (заголовок) является общей для всех таблиц, в то время как другая (данные) является индивидуальной для каждой таблицы. Структура заголовка:

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

В случае, когда используется поле RsdtAddress, структура всей таблицы имеет вид:

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

В случае, когда используется поле XsdtAddress, структура всей таблицы имеет вид:

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

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

Предположим, что нужно найти таблицу FADT. Так как FADT, является таблицей системных дескрипторов, она имеет заголовок с общей для всех таблиц структурой. Поле Signature должно содержать сигнатуру "FACP". Можно воспользоваться следующим кодом:

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;
}

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

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