Теоретический вопрос про доступ к железу из юзермода

Тема в разделе "WASM.OS.DEVEL", создана пользователем ormoulu, 14 авг 2022.

  1. Ahimov

    Ahimov Active Member

    Публикаций:
    0
    Регистрация:
    14 окт 2024
    Сообщения:
    719
    Entropy,

    Это нужно изучать acpi-spec.

    Часть ядра, которая выполняет выключение вот.
     

    Вложения:

    • power.pdf
      Размер файла:
      778,8 КБ
      Просмотров:
      28
    • ntos_36.txt
      Размер файла:
      1,1 МБ
      Просмотров:
      26
  2. Marylin

    Marylin Active Member

    Публикаций:
    0
    Регистрация:
    17 фев 2023
    Сообщения:
    371
    Имхо копать в сторону драйвера acpi бесполезно - там такой клубок, что концов не найдёшь. Если интересуют детали софт-отключения машины, лучше смотри в сторону чипсета мат.платы, т.к. acpi это встроенный в pch аппаратный контролер, а драйвер ос просто управляет им. Вот немного инфы, чтобы влиться в тему:

    1. Скачай pdf на свой чипсет (см. aida, speccy, hwinfo), и утилиту RW-Everything.
    2. Найди в утилите мост "LPC\ISA Bridge". В одном из его регистров лежит адрес контролера apci. На чипсетах Intel это всегда регистр 0x40, если-же чипсет AMD, то ищи его в pdf по маске "pmbase" (power management).

    pmbase.png rw1.png

    3. У меня Intel и этот регистр имеет значение 0х00000401, при этом младший бит определяет, где находятся порты девайса acpi: 1 = в пространстве ввода-вывода чипсета, 0 = промаплены в память mmio. В данном случае бит взведён, значит это физ.порт под номером 0x400. Утилита RW может не только отображать регистры портов, но и записывать в них значения. Так выглядят порты моего контролера acpi.

    acpi_io.png

    4. В доке на чипсет есть описание всех регистров порта, а в данном случае интересует 32-битный 0x04 под ником "PM1_Control". В его битах[12:10] системный модуль OSPM задаёт одно из пяти состояний процессора S0-S5, а последнее с маской 111b как-раз даёт команду чипсету на отключение питания Soft-Off.

    pm1.png pm_s5.png

    Остальные определены так:

    S0 = рабочее состояние.
    S1 = ожидание, находится в режиме пониженного энергопотребления.
    S2 = глубокий сон, нет питания на цп.
    S3 = ожидание с сохранением в озу (suspend to ram, standby).
    S4 = гибернация (suspend to hiberfil.sys).
    S5 = мягкое выключение Soft-Off, дежурное питание только на кнопке.

    Таким образом, логика управляется двумя битовыми полями регистра "PmControl" - это тип сна SLP_TYP, и его разрешение SLP_EN. Сначала задаём тип (для выкл = 111), после чего взводим бит(13). Чипсеты могут не поддерживать буквально все состояния S0-S5, поэтому osmp использует 2 таблицы acpi (см.утилиту rw):

    1. DSDT содержит объекты c именами S0-S5 - их наличие прямо указывает ос на поддержку. Внутри каждого объекта хранятся значения SLP_TYP_x, которые ос должна будет записать в регистр "PM1_Control" для перехода в нужное состояние.

    2. Таблица FACP (в спеке числится как FADT) сообщает системе, по какому конкретно адресу находится регистр управления питанием. Драйвер acpi получает адрес PMBASE (здесь 0x400) именно из FADT, а не из доки pdf на чипсет. Его хранит поле "PM1a_CNT_BLK" таблицы.

    В общем для выкл.питания Win берёт из DSDT значение объекта S5, затем из FACP адрес регистра управления питанием, и наконец прописывает в него ключ S5=111b.

    Чтобы получить пруфы, можно загрузись досом и потрассировать int 15h ax=5307h.
    Хоть это и устаревший интерфейс APM (Advanced Power Management), конечная точка всё-равно одна и acpi приведёт тебя туда-же. Вот код программного отключения БП-АТХ:
    Код (ASM):
    1.  
    2. org 100h
    3.     call   @f
    4.            db  "Press 'y' for Power Off $"
    5. @@: pop    dx
    6.     mov    ah,9
    7.     int    21h
    8.  
    9.     xor    ax,ax
    10.     int    16h      ; Yes/No
    11.     cmp    al,'y'
    12.     je     @pwrOff
    13.     ret
    14.  
    15. @pwrOff:
    16.     mov    ax,5307h     ;// ATX Power Off
    17.     mov    bx,1
    18.     mov    cx,3
    19.     int    15h
    20. ret
    21.  
     
    Последнее редактирование: 28 июн 2026
    _edge и Mikl___ нравится это.
  3. Entropy

    Entropy Member

    Публикаций:
    0
    Регистрация:
    23 авг 2020
    Сообщения:
    288
    Marylin, как я понял,если вмешаться напрямую в работу контроллера ACPI, это всё равно что выдернуть комп из розетки
     
  4. Marylin

    Marylin Active Member

    Публикаций:
    0
    Регистрация:
    17 фев 2023
    Сообщения:
    371
    Всё верно. Такие api как ExitWindowsEx() из user32.dll просто подготавливают систему к выключению, после чего драйвер acpi отправляет команду уже чипсету. Кстати он создаёт целый вагон детей\объектов (у меня 43), и обслуживает каждого из них.
    Код (Text):
    1. 0: kd> !drvobj acpi
    2. Driver object (fffffa800c719840) is for:  \Driver\ACPI
    3.  
    4. Device Object list:      <--------
    5.  
    6. fffffa8010504e40  fffffa801036f2f0  fffffa801044e040  fffffa8010195670
    7. fffffa8010181880  fffffa800d1b1730  fffffa800d1aa530  fffffa800d1aa750
    8. fffffa800d1a9170  fffffa800d1aaa00  fffffa800d1aac20  fffffa800d1aae40
    9. fffffa800d1aa060  fffffa800d1a9390  fffffa800d1a95b0  fffffa800d1a97d0
    10. fffffa800d192840  fffffa800d192a40  fffffa800d192c40  fffffa800d192e40
    11. fffffa800d192040  fffffa800d1917f0  fffffa800d18f7f0  fffffa800d1907f0
    12. fffffa800d18c720  fffffa800d18e7f0  fffffa800d18d7f0  fffffa800d29e060
    13. fffffa800d85b2f0  fffffa800d85b510  fffffa800d85b730  fffffa800d85ba00
    14. fffffa800d85bc20  fffffa800d85be40  fffffa800d29eb60  fffffa800d29ed80
    15. fffffa800d1cd5a0  fffffa800d5d3d70  fffffa800d1cda40  fffffa800d1a4830
    16. fffffa800d196190  fffffa800d1cd7c0  fffffa800c6fa830
    17.  
    18. 0: kd>
     
    Mikl___ нравится это.
  5. _edge

    _edge Well-Known Member

    Публикаций:
    1
    Регистрация:
    29 окт 2004
    Сообщения:
    657
    Адрес:
    Russia
    Marylin, знаю, что Вы также активно постили в свое время на форум whatis.ru , но он не работает более. Не хотите, если это возможно, где-то перепостить свои статьи с этого форума, ?

    При желании (и возможностях чипсета) вроде можно даже отключить реакцию машины на нажатие кнопки Reset. 20 лет назад на форуме lowlevel.h14.ru ребята во главе с Creoton'ом (автор Miraculix OS и утилиты AXE) извращались над тогдашними материнками. А Apple_Rom с форума rom.by делал свой обработчик SMM-режима, который выводил в порт 80 что-то, и это что-то можно было "ловить" Post-тестером. Давно это было..
     
    Последнее редактирование: 5 июл 2026 в 18:14
    Mikl___ и Marylin нравится это.
  6. Marylin

    Marylin Active Member

    Публикаций:
    0
    Регистрация:
    17 фев 2023
    Сообщения:
    371
    Если не ошибаюсь, это было в 2010-году и многое постил туда чисто для себя в качестве заметок.
    Всё ушло вместе со-старым винтом, который приказал долго жить. Думаю это уже не актуально.

    А на счёт сброса Reset - это запись в порт CF9h определённой маски.
    Для перехвата настраивается генерация SMI (System Management Interrupt) при обращении к этому порту i\o (см. Intel SDM том 3 глава 34 SMM).
    Код (ASM):
    1.  mov  dx,0xCF9
    2.  mov  al,6
    3.  out  dx,al
    cf9.png

    Есть так-же реакция на удержание кнопки Power в течении 4-сек,
    что равносильно переводу проца в режим S5 (отключение).

    owr_4.png
     
    Последнее редактирование: 5 июл 2026 в 20:38
    Mikl___ нравится это.