從os的角度來擴充套件一下Timer的答案:
透過os或者硬復位訊號給acpi傳送一個reset命令實現的 由電源模組完成重啟(硬重啟)
如果不是按了reset button,則使用者一般是透過作業系統提供的電源管理介面來實現重啟的,
這個時候作業系統需要告訴硬體(比如cpu, power, pch等等)讓其重啟至其初始狀態,一般情況下這些硬體都會存在一個reset的針腳,舉個例子來講cpu即會一個reset#的針腳,而該針腳一般是連在pch上邊,由pch來控制。
由於各家主機板或者筆記本生產廠商的電路設計不同,裡邊的各個模組也是不同的。比如講筆記本可能自帶無線網絡卡,但是一般桌上型電腦就沒有無線網絡卡,而這些裝置都需要reset,也就是最終不同的硬體平臺reset的方法是不同的,表現到software層面就是cpu要執行的硬體管理操作是不同的。
cpu主動與外圍通訊的方法一般有兩種:PIO和MMIO。PIO是指使用`in`, `out`這兩種特殊指令來與I/O space裡邊的埠通訊,MMIO是指直接讀寫系統的地址空間。假設reset是透過PIO來實現的,那麼不同的硬體平臺,`out(port, value)`裡邊的port和value就可能是不同的。
然而對於software(os)來說它是沒有辦法知道電路是如何實現的,也就是說它是沒有辦法來確切的知道port和value的值,因此就出現了一個標準acpi,該標準定義了一個software(也就是os)與hardware(也就是cpu, wireless nic)的一個電源管理和配置的規範。而這個spec就這定義了reset的一個標準。
也就是說hw vendor會提供一個表,該表會提供兩個值:1)reset_reg 2) reset_value,software要做的事情就是把 reset_value寫到reset_reg就可以實現重啟了,而這個表事先就由hw vendor寫到系統的bios/uefi裡邊。software(os)透過查表找到這兩個值,然後在使用者指示os要重啟時候就執行write reset_value to reset_reg即可以實現重啟。
以我的電腦舉例:
使用darwindumper可以看到facp表裡邊提供了reset_reg和reset_value的值
由上圖可知
reset_reg = cf9這個io port
reset_value = 06
也就是說我們要重啟只需要執行這條指令即可,`outb(0xfc9, 06)`。在windows平臺下,你可以透過r/w everything來直接給0xfc9所在port,手動賦值0x06即可實現重啟了。
從os的角度來擴充套件一下Timer的答案:
透過os或者硬復位訊號給acpi傳送一個reset命令實現的 由電源模組完成重啟(硬重啟)
如果不是按了reset button,則使用者一般是透過作業系統提供的電源管理介面來實現重啟的,
這個時候作業系統需要告訴硬體(比如cpu, power, pch等等)讓其重啟至其初始狀態,一般情況下這些硬體都會存在一個reset的針腳,舉個例子來講cpu即會一個reset#的針腳,而該針腳一般是連在pch上邊,由pch來控制。
由於各家主機板或者筆記本生產廠商的電路設計不同,裡邊的各個模組也是不同的。比如講筆記本可能自帶無線網絡卡,但是一般桌上型電腦就沒有無線網絡卡,而這些裝置都需要reset,也就是最終不同的硬體平臺reset的方法是不同的,表現到software層面就是cpu要執行的硬體管理操作是不同的。
cpu主動與外圍通訊的方法一般有兩種:PIO和MMIO。PIO是指使用`in`, `out`這兩種特殊指令來與I/O space裡邊的埠通訊,MMIO是指直接讀寫系統的地址空間。假設reset是透過PIO來實現的,那麼不同的硬體平臺,`out(port, value)`裡邊的port和value就可能是不同的。
然而對於software(os)來說它是沒有辦法知道電路是如何實現的,也就是說它是沒有辦法來確切的知道port和value的值,因此就出現了一個標準acpi,該標準定義了一個software(也就是os)與hardware(也就是cpu, wireless nic)的一個電源管理和配置的規範。而這個spec就這定義了reset的一個標準。
也就是說hw vendor會提供一個表,該表會提供兩個值:1)reset_reg 2) reset_value,software要做的事情就是把 reset_value寫到reset_reg就可以實現重啟了,而這個表事先就由hw vendor寫到系統的bios/uefi裡邊。software(os)透過查表找到這兩個值,然後在使用者指示os要重啟時候就執行write reset_value to reset_reg即可以實現重啟。
以我的電腦舉例:
使用darwindumper可以看到facp表裡邊提供了reset_reg和reset_value的值
由上圖可知
reset_reg = cf9這個io port
reset_value = 06
也就是說我們要重啟只需要執行這條指令即可,`outb(0xfc9, 06)`。在windows平臺下,你可以透過r/w everything來直接給0xfc9所在port,手動賦值0x06即可實現重啟了。