(工作需要自己翻譯了一下文章 本書為免費版本)

Linux Device Drivers, Third Edition

Linux Device Drivers, Third EditionThis is the web site for the Third Edition of Linux Device Drivers, by Jonathan Corbet, Alessandro Rubini, and Greg Kroah-Hartman. For the moment, only the finished PDF files are available; we do intend to make an HTML version and the DocBook source available as well.

This book is available under the terms of the Creative Commons Attribution-ShareAlike 2.0 license. That means that you are free to download and redistribute it. The development of the book was made possible, however, by those who purchase a copy from O'Reilly or elsewhere.

LDD3 is current as of the 2.6.10 kernel. See the LWN 2.6 API changes page for information on subsequent changes. 

 

An Introduction to Device Drivers

One of the many advantages of free operating systems, as typified by Linux, is that their internals are open for all to view. The operating system, once a dark and mysterious area whose code was restricted to a small number of programmers, can now be readily examined, understood, and modified by anybody with the requisite skills. Linux has helped to democratize operating systems. The Linux kernel remains a large and complex body of code, however, and would-be kernel hackers need an entry point where they can approach the code without being overwhelmed by complexity. Often, device drivers provide that gateway.

許多免費作業系統的優點之一,例如身為表率的Linux,他們的內部設計是完全公開給所有人檢視的。作業系統曾是一個摸不清又神祕的的區域,裡面的程式碼只有幾個程式設計師知道。現在完全能被閱讀、被驗證、被了解,甚至被任何人所修改,只要他們有足夠的能力。Linux已經大力的幫忙達成作業系統的民主化。Linux kernel裡保留了龐大和複雜的程式碼。無論如何,想要成為kernel hacker需要一個切入點,讓這些人可以成功的接近這些程式碼而不被他們的複雜程度給嚇倒。通常來說,驅動程式提供了這樣的管道。

 

Device drivers take on a special role in the Linux kernel. They are distinct “black boxes” that make a particular piece of hardware respond to a well-defined internal programming interface; they hide completely the details of how the device works. User activities are performed by means of a set of standardized calls that are independent of the specific driver; mapping those calls to device-specific operations that act on real hardware is then the role of the device driver. This programming interface is such that drivers can be built separately from the rest of the kernel and “plugged in ”at runtime when needed. This modularity makes Linux drivers easy to write, to the point that there are now hundreds of them available.

裝置驅動程式在Linux kernel裡扮演了一個特殊的角色。他們是個別獨立的黑盒子,建立起特別的片段將硬體對應到內部定義好的程式介面;他們完全隱藏了裝置怎麼動作的細節。使用者的操作將會被一組標準呼叫所執行且獨立在特定的驅動程式外;對應這些呼叫到指定的硬體操作,如何對實際硬體的操作就是驅動程式所扮演的角色。這樣的程式介面使得驅動程式可以被分開的建立在kernel之外,而且當系統運作時再裝上我們所需要的驅動程式即可。這樣的模組化特性使得linux驅動程式非常容易撰寫,我們現在可用的驅動程式就有幾百個。

 

There are a number of reasons to be interested in the writing of Linux device drivers. The rate at which new hardware becomes available (and obsolete!) alone guarantees that driver writers will be busy for the foreseeable future. Individuals may need to know about drivers in order to gain access to a particular device that is of interest to them. Hardware vendors, by making a Linux driver available for their products, can add the large and growing Linux user base to their potential markets. And the open source nature of the Linux system means that if the driver writer wishes, the source to a driver can be quickly disseminated to millions of users.

有需多令人感興趣的原因誘使大家撰寫linux驅動程式。新硬體的汰換速度非常的快,可預見的驅動程式撰寫將會變得非常忙碌。許多人為了去存取他們感興趣的特殊裝置,所以需要去了解驅動程式。而對硬體廠商來說,當他們的產品支援了linux驅動程式,能夠有效的增加linux使用者的支持,畢竟linux的潛在市場很大。而且由於linux開放原始碼的天性,只要寫驅動程式的人想要,source code就會傳播給數百萬的使用者。

 

This book teaches you how to write your own drivers and how to hack around in related parts of the kernel. We have taken a device-independent approach; the programming techniques and interfaces are presented, whenever possible, without being tied to any specific device. Each driver is different; as a driver writer, you need to understand your specific device well. But most of the principles and basic techniques are the same for all drivers. This book cannot teach you about your device, but it gives you a handle on the background you need to make your device work.

