情景1:玩游戏久了,内存使用率噌噌地往上涨,太卡了。于上按下WINDOWS左下角开始菜单,点“重新启动”按钮,过一会重新进入OS,不卡了。

情景2:使用电脑时,经常遇到机器无法正常工作。不得已,只得按下电脑机箱的RESET按键。电脑重新进入OS后,我们又可以愉快地玩它了。

这些都是重启,我们经常使用,但并一定了解里面的细节。本章内容就总结一下相关重启知识(PS:不敢称RESET,因为RESET包括的知识更宽泛)。

    重启就是将全部或一部分系统环境置为初始时的状态,至于是全部或是其中一部分被置为初始时状态,要靠重启类型来决定。不管重启类型是哪种,CPU PC指针都会指向一个固定的位置0xFFFFFFF0,从这个地址开始执行代码。重启类型,从肉眼来看,可以分为Full Reset和普通重启两种。Full Reset,我们会看到电源灯灭了,过一会,电源灯又亮了,即掉电又上电。普通重启,和FULL Reset不同的是,不牵涉电源状态切换。

 

1 Full Reset

    下Full Reset命令后,PCH的S3#,S4#和S5#变低,电源逻辑控制模块检测到这几个SUS PIN变低后,便拉掉平台相关的电源,但RSMRST#不能拉低。过几秒后,南桥PMC会重新将S3#,S4#和S5#拉高,电源逻辑控制模块再重新上平台的电源。此时,CPU程序指针重置,整个平台的代码开始跑。

    下图是RST_CNT寄存器的详细解释:


bios重启后无法开机 bios重启电脑_x86

图1 RST_CNT示意图

 

BIT3便是FULL RESET位。重启时将此位置1,SLP_S3#,SLP_S4#和SLP_S5#就会被拉低3-5秒钟。有时候我们会很奇怪,改了SETUP菜单的值,特别是有STRAP相关的选项,电源便会掉几秒钟,然后再起来。这个就是FULL RESET在起作用。

 

 

2 普通重启

         相对于Full Reset,我们更常用的是普通重启的功能。本文开篇提到的情景1和情景2都属于普通重启。它不牵涉电源切换,所以电源灯一直亮。普通重启后,CPU大部分MSR寄存器,都会被初始成默认值,包括CACHE LINE也会置成初始状态。

         根据PLTRST#是否动作,普通重启分为冷重启和热重启两种。根据图1所示,冷重启,就是PLTRST会有一个大约1ms的低脉冲的类型。热重启不会产生PLTRST的低脉冲。它们之间的区别是,冷重启除了重置CPU,还重置PCI设备。

 

2.1 冷重启

         主要有两种方法。

        方法1:使用RST_CNT寄存器的SYS_RST,将SYS_RST置1,如OutportB(0xCf9,0x06)。

        方法2:将南桥的SYS_RESET#拉低,机箱上电源开关旁边的小按键就是拉的这个PIN。

 

2.2 热重启

         主要有三种方法。

         方法1:使用RST_CNT寄存器,将SYS_RST置0。如OutportB(0xCF9,0x04)。

         方法2:使用InitRegister port 0x92,其中bit0 INIT_NOW全置1。如先使用Data保存0x92的值,然后执行OutportB(0x92,Data|0x01)。

         方法3:使用南桥的RCIN#,将其拉低至少16个PCI Clock。这也是OS重启最常用的KBCRST方法。做的时候一条语句搞定,Outportb(0x64,0xFE)。

         这几种方法,其实都是间接通过南桥,最终拉低CPU INIT# PIN做到的。

 

3 ACPI OS重启

         ACPIOS将BIOS作为它和硬件交互的桥梁,BIOS将硬件信息提供给ACPI OS的同时,也将重启的方法提供给了ACPI OS。

         众多ACPI Table,FADT是最重要的Table之一。FADT有两个字段:RESET_REG和RESET_VALUE,如果FADT的Flags中的RESET_REG_SUP为1,则操作系统便会使用OutportB(RESET_REG,RESET_VALUE)重启。RESET_REG可以是0x92,0xCF9也可以是0x64。如果是0x64时,FADT的IAPC_BOOT_ARCH字段的LEGACY_DEVICES和8042位也要置起来,代表平台支持KBCRST#功能。

 

 

(注:本文基于INTEL平台所写。INTEL文档是把Full Reset称为ColdReset,但BIOS代码中都是将hard reset当作冷重启。还是以代码为准吧,毕竟我们是软工,CODE才是我们的生存法宝。)