標籤

2014年10月27日 星期一

How to use RTC reigister to set wake up time

From EDKII, It is simple but useful. If your BIOS vendor not provide the items in setup menu, you may give it a try.

1. Check your RTC_EN at PCH.
2. Refer to http://stanislavs.org/helppc/cmos_ram.html, set your alarm time, don't forget to set update enable/disable and AIE bit.

That's all,  EDKII sample code as below

LibSetWakeupTime (
  IN BOOLEAN      Enabled,
  OUT EFI_TIME    *Time
  )
{
  EFI_STATUS            Status;
  EFI_TIME              RtcTime;
  RTC_REGISTER_B        RegisterB;
  UINT8                 Century;
  EFI_TIME_CAPABILITIES Capabilities;

  if (Enabled) {

    if (Time == NULL) {
      return EFI_INVALID_PARAMETER;
    }
    //
    // Make sure that the time fields are valid
    //
    Status = RtcTimeFieldsValid (Time);
    if (EFI_ERROR (Status)) {
      return EFI_INVALID_PARAMETER;
    }
    //
    // Just support set alarm time within 24 hours
    //
    LibGetTime (&RtcTime, &Capabilities);
    if (Time->Year != RtcTime.Year ||
        Time->Month != RtcTime.Month ||
        (Time->Day != RtcTime.Day && Time->Day != (RtcTime.Day + 1))
        ) {
      return EFI_UNSUPPORTED;
    }
    //
    // Make a local copy of the time and date
    //
    CopyMem (&RtcTime, Time, sizeof (EFI_TIME));

  }
  //
  // Acquire RTC Lock to make access to RTC atomic
  //
  EfiAcquireLock (&mRtc.RtcLock);

  //
  // Wait for up to 0.1 seconds for the RTC to be updated
  //
  Status = RtcWaitToUpdate (100000);
  if (EFI_ERROR (Status)) {
    EfiReleaseLock (&mRtc.RtcLock);
    return EFI_DEVICE_ERROR;
  }
  //
  // Read Register B, and inhibit updates of the RTC
  //
  RegisterB.Data      = RtcRead (RTC_ADDRESS_REGISTER_B);

  RegisterB.Bits.SET  = 1;
  RtcWrite (RTC_ADDRESS_REGISTER_B, RegisterB.Data);

  if (Enabled) {
    ConvertEfiTimeToRtcTime (&RtcTime, RegisterB, &Century);

    //
    // Set RTC alarm time
    //
    RtcWrite (RTC_ADDRESS_SECONDS_ALARM, RtcTime.Second);
    RtcWrite (RTC_ADDRESS_MINUTES_ALARM, RtcTime.Minute);
    RtcWrite (RTC_ADDRESS_HOURS_ALARM, RtcTime.Hour);

    RegisterB.Bits.AIE = 1;

  } else {
    RegisterB.Bits.AIE = 0;
  }
  //
  // Allow updates of the RTC registers
  //
  RegisterB.Bits.SET = 0;
  RtcWrite (RTC_ADDRESS_REGISTER_B, RegisterB.Data);

  //
  // Release RTC Lock.
  //
  EfiReleaseLock (&mRtc.RtcLock);

  return EFI_SUCCESS;
}

2014年2月18日 星期二

UEFI edkI vs edkII


其實由intel和這種大企業制定的標準,本來就會比較OOXX。
現在又來個大改版,更加模組化。
光看資料的長相就大不同。



UEFI從edk到edkII,來小小整理一下,希望不要理解錯誤