這本書教你怎麼寫你自己的驅動程式,也會教你怎麼進入kernel的這些部分。我們已經拿到了獨立於裝置外的路徑;設計程式的技巧和介面我們已經介紹過了,無論怎樣的可能性,都不會綁定到特定的硬體。每一個驅動程式都是不同的。做為一個設計驅動程式的人,你需要非常了解你自己的硬體。但是大多數的準則和基本技巧都適用於所有的驅動程式。本書不能教你怎麼搞定你的裝置,但是會給你讓裝置動起來的基本技巧。

 

As you learn to write drivers, you find out a lot about the Linux kernel in general; this may help you understand how your machine works and why things aren’t always as fast as you expect or don’t do quite what you want. We introduce new ideas gradually, starting off with very simple drivers and building on them; every new concept is accompanied by sample code that doesn’t need special hardware to be tested.

當你學著去寫驅動程式,你可以在linux kernel裡面找到很多寫好的驅動程式;這些或許可以幫你去了解你的機器怎麼工作的,為什麼東西總是快得超出你的預期或者沒有達到你想要的期待。我們會逐漸介紹新的東西,從一個非常簡單的驅動程式開始做起;每個新觀念會由範例碼帶入,不需要用新的硬體去測試。

 

This chapter doesn’t actually get into writing code. However, we introduce some background concepts about the Linux kernel that you’ll be glad you know later, when we do launch into programming.

本章並不會真的下去寫程式。無論如何,我們介紹一些關於kernel的背景觀念,當將來真的下去寫程式的時候,你會很開心你了解這些東西。

 

The Role of the Device Driver

 

As a programmer, you are able to make your own choices about your driver, and choose an acceptable trade-off between the programming time required and the flexibility of the result. Though it may appear strange to say that a driver is “flexible,” we like this word because it emphasizes that the role of a device driver is providing mechanism, not policy.

驅動程式的準則

身為一個程式開發者,你可以自由的選擇自己的驅動程式,在可接受的範圍內對開發時間或是較高彈性的成果中做衡量。雖然形容驅動程式是有彈性的有點奇怪,但這樣的形容詞正強調著驅動程式提供的是一種機制,而不是一種死版的規則。

 

The distinction between mechanism and policy is one of the best ideas behind the Unix design. Most programming problems can indeed be split into two parts: “what capabilities are to be provided” (the mechanism) and “how those capabilities can be used” (the policy). If the two issues are addressed by different parts of the program, or even by different programs altogether, the software package is much easier to develop and to adapt to particular needs.

這裡所謂的實作機制使用規則之間的區別可以說是Unix系統設計裡最好的創意之一。大多數的程式問題能夠被分成兩類:”可以提供甚麼樣的能力(實作機制)?”怎麼使用(使用規則)?”。假如這兩類議題能夠在程式裡分開處理,或是乾脆用不同的程式合作處理。這樣的軟體組合會更易於開發也更能適應各種特別的需求。

 

For example, Unix management of the graphic display is split between the X server, which knows the hardware and offers a unified interface to user programs, and the window and session managers, which implement a particular policy without knowing anything about the hardware. People can use the same window manager on different hardware, and different users can run different configurations on the same workstation. Even completely different desktop environments, such as KDE and GNOME, can coexist on the same system. Another example is the layered structure of TCP/IP networking: the operating system offers the socket abstraction, which implements no policy regarding the data to be transferred, while different servers are in charge of the services (and their associated policies). Moreover, a server like ftpd provides the file transfer mechanism, while users can use whatever client they prefer; both command-line and graphic clients exist, and anyone can write a new user interface to transfer files.

舉例來說,Unix裡的圖形顯示管理系統被分開成兩部分,X server: 熟知硬體能力並提供給使用者統一的介面、 window and session managers: 實做特定的規範,且不用去了解硬體的差異性。大家可以使用同一套window manager去控制不同的硬體,而且每個使用者可以在同一個工作站裡使用自己獨立的顯示設定檔。甚至完全不同的桌面環境,像KDE GNOME,可以共存在同個系統裡。另一個例子是TCP/IP網路的分層設計:作業系統提供socket抽象化,socket不對資料傳輸格式做具體規範,不同的server程式負責不同的services(service定義自己的資料傳輸規則)。再者,像ftpd這樣的server 提供了檔案傳輸的機制,使用者可以使用任何的client端程式;不論是command line 或圖形介面都可以,而且任何一個人都可以寫新的使用者介面去傳輸檔案。

 

Where drivers are concerned, the same separation of mechanism and policy applies. The floppy driver is policy free—its role is only to show the diskette as a continuous array of data blocks. Higher levels of the system provide policies, such as who may access the floppy drive, whether the drive is accessed directly or via a filesystem, and whether users may mount filesystems on the drive. Since different environments usually need to use hardware in different ways, it’s important to be as policy free as possible.

