首頁
中文書目錄
原文書目錄
 站內快速搜尋
資源中心
Book Series
Special Interest













■好消息,歐萊禮書籍已重新鋪貨至各大書局及網路書店,歡迎讀者選購       ■歡迎各院校採用歐萊禮書籍,學校團購請洽校園服務團隊

[書籍導讀]

Linux 驅動程式 第二版


導讀
這本書是針對 Linux 2.4 版核心而寫的。2.4.0 測試版剛推出時,兩位作者開始寫這本書,原文書出版時,2.4.11 已經推出了。我看完這本書並開始翻譯時,已經是 2.4.18 版的時代了,等到完成翻譯與校對工作,2.4.24 與 2.6.1 版都出現了。對於想要從本書獲得 2.6 版知識的讀者,現在就可以告訴你,死心吧。如果真的有什麼理由讓你非得研究 2.6 版不可,那麼,捐點小錢給作者,或許可以如願以償:https://lwn.net/Articles /driver-porting/。

如果你是第一版的讀者,或是已經有 Linux 驅動程式(或任何核心程式)的寫作經驗,請跳過這篇導讀,因為你己經知道我要交代的東西。如果你從沒在 Linux 系統上寫過任何程式,請將本書放回書架,因為這本書帶給你的挫折感,將遠高於你能得到的成就感。如果你懂 C 語言,而且也有一點程式設計經驗,但是從沒寫過 Linux 驅動程式,那麼,這一篇導讀或許對你能有所幫助。

基本知識
很顯然地,本書的主題 - 驅動程式 - 並不適合初學程式設計的新手。然而,本書第一版的經驗告訴我,有許多學校使用這本書當「系統程式」課程的教材,而學習這門課的學生卻不一定有豐富的程式設計經驗,所以,我想列出一些閱讀本書之前應該學習的知識,幫助莘莘學子做好課前準備。

首先,你要懂 C 語言,尤其是最難懂的指標(pointer)與結構(structure)。C 語言本身沒提供物件導向機制,但是 Linux 核心的研發團隊使用「結構」來模擬「類別」,使用「函式指標」(function pointer)與「註冊表」(函式指標陣列)來提供 subclassing 機制。因此,你會見到大量的結構與函式指標。關於 C 語言,請參閱 K & R 所著的那本聖經。

其次,你必須熟悉資料結構的操作,尤其是串列(list)。Linux 核心內部有許多稱為「佇列」(queue)或「表」(table)的資料結構,它們其實都是某種形式的串列。知道如何安插、刪除串列中的節點,可讓你在寫驅動程式時更加得心應手。關於 Linux 核心提供的通用串列支援,請參閱本書第十章的《10.5 鏈結串列》。

最後,也是最重要的,就是你必須了解 Unix 的「系統呼叫」(system call)機制。寫 Linux 驅動程式,基本上可說是在“實作”(implementing)應用程式可能用到的各種系統呼叫。例如,如果掃瞄機的應用程式會使用 open()、read()、close() 這三種系統呼叫來存取 /dev/scanner,那麼,/dev/scanner 的驅動程式就必須實作出 openreadclose 這三種作業方法。對於系統呼叫沒有概念的讀者,建議你閱讀《Understanding the Linux Kernel,2/e》的第九章。

本書的範例程式
本書的所有範例程式都可從 O'Reilly 的網站取得:

http://examples.oreilly.com/linuxdrive2/ (美國總站)

Linux 驅動程式 第二版 (台灣分站)

從美國總站取得的版本比較舊(ldd2-samples-1.0.1.tar.gz),這版本有部份檔案需要稍微修改,才可在 2.4.10 版之後的環境下順利編譯。我修改好的版本(ldd2-samples-1.0.2.tar.gz)放在台灣歐萊禮的網站上。讀者可用下列方式取得:

# wget http://www.oreilly.com.tw/bookcode/ldd2-samples-1.0.2.tar.gz

解開:

# tar xzvf ldd2-samples-1.0.2.tar.gz
# ls -F ldd2
allocator/
    Makefile.arm     misc-modules/ sbull/ simple/
Changes
      Makefile.ia64    misc-progs/ scull/ skull/
foo
        Makefile.m68k    oops/ scullc/ snull/
LICENSE
      Makefile.mips    pci/ scullp/ spull/
local-scratch
  Makefile.ppc     pci-compat.h scullv/ sysdep.h
Makefile
     Makefile.sparc    README short/ usb/
Makefile.alpha
  Makefile.sparc64  Rules.make shortprint/

