找回密码
 加入计匠网
搜索
热搜: BIOS ACPI CPU Windows
查看: 51921|回复: 26

[原创]BIOS知识点滴Follow Bini系列之---系统重启

[复制链接]
发表于 2007-12-11 15:23:54 | 显示全部楼层 |阅读模式
在和朋友聊天时,你是否碰到突然弹出一个重启?哈哈,也许你是中毒了,也许是系统更新.但重启,大家是否了解呢?本文将介绍几种重启行为,希望对大家有所帮助.
% J3 }* q; p8 A% I! y$ V: z5 B" |7 E# |* J' w
1、KBC Reset
; E( P- W& P4 X& w4 I: W 这是软件实现的一种重启方法,是AT系统的遗产。此种重启工作顺序为:软件发送0xFE至KBC,KBC收到后发送信息给南桥,南桥下拉CPU INIT# 大约16个PCI Clock让系统重启。代码如下:
  1. ;----------------------------------------------
    2 c, O" E' G# R& n
  2. ; 文件名:KBCReset.asm
    + l: W2 G) ?- t5 D0 c  A
  3. ;----------------------------------------------+ J/ E9 s8 m, t
  4. ;    2007-12-11    bini.Yi/易祝兵    For teaching
    / v+ J- D" o9 j4 d1 `0 a- [
  5. ;----------------------------------------------
    $ y, Z+ R; p. m
  6.     .386
    ! C! N5 }7 m5 ?2 u+ j
  7.     .model tiny
    ; [# v7 [8 _6 C  _
  8.     .code
    # c' Z- p: L% d
  9.     org     100h8 u* ^6 i; d, z( n5 S
  10.     * ?% `; q! l% R% \9 ?& Y
  11. ;; 如下代码参照 《PC技术内幕》第8章 键盘系统
    8 }! O  n  z. K- `

  12. 2 i9 ?( g$ k+ w2 e* i5 x0 O
  13. START:( t2 R  G. ], n1 C
  14.     mov     bl, 0FEh                ; KBC Reset命令2 O% z% N( l+ q6 q: t7 N; G! D
  15.     call    keyboard_cmd            ; 不应该有返回
    2 O: v! A% |) [/ h
  16.     hlt
    2 g3 ?% g* f/ x
  17. ! `' P! s# v  P6 Y2 u/ a
  18. IODELAY MACRO
    , j7 [& X6 i# t' U% }
  19.     out    0EDh, al; b- e. y' Y; N5 @( ?" R
  20. ENDM
    6 }/ |$ W7 h7 _% b8 d
  21.   V! t) Q% z6 n# E6 h
  22. ;----------------------------------------------4 s1 U, S  u- P8 r- G: B) A$ ^
  23. ;    keyboard_cmd()( A/ `" v% S$ Y6 b
  24. ;----------------------------------------------
    ; w4 L) z7 u5 s" X; ]' q
  25. ;    如果由于缓冲区满超时,则 ah 返回非零) `6 D1 o) d2 x6 m1 s

  26.   \3 P. e! q, N3 U
  27. ;    调用    bl = 命令字节  |/ p: ^* v! q0 M
  28. ;            ds = cs
    ' l% K( M% o  ~; f8 p+ A
  29. ;
    8 w! I2 l' g& g: h. L; g' \  `3 y
  30. ;    返回    如果 ah =0,则成功; J6 H% n+ T& Z) a
  31. ;            如果 ah =1,则失败8 ?( P0 Y1 O1 j8 z) h; z$ B+ H: n
  32. ;----------------------------------------------/ M4 o0 y  ]: y1 v! d5 e
  33. 4 j" p9 I  ]: z6 v
  34. keyboard_cmd    PROC    NEAR
    * Y' ]: o# w1 {% e5 j  x% y- c4 ~
  35.     xor     cx, cx                  ; 超时计数器(64K)1 M  G+ T0 ?5 Y. L
  36. ' H6 _: c6 ~& K4 y( W/ b5 o2 T# Q) [
  37. cmd_wait:* i+ y1 U" Q7 H
  38.     in      al, 64h                 ; 获取控制器状态
    + V& q! i3 f3 X: L' t9 U
  39.     IODELAY3 O: `! |% g# ~: K" M
  40.     test    al, 2                   ; bit1,输入缓冲区满?(控制器是否有数据没处理完)1 `0 ?2 H6 ]* y2 c( M  y4 ~
  41.     jz      cmd_send                ; 缓冲区空,准备接收命令.
    9 m% j+ ]; g$ g/ Z1 P
  42.     loop    cmd_wait                ; 缓冲区满,重试8 _, G9 Y" C5 H
  43.    
    : D8 }; P8 x/ D; U
  44.     jmp     cmd_error               ; 超时,失败
    8 R& y8 H6 O4 V8 z3 h0 M! T  @. ~! L
  45.    
    0 V! ~/ i2 {# K% J( X
  46. cmd_send:
    . M4 \0 u1 y( |# z6 b
  47.     mov     al, bl                  ; 取 bl 中的命令字节. O2 o/ U' R. Z& j7 J/ Y
  48.     out     64h, al                 ; 发送命令字节
    % `' {' ^$ X8 o5 C8 _" u4 m9 v/ x
  49.     IODELAY  ]4 O/ t! T# `& K+ s8 \' T
  50. 6 z5 j9 R7 H7 M. Z. L
  51.     xor     cx, cx                  ; 超时计数器(64K)
    ) \$ |1 \% T- {
  52. cmd_accept:
    9 T( D( v: }5 O9 T. ~: I5 V  D
  53.     in      al, 64h                 ; 获取控制器状态" p( |7 L$ A( n# n, ~! q$ I! ?8 c( M
  54.     IODELAY5 i" y3 p' X) X$ f( B. |) U$ C
  55.     test    al, 2                   ; bit1,输入缓冲区满?(控制器是否有数据没处理完)
    ! |( E: q/ v4 m! ~7 R
  56.     jz      cmd_ok                  ; 缓冲区空,处理完2 G& ^+ R) h; o2 J7 J0 J
  57.     loop    cmd_accept              ; 缓冲区满,重试
    4 |6 Y0 [% n* c& H, |
  58.     6 d' l8 g, s7 x) n
  59. cmd_error:                          ; 超时失败' f8 n7 ]9 Y  K4 O: U
  60.     mov     ah, 1                   ; 失败返回状态非零* V0 `' g3 l' A8 J: g
  61.     jmp     cmd_exit0 P8 ~$ M1 |% ?% V7 a0 y7 Z
  62. ) k2 D9 \7 x' d( V7 g/ j
  63. cmd_ok:
    . m% l3 ]$ L* x% |
  64.     xor     ah, ah                  ; 成功返回零- A% b- E5 A/ |5 v
  65.     5 Z  J8 {/ M/ u
  66. cmd_exit:3 g9 a2 v, z' K+ I
  67.     ret$ e  J, k1 F, J1 d: R% m( V. i
  68. keyboard_cmd    ENDP. v3 }; K: u( w/ z* Y: a
  69. 0 `$ f7 }$ l: \, x
  70.     END    START
复制代码
2、PORT 92h
5 i6 @3 Z7 v# y: _: [" F% E( l 从EISA系统之后,系统控制端口定义了一位用来快速重启的寄存器,就是在PORT 92h的Bit0,这种方式最终结果是和KBC一样的,HOST会拉CPU的INIT#以让系统重启。但这种方式不通过KBC,所以速度更快一点,代码如下:
  1. in al, 92h5 s; `9 H) a) t; A6 Q  u3 |
  2. IODELAY" O6 Z+ u, R' A. M& V
  3. or al, 1
    : L( e( N5 V% T' a6 N
  4. out 92h, al
    3 Z- a  H* A7 W/ T; _5 l
  5. hlt! @2 P' }! {5 m2 j# E
复制代码
3、Reset Control Register(Port CF9h)& u( [) T# m4 j3 i: s. N4 d
用此方法控制Reset,各Chip极有可能各芯片产商的做法会不同。* f0 }9 I$ m3 o/ ]( V( \0 y
这里大家可以认识几种Reset的名词: Platform Reset, PCI Reset, System Reset, Reset CPU.我们来看Intel的文档,如下图:4 T" K- H* D5 N& D9 u
          1.GIF 7 d  b+ R3 E6 V  c% l# R' [

5 P1 c8 O) f' l1 [ 大家注意看,如果System Reset bit位为1,那么如果Reset CPU bit从0变为1时,系统就会产生Platform Reset(包括产生PCI、FWH、SIO、LPC、MCH Reset),即称为Hard Reset;如System Reset bit位为0,那么系统就会产生Soft Reset,即:和KBC/PORT 92h Bit0一样,下拉CPU INIT# 16个PCI Clock。
; F: _* k) g7 y
$ _$ b* w1 S$ \2 m0 d 因此你可以用下如代码Hard Reset:
  1. mov al, 6- y: y) y: T  {, b+ {
  2. mov dx, 0CF9h( T" y; N4 t/ U' u7 X
  3. out dx, al) m) q/ Q) q. i# J' L/ J2 L2 {
  4. jmp $
    ) ~- w8 L* z6 D5 g4 h2 t& D9 z4 Q' i
复制代码
也可以用如下代码“关机”(看你的机器的做法,也就是对SLP_S3#,SLP_S4#,SLP_S5#的处理):
  1. mov al, 0Eh
    6 P9 k. t. z& k! y* p, Q: t
  2. mov dx, 0CF9h1 \& k7 ^1 T. K7 I' A4 D  Z
  3. out dx, al5 c+ ^# I' X( `1 k
  4. jmp $
    / f) T1 J5 B7 W- D3 s
复制代码
4、Ctrl+Alt+Del
6 k! R. ]. A6 v  J; A    这种方法“基本”是在“DOS”下有效,教课书上常称为"热启"。键盘中断会hook住你的按键,Hook就是BIOS的INT 09h软中断,当你按下这三个键时,就相当于Far jmp到 F000:FFF0处。用如下代码在DOS可实现热启动。
  1.     jmp     F000:FFF0
    5 Q& M! a& ]- e
  2.    
