device tree的搭建過程

 大家都應該知道
windows下面的驅動模型是分層的.大家構成一個樹狀結構.
那你知道這個結構是怎麼搭建起來的麼?
你會說是一個一個設備枚舉出來的,
那你又能說說具體是怎麼枚舉出來的麼?系統是怎麼知道有一個設備存在的?系統又是怎麼知道這個設備需要什麼樣子的資源?
你也許會說這個是由bus driver來完成的,說得沒錯
但是你知道bus driver是怎麼完成得麼?
也許你會說是跟每個bus相關的,確實也是這樣
但是你能說出你自己正在使用的計算機裏面的那個device tree是怎麼出來的麼?pci總線是怎麼完成設備枚舉的?

如果你能回答上面的這些問題,那到次打住,放鬆心情,有興趣的話就繼續看看,指導指導小弟我,看看下面的這些文字有什麼錯誤沒有..在下不盛感激.

如果你還對這些東西基本不瞭解,那也不用往下看了.

如果你對這個有一些模模糊糊的認識,又想知道具體是怎麼回事情,那看下去吧,我的文字就是爲你準備的,跟我共同進步吧..

廢話這麼多...正題開始...

首先,我覺得只是看文字是沒有太大用的,你應該放一個softice, device tree在手邊,一般看文章一般動手看看自己的系統,加深理解,還有一個要推薦的東西就是intel作了帶源代碼的asl編譯器,到google上或者到intel網站上一搜索就出來了.不是要用它的asl編譯器,而是要用它裏面附帶的一個aml反編譯工具.當然如果你有你主板bios的源代碼,這個工具就不需要了.附帶的說一句,它的源代碼有些小bug,有一點程序設計能力加上對windows註冊表有一定了解的人就能輕鬆搞定,這個就靠你自己搞定了.

先打開device tree看看你自己計算機上面的那個tree是個什麼樣子的.注意,是切換到pnp view的狀態,不是driver view的狀態

在最上面呢.是一個標記有enum的一個device,它屬於pnpmanager這個driver,看看windows的源代碼就知道這個driver是ntoskrnl在啓動的時候創建的一個buildin driver.它呢..有好多的pdo附加到上面,這些pdo就是它所枚舉出來的pdo.

首先你要知道的就是這些pdo是怎麼來的?其實他們是從註冊表裏面讀出來的,這個部分有源代碼的.他們都是通過讀取
LOCAL|MACHINE_SYSTEM|CurrentControlSet|Enum|Root|下面的key來一一生成的,這些pdo叫做madeup pdo,那這些key又是怎麼來的呢?這些key是你在安裝driver的時候就寫到註冊表裏面的.

這些pdo呢.你會看到有些並沒有attach一個fdo,有些卻有fdo.這個區別在什麼地方呢.仔細看看就會發現那些沒有attach fdo的key下面都有一個叫Legacy的設置成1的value.你也許要問這個lagacy是怎麼來的?這個是在安裝的時候生成的,它表示這個驅動是一個nt式的或者是一個filter

這些東西留給你慢慢研究了,我們看今天的主角,最上面的那個叫device|0000001的pdo,有一個fdo attach到上面,它是整個pnp系統的root fdo,它屬於driver ACPI_HAL,這個driver也是一個buildin driver,它是由hal.dll創建的,這個driver具體是起的什麼作用,是不是不管使用不使用acpi都會存在的呢?這些問題因爲我也只有這一個電腦沒有辦法試,就不知道了.

這個fdo有枚舉出了一個pdo,這個pdo的device id 是PNP0C08這個id表示了acpi本身(可查看acpi的specification),這個pdo還佔用了一箇中斷資源,它是SCI中斷線,這個數據的獲取是通過acpi的fadt完成的.略過這個步驟繼續下去.

新枚舉出來的pdo,attach到上面的fdo來自acpi驅動,這個fdo其實不僅僅是一個fdo,有很多本來該它下面的pdo完成的功能都由它來完成了,所以,它也算是一個pdo.

好,進入今天的關鍵部分了,fdo創建好了,發送IRP_MN_START到fdo, fdo開始初始化acpi系統,讀取acpi table,解釋其內容搭建acpi 的 namespace.預先創建好很多device的extension,然後枚舉出那些應該由它直接管理的pdo.

話這樣講得很簡單.其實是很複雜的.暫時打斷下流程,說說與acpi有關的幾個話題.

