?
【 作者 :張佩】【 原文 : http://www.yiiyee.cn/Blog/KernelBuildEnviroment/ 】
這一章驅動小z繼續(xù)帶大家遨游驅動王國。在這塊地面上,小z是個地頭蛇,跑動跑西慣了。貴讀者有什么去處想了解得,都可以告訴我。
所謂登高必有卑,在把大家引入到高山圣境之前,先要在山腳下徜徉幾時,為的是把一些預備的事情交代清楚。這一節(jié)講的是驅動程序編譯環(huán)境。Windows內核驅動的歷史有多久,它的開發(fā)環(huán)境就要有多久,所以是很有歷史的話題。話分兩頭講,它起先是很不好,后來則非常好。很不好的時代是舊社會,現(xiàn)在則已是非常好的新時代。
舊社會
在Win8以前開發(fā)內核驅動,準備編譯環(huán)境是個較繁瑣的事情。程序員需要手動下載WDK并安裝(注1),開發(fā)環(huán)境就在安裝好的WDK中。WDK是Windows Driver Kit縮寫,即Windows驅動開發(fā)包。它提供的開發(fā)環(huán)境簡陋得很,它不是一個便于開發(fā)的IDE環(huán)境,而僅僅是一些散裝的編譯工具包。
安裝好WDK后,WDK的編譯環(huán)境鏈接就顯示在開始菜單中了,要小心不能將它們刪掉,否則會麻煩,因為手動生成鏈接是麻煩事,后文會講。
編譯環(huán)境是分類的。首先根據(jù)目標系統(tǒng)分類,也就是要編譯生成運行在什么OS上的目標文件。微軟大部分的產品都保持了向后兼容的習慣,這條規(guī)律也適用于此處:使用Win7子系統(tǒng)環(huán)境編譯出來的驅動文件,一般都能運行在Vista和XP系統(tǒng)上,反之就不會成立(注2)。
其次根據(jù)硬件平臺分類,現(xiàn)在Windows系統(tǒng)能夠運行的平臺有四個:X86,X64,IA64和ARM。其中ARM是Win8才開始的故事,這里還輪不到它出場,這樣就只有前面三個硬件平臺(注3)。
最后又要根據(jù)編譯版本來分,即Checked(也可認做Debug)和Free(也可認作Release)這兩種。這樣來看,每個OS組別下面,就一定有6個編譯環(huán)境鏈接。
在這本書里面,如果用舊版本WDK編譯驅動,就默認使用Win7目標系統(tǒng)的編譯環(huán)境,生成Checked版本,目標平臺是X86或X64。所以就只會選兩種:X86 Checked Build Environment和X64 Checked Build Environment.
編譯環(huán)境打開來其實就是個控制臺。它當然不同于直接從cmd.exe運行起來的控制臺環(huán)境,區(qū)別在哪里呢?我們已經知道,上圖的這些黑色的編譯環(huán)境圖標,其實都是快捷方式。不妨就看看它的快捷方式的Target內容,或許就知道端倪了。以X64 Checked Build Environment這個環(huán)境為例,打開來看到如下內容:
C:\Windows\System32\cmd.exe /k C:\WinDDK\7600.16385.1\bin\setenv.bat C:\WinDDK\7600.16385.1\ chk x64 WIN7
這一行內容仔細一看就很簡單了。原來所謂的編譯環(huán)境,就是一個運行cmd.exe的控制臺進程,只不過它執(zhí)行了用于初始化的/k參數(shù)。在Cmd.exe命令的幫助中,/k參數(shù)是這樣描述的:Carries out the command specified by string but remains(執(zhí)行一個命令,執(zhí)行完之后不退出程序)。也就是說,啟動控制臺進程并執(zhí)行命令,執(zhí)行完后,控制臺程序留給用戶繼續(xù)使用。
那么/k之后的所有內容,都是一條初始化的命令:
C:\WinDDK\7600.16385.1\bin\setenv.bat C:\WinDDK\7600.16385.1\ chk x64 WIN7
它卻又可拆成幾個部分來分析。第一個setenv.bat是初始化編譯環(huán)境的批文件。后面的是它的參數(shù):第一個參數(shù),是WDK的路徑,通過它可以找到編譯器程序;第二個參數(shù)是指明要編譯生成checked版本目標文件;第三個指明硬件平臺是x64;第三個指明目標系統(tǒng)是Win7。
位于WDK中的Setenv.bat文件是負責編譯環(huán)境配置的總廚,你把什么參數(shù)遞給它,它就給你配出什么類型的編譯環(huán)境來(菜也)。
怎么在這個控制臺里面編譯驅動呢?我們統(tǒng)一用使用以下步驟:
通過CD命令,定位到含有source文件的那個驅動目錄;
輸入build或bld(build –cz的簡寫)命令進行編譯;
如果編譯成功,將生成驅動文件,否則會有錯誤或警告信息顯示出來;也可通過查看目錄文件夾下面的相關log文件查看詳細的錯誤或警告信息。
走到這里,編譯的事情算弄明白了。可能還會有朋友問我,我用什么東西寫代碼呢?不好意思,關于這個問題,此時還沒有康莊大道供大家駟馬高車,不過千萬條小路卻是現(xiàn)成的。您可以用notepad記事本或者任何文本編輯器來編輯代碼,如果不嫌麻煩,用Visual Studio寫代碼也可以,只不過僅作代碼編輯而已。
手動集成VS環(huán)境
放著Visual Studio這一利器而不用,降身辱命而用文本編輯器,是很不爽的事情。所以就有聰明人琢磨這件事情,最后終于琢磨出來了,就是通過手動改造VS工程的辦法,將驅動項目也集成到其中去。
我遇到過兩種改造辦法,第一種是笨方法,而且是很麻煩的笨方法。它試圖直接使用VC編譯器來編譯驅動,通過改造一個普通的Win32工程,修改其種種配置,包括庫文件,編譯宏等,來達到編譯驅動程序的目的。有人貼出過詳細的實現(xiàn)細節(jié),我曾嘗試過,但從來沒有成功。
第二種方法很聰明,它需要創(chuàng)建一個Makefile工程,并通過直接調用WDK的編譯器來編譯驅動程序。這種方法很巧妙和便捷,唯一的缺點是最近的VS軟件早已不包括Makefile項目模板。所以通過VS自身來創(chuàng)建一個Makefile工程師不可能的。最好的辦法就是從別處拷貝一個現(xiàn)成的Makefile項目文件使用之。讀者將一個空的Makefile項目文件放到項目文件夾中,打開這個項目文件后,再把需要的源文件拖進去。讀者可以在本文下方下載到這個空項目文件。
打開Makefile項目的屬性后,看到下圖所示NMake屬性設置界面。
這個NMake是很關鍵的東西,它對應了NMake.exe程序。這個程序是干什么用的呢?專門用來運行makefile文件的!關于NMake.exe這個小程序,讀者可以自行找一找,在Visual Stuio的安裝目錄里一定會有。這個工具的文件屬性對它的描述是:Microsoft Program Maintenance Utility(微軟工程管理工具)。Makefile就是個工程管理文件,現(xiàn)在Linux/Unix系統(tǒng)上大量使用。以前在微軟平臺上,可能也大量使用過,只不過現(xiàn)在不用了,轉而使用Visual Studio的項目文件了。
但這時候的Windows內核驅動程序,恰恰還是在用makefile和sources文件的。這不就巧了嘛!兩方面碰到一起了,給我們一個使用VS的Makefile工程來編譯驅動的機會。
NMake的屬性設置里面,要手動填寫B(tài)uild/Rebuild/Clear這三個命令的實現(xiàn)。上面都已經介紹過控制臺編譯環(huán)境的實現(xiàn)了,照搬過來就可以了。以Build命令為例,先調用setenv.bat來初始化,然后調用build或blk命令編譯之。那么我們就可以在build設置下面的兩條命令來編譯生成Win7 OS下X86平臺上Checked類型驅動:
call %BASEDIR%\bin\setenv.bat %BASEDIR% chk x86 win7; bld
讀者要是想編譯其它類型驅動,改動一下參數(shù)即可。那么兩條命令是不怎么美觀的,所以上面稍微只能了一點,在系統(tǒng)目錄里面放了一個名為my_build.bat的批文件,這個批文件內容如下:
@echo on
if "%4"=="/a" call my_clean %1 %2 %3
call %BASEDIR%\bin\setenv.bat %BASEDIR% %1 %2 %3
bld
還有一個Clear命令,其實就是把目標文件刪除掉,使用del或rd命令即可,同樣有一個名為my_clean.bat的批文件,其內容如下:
if exist Debug rd /s /q Debug
if exist Release rd /s /q Release
if exist obj%1_%3_%2 rd /s /q obj%1_%3_%2
新時代
好,舊社會的苦故事已經劇終了。現(xiàn)在開始講翻身得解放的故事。新時代忽然就來了,VS2012給了我們新生活(此處當響起為英雄而歡呼般的掌聲)!VS2012是Win8發(fā)布后出來的,有很多針對Win8的特性,但也能在Win7/Vista系統(tǒng)上運行。請您先下載安裝VS2012軟件,再安裝Win8的WDK,WDK的編譯環(huán)境會自動集成到VS2012中去。當您再次打開VS2012的時候,在新項目向導里面,就能夠找到內核驅動項目了。
您會忍不住立刻新建一個WDF驅動項目,打開它,發(fā)現(xiàn)竟然有幾百行自動生成的代碼已經微笑著列隊歡迎您了,是不是很開心?玩味個不停后,猛然按下F7,靠!竟然開始編譯了,并且還能夠編譯成功,生成了一個.sys文件!而且不單生成一個.sys文件,并且把一個完整的驅動安裝包都給您準備妥當了呢(包含簽過名的.sys/.cat/.inf文件)。爽吧!
總有一天,新進的程序員見此會覺得天經地義,理所當然的事情。而此刻,我們這些個老家伙們,卻已在幸福中垂淚不止了。可憐見地,后來的人們啊,請愛惜來之不易的好生活吧。
得了,我們細細地來看一下VS2012的驅動工程吧。下圖是新建VS2012工程的時候模板選擇界面。這里可以看到Windows Driver目錄樹下面目前提供的幾個模板組別。我們現(xiàn)在只把注意力集中在WDF這個組別上面。點擊WDF后,它里面包含三個模板項,分別是有自動生成代碼的KMDF和沒有自動代碼的KMDF,以及UMDF。選擇第一個模板后,填寫項目名稱后點擊確認。沒有其它的設置需要完成了,直接產生項目文件,并跳入到生成的項目界面中。假設您填寫的項目名稱也是MyKMDF1。
解決方案包括兩個項目工程,一個是驅動項目,另一個是驅動安裝包項目。前者包含實際的驅動代碼,生成驅動文件。后者為驅動文件打包,它根據(jù).inf文件生成.cat文件,并用指定的數(shù)字證書對驅動文件進行簽名。
現(xiàn)在請移動尊手指,在鍵盤上敲擊F7鍵,啟動編譯過程,觀察能否成功生成MyKMDF1.sys文件及相應的驅動包?這是一個重要的里程碑,請勿掉隊,如果你在這里不幸碰到了錯誤,需想辦法解決之。
1>------ 已啟動生成: 項目: MyKMDF1, 配置: Vista Debug Win32 ------
1> Stamping VistaDebug\MyKMDF1.inf [Version] section with DriverVer=05/14/2013,17.17.5.125
1> Device.c
1> Driver.c
1> Queue.c
1> 正在生成代碼...
1> MyKMDF1.vcxproj -> C:\Users\mozhang\Documents\Visual Studio 2012\Projects\MyKMDF1\VistaDebug\MyKMDF1.sys
1> Done Adding Additional Store
1> Successfully signed: C:\Users\mozhang\Documents\Visual Studio 2012\Projects\MyKMDF1\VistaDebug\MyKMDF1.sys
1>
2>------ 已啟動生成: 項目: MyKMDF1 Package, 配置: Vista Debug Win32 ------
2> ......................
2> Signability test complete.
2>
2> Errors:
2> None
2>
2> Warnings:
2> None
2>
2> Catalog generation complete.
2> C:\Users\mozhang\Documents\Visual Studio 2012\Projects\MyKMDF1\VistaDebug\MyKMDF1 Package\mykmdf1.cat
2> Done Adding Additional Store
2> Successfully signed: C:\Users\mozhang\Documents\Visual Studio 2012\Projects\MyKMDF1\VistaDebug\MyKMDF1 Package\mykmdf1.cat
2>
========== 生成: 成功 2 個,失敗 0 個,最新 0 個,跳過 0 個 ==========
驅動包項目
我們來學習一下這個總是自動生成的驅動包項目,它能為我們做些什么?我們通過觀察,總結它做了四件事情:
- 為.sys文件進行數(shù)字簽名
- 根據(jù).inf文件生成.cat文件
- 給簽名文件打時間戳
- 生成驅動包
注1:WDK安裝目錄不能含有空格和中文字符,如安裝在c:\documents and users目錄下即錯,或安裝在c:\我的驅動目錄下亦錯。錯誤并非發(fā)生在安裝過程中,而是發(fā)生在使用WDK編譯的時候。
注2:內核編譯器編譯的DLL文件不符合向后兼容特性
注3:Win8以后的系統(tǒng)不再支持IA64平臺,所以Win8也只支持三種硬件平臺。
?
?
更多文章、技術交流、商務合作、聯(lián)系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯(lián)系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
