BIOS开发笔记 5 – CMOS
简介
CMOS原来指的是一种生产电子电路的工艺,在PC上一般指的是RTC电路单元,因为早期它是由这种工艺生产出来的,所以又把RTC称作了CMOS。
RTC(Real Time Clock)即实时时钟,用于保存记录时间和日期,也可以用来做定时开机功能。RTC靠一组独立的电源给它供电,这样设计的目的就是为了不受系统电源的影响,可以保持一直有电,哪怕是在关机状态下。当然这是理想状态下的,因为会有一些不可抗拒的原因,可能会导致断电,比如电池电量消耗完。
RTC的供电设计有两种:台式机上使用常见的RTC电池,笔记本上也有使用RTC电池的,但有些为了节省空间和减低成本,直接共用笔记本电池的电源。RTC功耗极低,根本不需要忧虑它会对对电池造成大的负担。
要使RTC正常工作,除了电源,还需要一个32.768KHZ的晶振。RTC通过对晶振所产生的振荡频率分频和累加,得到年、月、日、时、分、秒等时间信息,并将其保存在一段RAM中。
RTC RAM
在UEFI问世之前,BIOS存储一些变量(如BIOS SETUP设置)的方法就是放在RTC RAM中的,只要RTC有电,数据就可以一直保存。如果要恢复默认设置,或忘记密码等,便可以通过拆卸 RTC 电池的办法来达到目的。
至今,“清CMOS”这个词还在沿用,虽然目的都是为了恢复BIOS SETUP初始值,但原理已经变了,UEFI中“清CMOS”并不能达到恢复默认设置的目的,因为数据不是存放在CMOS中了,而是BIOS ROM。那现在的“清CMOS”是怎么实现的呢?原理就是BIOS启动的时候去判断RTC是否掉过电(如Intel中的RTC_PWR_STS),是的话代码就执行恢复动作。注意,这里的恢复是代码实现的,而原来利用的是RTC掉电,数据会清除的原理!
RTC RAM 共有128字节,前14字节是有标准定义的,可以用来控制实时时钟,而其它字节对现在来说都已经过时了,基本没什么用,最多拿来临时存一些数据作标记。
前14字节定义(具体需要参照各平台芯片设计厂商相关的手册)
前面所写的指的是传统的RTC RAM,后面又有了一个扩展的RTC RAM,它相比传统的RTC RAM,可使用的寄存器增加到了256个,不过也很少用到。。
访问
RTC RAM分为两部分,第一部分传统CMOS,只有128字节,第二部分为扩展CMOS,有256字节,需要分开使用70/71或72/73端口访问,每次读写只支持单字节操作。通过RW查看,如下:
RW中直接可以看到在跳动的秒数,操作系统下的时间和日期都是从RTC读出来的。如果在OS下更改时间或日期,RTC中相关寄存器也会被变更。
代码访问CMOS直接使用 IoRead8() 和 IoWrite8() 就可以了,比较简单,EDK2中有相关函数,如下:
UINT8 EFIAPI CmosRead8 ( IN UINTN Index ) { IoWrite8 (0x70, (UINT8) Index); return IoRead8 (0x71); } UINT8 EFIAPI CmosWrite8 ( IN UINTN Index, IN UINT8 Value ) { IoWrite8 (0x70, (UINT8) Index); IoWrite8 (0x71, Value); return Value; }
定时开机
定时开机的叫法有几种,如RTC Wake Up、RTC Alarm、Wake Up From S5 等,原理就是设置RTC中几个Alarm寄存器,当Alarm寄存器的值跟当前时间一样时,RTC就会产生一个Alarm,如果此时RTC Alarm Enable有被设置启用的话,则会产生一个唤醒事件(wake event)唤醒计算机,达到一个定时开机的作用。
定时开机常见的应用场景有两种,一种是在BIOS SETUP做的定时开机功能,另一种则是由APP设置的定时开机,如常用于测试跑自动开关机的工具Pwrtest.exe(它是微软提供的,在SDK中可找到它,由于EWDK包含SDK,所以EWDK也有,用everything搜一下很快可以找到),原理也是在关机的时候设置了RTC Alarm,然后不断重复这个动作,便实现了自动开关机的功能。
版权声明:
作者:bin
链接:https://ay123.net/mystudy/bios/1404/
来源:爱影博客
文章版权归作者所有,未经允许请勿转载。
共有 0 条评论