UFEI是個interface,跟windows很像((畢竟就是這些人訂的
像是FV->folder, FFS->file,
所有描述的方式都是為了讓UFEI"認識"這是什麼東西。

到了edkII,又多了一個package,要讓他更模組化。
以往寫的driver或是module,就是一隻一隻的,沒有模組的概念。
現在可以把這些driver包起來變成一package。
蠻直觀,EX: Securitypkg,那大概裡面放的都是跟security有關的driver,
裡面會有自己的dsc,也可以分開build 這些package。
如果你發現package folder裡面沒有dsc檔,那是因為bios vendor幫你auto generate。
而且是for 整個project,我覺得失去edk2的原意,但你還是可以自己寫code去build。

缺點,是我覺得讓整個CODE又更加肥大了。

為了這樣的改變,就必須多一些描述,讓UEFI認識這些新東西。
像是inf裡面
[Packages]
  MdePkg/MdePkg.dec
  MdeModulePkg/MdeModulePkg.dec
[Pcd]
  gEfiMdeModulePkgTokenSpaceGuid.PcdLoadFixAddressBootTimeCodePageNumber    ## SOMETIMES_CONSUMES
  gEfiMdeModulePkgTokenSpaceGuid.PcdLoadFixAddressRuntimeCodePageNumber     ## SOMETIMES_CONSUMES
  gEfiMdeModulePkgTokenSpaceGuid.PcdLoadModuleAtFixAddressEnable            ## CONSUMES
  gEfiMdeModulePkgTokenSpaceGuid.PcdMaxEfiSystemTablePointerAddress         ## CONSUMES

多了packages and PCD的描述

至於PCD,platform configuration database,又讓code海更加茫茫。
翻開SPEC可用的protocol很簡單,不是get就是set。

我暫時簡單理解他像Setup variable那樣,也實際佔了ROM size,只是用途不同,可以runtime改變這些PCD的值((透過PCD的PROTOCOL去存取。
實作上還完全不明白。

DEC
定義PCD的entry,PCD entries會被build tool自動產生成 autogen.h autogen.c。

待續






Not least of which

"Not the least of which" usually follows a plural noun phrase that implies a set of things or qualities, and draws attention to a significant member of that set, e.g.

1. Tom has many engaging qualities, not the least of which is his considerable good humour.

Thus here, the underlined part is the set, and the emboldened part is the significant member of that set.

In your example, which is extremely elliptic, the set is only implicit:

2. Tom is a bad guy, [with many bad qualities], not the least of which [is the fact that] he is always criticizing others.

http://forum.wordreference.com/showthread.php?t=1442830

2014年1月24日 星期五

An Introduction To Programming With ATA And ATAPI

http://lateblt.tripod.com/atapi.htm

If you're familiar with computer maintenance procedures, you're probably familiar with IDE (Integrated Drive Electronics), the typical standard for connecting hard drives and CD-ROM drives to a PC. ATA (AT Attachment) is essentially the same thing as IDE; just a different name.
Most motherboards today have two IDE controllers built-in, designated as the primary and the secondary IDE controller. These two IDE controllers use the following standard I/O addresses:
Primary IDE controller: 1F0h to 1F7h and 3F6h to 3F7h
Secondary IDE controller: 170h to 177h and 376h to 377h
Each I/O address corresponds to a register on the IDE controller. The following is a list of each I/O address used by ATA controllers and the corresponding regiuster. (I/O addys given are for the primary IDE controller, obviously, but they correspond to the same secondary IDE controller addresses. Thus, for example, the secondary IDE controller's data register is at 170h, the secondary controller's error and features register is at 171h, and so on):
1F0 (Read and Write): Data Register
1F1 (Read): Error Register
1F1 (Write): Features Register
1F2 (Read and Write): Sector Count Register
1F3 (Read and Write): LBA Low Register
1F4 (Read and Write): LBA Mid Register
1F5 (Read and Write): LBA High Register
1F6 (Read and Write): Drive/Head Register
1F7 (Read): Status Register
1F7 (Write): Command Register
3F6 (Read): Alternate Status Register
3F6 (Write): Device Control Register
The status register is an 8-bit register which contains the following bits, listed in order from left to right:
BSY (busy)
DRDY (device ready)
DF (Device Fault)
DSC (seek complete)
DRQ (Data Transfer Requested)
CORR (data corrected)
IDX (index mark)
ERR (error)
The error register is also an 8-bit register, and contains the following bits, again listed in order from left to right:
BBK (Bad Block)
UNC (Uncorrectable data error)
MC (Media Changed)
IDNF (ID mark Not Found)
MCR (Media Change Requested)
ABRT (command aborted)
TK0NF (Track 0 Not Found)
AMNF (Address Mark Not Found)
ATA commands are issued by writing the commands to the command register. More specifically, ATA commands are issued using the following steps:
1. Poll the status register until it indicates the device is not busy (BUSY will be set to 0)
2. Disable interrupts (assembler "cli" command)
3. Poll the status register until it indicates the device is ready (DRDY will be set to 1)
4. Issue the command by outputting the command opcode to the command register
5. Re-enable interrupts (assembler "sti" command)
The following program is a relatively simple assembler program to run the ATA "IDENTIFY DRIVE" command, and print out the results of this command to the screen.
MOV DX, 1F7h ;status register
LOOP1:
IN AL, DX ;sets AL to status register (which is 8 bits)

;If the first bit of the status register (BUSY) isn't 0, the device is busy,
;so keep looping until it isn't.

AND AL, 10000000xB
JNE LOOP1

;----------------------------------------------------------------------------

;Clear interrupts so something doesn't interrupt the drive or controller
;while this program is working.
CLI

;----------------------------------------------------------------------------

MOV DX, 1F7h ;status register again
LOOP2:
IN AL, DX ;sets AL to status register again

;If the second bit of the status register (DRDY) isn't 1, the device isn't
;ready, so keep looping until it is.

AND AL, 01000000xB
JE LOOP2

;----------------------------------------------------------------------------

MOV DX, 1F6h ;device/head register
MOV AL, 0 ;0 selects device 0 (master). 10h would select device 1 (slave).
OUT DX, AL ;selects master device

MOV DX, 1F7h ;command register
MOV AL, 0ECh ;"IDENTIFY DRIVE" command
OUT DX, AL ;sends the command!

;----------------------------------------------------------------------------

MOV DX, 1F7h ;status register
LOOP3:
IN AL, DX

AND AL, 00001000xB ;if DRQ is not high, the device doesn't have data for us
JE LOOP3 ;yet, so keep looking until it does!

;----------------------------------------------------------------------------

MOV DX, 1F0h ;data register
MOV DI, OFFSET buff ;points DI to the buffer we're using
MOV CX, 256 ;256 decimal. This controls the REP command.
CLD ;clear the direction flag so INSW increments DI (not decrements it)
REP INSW

;----------------------------------------------------------------------------

;We now have the string data in buff, so let's re-enable interrupts.

STI

;----------------------------------------------------------------------------

;...And now we can display the contents of buff!

MOV ES, SEG buff
MOV BX, OFFSET buff
MOV CX, 256 ;256 decimal
MOV AH, 2 ;"display output" option for INT 21
LOOP4:
MOV DL, [BX] ;moves the contents of the byte from "buff" into DL
INT 21h
INC BX
LOOPNZ LOOP4 ;does this 256 times, because CX was set to 256

mov ah,004C  ;terminate program
int 21h

buff db 256 DUP(?) ;buffer to hold the drive identification info
ATAPI (ATA Packet Interface) is an extension to ATA which essentially allows SCSI commands (commands used to control SCSI devices) to be sent to ATA devices. ATAPI is used specifically for CD-ROM drives, which, when they first started appearing for computers, were almost universally SCSI. Because SCSI controllers were expensive and clunky, the SCSI command set was eventually adopted for IDE, and typical CD-ROM drives today use ATAPI. ATAPI basically uses "packets" (similar to the packet concept of computer networking as it applies to TCP/IP, for example) to send and receive data and commands. Properly speaking, ATAPI is part of the EIDE (Enhanced IDE) standard.
A packet sent to an ATAPI device which contains a command is called a command packet. These command packets are written to the data register via the ATA interface, and that's how ATAPI devices receive their commands. The command packet has a 12-byte standard format, and the first byte of the command packet contains the actual operation code. (The remaining 11 bytes supply parameter info for the command.) Note that although the command packet is 12 bytes long, the packet is sent to the ATAPI device through word writes, not byte writes. A "word" in PC assembly language is 2 bytes, so you'll actually send the 12-byte command packet in only 6 write operations.
The "operation code" value you place in the ATAPI command packet is actually a SCSI command code. You do not use ATA commands with ATAPI devices; ATAPI devices use SCSI commands. For example, the SCSI command to eject a CD-ROM drive tray is the "START/STOP UNIT" command, which is SCSI command 1Bh. Similarly, to get an ATAPI CD-ROM drive to eject, you'd send it a command packet with 1Bh for an operation code.
ATAPI contains several commands, but the most fundamental of these is the PACKET command, which has an ATAPI opcode of A0h. The first step in sending a command to an ATAPI device is to send it the PACKET command over the regular ATA command register, just as the program above sends the IDENTIFY DEVICE command. Once this PACKET command is sent, the ATAPI interface goes into a condition called HPD0: Check_Status_A State, which means that the ATA controller is to wait for 400 nanoseconds, then poll the status register until the BSY bit is zero. If the BSY bit is one, the host is supposed to keep polling the status register until the BSY bit clears.
Once the BSY bit does clear (and DRQ is set to one), the ATAPI interface changes to HPD1: Send_Packet State. In this state, the host is supposed to send the command packet to the ATA controller's data register, one byte at a time. When all the bytes of the command packet have been sent, the host is to either transition to HPD2: Check_Status_B State (if nIEN is set to one), or to HPD3: INTRQ_Wait State (if nIEN is set to zero). Note that nIEN is the second-rightmost bit of the ATA Device Control Register. You will note that this register is write-only, so you should write to this register to set nIEN before you begin sending the ATAPI packet.
If the host does transition to HPD3: INTRQ_Wait State, all it's supposed to do is wait for INTRQ to be asserted. When INTRQ is asserted, then the host shall transition to HPD2: Check_Status_B State.
The HPD2: Check_Status_B State is where things get a little hairy. This is where you check the status register, but there are a lot of condition bits you're supposed to check. First of all, the ATAPI spec specifies that "When entering this state from the HP1 ... state, the host shall wait one PIO transfer cycle time before reading the Status register. The wait may be accomplished by reading the Alternate Status register and ignoring the result."
Once that's done, start checking the status register. First of all, if BUSY is set to 1, the host is not to leave the HPD2 state. The host is supposed to remain in HPD2 until BUSY clears to zero.
Once BUSY is zero, check DRQ. If DRQ is set to one, then the host shall transition to yet another state, called the HPD4: Transfer_Data State. However, the only time you'd need to enter HPD4 is if DRQ is 1 during the HPD2 State. If DRQ is zero now, you can skip HPD4 altogether.
If both BUSY and DRQ are zero, then, the command is probably complete. Technically, there are a few other things you're supposed to check, but we won't worry about those now.
The following is an ugly program in assembler to eject a CD-ROM drive. I haven't cleaned up the code as nicely as I should, but it does work as long as you run it in real mode (what Win9x users would call "DOS mode").
MOV DX, 177h ;status register
LOOP1:
IN AL, DX ;sets AL to status register (which is 8 bits)

;If the first bit of the status register (BUSY) isn't 0, the device is busy,
;so keep looping until it isn't.

AND AL, 10000000xB
JNE LOOP1

;----------------------------------------------------------------------------

;Clear interrupts so something doesn't interrupt the drive or controller
;while this program is working.
CLI

;----------------------------------------------------------------------------

MOV DX, 177h ;status register again
LOOP2:
IN AL, DX ;sets AL to status register again

;If the second bit of the status register (DRDY) isn't 1, the device isn't
;ready, so keep looping until it is.

AND AL, 01000000xB
JE LOOP2

;----------------------------------------------------------------------------

MOV DX, 176h ;device/head register
MOV AL, 0 ;0 selects device 0 (master). 10h would select device 1 (slave).
OUT DX, AL ;selects master device

;IMPORTANT: Set nIEN before you send the PACKET command!
;Let's set nIEN to 1 so we can skip the INTRQ_Wait state.

MOV DX, 3F6h ;Device Control register
MOV AL, 00001010xB ;nIEN is the second bit from the right here
OUT DX, AL ;nIEN is now one!

MOV DX, 177h ;command register
MOV AL, 0A0h ;PACKET command
OUT DX, AL ;sends the command!

;After sending the PACKET command, the host is to wait 400 nanoseconds before
;doing anything else.
MOV CX,0FFFFh
WAITLOOP:
LOOPNZ WAITLOOP

;----------------------------------------------------------------------------

MOV DX, 177h ;status register again
LOOP3:
IN AL, DX ;sets AL to status register again

;Poll until BUSY bit is clear.

AND AL, 10000000xB
JNE LOOP3

;Also, poll until DRQ is one.
MOV DX, 177h ;status register again
LOOP4:
IN AL, DX
AND AL, 00001000xB
JE LOOP4

;----------------------------------------------------------------------------
;NOW WE START SENDING THE COMMAND PACKET!!!

MOV CX, 6 ;do this 6 times because it's 6 word writes (a word is 2 bytes)
MOV DS, SEG buff
MOV SI, OFFSET buff
;DS:SI now points to the buffer which contains our ATAPI command packet
CLD ;clear direction flag so SI gets incremented, not decremented

COMPACKLOOP: ;command packet sending loop
MOV DX, 170h ;data register

;Because we're going to need to write a word (2 bytes), we can't just use an
;8-bit register like AL. For this operation, we'll need to use the full width
;of the 16-bit accumulator AX. We'll use the LODSW opcode, which loads AX
;with whatever DS:SI points to. Not only this, but if the direction flag is
;cleared (which we did a few lines above with the CLD instruction), LODSW
;also auto-increments SI.
LODSW
OUT DX, AX ;send the current word of the command packet!!!

MOV DX, 3F6h ;Alternate Status Register
IN AL, DX ;wait one I/O cycle

LOOPNZ COMPACKLOOP

;----------------------------------------------------------------------------

;Once again, let's read the Alternate Status Register and ignore the result,
;since the spec says so.

MOV DX, 3F6h
IN AL, DX

;Okay... That's done.
;Time to poll the status register until BUSY is 0 again.

MOV DX, 177h ;status register
LOOP5:
IN AL, DX

AND AL, 10000000xB
JNE LOOP5

;BUSY is zero here.
;We're also supposed to check DRQ, but hey, screw it.

STI

;----------------------------------------------------------------------------

mov ah,004C  ;terminate program
int 21h

buff db 1Bh, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0

2011年7月21日 星期四

[轉貼] BIOS中SLIC 2.1表詳細組成及驗證激活相關解釋說明

http://hi.baidu.com/elffin/blog/item/fbab8ced160438db2e2e21f0.html



目前,Windows 7比較完美的破解方式是通過OEM方式激活。SLIC表是OEM激活中的關鍵部分,我們可以選擇喜歡品牌的SLIC,修改加入本機的BIOS中,實現Windows的OEM完美激活。

了解SLIC表構成原理及其驗證方式對於修改或定制BIOS進行OEM激活是非常重要的。

本來我想這方面應有較詳細的解釋教程,但是只找到了http://www.bios.net.cn/bbs/thread-66783-14-7.html關於SLIC構成的文章。該文對SLIC表頭進行了說明,但缺乏其他兩部分以及SLIC表含義等的一些解釋。理解了這些問題,才能選擇合適的SLIC表,正確手動修改BIOS,而且知道能否可以成功通過驗證激活。

在此只好自己動筆對SLIC表相關內容進行整理解釋,其中有些是我的經驗、理解和推想,不一定完全正確,歡迎指正。如果轉載請註明出處,謝謝!

微軟公司一直在加強防盜版方面工作。從Windows XP微軟開始引入了SLP(System-Locked Preinstallation)技術,在預安裝過程中將系統同硬件鎖定來防止盜版,該技術僅用於OEM方式的產品激活。Windows 7採用的是SLP 2.1技術,對於驗證信息進行逐級保護,驗證激活過程需要SLIC表支持。(關於SLP技術和OEM激活相關內容可參考《Windows 7的OEM激活條件及驗證過程相關說明》,該文可與本文互相印證有助理解)

SLIC是軟件許可內部代碼(Software Licensing Internal Code)的縮寫,它位於BIOS的ACPI中,由OEM廠商根據微軟的的要求進行製作,包含了SLP 2.x驗證需要的相關信息。
下面表2我們以HP的SLIC 2.1為例進行說明,不同顏色表示各個組成部分,表1對其各個部分進行說明。

從表中我們可以看到,SLIC總體分成三個部分:一個表頭部分,兩個存儲內容的部分。表頭部分包含SLIC表的一些基本信息。Public Key部分保存公鑰信息。Marker部分保存標記信息和數字簽名。具體參考表1中說明。


位置
中文描述
英文描述
字节长度
说    明
000~023
表头部分
Header
36
提供SLIC表相关基本信息。
000~003
标识
Signature
4
表名: SLIC
004~007
表长
Length
4
整个表的长度: 176H,即374字节。
008
修订
Revision
1
SLIC的版本,目前为1
009
校验位
Checksum
1
重要。修正此项使整个SLIC表校验和为0
00A~00F
OEM标识
OEMID
6
重要。用来标识OEM厂商。
010~017
OEM Table 标识
OEM Table ID
8
重要。OEM厂商用来标识机型、主板或者BIOS。
018~01B
OEM 修订
OEM Revision
4
OEM 厂商进行的修订,主要为提供 OEM Table ID
01C~01F
创建者标识
Creator ID
4
创建此表的工具提供者标识
020~023
创建者修订
Creator Revision
4
创建此表的工具修订信息
024~0BF
软件许可公钥部分
Software Licensing Public Key structure
156
由OEM厂商创建并提供的RSA公钥,二进制形式
03C~03F
公钥指数
Public Key Exponent
4
RSA公钥的指数部分,总是为 01 00 01 00 。
040~0BF
公钥模数
Public Key Modulus
128
RSA公钥的模数部分,用来解密数字签名 。
0C0~175
软件许可Windows标记部分
Software Licensing Windows marker structure
182
Windows 标记信息及其数字签名
0C8~0F5
标记信息
Marker Message
46
Windows 标记所包含信息
0C8~0CB
标记版本
Windows Marker Version
4
目前总是为00 00 02 00 。
0CC~0D1
OEM标识
OEMID
6
重要。同上。
0D2~0D9
OEM Table 标识
OEM Table ID
8
重要。同上。
0DA~0E2
Windows 旗标
Windows Flag
8
总是为 “Windows ”
0E2~0E5
备用标记版本
Reserved Marker Version
4
重要。备用的标记版本信息,SLIC2.1中使用。
0E6~0F5
备用字节
Reserved Bytes
16
为保存将来信息备用。目前总是全部为00 。
0F6~175
标记数字签名
Marker Digital Signature
128
Windows 标记信息的数字签名,用来保护标记信息

表1 SLIC表组成部分详细说明


ACPI_SLIC
00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
   
00000000:
00000010:
00000020:
00000030:
00000040:
00000050:
00000060:
00000070:
00000080:
00000090:
000000A0:
000000B0:
000000C0:
000000D0:
000000E0:
000000F0:
00000100:
00000110:
00000120:
00000130:
00000140:
00000150:
00000160:
00000170:
53 4C 49 43 76 01 00 00   01 AB 48 50 51 4F 45 4D
53 4C 49 43 2D 4D 50 43   01 00 00 00 48 50 51 20
01 00 00 00 00 00 00 00   9C 00 00 00 06 02 00 00
00 24 00 00 52 53 41 31   00 04 00 00 01 00 01 00
5B AB 60 56 BC 58 1E E8   C1 D2 A1 5C E5 4F BB FD
1D A9 8C 94 B4 AE 08 11   DC 13 59 D3 7F F6 3E 87
31 B9 95 74 10 DA 3B A4   5B B5 19 82 7C 39 D7 0D
7C 22 AC 1C 2A 84 E9 0A   88 6D FA B1 E2 D8 E8 21
96 E1 2E 68 9A BF 44 45   3E 3C 8E 99 90 DE 37 38
57 0B 92 15 BC DE FF F2   07 7E B5 40 8C 51 3A C3
02 48 F6 13 12 72 FB 42   78 E6 47 88 54 C7 B0 F0
93 9E FB 04 B7 B8 B8 90   DE DB ED 32 E1 FB 54 A6
01 00 00 00 B6 00 00 00   00 00 02 00 48 50 51 4F
45 4D 53 4C 49 43 2D 4D   50 43 57 49 4E 44 4F 57
53 20 01 00 02 00 00 00   00 00 00 00 00 00 00 00
00 00 00 00 00 00 30 90   1F B4 A4 BE 80 1E E9 33
EC 7F FC B1 28 0E A6 CE   43 72 8C 79 30 B4 F4 59
EA 7D CF B7 11 8B DA 70   C5 C8 3F 79 20 08 6F 64
CA 07 88 B3 B1 16 B4 BA   1A F1 85 52 B1 F5 07 55
B5 70 61 EF 44 8C AA 5F   78 14 66 98 9C F3 58 D8
AA 48 E0 37 F8 F6 AB 64   FA DA 17 2A 62 E3 04 1D
32 2D D5 EA 33 66 5C 5B   3B 0E F7 09 66 42 32 AA
14 99 C3 EE 1A 62 3B 07   5F F0 48 44 C4 E6 32 59
1F 14 3E F1 B2 38 
SLICv....«HPQOEM
SLIC-MPC....HPQ 
........œ.......
.$..RSA1........
[«`V¼X.èÁÒ¡\åO»ý
.©Œ”´®..Ü.YÓ ö>‡
1¹•t.Ú;¤[µ.‚|9×.
|"¬.*„é.ˆmú±âØè!
–á.hš¿DE>
W.’.¼Þÿò.~µ@ŒQ:Ã
.Hö..rûBxæGˆTǰð
“?û.·¸¸?ÞÛí2áûT¦
....¶.......HPQO
EMSLIC-MPCWINDOW
S ..............
......0?.´¤¾ .é3
ì ü±(.¦ÎCrŒy0´ôY
ê}Ï·.‹ÚpÅÈ?y .od
Ê.ˆ³±.´º.ñ…R±õ.U
µpaïDŒª_x.f˜œóXØ
ªHà7øö«dúÚ.*bã..
2-Õê3f\[;.÷.fB2ª
.™Ãî.b;._ðHDÄæ2Y
..>ñ²8
表2 SLIC表组成内容样例(HP的HPQOEMSLIC-MPC SLIC 2.1)

* 簡要解釋一下SLIC相關原理及使用,對錶格內容做一下補充說明

1. 查看SLIC表時要注意,表中數值採用倒序(Little Endian)方式存儲,即高位字節在後、低位字節在前,這是IA架構慣用的存儲方式。

2. SLIC表提供了驗證相關信息。其中表頭信息不必解釋。SLIC表將驗證所需的重要信息保存在Marker Message部分,並加入了數字簽名技術以防偽造。就是說,OEM廠商創建了一對相匹配的公鑰和私鑰,將私鑰秘密保存並用私鑰對Marker Message部分進行簽名,將簽名結果保存在Marker Digital Siginature部分,並將用來解密的公鑰放在Public Key部分發佈出來。

任何人都可利用公鑰對數字簽名通過模冪運算進行解密,然後與Message進行對照驗證是否正確。但是沒有私鑰,無法自己偽造正確的簽名。這就保證了所存儲信息的安全。以上概述不盡準確,更具體的過程請參考http://forums.mydigitallife.info/showthread.php?t=7532。

2.還要防止發布的公鑰被篡改,這通過與OEM證書的匹配驗證來實現,OEM證書中保存了公鑰、OEMID、Marker Version相匹配的信息,可用來匹配驗證公鑰等信息的正確性、關於證書與SLIC的匹配參考http://forums.mydigitallife.info/showthread.php?t=4792。當然,另一步還要保證OEM證書不被偽造,這不屬於本文內容。(以上兩篇參考文章BIOS之家有oho77的譯文) 

3. SLIC的正確性檢查還包括校驗正確,OEMID和OEMTableID和RSDT以及XSDT中的相應部分一致等。 

4. SLIC表由OEM廠商發布,幾乎無法偽造。因為它包含了利用RSA演算法原理進行加密的數字簽名,並使用1024位密鑰,理論上說破解它需要的計算資源是不現實的。因此只能從電腦中提取OEM廠商公佈的SLIC表。可查看《多家OEM品牌SLIC2.1及證書打包下載》。當然一些不受保護的部分可以修改,比如表頭中的一些內容。

5. SLP 2.0的時候,微軟使用Windows Marker Version部分標示版本,但是該部分受到匹配OEM證書的保護。如果改變就需要新的OEM證書。可能微軟覺得麻煩,在2.1中改用原來保留字節0E2~0E5做為新的Marker版本,該部分還沒有名字,這裡的名字(Reserved Marker Version)是我加的。

6.由於Messege部分的Reserved Marker Version做了改變,即使OEMID、OEM Table ID和公鑰沒有改變,Marker中的數字簽名需要重新生成。我想這可能是SLIC 2.0和2.1的僅有區別。

7. 發布Windows 7以後,大部分OEM廠商可能為省事,仍然使用Vista也就是SLP 2.0時候的密鑰。而OEMID、Marker Version部分通常也沒改變,因此在Windows 7中仍然可以使用Vista的證書。這些廠商包括HP、DELL、Lenovo等等。部分OEM廠商更換了新的密鑰,因此需要新的證書,這包括Acer、BenQ等。(對後者,我想如果用Vista也需要使用新的證書)

8. 實際觀察SLIC發現,大多數OEM廠商只使用一個OEMID,比如HP的OEMID為HPQOEM,IBM的為LENOVO。但是也有例外,比如Toshiba,使用TOSASU、TOSCPL、TOSINV等幾個OEMID,因此需要對應不同的OEM證書。

9. 對絕大數相同OEMID,使用同一個密鑰,因此可使用同一個OEM證書,而不必管OEM Table ID是什麼。比如,LENOVOTP-6F、LENOVOTP-6H、LENOVOTC-5I、LENOVOTP-7X等等都可以使用同一個證書。但也有個別例外,比如OEMID同為PacBel的SLIC 2.0就採用了兩種以上的密鑰,需要對應不同證書。

10.整個驗證過程重要的是OEMID、OEM Table ID等信息。同一個OEM廠商,通常設置不同的OEM Table ID從而產生不同的SLIC(Marker部分不同),用於不同的機型。OEM Creator ID、Revision等對驗證過程基本上沒有影響。

11.並非所有的SLIC表在BIOS中都是這種標準構成形式,有的形式可能有所改變,比如聽說有的DELL的Marker部分和Public Key部分會調換等。

12. 微軟在盜版保護有關說明中提到,BIOS中的SLIC有關信息是不能改變的,包括BIOS中的其他有關驗證內容。因此有些OEM刷新程序在更新BIOS的時候會跳過SLCI部分,以防止SLIC被修改。

13. SLIC主要用來提供正確的OEM廠商相關信息,與Windows版本無關。也就是說同樣SLIC可以用於32或64位 Windows 7各種版本的安裝。而且SLIC 2.1可以向下兼容各種版本Vista的安裝。

* OEM廠商製作和使用SLIC表的過程說明

了解SLIC表的製作過程可以有助於更好的理解SLIC表的內容。OEM廠商製作SLIC表的過程如下:
1.到微軟OEM在線(MOO)網站提交OEM激活2.x的申請材料。
2.獲得相關激活資料,包括激活工具OATool.exe 。
3.利用OATool產生一對匹配的RSA公鑰(Public Key)和密鑰。
4.利用OATool,創建SLIC Public Key部分,和包含公鑰、OEMID等信息的待簽名xml文件。
5.將該xml文件提交給微軟,獲得經過微軟簽名認證過的OEM證書。
6.根據產品情況設置OEM Table ID。
7.利用OATool,根據OEM ID和OEM Table ID等信息,用自己的私鑰進行簽名,生成SLIC Marker部分。該Marker部分包含了Marker版本(是否為2.1)等信息。
8.按照SLIC結構,建立符合APCI標準,包含OEMID、OEM Table ID、Public Key和Marker等部分的SLIC表。
9.將該SLIC表放到Windows可以通過ACPI_SLIC BIOS系統表訪問的BIOS相應位置。並保證RSDT和XSDT中的OEMID、OEMTABLEID相一致。
10.製作包含序列號和證書的自動安裝光盤。

*幾個SLIC表相關工具 
——用於查看和提取本機SLIC的工具:SLIC_Dump_Toolkit 
——用於查看SLIC文件和防偽驗證工具:SLICInfo 
——用於檢測和修復SLIC文件校驗字節的工具:SLIC-Checker
——用於驗證SLIC文件和OEM證書是否匹配工具:PubKeyCompare 
以上可以工具在《多家OEM品牌SLIC2.1及證書打包下載》中下載。 

—— 推薦:用來查看和防偽驗證SLIC文件及OEM證書、並驗證是否匹配的在線工具http://www.d-fault.nl/test/。 該頁面沒有製作者信息,前幾天看到有人懷疑這是微軟或者其他人用來收集相關信息的。這裡說明一下,該在線工具可以放心使用,其維護者是mydigitallife.info上的網友freeStyler ,請看http://forums.mydigitallife.info/showpost.php?p=107444&postcount=257及該主題相關信息。