复制代码
OK,你对系统重启是否又清楚了一些呢?
发表于 2007-12-12 09:19:53 | 显示全部楼层

不错啊
回复

使用道具 举报

发表于 2007-12-12 16:10:17 | 显示全部楼层
不错,学习了。2 I5 s5 f  t) Z
还有人这样写:
: J5 W' _0 p8 h  Vmov     dx, 64h  
: b) M/ l( L" [/ l1 Ymov     al, 0FEh 7 e3 \. H+ _+ M9 u
out     dx, al          * _7 n- ~' Y  G* C
in      al, 92h, R7 z6 U/ h* H/ [1 A& W# `
or      al, 18 v5 R$ w, D6 J* Q
out     92h, al
/ y* g; c8 U$ Y. \- x; Vmov     dx, 0CF9h
% H* V6 k5 x8 k% v8 S0 A) pin      al, dx
) h1 }6 r) w5 B% Tor      al, 6# K4 S% b& ]1 r9 e" L
out     dx, al
回复

使用道具 举报

发表于 2008-1-14 16:15:03 | 显示全部楼层
不错,各种方法都说了,谢谢。
回复

使用道具 举报

发表于 2008-2-19 16:12:50 | 显示全部楼层
CPU reset 好像不如Rci Reset彻底,经常不能完全Reset
回复

