Ads 468x60px

##EasyReadMore##

10 8月, 2015

Linux HAL (Hardware Abstraction Layer)的工作原理

HAL是Hardware Abstraction Layer的首字母縮寫。我最早是在Winnt 3.5的幫助中知道這個名詞的,對幫助文檔中的說法我比較認同,所以一直對它抱有好感。不過Windows下的HAL和Linux下的HAL兩者所指並非相同之物:
 
Windows下的HAL:位於操作系統的最底層,直接操作物理硬件,隔離與硬件相關的信息,為上層的操作系統和設備驅動程序提供一個統一的接口,起到對硬件的抽像作用。有了HAL,編寫驅動程序就容易多了,因為HAL的接口不但使用簡單,而且具有更好的可移植性(沒用過)。
 
Linux 下的HAL:至於對硬件的抽象,Linux內核早就有類似機制,只不過沒有專門的名稱罷了。而Linux的HAL指的並非這個,它不是位於操作系統的最底層,直接操作硬件,相反,它位於操作系統和驅動程序之上,是一個運行在用戶空間中服務程序。
 
我們知道,Linux和所有的Unix一樣,習慣用文件來抽象設備,任何設備都是一個文件,比如/dev/mouse是鼠標的設備文件。這種方法看起來不錯,每個設備都有統一的形式,但使用並不那麼容易,設備文件名沒有什麼規範,從簡單的一個文件名,你無法得知它是什麼設備,具有有什麼特性。
 
結果形成這樣的尷尬:有了設備和設備驅動程序,卻不知道如何使用它。這些亂七八糟的設備文件,讓設備的管理和應用程序的開發都變得很麻煩,所以有必要提供一個硬件抽象層,來為上層應用程序提供一個統一的接口,Linux的HAL就這樣應運而生了。
 
但HAL並不提供諸如拍照和刻錄等之類的功能,相反它只是告訴應用程序,系統中有哪些設備可用,以及這些設備的類型、特性和能力等。主要說來,它提供以下幾項功能:
1. 獲取指定類型的設備列表。
2. 獲取/更改設備的屬性值。
3. 獲取設備具有的能力描述。
4. 設備插入/拔除時,通知相關應用程序。
5. 設備屬性或能力變化時,通知相關應用程序。
 
udev創建dev下的文件結點,加載驅動程序,讓設備處於可用狀態。而HAL則告訴應用程序,現在有哪些設備可用,這些設備的類型、特性和能力,讓應用程序知道如何使用它們。
 
設備的屬性管理是HAL最重要任務之一,有的設備屬性來源於實際的硬件,有的來源於設備信息文件(/usr/share/hal/fdi/),有的來源其它配置信息(如/ usr/share/hwdata/)。設備屬性的都有標準的定義,這些屬性定義是HAL的SPEC的主要內容之一,可以參考http://people.freedesktop.org/~david/hal-spec/hal-spec.html。
 
HAL作為一個後台服務程序運行,它的主體架構基於MVC的模型,在DBUS的幫助下,實現了異步事件通知機制。 HAL的分層視圖如下:

 image


說明:
1. 實線箭頭為主動調用,虛線箭頭為事件上報。
 
2. udev通過NetLink註冊內核的設備事件,當有設備插入/拔除時,udev就會收到通知,它會從事件中所帶參數和sysfs中的信息,加載適當的驅動程序,創建dev下的結點,讓設備處於可用的狀態。
 
3. udev只是一個框架,它的行為完全受它的規則所控制,這些規則存放在目錄/etc/udev/rules.d/中,其中90-hal.rules是用來讓udev把設備插入/拔除的事件通過socket socket:/org/freedesktop/hal/udev_event轉發給HAL的。
 
4. HAL掛在socket:/org/freedesktop/hal/udev_event上等待事件,有事件發生時就調用函數hald_udev_data處理,它先從事件中取出主要參數,創建一個hotplug_event對象,把它放入事件隊列中,然後調用hotplug_event_process_queue處理事件。
 
5. 函數hotplug_event_begin負責具體事件的處理,它把全部事件分為四類,並分別處理hotplug_event_begin_sysfs處理普通設備事件,hotplug_event_begin_acpi處理ACPI事件,hotplug_event_begin_apm處理APM事件,hotplug_event_begin_pmu處理PMU事件。要注意的是,後三者的事件源並非源於udev,而是在device_reprobe時觸發的(osspec_device_reprobe/hotplug_reprobe_tree/hotplug_reprobe_generate_add_events/acpi_generate_add_hotplug_event)。
 
6. 函數hotplug_event_begin_sysfs中,如果是插入設備,則創建一個設備對象,設置設備的屬性,調用相關callouts,然後放入設備列表中,並觸發sig​​nal讓dbus通知相關應用程序。如果是拔除設備,則調用相關callouts,然後從設備列表中刪除,並觸發sig​​nal讓dbus通知相關應用程序。
 
7. 應用程序可以主動調用HAL提供的DBUS接口函數,這些函數在libhal.h中有定義。應用程序也可以註冊HAL的signal,當設備變化時,HAL通過DBUS上報事件給應用程序。
 
8. callout是HAL一種擴展方式,它在設備插入/拔除時執行。可以在設備信息文件中(/usr/share/hal目錄)指定。
 
9. addon也是HAL一種擴展方式,它與callout的不同之處在於addon往往是事件的觸發者,而不是事件的消費者。 HAL的事件源主要源於udev,而udev源於kernel的hotplug,然而有的設備如電源設備、磁盤設備和特殊按鍵等,它們並不產生hotplug事件。 HAL就得不到通知,怎麼辦呢,addon就是用於支持新事件源的擴展方式。比如addon-acpi從/proc/acpi/event或者/var/run/acpid.socket收到事件,然後轉發成HAL事件。 addon-storage檢測光盤或磁盤的狀態,並設置設備的屬性。 addon-keyboard檢測一些特殊按鍵,並觸發相應事件。
 
access-check/ci-tracker/ck-tracker負責權限的檢查,裡面提到的PolicyKit/ConsoleKit不是太熟悉,有時間再看看。

http://blog.csdn.net/absurd

0 意見:

張貼留言

 
Blogger Templates