アセンブリ コードのみを使用してコンピューターをシャットダウンするにはどうすればよいですか?
10 に答える
それがどのプロセッサファミリーで、どの OS を使用しているかを言う必要があります。また、コードが実行されている特権 - カーネル コードの場合、ユーザー コードよりも多くの特権を持っています。
Intel x86 ファミリー CPU で Windows NT ファミリー (XP または Vista を含む) のメンバーを使用していて、コードが通常の (ユーザー空間) コードであると仮定すると、... Windows 組み込み関数を呼び出して、これを行う。アセンブリの魔法のシーケンスを実行することはできません。
アセンブリのマジック シーケンスを実行できたとしても、そうしたくないでしょう。ほとんどの場合、OS にディスク キャッシュからディスクにデータを書き込んだり、その他の正常なシャットダウンを実行したりします。
x86 用に独自の OS を作成している場合は、ACPI (または APM) の仕様を確認する必要があります。GPL コードに問題がなければ、関連する Linux カーネル ルーチンはここ (ACPI)とここ (APM)にあります。
これは、私がDOSモードでコンピューターの電源を切るために何年も使用している29バイトのプログラムです。
;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のRalfBrownの割り込みリストを使用して、より多くの関数を検索できます。
Linux では、reboot(2) を参照してください。
対象のソース ファイル:
kernel/sys.c kernel/exit.c および arch/x86/kernel/apm.c
完全な答えではありませんが、良いスタートだと思います。BIOS マシン コードを読み取って、その動作を確認する必要があります。ただし、この部分はマシン固有です。マザーボードの IC 制御電源がわかっていれば、必要な IO ポート、レジスタ、およびコマンドがわかります。次に、適切なボード/デバイスの状態をセットアップし、コマンドを発行して電源をオフにします。
BIOS manage power via INT 15h ah=53h (いわゆる Advanced Power Management aka APM ) 関数 al=07 Linux で使用されるのは、電源状態の設定コマンドです。パラメータ bx=0001h はすべてのデバイスを意味し、cx=0003k は停止を意味します。
arch/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」を検索します。
とても簡単です。また、皆さん、OP は独自のパワー マネージャーに取り組んでいる可能性があります。私がやっていることとまったく同じです。これは、ユーザーがマシンをシャットダウンできるようにする例です。非常に単純で、ユーザーに OK とキャンセルのメッセージ ボックスを表示するだけです。ユーザーが [OK] を押すと、マシンはシャットダウンします。ユーザーが [キャンセル] を押すと、プログラムは終了します。NT ベースの Windows バージョンでテストされており、ME、95、98 などの古いバージョンでも動作するはずです。
これは私自身のコードであり、誰もが自由に使用できます。 http://pastebin.com/ccw3mWtw
グラブ
$ 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