使用道具 举报

发表于 2008-4-17 10:11:09 | 显示全部楼层
请教各位下 & W$ O: H4 ?* _8 h6 b) u
经常看到 “reset with power cycle”。当powercycle时,看到板子跑了一段又再重启。在代码中powercycle具体是做了什么呢?是否跑完了Bootblock?powercycle的作用又是什么呢?请各位大虾指点。
回复

使用道具 举报

 楼主| 发表于 2008-4-17 10:39:08 | 显示全部楼层
可能是特定平台的BIOS与KBC的system flag的问题,启动时,KBC标识System flag为warm reset时,可能BIOS还会发一次System reset。(也许是为了解决一些BUG而设的重启吧)
回复

使用道具 举报

发表于 2008-4-23 13:56:08 | 显示全部楼层
谢谢分享,学习了,收藏了。
回复

使用道具 举报

发表于 2008-7-28 16:36:54 | 显示全部楼层
好像对重启有些了解了
回复

使用道具 举报

发表于 2008-10-14 09:50:55 | 显示全部楼层
学习了,挺全面的,收藏了
回复

使用道具 举报

发表于 2008-10-31 10:39:18 | 显示全部楼层
最近研究了一下Windows 2003 reboot flow:
! h7 ]9 K0 t% K; H( ?7 gIf(BIOS报告的ACPI Tabler版本>=2.0 && FADT中RESET_REG_SUP标志设置 && 系统中没有8042键盘控制器) {
0 k& {0 b% P8 j  d, z( I% x6 f: D4 R  通过FADT报的RESET REGister和REset value reboot;
# x6 Z; x: ^: J# J. y} else {' P0 }: j' ~' B6 S% E$ J' r
  port(64h)=0feh // 这种reset不是整个系统范围的reset,BIOS一般会检测到这种reset,并转换为RESET REG reset( f& l; t: N( Y5 }4 ]2 p9 l+ e
}
+ y. E$ D7 }4 }9 N+ T
9 J& K* |" B! O  b& n2 r+ ]如果是UEFI的Windows,可能通过ResetSystem() runtime service来reboot.
回复

使用道具 举报

发表于 2008-10-31 12:29:21 | 显示全部楼层
Reset Register=0xCF9, Reset Value=0x06 or 0x0E ?
. }8 Z9 x: u2 F+ y6 g4 L1 LReset Register还可以在Memory或者PCI configuration space
回复

