2009年6月17日 星期三

Kernel API always changes

最近因為工作上的需要,花了些時間學習如何撰寫 Linux 區塊裝置驅動程式,以及了解 Linux block subsystem 的架構。我主要參考兩本書藉,其中一本正是大名鼎鼎的 Linux Device Drivers 3rd (LDD3);而另外一本則是去年才出版的書藉 Essential Linux Device Drivers

我嘗試依照書本上的內容寫了一個 RAM-based 的區塊驅動程式,但在我的電腦上卻因為參考不到函式呼叫而無法成功編譯 (核心版本 2.6.28)。原因當然是因為核心 API 的改變,正如許多資深開發者所言,由於開發的需要,核心 API 總是不斷地在變化,因此若不將程式碼合併回主流版本,後續的維護將會非常麻煩。

以 LDD3 來說,其所列的範例程式片段如下:

sectors_xferred = sbull_xfer_request(dev, req);
if (! end_that_request_first(req, 1, sectors_xferred)) {
    blkdev_dequeue_request(req);
    end_that_request_last(req);
}

請注意 LDD3 所依據的核心版本為 2.6.10,到了 2.6.28,這些函式已被移除,取而代之的是:

sectors_xferred = sbull_xfer_request(dev, req);
__blk_end_request(req, 0, sectors_xferred << 9);

由於 __blk_end_request() 函式的第三個參數為成功傳輸的位元組 (byte),而非區段 (sector),所以需做單位轉換。另外可能會造成混淆的地方是 block subsystem 也提供另一個函式 blk_end_request(),兩者功能相同,差別在於後者是有加上 spin lock 的版本;不過由於核心在執行上述的程式碼之前已先行上鎖了,是故就不需要再上鎖一次了。

由以上範例,我們可以了解到,核心 API 的改變對於驅動程式的維護而言,並不僅僅是舊函式的消滅或新函式的加入而已,我們還需要評估應如何修改程式,以及修改後是否會影響程式的行為。通常核心開發者會負責將所有相關的驅動程式修改到好,但若是 out of tree 的程式碼,這部分可就得自己傷腦筋了。

2009年6月8日 星期一

移植 Ångström

因為看到另一個基於 OpenEmbedded 的 distribution Ångström,覺得它比起 Poky 來說提供更多的套件選擇,且由於 Ångström 的目錄架構和 OE 相同,所以在 OE 下新增的套件,馬上就可以套用在 Ångström 之上,而不需做任何修正。是故就決定以 Ångström 做為我移植軟體至開發板的基礎開發套件。

於是上個月的工作就是將原來寫給 Poky 用的設定檔修改以後再移到 Ångström 的目錄之下,然後再修改 Ångström 下的 linux recipe 來支援我目前使用的開發板,接著測試完成後,再提交至 OE mailing list。大功告成。