Как полностью приостановить процессор? - PullRequest
6 голосов
/ 20 сентября 2010

Я пишу небольшой загрузчик для ПК на базе x86. Проблема в том, что ЦП все еще остается активным после выполнения этих инструкций:

sti
hlt

sti должен отключать прерывания для следующей инструкции
hlt должен полностью остановить процессор

Поскольку они используются вместе, я предполагал, что они просто "заморозят" компьютер. Но когда я собираю его и монтирую в VirtualBox в качестве образа дискеты, мой процессор переходит на 100%.

Что я делаю не так?

Ответы [ 3 ]

13 голосов
/ 21 сентября 2010

Я хотел бы добавить комментарий о 'cli', так как я был укушен этим пару раз в прошлом. Инструкция «cli» не блокирует все прерывания - она ​​блокирует только маскируемые. Возможно, система все еще может быть разбужена из-за немаскируемого прерывания (NMI).

Поскольку один из комментариев указывает на то, что компьютер готов к выключению, я ожидаю, что в системе нет других потоков / процессов / задач, готовых для запуска (в противном случае NMI может привести к перепланировке). Для описываемого вами сценария NMI маловероятен; однако в зависимости от вашего уровня паранойи что-то пойдет не так, вы можете захотеть добавить петлю для защиты от этой возможности.

sysSuspend:
    cli
    hlt
    jmp sysSuspend
11 голосов
/ 20 сентября 2010

Я думаю, вы немного запутались в обеих этих командах.

Команда sti разрешает прерывания, а команда cli отключает их.

Состояние остановки аналогичноцикл ожидания, поэтому он не приостанавливает работу процессора.

Вот несколько ссылок, которые могут вам помочь: Информация о командах STI / CLI: http://en.wikipedia.org/wiki/STI_%28x86_instruction%29

Информация о инструкциях x86: http://en.wikipedia.org/wiki/X86_instruction_listings Отсюда есть ссылка на команду hlt, которая может помочь.

Если вы приостановите процессор, как вы снова его разбудите, если отключите прерывания?

5 голосов
/ 12 марта 2014

Этот вопрос можно переформулировать в более правильный вопрос: как полностью приостановить поток управления?Фактически эту задачу можно разделить на две подзадачи:

  1. Приостановка текущего (синхронного) потока управления.

    • Простой цикл занятости (100% Использования ЦП, большое энергопотребление, высокий тепловой эффект).

    • Цикл на основе остановки (режим энергосбережения C1, большая часть логики ЦП отключена).

  2. Предотвращение асинхронного переключения потоков управления.

    • Обработчики прерываний-заглушек в IDT.

    • Маскировкапрерывания на глобальном контроллере прерываний (PIC или IO APIC).

    • Маскировка прерываний на локальном контроллере прерываний (Local APIC).

    • Маскировка прерывания на логике ядра ЦП.

В любом случае вы должны быть осведомлены и подготовлены к обработке NMI, потому что нет механизмов, которые дают вампитание для их отключения.

Идеальное решение:

    mov  EDX, NMI_INT_HANDLER_STUB; // address of installed handler
    mov  ECX, 0x02                ; // id of the NMI handler in IDT 
    call InstallHandlerInIDT      ; 
    cli                           ; // mask all maskable interrupts on CPU core
SUSPEND:
    hlt                           ; // turn CPU into HALT state (power saving mode C1)
    jmp SUSPEND                   ; // try again if NMI had happened

NMI_INT_HANDLER_STUB:
    iretd                         ; // Complete handling immediatelly and return back.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...