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

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

[复制链接]
发表于 2007-12-11 15:23:54 | 显示全部楼层 |阅读模式
在和朋友聊天时,你是否碰到突然弹出一个重启?哈哈,也许你是中毒了,也许是系统更新.但重启,大家是否了解呢?本文将介绍几种重启行为,希望对大家有所帮助.: w. b+ h5 [; j) {1 ^1 v0 p  O
9 X  w! |6 T; A6 b( p) T  @3 _! a
1、KBC Reset0 @* G" K) n5 G4 V/ W! S
这是软件实现的一种重启方法,是AT系统的遗产。此种重启工作顺序为:软件发送0xFE至KBC,KBC收到后发送信息给南桥,南桥下拉CPU INIT# 大约16个PCI Clock让系统重启。代码如下:
  1. ;----------------------------------------------+ D+ z) X( J- U+ ]7 @  D4 ~( d
  2. ; 文件名:KBCReset.asm+ t6 G% l' N' p1 `
  3. ;----------------------------------------------* M' B, U+ |0 w. v0 ]
  4. ;    2007-12-11    bini.Yi/易祝兵    For teaching
    2 i1 f9 J  f+ T2 \) O4 I6 [
  5. ;----------------------------------------------0 h! [) o( n# ^, T% b* A, i
  6.     .386
    ' C+ Y; L9 e( {. C, h: k- H2 A
  7.     .model tiny8 r" k$ f& O  ?* t8 F
  8.     .code) ^& D" L- Y0 a7 j
  9.     org     100h
    ! h% O3 ^/ U0 h( v& S
  10.     0 Z; L3 Y/ i, D
  11. ;; 如下代码参照 《PC技术内幕》第8章 键盘系统
    ) p( x" F% x1 P( A) k# U1 w

  12. ! E" {0 v# C4 o
  13. START:
    ( Q: y& F. j; @/ m0 Q+ G
  14.     mov     bl, 0FEh                ; KBC Reset命令, U2 m9 j# X* b6 Z+ J2 D4 s
  15.     call    keyboard_cmd            ; 不应该有返回
    : V0 v0 E- |# u: B
  16.     hlt
    4 U. G" b7 t! d, p/ R% L
  17. $ j  b, T* W$ \3 u
  18. IODELAY MACRO4 m: z% K  d4 _  X* s/ ^
  19.     out    0EDh, al5 O  Y% B; }2 p
  20. ENDM
    ( R$ j( T8 y, a6 o$ ^
  21. & `( a0 Q& K% V( c3 F' n) i
  22. ;----------------------------------------------
    % j2 J& c% w" c# J
  23. ;    keyboard_cmd()9 N$ k4 F( l' S2 C
  24. ;----------------------------------------------
    : Y. X; }0 o- u) E; \
  25. ;    如果由于缓冲区满超时,则 ah 返回非零
    9 b1 c9 {3 E9 A5 s

  26. 9 F) z/ ]; G5 E! S  [0 x" @# \7 u! ~
  27. ;    调用    bl = 命令字节0 h" v- o. m0 M" G
  28. ;            ds = cs5 W$ P8 @0 L9 O! d  t
  29. ;! h8 R" ]- {% U4 l
  30. ;    返回    如果 ah =0,则成功6 q" k) K. M( ]  R$ m
  31. ;            如果 ah =1,则失败
    , L0 r$ R$ V# v/ P6 [* ?& {
  32. ;----------------------------------------------# o* }6 B5 e$ |
  33. * ~5 W& l' C( w# E& o3 _
  34. keyboard_cmd    PROC    NEAR
    4 p# ^' L4 M$ W0 U( W" j1 X
  35.     xor     cx, cx                  ; 超时计数器(64K)' O  T/ H# }  n" a2 ^
  36. 7 `( Y. r9 c# @! ^2 ]& m
  37. cmd_wait:
    ' M+ j5 v5 N+ @5 J6 c
  38.     in      al, 64h                 ; 获取控制器状态
    # c6 ?" p7 i' Y. D* n8 y; x
  39.     IODELAY6 a0 W9 z1 j' T8 I6 r
  40.     test    al, 2                   ; bit1,输入缓冲区满?(控制器是否有数据没处理完). ^0 ^. z7 `$ `, A
  41.     jz      cmd_send                ; 缓冲区空,准备接收命令.
    $ X( e; ?2 ]! b& {
  42.     loop    cmd_wait                ; 缓冲区满,重试
    7 e, P" x4 Q5 m. b2 n# R4 A
  43.    
    # u$ K% y) t% p( ~: b  t( @
  44.     jmp     cmd_error               ; 超时,失败
    ! Z5 F3 a- o0 ~6 [" {* }; U
  45.     , X+ X- B+ F# V: e2 V( X
  46. cmd_send:
    # E' M$ T! }" i- w4 m, T
  47.     mov     al, bl                  ; 取 bl 中的命令字节2 n" I: n# f2 p9 |% l: k  y: q
  48.     out     64h, al                 ; 发送命令字节* u  g8 N( t( R' \0 E
  49.     IODELAY
    , E: G: [5 q$ r6 n: C

  50. " _2 N+ ]9 Q# U; x
  51.     xor     cx, cx                  ; 超时计数器(64K)* D- o# C; I% k
  52. cmd_accept:
    & g" [; D+ A5 ^" _% b
  53.     in      al, 64h                 ; 获取控制器状态/ _* k0 A" [1 F# |; S1 {
  54.     IODELAY% f( Y* N6 ~1 J# m! ^9 w0 g
  55.     test    al, 2                   ; bit1,输入缓冲区满?(控制器是否有数据没处理完)' R0 Y, x+ b1 A
  56.     jz      cmd_ok                  ; 缓冲区空,处理完: c8 v7 S; v4 L5 @
  57.     loop    cmd_accept              ; 缓冲区满,重试; V: l6 R- E1 F% y+ r0 t2 K4 `0 r
  58.     ) ]( b" i3 d+ E4 U! M/ |% B
  59. cmd_error:                          ; 超时失败5 B/ l5 I# N/ W
  60.     mov     ah, 1                   ; 失败返回状态非零
    & I4 m% C& p' l
  61.     jmp     cmd_exit
    ( d  {- S) _# ?  d( b  `% ~

  62. 1 z7 B. S% K% M
  63. cmd_ok:2 u7 R  x* `1 K! p- @! C1 F
  64.     xor     ah, ah                  ; 成功返回零
    2 O5 y5 T% t# k
  65.    
    3 [9 K% A: U. Q3 `
  66. cmd_exit:
    ! z; U1 a8 G  [( O6 V+ A- O0 N( d& I( j
  67.     ret
    " V7 r7 C' b4 `" R# H
  68. keyboard_cmd    ENDP
    ! [: C3 a+ y! e! ^4 o. r  L

  69. / Y9 H" _! h) m, \% J  ]9 X1 m
  70.     END    START
复制代码
2、PORT 92h5 Z8 q; y( c& j+ Z$ M
从EISA系统之后,系统控制端口定义了一位用来快速重启的寄存器,就是在PORT 92h的Bit0,这种方式最终结果是和KBC一样的,HOST会拉CPU的INIT#以让系统重启。但这种方式不通过KBC,所以速度更快一点,代码如下:
  1. in al, 92h
    / M# j+ X% h. C2 a' z" o
  2. IODELAY3 x2 Z" U4 T4 A3 c8 E- `7 k1 a
  3. or al, 1
    9 ~# D% f1 G; i" s9 _: w
  4. out 92h, al
      f# T% d+ @3 {3 L3 r
  5. hlt
    8 g0 R- H& N) g" i* w
复制代码
3、Reset Control Register(Port CF9h). B9 k% W! v: d4 Y
用此方法控制Reset,各Chip极有可能各芯片产商的做法会不同。
1 Y; h$ A) p" f: \/ ? 这里大家可以认识几种Reset的名词: Platform Reset, PCI Reset, System Reset, Reset CPU.我们来看Intel的文档,如下图:7 z) d2 S. F1 R
          1.GIF ! R( [9 q' K  K; B4 Q6 O
( D- m: s0 k( t
大家注意看,如果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。; `- r2 ]" g1 V: p# y) {

6 o5 f9 i+ P6 ] 因此你可以用下如代码Hard Reset:
  1. mov al, 6# r" ^5 U: B' S% u& h0 L& [6 |
  2. mov dx, 0CF9h
    0 I2 `8 a% o3 J  e  u6 Q
  3. out dx, al4 d) q' y/ F5 }0 Q# Z3 |2 N
  4. jmp $& |, Z' P) C/ q( k  A/ L) r
复制代码
也可以用如下代码“关机”(看你的机器的做法,也就是对SLP_S3#,SLP_S4#,SLP_S5#的处理):
  1. mov al, 0Eh' n1 T- i" x& O
  2. mov dx, 0CF9h
    ) ^7 t9 ^, R3 ~$ K" F9 Z! [9 x
  3. out dx, al
    / I, Z  p8 c5 h, K" G
  4. jmp $, z, Z; Y( b. M  ]
复制代码
4、Ctrl+Alt+Del; X& _9 O8 E( U
    这种方法“基本”是在“DOS”下有效,教课书上常称为"热启"。键盘中断会hook住你的按键,Hook就是BIOS的INT 09h软中断,当你按下这三个键时,就相当于Far jmp到 F000:FFF0处。用如下代码在DOS可实现热启动。
  1.     jmp     F000:FFF0
    3 s8 l( h: D3 z
  2.    
复制代码
OK,你对系统重启是否又清楚了一些呢?
发表于 2007-12-12 09:19:53 | 显示全部楼层

不错啊
回复

使用道具 举报

发表于 2007-12-12 16:10:17 | 显示全部楼层
不错,学习了。9 I) q) W$ I6 z3 `' k% ]3 }
还有人这样写:
! u7 o( f" S. S9 c) L1 Pmov     dx, 64h  7 A6 K' q1 c" m& q
mov     al, 0FEh
, U/ z, }, u, h& G4 uout     dx, al          : d' J# ~2 j( X. y4 @% D# t
in      al, 92h* b4 r1 m4 p! y+ u
or      al, 1! s3 k0 }4 t9 |4 N; C  k/ ]# m  a: E
out     92h, al
$ Q) y+ C2 S: U$ R' h) ]mov     dx, 0CF9h
9 T: l, G  r& E% H: K* e* bin      al, dx
# d& j+ [) M- b# l0 H4 l' ior      al, 6
& f8 [5 h0 Z* u( m* I4 g# b% oout     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 | 显示全部楼层
请教各位下 * E% v- T2 f+ p/ d4 r# w0 `! t) `
经常看到 “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:# l1 w0 J" M/ Q* s3 F
If(BIOS报告的ACPI Tabler版本>=2.0 && FADT中RESET_REG_SUP标志设置 && 系统中没有8042键盘控制器) {
9 O* u* }7 w' T; T  通过FADT报的RESET REGister和REset value reboot;
# r7 @+ u; j4 }% {5 g1 {; T$ D: S} else {8 ~, L% ]7 r: f9 M+ z" v
  port(64h)=0feh // 这种reset不是整个系统范围的reset,BIOS一般会检测到这种reset,并转换为RESET REG reset
# c# F, m: l1 w- @) J' U/ c}
) U  k3 n1 J1 q$ {% ^8 c' }9 X( Y# {4 W* }5 y# I
如果是UEFI的Windows,可能通过ResetSystem() runtime service来reboot.
回复

使用道具 举报

发表于 2008-10-31 12:29:21 | 显示全部楼层
Reset Register=0xCF9, Reset Value=0x06 or 0x0E ?; w, X9 K$ i/ g9 Y' r
Reset 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' e" d+ _3 |9 V* g* E/ I+ A
IODELAY
0 N. W# p2 r/ o6 g' p  v- R6 Wor al, 1
7 J% F' n5 _1 o. u% `/ Fout 92h, al6 J6 Y% ~5 E/ k7 E
hlt8 r- Q! L# n% J3 ~, C* Z( z$ o+ y% D

- K; U$ V% c# f) |) N  [9 `这个 有个问题 在 PC技术内幕 中第13章 提到这个92h端口时,说了在MCA中bit0确实是做重启& U; L9 B/ K0 d
但是在EISA中 bit0 只给了4个字的说明 :普通情况...
+ v& f, G" ^" J& n( Z! H5 A! i不解ing....
+ L! M! m0 M% B: J! d) B这样看 是不是 bit0 = 1也是做了重启?还是别的?! z( Y* T; R; u9 L* c
而且我目前的水平还不知道该怎么验证?  也许我对MCA和EISA没吃透...
回复

使用道具 举报

发表于 2009-3-3 12:50:24 | 显示全部楼层
参照ICH spec中对92h的说明: R: |+ E- P9 p( w* ^5 o7 E( o( B
INIT_NOW — R/W. When this bit transitions from a 0 to a 1, the Intel® ICH7 will force+ m! F1 g  v/ B
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:0 o2 t% x/ `. P! m' s
   srcore,( ]% ]- J8 n! u1 w1 T
      按照你所述,windows 下的重启,如果有KBC(EC),就是发0XFE吗?而我去追了一下,在EC收到0xFE 的地方 下了个断点,然后做windows 下重启, 以及CTRL+ALT+DEL,发现均没走这个流程,而是直接跑到了 EC check   warm reset 的位置去了(EC在不停的check  RSTRDY# 是否低,低则 warm reset )   ,难道是我们做的有问题?期待回复,谢谢!' O* p4 q! `4 |# A& K/ K3 R
  melow 平台(SCH+AMI CORE8)
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-5-5 19:01 , Processed in 0.044501 second(s), 19 queries .

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

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