acpi提供了一種方便的資源配置與電源管理解決方案,它用一種腳本語言來描述主板上的設備所佔用的資源(內存,端口,中斷),以及完成電源管理所需要進行的操作(比如讀某個端口,寫某個端口).腳本的解釋由操作系統完成,這樣通過加入一箇中間緩衝層來達到os與bios的隔離,bios不用在意自己的代碼運行在real mode,或者是protect mode,os也不用爲了運行bios的代碼切換到real mode(在apm中有部分就是這樣完成的).

這種bios用來描述的腳本語言就是asl跟aml,asl是一個源代碼,aml是一個編譯出來的中間代碼,os解釋的就是aml,

bios程序員在寫bios的時候會準備這些個aml,然後把他們放到一個數據結構裏面(RSDT)作爲一個數據模塊加入到bios裏面,os在啓動的時候,在一個恰當的時間獲取到這個數據結構,這樣完成bios與os之間的銜接.

很顯然asl是跟每個主板相關的,這個部分也是主板bios開發中最麻煩的部分,上面intel的那個工具能還原你主板的asl代碼,建議看看,不算複雜(腳本語言都這樣),然後找找你主板南橋北橋芯片的data sheet看看,也許你會有所領悟的哦..

bios程序員在作bios的時候就用asl描述好了主板上的設備都要使用些什麼樣子的資源,怎樣去分配這些資源.接下來os的任務就簡單的,解釋執行aml代碼就能獲取到這些信息.

所以acpi創建的fdo的QueryBusRelations跟QueryResource跟QueryResourceRequirement都是讀取aml代碼解釋執行而已.

只有幾個aml描述的device(|_SB.|下面device)是屬於acpi直接管轄的pdo,acpi也只暫時的創建了這些pdo,然後交給os繼續枚舉它創建的device,其他的諸如cpu(|_SB.|_PR.|),fixedbutton(FADT描述)等等的fdo就不多說了,如果你使用的pci總線,那麼就會有一個|_SB.|PCI0|的device在aml的描述中出現,acpi枚舉到它,os給它attach它的fdo,由pci.sys提供.

然後os繼續枚舉,這次的重點轉移到pci上面了,這裏就跟acpi的關係少很多了,pci有自己的獲取資源,配置資源,枚舉設備的方式,你應該要知道這些是用pci config space來完成的.

pci開始枚舉每個bus上的每個device,爲每個device的每個function創建一個pdo,繼續的bridge device繼續爲它的bus 枚舉pdo,在這個過程中完成bus number的動態配置,這些信息可以參考(pci 跟 pci-to-pci bridge 的specification),對於每個pdo,pci通過讀取它的base address register 的值來完成resource requirements的獲取.

這裏又會有acpi用武的地方,IRP_MN_QUERYRELAIONS(bus)會發送到fdo,fdo會把這個irp傳遞給pdo,正常情況下pdo會直接complete這個irp,但是acpi創建的pdo卻不是這樣,它會查找acpi namespace,爲新枚舉出來的pdo插入合適的bus filter device,這個filter device用來電源管理以及在quire resource的時候加入一些resource,這裏只是在當主板bios的aml裏面有描述到新創建出來的pdo的描述的時候纔會發生,這個部分你可以看看你的bios的asl代碼,對比看看device tree的結構,看看acpi究竟在什麼地方插入了bus filter device,來理解這種按需創建的原則.

再往上,os爲這些新創建出來的pdo attach合適的fdo,fdo繼續枚舉自己的pdo,這裏注意一點,如果你的pdo在bios裏面有描述,那麼fdo與pdo之間是有一個bus filter的.加載的fdo開始枚舉自己的pdo,這個irp同樣又發送給了bus filter,嘿.這個bus filter又會查找acpi namespace適當的加入某些 bus filter,用這種一層一層的方式完成filter的透明加入過程.

以上便是整個的枚舉流程.
全部都是屬於文字的描述.不知道大家看明白了沒有.

如果你想更近一步的更加詳細的瞭解具體的過程
你可以用ida反編譯acpi.sys跟pci.sys,花點時間瞭解下流程
在這個過程中acpi跟pci的符號表也是很重要的
在ntoskrnl的符號表裏面能找到pci使用的大部分類型信息
而acpi本身的符號表裏面能找到acpi使用的幾乎全部的類型信息
這兩個類型信息在幫助我理解acpi跟pci.sys的反彙編代碼方面起了天大的作用,一點都不誇張.

當然softice跟win2000的源代碼更是必不可少的東西.

主板的data sheet跟asl代碼也是非常重要的.

當然xxx spec更是不能少.....

長期困擾我的大問題終於在今天有個比較滿意的答案了
大家跟我一起高興吧.......
發佈了0 篇原創文章 · 獲贊 3 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章