Выключите компьютер с помощью сборки - PullRequest
14 голосов
/ 24 марта 2009

Как выключить компьютер, используя только код сборки?

Ответы [ 8 ]

10 голосов
/ 24 марта 2009

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

Если вы используете какой-либо член семейства Windows NT (включая XP или Vista) на процессоре семейства Intel x86, а ваш код - это обычный (пользовательский) код, то ... вам нужно вызвать встроенный Windows в функции, чтобы сделать это. Вы не можете просто выполнить магическую последовательность сборки.

Даже если бы вы могли просто выполнить какую-то магическую последовательность сборки, вы бы этого не хотели - вы почти наверняка хотите дать ОС возможность записывать данные из дискового кэша на диск и делать другие Изящные выключатели.

Если вы пишете свою собственную ОС для x86, вам нужно взглянуть на спецификации ACPI (или APM). Если код GPL в порядке, то соответствующие подпрограммы ядра Linux: здесь (ACPI) и здесь (APM) .

9 голосов
/ 09 марта 2011

Это 29-байтовая программа, которую я использовал для выключения компьютера в режиме DOS в течение многих лет.

;Connect to APM API
MOV     AX,5301
XOR     BX,BX
INT     15

;Try to set APM version (to 1.2)
MOV     AX,530E
XOR     BX,BX
MOV     CX,0102
INT     15

;Turn off the system
MOV     AX,5307
MOV     BX,0001
MOV     CX,0003
INT     15

;Exit (for good measure and in case of failure)
RET

Вы можете искать больше функций с Списком прерываний Ральфа Брауна в DJGPP .

6 голосов
/ 26 сентября 2009

В Linux прочитайте перезагрузку (2).

исходные файлы, представляющие интерес:

kernel / sys.c kernel / exit.c и arch / x86 / kernel / apm.c

не полный ответ, но я думаю, что это хорошее начало. Я должен прочитать мой машинный код BIOS, чтобы увидеть, что они делают. но эта часть зависит от конкретной машины. Мэйби, если вы знаете, какая плата управления IC на вашей материнской плате, вы можете определить, какой порт ввода-вывода, зарегистрироваться и дать команду, которая вам нужна. затем настройте правильные состояния платы / устройств и затем подайте команду, чтобы отключить питание.

BIOS управляет питанием через INT 15h, ах = 53h (так называемое Advanced Power Management aka APM) Функция al = 07, используемая в Linux, является установленным состоянием питания cmd. параметры bx = 0001h означают все устройства, а cx = 0003k означают останов.

4 голосов
/ 22 августа 2013

Преобразование ответа @larz выше в сборку носа выполняется следующим образом:

Пререквизиты: Bochs, Nasm

Этот пример был запущен на Debian Wheezy со стандартными пакетами.

Код (имя файла: shutdown.asm):

    org 0x7c00
    jmp main

Shutdown:
    mov ax, 0x1000
    mov ax, ss
    mov sp, 0xf000
    mov ax, 0x5307
    mov bx, 0x0001
    mov cx, 0x0003
    int 0x15

WaitForEnter:
    mov ah, 0
    int 0x16
    cmp al, 0x0D
    jne WaitForEnter
    ret

main:   
    call WaitForEnter
    call Shutdown

times 510-($-$$) db 0
dw 0xaa55

Насмия:

nasm -f bin -o boot_sect.img shutdown.asm

Файл конфигурации Bochs (имя файла: .bochsrc) в том же каталоге, что и код (shutdown.asm)

display_library: sdl
floppya: 1_44=boot_sect.img, status=inserted
boot: a

* Примечание. Я использую библиотеку sdl для bochs, которая является отдельным пакетом от самого bochs

Запуск bochs (из той же директории, что и раньше):

bochs

Нажмите Enter, чтобы выключить

* Примечание. Я не уверен, что все строки между меткой завершения работы и меткой WaitForEnter являются необходимыми

3 голосов
/ 22 апреля 2010

Из архива / x86 / kernel / amp.c:

/**
 * apm_power_off - ask the BIOS to power off
 *
 * Handle the power off sequence. This is the one piece of code we
 * will execute even on SMP machines. In order to deal with BIOS
 * bugs we support real mode APM BIOS power off calls. We also make
 * the SMP call on CPU0 as some systems will only honour this call
 * on their first cpu.
 */

static void apm_power_off(void)
{
 unsigned char po_bios_call[] = {
  0xb8, 0x00, 0x10, /* movw  $0x1000,ax  */
  0x8e, 0xd0,  /* movw  ax,ss       */
  0xbc, 0x00, 0xf0, /* movw  $0xf000,sp  */
  0xb8, 0x07, 0x53, /* movw  $0x5307,ax  */
  0xbb, 0x01, 0x00, /* movw  $0x0001,bx  */
  0xb9, 0x03, 0x00, /* movw  $0x0003,cx  */
  0xcd, 0x15  /* int   $0x15       */
 };

 /* Some bioses don't like being called from CPU != 0 */
 if (apm_info.realmode_power_off) {
  set_cpus_allowed_ptr(current, cpumask_of(0));
  machine_real_restart(po_bios_call, sizeof(po_bios_call));
 } else {
  (void)set_system_power_state(APM_STATE_OFF);
 }
}

Код теперь находится в apm_32.c . Поиск "apm_power_off".

2 голосов
/ 14 июня 2011

Это довольно просто. Также, ребята, OP может работать над своим собственным управляющим. То же самое, что я делаю. Это пример, который позволит пользователю выключить компьютер. Очень просто, просто дает пользователю окно сообщения с OK и Отмена. Если пользователь нажимает «ОК», машина выключается, если пользователь нажимает «Отмена», программа просто завершается. Он протестирован на версиях Windows на базе NT и должен работать на более старых версиях, таких как ME, 95 и 98.

Это мой собственный код, и каждый может его использовать. http://pastebin.com/ccw3mWtw

1 голос
/ 24 марта 2009

Вызвать функцию API ExitWindowsEx в kernel32.dll

0 голосов
/ 27 февраля 2013

1001 * GRUB * $ bzr branch http://bzr.savannah.gnu.org/r/grub/trunk/grub $ vi grub/grub-core/commands/acpihalt.c +303 или здесь на зеркале Github: https://github.com/dajhorn/grub/blob/trunk/grub/grub-core/commands/acpihalt.c#L303

...