使用道具 举报

发表于 2008-11-12 16:57:04 | 显示全部楼层

out 0EDh, al

今天在查寻 out    0EDh, al这个句子的时候再次回到了这个帖子 ,以前在看程序的时候居然没留意
回复

使用道具 举报

发表于 2008-11-13 13:47:19 | 显示全部楼层
完全Reset是會斷一次電的,這個可以在這你發Hardware Reset的時候根據要求調節參數達到..
回复

使用道具 举报

发表于 2008-11-27 06:58:18 | 显示全部楼层
不错的文章,学习了!!!
回复

使用道具 举报

发表于 2009-2-22 09:46:25 | 显示全部楼层
不錯的整理,学习了!!!
回复

使用道具 举报

发表于 2009-2-28 20:06:41 | 显示全部楼层
in al, 92h! S2 F" ]2 D$ S! g( J; b
IODELAY( P" T( @, y; t9 B4 J
or al, 1' U2 f8 Q5 G4 |$ ]. \" r
out 92h, al6 U" M6 y3 E2 H
hlt& u) }/ Y/ E# s) e) P& w
2 u3 l2 D3 |% l! Q  `# I. U+ f) h
这个 有个问题 在 PC技术内幕 中第13章 提到这个92h端口时,说了在MCA中bit0确实是做重启5 H& g2 D8 X" ?2 Y5 x$ |
但是在EISA中 bit0 只给了4个字的说明 :普通情况...7 C, _# w) C; J
不解ing....
3 p5 H& v6 ~, d& I0 Z$ R这样看 是不是 bit0 = 1也是做了重启?还是别的?
" K6 M" C! _& A# `' J& J* o5 N- {% B! s而且我目前的水平还不知道该怎么验证?  也许我对MCA和EISA没吃透...
回复

使用道具 举报

发表于 2009-3-3 12:50:24 | 显示全部楼层
参照ICH spec中对92h的说明2 G3 L5 N! \8 ~1 c! V2 _7 c7 [
INIT_NOW — R/W. When this bit transitions from a 0 to a 1, the Intel® ICH7 will force
0 v; V4 w8 _0 Q5 h4 I# w0 q, l5 |% _INIT# active for 16 PCI clocks.
回复

使用道具 举报

发表于 2009-3-23 15:11:22 | 显示全部楼层

ACPI FADT中,KB8042和RESET_REG_SUP均不支持, ACPI OS 如何Reset?

ACPI FADT中,KB8042和RESET_REG_SUP均不支持, ACPI OS 如何Reset?
回复

使用道具 举报

发表于 2009-8-7 11:19:43 | 显示全部楼层

回复 11# 的帖子

Hi:$ x" P# j6 A: G) i" Q" J
   srcore,& ^. q, P- G) f3 w* ]) P
      按照你所述,windows 下的重启,如果有KBC(EC),就是发0XFE吗?而我去追了一下,在EC收到0xFE 的地方 下了个断点,然后做windows 下重启, 以及CTRL+ALT+DEL,发现均没走这个流程,而是直接跑到了 EC check   warm reset 的位置去了(EC在不停的check  RSTRDY# 是否低,低则 warm reset )   ,难道是我们做的有问题?期待回复,谢谢!1 v6 u! k) h+ c6 x/ ?3 s  f$ `1 g5 r! q
  melow 平台(SCH+AMI CORE8)
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 加入计匠网

本版积分规则

Archiver|手机版|小黑屋|计匠网

GMT+8, 2026-4-4 14:34 , Processed in 0.085270 second(s), 20 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表