在這我們想套用相同的方法到driver身上,將機制和使用規則分開。Floppy驅動程式就不需要規範-他只需要把磁片展現成一個連續的資料區塊陣列。更高層的系統會提供控制規則,例如誰能夠存取磁碟槽,磁碟槽是否可以被直接操作或需要經過檔案系統,也規範哪些使用者可以掛載檔案系統在這個磁碟槽上。由於不同的環境通常對硬體有不同的使用方法,能夠更自由的訂定控制規則被視為很重要的一環。

 

When writing drivers, a programmer should pay particular attention to this fundamental concept: write kernel code to access the hardware, but don’t force particular policies on the user, since different users have different needs. The driver should deal with making the hardware available, leaving all the issues about how to use the hardware to the applications. A driver, then, is flexible if it offers access to the hardware capabilities without adding constraints. Sometimes, however, some policy decisions must be made. For example, a digital I/O driver may only offer byte-wide access to the hardware in order to avoid the extra code needed to handle individual bits.

當寫驅動程式的時候,程式設計師應該特別注意以下基本的觀念: kernel code存取硬體,但不要強迫使用者用特別的使用規則,因為不同的使用者有不同的需求。驅動程式負責的事情是要讓硬體可以使用,讓所有如何使用硬體的議題留給應用程式去處理。一個有彈性的驅動程式,是要能提供存取硬體的能力,而且沒有增加額外的限制。有些時候,實作機是必須要被制訂的。舉例來說,一個數位I/O驅動程式可能只提供byte-wide的方式去存取硬體,以避免需要額外的程式碼去處理多出來的bits

 

You can also look at your driver from a different perspective: it is a software layer that lies between the applications and the actual device. This privileged role of the driver allows the driver programmer to choose exactly how the device should appear: different drivers can offer different capabilities, even for the same device. The actual driver design should be a balance between many different considerations. For instance, a single device may be used concurrently by different programs, and the driver programmer has complete freedom to determine how to handle con currency. You could implement memory mapping on the device independently of its hardware capabilities, or you could provide a user library to help application programmers implement new policies on top of the available primitives, and so forth. One major consideration is the trade-off between the desire to present the user with as many options as possible and the time you have to write the driver, as well as the need to keep things simple so that errors don’t creep in.

你也可以從不同的角度來看你的驅動程式:這是一個介於應用程式和實際硬體中的軟體層。這個特殊的角色允許驅動程式設計者去選擇甚麼時間點這個裝置應該出現;不同的驅動程式可以提供不同的能力,甚至是對於同個裝置而言。實際的驅動程式設計必須要在各種不同的考量間做平衡。舉例來說,一個單獨的裝置可能會同時被不同的程式所使用。而驅動程式設計者有完全的自由去處理怎麼處理這個情況。你可以在裝置上實做memory mapping而不用考慮硬體的實際能力,或是你可以提供一個user library幫助應用程式設計者在上層可用的原素中實做新的規則。一個主要的考量是你想要提供多少功能給使用者以及要花多久的時間在設計驅動程式上。也需要盡量讓事情保持簡單以避免造成錯誤蔓延。

 

 

Policy-free drivers have a number of typical characteristics. These include support for both synchronous and asynchronous operation, the ability to be opened multiple times, the ability to exploit the full capabilities of the hardware, and the lack of software layers to “simplify things” or provide policy-related operations. Drivers of this sort not only work better for their end users, but also turn out to be easier to write and maintain as well. Being policy-free is actually a common target for software designers.

不用規則的驅動程式有一些特性。這些包括了同步和非同步的操作,有能力被同時打開,有能力去利用硬體的全部能力,也缺少軟體層去簡化該做的事情,或是提供有規則的操作。這類的驅動程式不只對使用者來說很好使用,相對來說也很好設計和維護。不用規則實際上對軟體設計者來說是個普遍公開的議題。

 

 

Many device drivers, indeed, are released together with user programs to help with configuration and access to the target device. Those programs can range from simple utilities to complete graphical applications. Examples include the tunelp program, which adjusts how the parallel port printer driver operates, and the graphical cardctl utility that is part of the PCMCIA driver package. Often a client library is provided as well, which provides capabilities that do not need to be implemented as part of the driver itself.

 

許多的驅動程式,也會一起發布使用程式用以幫忙設定和存取裝置。這些程式的範圍從簡單的能力到完全的圖形化介面都有。譬如說tunelp這個程式,可以調整並列埠印表機的操作,圖形化的cardctl包含在PCMCIAdriver package裡。通常client library也會被提供,而他提供的能力並不需要被實做在驅動程式本身。

 

arrow
arrow

    筱寒Love分享 發表在 痞客邦 留言(0) 人氣()