
これrestart() マンページ説明する
LINUX_REBOOT_CMD_RESTART2
(0xa1b2c3d4; Linux 2.1.30以降)。 「 '%s'コマンドでシステムを再起動しています」というメッセージを印刷してすぐに再起動します(argで指定されたコマンド文字列を使用)。以前の同期(2)がないと、データは失われます。
シャットダウンプロセス中にargに指定されたコマンド文字列はどのように正確に実行されますか?
https://unix.stackexchange.com/a/489651/674について話すLINUX_REBOOT_CMD_RESTART2
reboot()
ここでの追加の混乱は、システムコールが再起動を実行するプロセスを実行できるように見えるためです(ただしこれは機能します)。
argに提供されたコマンド文字列はカーネルが終了する前に実行されるため、カーネルが終了する前にコマンドがいくつかのクリーンアップ操作を実行できますか?
ありがとうございます。
答え1
コマンドはいいえシャットダウン中に実行されます。これはシェルコマンドやそれと似ていません。machine_restart()
一部のドライバ(watchdogなど)によってdo_kernel_restart()
登録された再起動ハンドラにコールバックデータ(=>を介して)に渡す必要がある文字列。register_restart_handler()
ただし、このメカニズムはx86では使用されません。そこの「コマンド」は完全に無視されます。 ~からarch/x86/kernel/reboot.c
:
void machine_restart(char *cmd) { machine_ops.restart(cmd); struct machine_ops machine_ops __ro_after_init = { ... .restart = native_machine_restart, static void native_machine_restart(char *__unused) {
この文字列は登録されたハンドラにも渡されます。register_reboot_notifier()
。唯一の(虐待)使用されたドライバは次のとおりです。EFIブートローダ制御不揮発性設定です。LoaderEntryOneShot
EFI変数を使用すると、一部のブートローダは次に起動する必要があるオペレーティングシステムを決定します。このドライバはAndroid以外で使用されたことがないようです。しかし、以前のlmlにも詳しく説明されているので、とにかく這いそうです。議論する以前のバージョンも同じです。
答え2
実装されていません。このコマンドには、再起動原因レジスタに書き込むために再起動モードドライバに渡される対応する値があります。再起動後、ブートローダはレジスタから原因値を読み込み、クイックブート、リカバリなど、選択したコマンドに基づいてブートを決定します。
たとえば、Qualcomm MSM8916 SOCベースの電話には、再起動理由レジスタを含む電源投入デバイスがあります。コマンド(形式mode-<command>
)とその理由の値については、以下に説明します。デバイスツリー:
pon@800 {
compatible = "qcom,pm8916-pon";
reg = <0x800>;
mode-bootloader = <0x2>;
mode-recovery = <0x1>;
したがって、コマンド文字列をreboot(2)
使用して呼び出すとbootloader
ドライバー起動デバイスの場合、0x2
再起動理由レジスタに書き込みます。
次回起動すると、ブートローダ(例:lk2nd)は原因レジスタを確認し、適切なモードで起動しますaboot_init()
。aboot.c):
#if USE_PON_REBOOT_REG
reboot_mode = check_hard_reboot_mode();
#else
reboot_mode = check_reboot_mode();
#endif
if (reboot_mode == RECOVERY_MODE)
{
boot_into_recovery = 1;
}
else if(reboot_mode == FASTBOOT_MODE)
{
boot_into_fastboot = true;
}
RECOVERY_MODE
FASTBOOT_MODE
lk2ndで定義されています。再起動.h上記のデバイスツリーと同じ値を持ちます(「fastboot」を「bootloader」と呼びます)。
#define RECOVERY_MODE 0x01
#define FASTBOOT_MODE 0x02
この動作をテストするためにrestartコマンドを使用できるユーティリティについてはわかりませんが、ctypesを使用してPythonでこれを行うことができます。
python -c "import ctypes; ctypes.CDLL('libc.so').syscall(142, 0xfee1dead, 0x20112000, 0xa1b2c3d4, b'bootloader')"
142
上記はreboot(2)
arm64のシステムコール番号です。 16進マジックナンバーはから出ますman 2 reboot
。