作者提供的範例程式是依據 Linus 本人發佈的正式版核心而寫的(來自 http://www.kernel.org/ 的版本),如果你使用 Red Hat 或 SuSE 隨附的版本,在編譯上可能會遇到一些困難。因此,我們建議你從 kernel.org 下載最新的 2.4.x 版核心原始程式:

[root@linux ~]# cd /usr/src/
[root@linux /usr/src]# wget http://www.kernel.org/pub/linux/kernel/v2.4/linux-2.4.24.tar.bz2
[root@linux /usr/src]# tar xvjfp linux-2.4.24.tar.bz2
[root@linux /usr/src]# chown -R root.root linux-2.4.24/
[root@linux /usr/src]# ln -s linux-2.4.24/ linux

使用 RedHat 或 SuSE 的讀者,請一併修正 /usr/include/linux/ 與 /usr/include/asm/,讓它們分別指向正確版本的目錄:

[root@linux /usr/src]# cd /usr/include/
[root@linux /usr/include]# mv linux linux.redhat
[root@linux /usr/include]# mv asm asm.redhat
[root@linux /usr/include]# ln -s /usr/src/linux/include/linux/ linux
[root@linux /usr/include]# ln -s /usr/src/linux/include/asm/ asm

編譯新版核心:

[root@linux /usr/include]# cd /usr/src/linux
[root@linux /usr/src/linux]# make clean
[root@linux /usr/src/linux]# make menuconfig
...(略)...
[root@linux /usr/src/linux]# vi Makefile
(非必要)
[root@linux /usr/src/linux]# make dep
[root@linux /usr/src/linux]# make bzImage
x86



[root@linux /usr/src/linux]# make vmlinuxsparc64 或其它平台)
...(下午茶時間)...
[root@linux /usr/src/linux]# make modules
[root@linux /usr/src/linux]# make modules_install

安裝新版核心:

[root@linux /usr/src/linux]# cp arch/i386/boot/bzImage /boot/vmlinuz-2.4.24 x86



[root@linux /usr/src/linux]# cp vmlinux /boot/vmlinux-2.4.24
[root@linux /usr/src/linux]# cp .config /boot/config-2.4.24
[root@linux /usr/src/linux]# cp System.map /boot/System.map.2.4.24
[root@linux /usr/src/linux]# vi /etc/lilo.conf

或 silo.conf、milo.conf、grub.conf,看你所用的 bootloader 而定。

參考設定內容:

# (lilo.confsilo.confmilo.conf):

image=/boot/vmlinuz-2.4.24 # 如果你的 /boot 是位於自己的分割區,
label=mylinux # 請改成 image=/vmlinuz-2.4.24
read-only
root=/dev/hda3


# grub.conf:
title gpLinux (2.4.24 custom kernel)
root (hd0,0)
kernel /vmlinuz-2.4.24 ro root=/dev/hda3


[root@linux /usr/src/linux]# lilox86 only
[root@linux /usr/src/linux]# reboot ( 阿彌陀佛 ... )

重新開機後,用 dmesg 檢視開機訊息,看看是否所有必要裝備都啟動了。有興趣看本書的讀者,至少都應該是玩家級的高手,所以我就不再解釋上述步驟的意義。

如果能順利啟動新核心,就可以試著編譯看看範例程式了。

[root@sparc ~/ldd2]# cd misc-modules/
[root@sparc ~/ldd2/misc-modules]# make clean
[root@sparc ~/ldd2/misc-modules]# make

跑跑看:

[root@sparc ~/ldd2/misc-modules]# insmod ./hello.o
Warning: loading ./hello.o will taint the kernel: no license
[root@sparc ~/ldd2/misc-modules]# tail -n 1 /var/log/messages
Jan 19 20:59:49 sparc kernel: Hello, world

出現「no license」警告訊息是正常的,如果你不想看到這段訊息,請修改原始程式,在 #include <linux/module.h> 之後加入下列敘述:

MODULE_LICENSE("GPL");

然後重新編譯一次,再試試看。

批評指教
雖然我自認在這本書的翻譯與校稿上投入了大量的心力,但是無論編譯過程如何嚴謹,我仍不敢保證本書沒有瑕疵。如果讀者認為本書譯文有任何模稜兩可或交代不清之處,或是有任何錯誤(漏字、錯字、贅字、技術描述 ...),或是您有任何能使本書更好的建議,我非常歡迎讀者提供批評指教。

台灣歐萊禮公司特地設置 bookq@oreilly.com.tw 信箱,如果讀者對於本公司出版品內容有任何意見(包括技術問題),請寫信到此信箱,或是直接寫給我也可以。我很珍惜每一位讀者的指教。對於錯誤糾正,在經過查證之後,我會公佈在本書中文網頁的勘誤表,並於下一刷改正。如果您對本書的內容有疑問,在您回報錯誤之前,請先查閱網頁上的勘誤表,看看是不是已經有人發現了。

林長毅 謹識
lin@oreilly.com.tw
中華民國 93 年一月 台北

| 首頁 | 聯絡我們 |
© 2009, O'Reilly Media, Inc. Taiwan Branch