Windows XP implements ACPI 1.0b and supports a few new features defined in ACPI 2.0
將自己踏入BIOS領域中所學習到的知識做一些心得整理,像是Legacy BIOS、EFI BIOS、Windows Driver...etc. ※版權與智慧財產權聲明:保留所有法律權利。我在寫文章時如果有引用到其他人的地方我會盡量說明參考出處,如果有遺漏的地方請告訴我,我會馬上註明! 而轉貼我的文章時也請您註明出處!
星期六, 11月 06, 2010
ACPI1.0/ ACPI2.0 傻傻分不清楚?
Windows XP implements ACPI 1.0b and supports a few new features defined in ACPI 2.0
星期四, 10月 14, 2010
星期三, 9月 15, 2010
#include 用法
星期一, 8月 16, 2010
基本攝影入門
星期二, 7月 27, 2010
Memory Access
星期日, 7月 25, 2010
SF100 燒錄程式
星期日, 7月 11, 2010
EFI_DRIVER_ENTRY_POINT() 的意義
如果你有追進去看他的定義,你就會發現在一般的情況下,他其實是一個空的巨集定義
也就是不代表任何意義,在你Compiler code之後,也不會產生任何東西! 因此,在你的Driver.c內有沒有這個巨集並不會影響到你的code的執行!
不過,一般我們都還是會定義成跟你的Driver EntryPoint函數名稱一樣,來增加"可讀性"
除了一般的情況之外,如果你想把你的Driver放到NT模擬器下面執行時,這個巨集就非常重要了! 因為Window 32 bit環境下的執行檔案的進入點跟EFI不同,所以你的Driver想要在模擬器下執行時,你就必須透過這個巨集來重新定義函數原型宣告,不然你就沒辦法在NT下的模擬器執行你的EFI Driver.
所以結論就是:
如果你沒有要在NT模擬器跑你的EFI Driver,那你是可以忽略這個寫法! 但是,還是建議你保持良好的寫code習慣,增加可讀性,所以多一行code應該是不會花你太多時間啦~
星期三, 6月 30, 2010
EFI_SOURCE
而加入$(EFI_SOURCE)跟沒有加入的差別在哪裡?
答案就是:
有加 $(EFI_SOURCE) 就會是絕對位置
沒加 $(EFI_SOURCE) 就會是相對位置
星期二, 6月 01, 2010
星期四, 5月 20, 2010
Unicode 字元查詢
而有一些特殊字元顯示在畫面上時可能會需要做一些修改,此時如果能知道那個字元的形狀,修改起來就更方便。
這邊就介紹一下我常用的網站,用來查詢 Unicode 字元的地方:
http://www.fileformat.info/info/unicode/char/search.htm?q=U%2B25ba&preview=entity
這個網站可以方便你搜尋你要的字元,你只要在Unicode Character Search的地方的Query輸入你想要的搜尋字元 (格式: U + Unicode) ,例如我要查詢0x25BA這個字元我就輸入:
按下Search 後,就會在下面的地方出現相關的資訊,如下圖所示:
你可以看到我查詢的字元是一個"右箭頭"........ 很方便吧! ^^
星期四, 4月 29, 2010
申請美簽~
因為有點小複雜,所以把一些同事跟我自己填資料的心得分享一下:
1.先到AIT美國在臺協會網站填寫預約申請,預約面試日期
http://www.ait.org.tw/zh/visa/niv/#application
a. DS-156(非移民簽證申請表): 線上填寫申請表跟一般申請表
b. 男性還需要多填一份:DS-157 (非移民簽證申請表補充說明) 申請表
2.外交部網站可以方便你查詢護照外文姓名拼音對照表
(一般護照拼音最好跟信用卡英文姓名一樣,以避免國外刷卡問題)
http://www.boca.gov.tw/ct.asp?xitem=1608&ctnode=193
3.男性還要多填一份 DS-157表格,而這份表格內需要填的資料中有些比較特別:
a.會有兵種的兵階資訊,可以從下面網站查詢:
http://en.wikipedia.org/wiki/Military_of_the_Republic_of_China
陸軍:ARMY 海軍:Navy 空軍Air Force 憲兵隊:Military Police
b.國中/高中/大學/研究所資訊可以直接用google去查到你的母校的網站,一般都會有英文版
如果沒有英文版的網頁,那你就要靠下面的郵局網站來幫你轉換學校的中文地址:
http://www.post.gov.tw/post/internet/f_searchzone/index.jsp?ID=190103
4.以下是我們同事申辦美簽的經驗分享:
a. 早上8:00的預約的話就是AM8:00進去,如果護照沒帶的話AM10:30前警衛都會放你進去。
不然就要在網路上重新登記,就不能在當天辦好。也就是說只能改天再來。
b. 進去時候警衛會叫你把手機與名片(證件)拿在手上,他會幫你放在置物櫃保管,並給你號碼牌。等下出來的時候可以憑號碼牌跟警衛領回手機。之後會通過X光機,身上的金屬物品(皮帶,手錶)最好放在袋子中。然後袋子要過像海關一樣的X光機。人就過人要走的X光機。領回袋子後就可以走進去排隊。
c.會檢查文件(DS-156 男生要加填DS-157)是不是齊全。像我就是照片貼太上面,沒有延著虛線貼。有點擋到條碼部分。所以那邊的服務人員會幫我重貼,他身上有膠水。我只要照著他們吩咐排隊,坐在椅子上等待。等到我要辦手續的時候,他自然會幫我處理。那邊也有電視,會撥按指紋與下面幾個流程的說明。可以坐在椅子上看要怎麼樣給他們刷條碼,自己要按指紋。
d.家人最好走在一起,因為有些手續家人要一起辦。
e.然後進到面談那關! 面試通過後,遞給你快遞單然後出去填資料。送件地址我就填公司地址。那邊有快遞公司的人會幫你服務。單子填完交給他就好。然後人就可以到外面憑號碼牌領回自己的手機。就可以回去等快遞把我的護照寄來了。 (錢等快遞到的時候再付錢)
我面試日期在下星期,希望也能順利拿到美簽啦~
星期四, 4月 22, 2010
Cx State
先說說Cx State 在BIOS端是怎麼跟CPU還有ASL code甚至是SetupMenu串再一起的.
首先,一般BIOS會在SetupMenu中建立出一些item來控制Cx State的Enable/Disable,這部分會因為各家BIOS在SetupMenu上的做法不同而有所不同,但是你只要知道一個東西! 就是一定會有一個地方儲存好SetupMenu上選項內的設定值. (Ex: CMOS/EFI Variable...)
接著,在PPM 的相關 Reference code那邊 (一般都是Ixxel的CPU的PPM reference code)會去參考SetupMenu內的設定值來組態CPU內部的MSR暫存器,至於他是如何得到SetupMenu的設定值又會因為不同的BIOS而有所不同,像是EFI就可能透過Policy來得到,所以要有人把SetupMenu的值放進去Policy內,這樣子Reference code才能參考SetupMenu的選項來組態MSR!
當這邊在一般組態MSR時,他會一邊修改Acpi Table! 例如你想關閉C2/C3,大家都知道去ACPI Table把值改成>100 或是 > 1001就可以了,所以這邊的Reference code會去參考你的SetupMenu的設定值來決定要不要修改ACPI Table內那個回報給OS的值!
其他的部分有牽扯到ASL code的部分我可能就不明說了,請大家搜尋CFGD這個值,看看他在哪邊被放進,然後ASL code為什麼要判斷他! 追個一遍就清楚了^^Y
星期三, 4月 07, 2010
星期六, 4月 03, 2010
DirectX v.s VGA driver
結果在執行的時候,卻發現他跳出了一個錯誤訊息:
File=dxvideo.cpp,Line=649,Code=80004001
原本以為是VGA driver的問題,所以花了很多時間去找了最新版的Nvidia driver重新安裝,
然後再去抓了DirectX for XP SP3的更新檔來安裝! 但是結果還是沒辦法進入遊戲之中!
因此秉持著研究的精神,先去研究了一下這個網路遊戲需要的解析度,發現這個2D網路遊戲
神州Online 是預設 640 x 480 x 16 的解析度,而網路上相關的討論是說去修改遊戲目錄內的
Online.ini:
[SYSTEM]
Width = 800
Height = 600
Fullscreen = 0
Switchscreen = 1
把他強制設定成800 x 600這樣子就可以進入遊戲,然後不要全螢幕(Fullscreen = 0) ,
而Switchscreen =1是用來設定這款遊戲能不能用Alt+Enter 來切換視窗化!
雖然這樣子可以進入遊戲 ,但是畫面就是變成視窗化那樣子! 玩起來總是感覺怪怪的!
因此很不死心的繼續追問題~在google大神找了很久之後發現可以利用Dxdiag這個工具來檢
查一下你的系統的DirectX有沒有甚麼問題!
因此我就選了開始->執行->鍵入dxdiag,然後就看到測試的視窗出現了!
從畫面上可以看到我的顯示晶片是Quadro NVS 140M,然後你可以點選【測試DirectDraw】
或是【測試Direct3D】,我是先選了【測試DirectDraw】。
然後就看到了下面的地方出現了:
DirectDraw test results: Failure at step 17 (SetDisplayMode to 640x480x16): HRESULT = 0x80004001 (Not implemented)
Direct3D 7 test results: Failure at step 39 (SetDisplayMode to 640x480x16): HRESULT = 0x80004001 (Not implemented)
啥米? 我的螢幕解析度不支援640 x 480??! 所以我就看了一下我的螢幕解析度的支援!
還真的不能使用640 x 480,最小只到800 x 600 ,難怪我的遊戲一直會出現dxvideo.cpp 有問題!
因為根本就沒辦法切過去640 x 480!
而知道的問題的原因之後,就開始針對Quadro NVS 140M來找解決方案!
然後就找到了一個網站跟他所提到的工具可以解決這個顯示晶片不支援640x480的方法:
http://werdna1222coldcodes.blogspot.com/2010/02/directdraw-init-failed.html
於是在使用了這個RivaTuner的方式自己增加了一個640x480x16的解析度之後,再重新開機!
開機完重新執行dxdiag跟我的網路遊戲,結果問題真的就解決了耶!
所以結論就是: 太好的VGA,會讓你沒辦法玩舊款遊戲! 但是想玩遊戲,就只好多認真點學些
東西! 希望這篇文章能夠幫助一些人可以多玩一些遊戲啦~ 呵呵!
星期二, 3月 23, 2010
64 bit 組合語言
1.多了一些64 bit暫存器
r8,r9,r10,r11,r12,r13,r14,r15
2.暫存器長度變成64 bit
rax,rbx,rcx,rdx,rsi,rdi,rsp,rbp
3.堆疊操作指令要對應64 bit暫存器
ex: (Push, pop, call, ret, enter, and leave) push eax;這是非法的
push rax;這是合法的
4.RIP變成合法化來存取資料
mov,rax,qword ptr [rip+300];以前IP只能當成程式記數器,現在可以參與資料獲取 也因此在64 bit下,DS/ES/SS/CS變的很沒有意義了!
5.Calling Conventions (呼叫慣例)變成Callee(被呼叫者)不需要清除Stack,這是Caller呼叫者的工作
EX:
Function(arg1,arg2,arg3,arg4,arg5) ,假設arg1~4都是整數,他們分別會被放進去對應的暫存器
RCX: 1st integer arg
RDX: 2nd integer arg
R8: 3rd integer arg
R9: 4th integer arg
arg5才會被放進去Stack,但是這個stack會先幫這幾個arg預留空間,
所以第5個參數會是放在 rsp+0x20的地方!
這個概念跟我們以前32 bit觀念不同,他並不是__cdecl/ __stdcall/ __fastcall
所以從下面的範例中可以看到呼叫者會去清除stack:
The stack must be kept 16-byte aligned. Since the "call" instruction
pushes an 8-byte return address, this means that every non-leaf
function is going to adjust the stack by a value of the form 16n+8 in
order to restore 16-byte alignment.
ex:
void SomeFunction(int a, int b, int c, int d, int e);
void CallThatFunction()
{
SomeFunction(1, 2, 3, 4, 5);
SomeFunction(6, 7, 8, 9, 10);
}
On entry to CallThatFunction, the stack looks like this:
xxxxxxx0 | .. rest of stack .. | |
xxxxxxx8 | return address | <- RSP |
Due to the presence of the return address, the stack is misaligned. CallThatFunction sets up its stack frame, which might go like this:
sub rsp, 0x28
Notice that the local stack frame size is 16n+8, so that the result is a realigned stack.
xxxxxxx0 | .. rest of stack .. | |
xxxxxxx8 | return address | |
xxxxxxx0 | (arg5) | |
xxxxxxx8 | (arg4 spill) | |
xxxxxxx0 | (arg3 spill) | |
xxxxxxx8 | (arg2 spill) | |
xxxxxxx0 | (arg1 spill) <- RSP |
Now we can set up for the first call:
mov dword ptr [rsp+0x20], 5 ; output parameter 5
mov r9d, 4 ; output parameter 4
mov r8d, 3 ; output parameter 3
mov rdx, 2 ; output parameter 2
mov rcx, 1 ; output parameter 1
call SomeFunction ; Go Speed Racer!
When SomeFunction returns, the stack is not cleaned, so it still looks like it did above. To issue the second call, then, we just shove the new values into the space we already reserved:
mov dword ptr [rsp+0x20], 10 ; output parameter 5CallThatFunction is now finished and can clean its stack and return.
mov r9d, 9 ; output parameter 4
mov r8d, 8 ; output parameter 3
mov rdx, 7 ; output parameter 2
mov rcx, 6 ; output parameter 1
call SomeFunction ; Go Speed Racer!
add rsp, 0x28
ret
Notice that you see very few "push" instructions in amd64 code, since the paradigm is for the caller to reserve parameter space and keep re-using it.
這種呼叫慣例比較像是結合了__cdecl/ __fastcall 的特性:__cdecl : 在被呼叫者(Callee) return後,由呼叫者(Caller)清除堆疊
__fastcall : 32bit時是將最左邊兩個參數會放在ecx跟edx ,而64 bit 這邊是放在rcx,rdx,r8,r9
Reference
http://blogs.msdn.com/oldnewthing/archive/2004/01/14/58579.aspx
星期六, 3月 13, 2010
安裝VB6的問題
這先就提供你一個方式可以解決這個問題.
首先你先建立一個批次檔,例如叫做VB6Setup.bat
然後輸入下面的這些內容:
@ECHO OFF
set VB6FOLDER=F:\vb6
del %temp%\*.* /y
%VB6FOLDER%\SETUP\ACMSETUP.EXE /T VB98ENT.STF /S %VB6FOLDER% /n "" /o "" /k "0000000000" /b 1
那個VB6FOLDER的路徑你可以設定成你的VB6放置的位置
例如你是放在光碟機,你就可以寫成set VB6FOLDER=E:
然後執行這個批次檔,然後你就會看到開始安裝的畫面了!
星期三, 3月 03, 2010
有趣的Code-BootOption 的建立
雖然很搞不清楚他為什麼要這樣做,但是一般情況下不可能只有SimpleFileSystem存在!
所以應該是要防呆吧! 怕哪一天真的有Hanlde上面只掛SimpleFileSystem而沒有BlkIo.
這種Hanlde他還是會幫他建立出一個BootOption!
gBS->LocateHandleBuffer (
...
&gEfiSimpleFileSystemProtocolGuid,
...
);
for (Index = 0; Index < NumberFileSystemHandles; Index++) {
Status = gBS->HandleProtocol (
...
&gEfiBlockIoProtocolGuid,
(VOID **) &BlkIo
);
if (!EFI_ERROR (Status)) {
continue; //這邊會Skip
}
...
}
星期日, 2月 28, 2010
C語言複習3
問題一: 底下的這個做法的概念
int a;
*&a=30;
Ans:
int a; 可以看成 _A WORD ?
&a 可以看成 LEA BX,_A
* 可以看成 MOV 東西到某個記憶體,所以*&a=30 等同於MOV [BX],30
其實他是等同於a=30,但是這樣子寫會跑更慢!code更大!
問題二:
*200 = 30;
Ans:
這樣子寫是非法的,因為雖然a 在記憶體200的位址,但是你不知道a是多大
所以你要告訴Compiler要一次搬兩個byte. 所以(int *) 等同於word ptr.
*(int *)200=30;
用組語來看會類似 mov word ptr [200],30
其中word ptr是假指令,用來一次搬兩個BYTE
[200] 代表記憶體位址200
星期一, 2月 22, 2010
C語言複習2
&& 是邏輯運算
& 是AND運算
EX: 當 x=1,y=2
if(x&&y) 這邊會是1&&2=TRUE
if(x&y) 這邊會是1&2 = 0 = FALSE
2.條件式判斷
Expression1?Expression2:Expression3
EX: 當x>3 成立時,會執行x=1
XXX= x > 3?1:0
他等同於:
if(x>3)
XXX=1
else
XXX=0
3.逗號語法
Expression1,Expression2,Expression3,....ExpressionN
if( x+1,y+2,z<=3)
k=1
else
k=0
他會依序執行將 X+1,Y+2,直到遇到判斷式Z<=3時才會跳出if()
簡單說就是當Z<=3成立時(TRUE),會得到K=1,雖然沒有人會這樣子寫,但是可以這樣子用!
一般比較常看到的寫法會是:
while(ch=getch(),ch=='a')
{
...
}
4.陣列
array[i]等同於*(array+i)
C語言複習
EX1:
{
int i; //只在括號內有效
}
EX2:
static int i; //只在本文件內有效
EX3:
extern int i; //不管幾個文件中都只有一個實體i;
//他等同於你在File Scope(你在寫#include的那個區塊)中宣告int i;
//只是為了可讀性所以加入extern 這個關鍵字,不加也是可以!
2.for/while/do..while/break/continue
while(Expression)
Statement
for(Expression1;Expression2;Expression3)
Statement
do{
Statement
}while(Expression)