當(dāng)前位置:首頁>職場>linux內(nèi)核有哪些內(nèi)容(深度一文看懂Linux內(nèi)核)
發(fā)布時間:2024-01-24閱讀(17)
作用是將應(yīng)用層序的請求傳遞給硬件,并充當(dāng)?shù)讓域?qū)動程序,對系統(tǒng)中的各種設(shè)備和組件進行尋址。目前支持模塊的動態(tài)裝卸(裁剪)。linux內(nèi)核就是基于這個策略實現(xiàn)的。Linux進程1.采用層次結(jié)構(gòu),每個進程都依賴于一個父進程。內(nèi)核啟動init程序作為第一個進程。該進程負責(zé)進一步的系統(tǒng)初始化操作。init進程是進程樹的根,所有的進程都直接或者間接起源于該進程。virt/ ---- 提供虛擬機技術(shù)的支持。
Linux內(nèi)核預(yù)備工作理解Linux內(nèi)核最好預(yù)備的知識點:
懂C語言懂一點操作系統(tǒng)的知識熟悉少量相關(guān)算法懂計算機體系結(jié)構(gòu)
Linux內(nèi)核的特點:
結(jié)合了unix操作系統(tǒng)的一些基礎(chǔ)概念


【文章福利】私信我回復(fù){內(nèi)核}領(lǐng)取linux內(nèi)核資料包(含視頻教程、電子書、實戰(zhàn)項目及代碼)

Linux內(nèi)核的任務(wù):
1.從技術(shù)層面講,內(nèi)核是硬件與軟件之間的一個中間層。作用是將應(yīng)用層序的請求傳遞給硬件,并充當(dāng)?shù)讓域?qū)動程序,對系統(tǒng)中的各種設(shè)備和組件進行尋址。
2.從應(yīng)用程序的層面講,應(yīng)用程序與硬件沒有聯(lián)系,只與內(nèi)核有聯(lián)系,內(nèi)核是應(yīng)用程序知道的層次中的最底層。在實際工作中內(nèi)核抽象了相關(guān)細節(jié)。
3.內(nèi)核是一個資源管理程序。負責(zé)將可用的共享資源(CPU時間、磁盤空間、網(wǎng)絡(luò)連接等)分配得到各個系統(tǒng)進程。
4.內(nèi)核就像一個庫,提供了一組面向系統(tǒng)的命令。系統(tǒng)調(diào)用對于應(yīng)用程序來說,就像調(diào)用普通函數(shù)一樣。內(nèi)核實現(xiàn)策略:
1.微內(nèi)核。最基本的功能由中央內(nèi)核(微內(nèi)核)實現(xiàn)。所有其他的功能都委托給一些獨立進程,這些進程通過明確定義的通信接口與中心內(nèi)核通信。
2.宏內(nèi)核。內(nèi)核的所有代碼,包括子系統(tǒng)(如內(nèi)存管理、文件管理、設(shè)備驅(qū)動程序)都打包到一個文件中。內(nèi)核中的每一個函數(shù)都可以訪問到內(nèi)核中所有其他部分。目前支持模塊的動態(tài)裝卸(裁剪)。Linux內(nèi)核就是基于這個策略實現(xiàn)的。哪些地方用到了內(nèi)核機制?
1.進程(在cpu的虛擬內(nèi)存中分配地址空間,各個進程的地址空間完全獨立;同時執(zhí)行的進程數(shù)最多不超過cpu數(shù)目)之間進行通 信,需要使用特定的內(nèi)核機制。
2.進程間切換(同時執(zhí)行的進程數(shù)最多不超過cpu數(shù)目),也需要用到內(nèi)核機制。
進程切換也需要像FreeRTOS任務(wù)切換一樣保存狀態(tài),并將進程置于閑置狀態(tài)/恢復(fù)狀態(tài)。
3.進程的調(diào)度。確認哪個進程運行多長的時間。Linux進程1.采用層次結(jié)構(gòu),每個進程都依賴于一個父進程。內(nèi)核啟動init程序作為第一個進程。該進程負責(zé)進一步的系統(tǒng)初始化操作。init進程是進程樹的根,所有的進程都直接或者間接起源于該進程。
2.通過pstree命令查詢。實際上得系統(tǒng)第一個進程是systemd,而不是init(這也是疑問點)
3.系統(tǒng)中每一個進程都有一個唯一標(biāo)識符(ID),用戶(或其他進程)可以使用ID來訪問進程。
Linux內(nèi)核源代碼的目錄結(jié)構(gòu)
Linux內(nèi)核源代碼包括三個主要部分:
1. 內(nèi)核核心代碼,包括第3章所描述的各個子系統(tǒng)和子模塊,以及其它的支撐子系統(tǒng),例如電源管理、Linux初始化等
2. 其它非核心代碼,例如庫文件(因為Linux內(nèi)核是一個自包含的內(nèi)核,即內(nèi)核不依賴其它的任何軟件,自己就可以編譯通過)、固件集合、KVM(虛擬機技術(shù))等
3. 編譯腳本、配置文件、幫助文檔、版權(quán)說明等輔助性文件
使用ls命令看到的內(nèi)核源代碼的頂層目錄結(jié)構(gòu),具體描述如下。
include/ ---- 內(nèi)核頭文件,需要提供給外部模塊(例如用戶空間代碼)使用。
kernel/ ---- Linux內(nèi)核的核心代碼,包含了3.2小節(jié)所描述的進程調(diào)度子系統(tǒng),以及和進程調(diào)度相關(guān)的模塊。
mm/ ---- 內(nèi)存管理子系統(tǒng)(3.3小節(jié))。
fs/ ---- VFS子系統(tǒng)(3.4小節(jié))。
net/ ---- 不包括網(wǎng)絡(luò)設(shè)備驅(qū)動的網(wǎng)絡(luò)子系統(tǒng)(3.5小節(jié))。
ipc/ ---- IPC(進程間通信)子系統(tǒng)。
arch// ---- 體系結(jié)構(gòu)相關(guān)的代碼,例如arm, X86等等。arch//mach- ---- 具體的machine/board相關(guān)的代碼。arch//include/asm ---- 體系結(jié)構(gòu)相關(guān)的頭文件。arch//boot/dts ---- 設(shè)備樹(Device Tree)文件。
init/ ---- Linux系統(tǒng)啟動初始化相關(guān)的代碼。block/ ---- 提供塊設(shè)備的層次。sound/ ---- 音頻相關(guān)的驅(qū)動及子系統(tǒng),可以看作“音頻子系統(tǒng)”。drivers/ ---- 設(shè)備驅(qū)動(在Linux kernel 3.10中,設(shè)備驅(qū)動占了49.4的代碼量)。
lib/ ---- 實現(xiàn)需要在內(nèi)核中使用的庫函數(shù),例如CRC、FIFO、list、MD5等。crypto/ ----- 加密、解密相關(guān)的庫函數(shù)。security/ ---- 提供安全特性(SELinux)。virt/ ---- 提供虛擬機技術(shù)(KVM等)的支持。usr/ ---- 用于生成initramfs的代碼。firmware/ ---- 保存用于驅(qū)動第三方設(shè)備的固件。
samples/ ---- 一些示例代碼。tools/ ---- 一些常用工具,如性能剖析、自測試等。
Kconfig, Kbuild, Makefile, scripts/ ---- 用于內(nèi)核編譯的配置文件、腳本等。
COPYING ---- 版權(quán)聲明。MAINTAINERS ----維護者名單。CREDITS ---- Linux主要的貢獻者名單。REPORTING-BUGS ---- Bug上報的指南。
Documentation, README ---- 幫助、說明文檔。
Linux內(nèi)核體系結(jié)構(gòu)簡析簡析
圖1 Linux系統(tǒng)層次結(jié)構(gòu)
最上面是用戶(或應(yīng)用程序)空間。這是用戶應(yīng)用程序執(zhí)行的地方。用戶空間之下是內(nèi)核空間,Linux 內(nèi)核正是位于這里。GNU C Library (glibc)也在這里。它提供了連接內(nèi)核的系統(tǒng)調(diào)用接口,還提供了在用戶空間應(yīng)用程序和內(nèi)核之間進行轉(zhuǎn)換的機制。這點非常重要,因為內(nèi)核和用戶空間的應(yīng)用程序使用的是不同的保護地址空間。每個用戶空間的進程都使用自己的虛擬地址空間,而內(nèi)核則占用單獨的地址空間。
Linux 內(nèi)核可以進一步劃分成 3 層。最上面是系統(tǒng)調(diào)用接口,它實現(xiàn)了一些基本的功能,例如 read 和 write。系統(tǒng)調(diào)用接口之下是內(nèi)核代碼,可以更精確地定義為獨立于體系結(jié)構(gòu)的內(nèi)核代碼。這些代碼是 Linux 所支持的所有處理器體系結(jié)構(gòu)所通用的。在這些代碼之下是依賴于體系結(jié)構(gòu)的代碼,構(gòu)成了通常稱為 BSP(Board Support Package)的部分。這些代碼用作給定體系結(jié)構(gòu)的處理器和特定于平臺的代碼。
Linux 內(nèi)核實現(xiàn)了很多重要的體系結(jié)構(gòu)屬性。在或高或低的層次上,內(nèi)核被劃分為多個子系統(tǒng)。Linux 也可以看作是一個整體,因為它會將所有這些基本服務(wù)都集成到內(nèi)核中。這與微內(nèi)核的體系結(jié)構(gòu)不同,后者會提供一些基本的服務(wù),例如通信、I/O、內(nèi)存和進程管理,更具體的服務(wù)都是插入到微內(nèi)核層中的。每種內(nèi)核都有自己的優(yōu)點,不過這里并不對此進行討論。
隨著時間的流逝,Linux 內(nèi)核在內(nèi)存和 CPU 使用方面具有較高的效率,并且非常穩(wěn)定。但是對于 Linux 來說,最為有趣的是在這種大小和復(fù)雜性的前提下,依然具有良好的可移植性。Linux 編譯后可在大量處理器和具有不同體系結(jié)構(gòu)約束和需求的平臺上運行。一個例子是 Linux 可以在一個具有內(nèi)存管理單元(MMU)的處理器上運行,也可以在那些不提供 MMU 的處理器上運行。
Linux 內(nèi)核的 uClinux 移植提供了對非 MMU 的支持。
圖2是Linux內(nèi)核的體系結(jié)構(gòu)

圖2 Linux內(nèi)核體系結(jié)構(gòu)
Linux內(nèi)核的主要組件有:系統(tǒng)調(diào)用接口、進程管理、內(nèi)存管理、虛擬文件系統(tǒng)、網(wǎng)絡(luò)堆棧、設(shè)備驅(qū)動程序、硬件架構(gòu)的相關(guān)代碼。
(1)系統(tǒng)調(diào)用接口
SCI 層提供了某些機制執(zhí)行從用戶空間到內(nèi)核的函數(shù)調(diào)用。正如前面討論的一樣,這個接口依賴于體系結(jié)構(gòu),甚至在相同的處理器家族內(nèi)也是如此。SCI 實際上是一個非常有用的函數(shù)調(diào)用多路復(fù)用和多路分解服務(wù)。在 ./linux/kernel 中您可以找到 SCI 的實現(xiàn),并在 ./linux/arch 中找到依賴于體系結(jié)構(gòu)的部分。
(2)進程管理
進程管理的重點是進程的執(zhí)行。在內(nèi)核中,這些進程稱為線程,代表了單獨的處理器虛擬化(線程代碼、數(shù)據(jù)、堆棧和 CPU 寄存器)。在用戶空間,通常使用進程 這個術(shù)語,不過 Linux 實現(xiàn)并沒有區(qū)分這兩個概念(進程和線程)。內(nèi)核通過 SCI 提供了一個應(yīng)用程序編程接口(API)來創(chuàng)建一個新進程(fork、exec 或 Portable Operating System Interface [POSIX] 函數(shù)),停止進程(kill、exit),并在它們之間進行通信和同步(signal 或者 POSIX 機制)。
進程管理還包括處理活動進程之間共享 CPU 的需求。內(nèi)核實現(xiàn)了一種新型的調(diào)度算法,不管有多少個線程在競爭 CPU,這種算法都可以在固定時間內(nèi)進行操作。這種算法就稱為 O(1) 調(diào)度程序,這個名字就表示它調(diào)度多個線程所使用的時間和調(diào)度一個線程所使用的時間是相同的。O(1) 調(diào)度程序也可以支持多處理器(稱為對稱多處理器或 SMP)。您可以在 ./linux/kernel 中找到進程管理的源代碼,在 ./linux/arch 中可以找到依賴于體系結(jié)構(gòu)的源代碼。
(3)內(nèi)存管理
內(nèi)核所管理的另外一個重要資源是內(nèi)存。為了提高效率,如果由硬件管理虛擬內(nèi)存,內(nèi)存是按照所謂的內(nèi)存頁 方式進行管理的(對于大部分體系結(jié)構(gòu)來說都是 4KB)。Linux 包括了管理可用內(nèi)存的方式,以及物理和虛擬映射所使用的硬件機制。不過內(nèi)存管理要管理的可不止 4KB 緩沖區(qū)。Linux 提供了對 4KB 緩沖區(qū)的抽象,例如 slab 分配器。這種內(nèi)存管理模式使用 4KB 緩沖區(qū)為基數(shù),然后從中分配結(jié)構(gòu),并跟蹤內(nèi)存頁使用情況,比如哪些內(nèi)存頁是滿的,哪些頁面沒有完全使用,哪些頁面為空。這樣就允許該模式根據(jù)系統(tǒng)需要來動態(tài)調(diào)整內(nèi)存使用。為了支持多個用戶使用內(nèi)存,有時會出現(xiàn)可用內(nèi)存被消耗光的情況。由于這個原因,頁面可以移出內(nèi)存并放入磁盤中。這個過程稱為交換,因為頁面會被從內(nèi)存交換到硬盤上。內(nèi)存管理的源代碼可以在 ./linux/mm 中找到。
(4)虛擬文件系統(tǒng)
虛擬文件系統(tǒng)(VFS)是 Linux 內(nèi)核中非常有用的一個方面,因為它為文件系統(tǒng)提供了一個通用的接口抽象。VFS 在 SCI 和內(nèi)核所支持的文件系統(tǒng)之間提供了一個交換層(請參看圖4)。

圖3 Linux文件系統(tǒng)層次結(jié)構(gòu)
在 VFS 上面,是對諸如 open、close、read 和 write 之類的函數(shù)的一個通用 API 抽象。在 VFS 下面是文件系統(tǒng)抽象,它定義了上層函數(shù)的實現(xiàn)方式。它們是給定文件系統(tǒng)(超過 50 個)的插件。文件系統(tǒng)的源代碼可以在 ./linux/fs 中找到。文件系統(tǒng)層之下是緩沖區(qū)緩存,它為文件系統(tǒng)層提供了一個通用函數(shù)集(與具體文件系統(tǒng)無關(guān))。這個緩存層通過將數(shù)據(jù)保留一段時間(或者隨即預(yù)先讀取數(shù)據(jù)以便在需要是就可用)優(yōu)化了對物理設(shè)備的訪問。緩沖區(qū)緩存之下是設(shè)備驅(qū)動程序,它實現(xiàn)了特定物理設(shè)備的接口。
(5)網(wǎng)絡(luò)堆棧
網(wǎng)絡(luò)堆棧在設(shè)計上遵循模擬協(xié)議本身的分層體系結(jié)構(gòu)?;叵胍幌拢琁nternet Protocol (IP) 是傳輸協(xié)議(通常稱為傳輸控制協(xié)議或 TCP)下面的核心網(wǎng)絡(luò)層協(xié)議。TCP 上面是 socket 層,它是通過 SCI 進行調(diào)用的。socket 層是網(wǎng)絡(luò)子系統(tǒng)的標(biāo)準(zhǔn) API,它為各種網(wǎng)絡(luò)協(xié)議提供了一個用戶接口。從原始幀訪問到 IP 協(xié)議數(shù)據(jù)單元(PDU),再到 TCP 和 User Datagram Protocol (UDP),socket 層提供了一種標(biāo)準(zhǔn)化的方法來管理連接,并在各個終點之間移動數(shù)據(jù)。內(nèi)核中網(wǎng)絡(luò)源代碼可以在 ./linux/net 中找到。
(6)設(shè)備驅(qū)動程序
Linux 內(nèi)核中有大量代碼都在設(shè)備驅(qū)動程序中,它們能夠運轉(zhuǎn)特定的硬件設(shè)備。Linux 源碼樹提供了一個驅(qū)動程序子目錄,這個目錄又進一步劃分為各種支持設(shè)備,例如 Bluetooth、I2C、serial 等。設(shè)備驅(qū)動程序的代碼可以在 ./linux/drivers 中找到。
(7)依賴體系結(jié)構(gòu)的代碼
盡管 Linux 很大程度上獨立于所運行的體系結(jié)構(gòu),但是有些元素則必須考慮體系結(jié)構(gòu)才能正常操作并實現(xiàn)更高效率。./linux/arch 子目錄定義了內(nèi)核源代碼中依賴于體系結(jié)構(gòu)的部分,其中包含了各種特定于體系結(jié)構(gòu)的子目錄(共同組成了 BSP)。對于一個典型的桌面系統(tǒng)來說,使用的是 x86 目錄。每個體系結(jié)構(gòu)子目錄都包含了很多其他子目錄,每個子目錄都關(guān)注內(nèi)核中的一個特定方面,例如引導(dǎo)、內(nèi)核、內(nèi)存管理等。這些依賴體系結(jié)構(gòu)的代碼可以在 ./linux/arch 中找到。
如果 Linux 內(nèi)核的可移植性和效率還不夠好,Linux 還提供了其他一些特性,它們無法劃分到上面的分類中。作為一個生產(chǎn)操作系統(tǒng)和開源軟件,Linux 是測試新協(xié)議及其增強的良好平臺。Linux 支持大量網(wǎng)絡(luò)協(xié)議,包括典型的 TCP/IP,以及高速網(wǎng)絡(luò)的擴展(大于 1 Gigabit Ethernet [GbE] 和 10 GbE)。Linux 也可以支持諸如流控制傳輸協(xié)議(SCTP)之類的協(xié)議,它提供了很多比 TCP 更高級的特性(是傳輸層協(xié)議的接替者)。
Linux 還是一個動態(tài)內(nèi)核,支持動態(tài)添加或刪除軟件組件。被稱為動態(tài)可加載內(nèi)核模塊,它們可以在引導(dǎo)時根據(jù)需要(當(dāng)前特定設(shè)備需要這個模塊)或在任何時候由用戶插入。
Linux 最新的一個增強是可以用作其他操作系統(tǒng)的操作系統(tǒng)(稱為系統(tǒng)管理程序)。最近,對內(nèi)核進行了修改,稱為基于內(nèi)核的虛擬機(KVM)。這個修改為用戶空間啟用了一個新的接口,它可以允許其他操作系統(tǒng)在啟用了 KVM 的內(nèi)核之上運行。除了運行 Linux 的其他實例之外, Microsoft Windows也可以進行虛擬化。惟一的限制是底層處理器必須支持新的虛擬化指令。
Linux體系結(jié)構(gòu)和內(nèi)核結(jié)構(gòu)區(qū)別1.當(dāng)被問到Linux體系結(jié)構(gòu)(就是Linux系統(tǒng)是怎么構(gòu)成的)時,我們可以參照下圖這么回答:從大的方面講,Linux體系結(jié)構(gòu)可以分為兩塊:
(1)用戶空間:用戶空間中又包含了,用戶的應(yīng)用程序,C庫
(2)內(nèi)核空間:內(nèi)核空間包括,系統(tǒng)調(diào)用,內(nèi)核,以及與平臺架構(gòu)相關(guān)的代碼

2.Linux體系結(jié)構(gòu)要分成用戶空間和內(nèi)核空間的原因:
1)現(xiàn)代CPU通常都實現(xiàn)了不同的工作模式,
以ARM為例:ARM實現(xiàn)了7種工作模式,不同模式下CPU可以執(zhí)行的指令或者訪問的寄存器不同:
(1)用戶模式 usr
(2)系統(tǒng)模式 sys
(3)管理模式 svc
(4)快速中斷 fiq
(5)外部中斷 irq
(6)數(shù)據(jù)訪問終止 abt
(7)未定義指令異常
以(2)X86為例:X86實現(xiàn)了4個不同級別的權(quán)限,Ring0—Ring3 ;Ring0下可以執(zhí)行特權(quán)指令,可以訪問IO設(shè)備;Ring3則有很多的限制
2)所以,Linux從CPU的角度出發(fā),為了保護內(nèi)核的安全,把系統(tǒng)分成了2部分;
3.用戶空間和內(nèi)核空間是程序執(zhí)行的兩種不同狀態(tài),我們可以通過“系統(tǒng)調(diào)用”和“硬件中斷“來完成用戶空間到內(nèi)核空間的轉(zhuǎn)移
4.Linux的內(nèi)核結(jié)構(gòu)(注意區(qū)分LInux體系結(jié)構(gòu)和Linux內(nèi)核結(jié)構(gòu))

Linux的這種platform driver機制和傳統(tǒng)的device_driver機制相比,一個十分明顯的優(yōu)勢在于platform機制將本身的資源注冊進內(nèi)核,由內(nèi)核統(tǒng)一管理,在驅(qū)動程序中使用這些資源時通過platform_device提供的標(biāo)準(zhǔn)接口進行申請并使用。這樣提高了驅(qū)動和資源管理的獨立性,并且擁有較好的可移植性和安全性。下面是SPI驅(qū)動層次示意圖,Linux中的SPI總線可理解為SPI控制器引出的總線:

和傳統(tǒng)的驅(qū)動一樣,platform機制也分為三個步驟:
1、總線注冊階段:
內(nèi)核啟動初始化時的main.c文件中的kernel_init()→do_basic_setup()→driver_init()→platform_bus_init()→bus_register(&platform_bus_type),注冊了一條platform總線(虛擬總線,platform_bus)。
2、添加設(shè)備階段:
設(shè)備注冊的時候Platform_device_register()→platform_device_add()→(pdev→dev.bus = &platform_bus_type)→device_add(),就這樣把設(shè)備給掛到虛擬的總線上。
3、驅(qū)動注冊階段:
Platform_driver_register()→driver_register()→bus_add_driver()→driver_attach()→bus_for_each_dev(), 對在每個掛在虛擬的platform bus的設(shè)備作__driver_attach()→driver_probe_device(),判斷drv→bus→match()是否執(zhí)行成功,此時通過指針執(zhí)行platform_match→strncmp(pdev→name , drv→name , BUS_ID_SIZE),如果相符就調(diào)用really_probe(實際就是執(zhí)行相應(yīng)設(shè)備的platform_driver→probe(platform_device)。)開始真正的探測,如果probe成功,則綁定設(shè)備到該驅(qū)動。
從上面可以看出,platform機制最后還是調(diào)用了bus_register() , device_add() , driver_register()這三個關(guān)鍵的函數(shù)。
下面看幾個結(jié)構(gòu)體:
struct platform_device (/include/linux/Platform_device.h){ const char * name; int id; struct device dev; u32 num_resources; struct resource * resource;};
Platform_device結(jié)構(gòu)體描述了一個platform結(jié)構(gòu)的設(shè)備,在其中包含了一般設(shè)備的結(jié)構(gòu)體struct device dev;設(shè)備的資源結(jié)構(gòu)體struct resource * resource;還有設(shè)備的名字const char * name。(注意,這個名字一定要和后面platform_driver.driver àname相同,原因會在后面說明。)
該結(jié)構(gòu)體中最重要的就是resource結(jié)構(gòu),這也是之所以引入platform機制的原因。
struct resource ( /include/linux/ioport.h){ resource_size_t start; resource_size_t end; const char *name; unsigned long flags; struct resource *parent, *sibling, *child;};其中 flags位表示該資源的類型,start和end分別表示該資源的起始地址和結(jié)束地址(/include/linux/Platform_device.h):
struct platform_driver { int (*probe)(struct platform_device *); int (*remove)(struct platform_device *); void (*shutdown)(struct platform_device *); int (*suspend)(struct platform_device *, pm_message_t state); int (*suspend_late)(struct platform_device *, pm_message_t state); int (*resume_early)(struct platform_device *); int (*resume)(struct platform_device *); struct device_driver driver;};Platform_driver結(jié)構(gòu)體描述了一個platform結(jié)構(gòu)的驅(qū)動。其中除了一些函數(shù)指針外,還有一個一般驅(qū)動的device_driver結(jié)構(gòu)。
名字要一致的原因:
上面說的驅(qū)動在注冊的時候會調(diào)用函數(shù)bus_for_each_dev(), 對在每個掛在虛擬的platform bus的設(shè)備作__driver_attach()→driver_probe_device(),在此函數(shù)中會對dev和drv做初步的匹配,調(diào)用的是drv->bus->match所指向的函數(shù)。platform_driver_register函數(shù)中drv->driver.bus = &platform_bus_type,所以drv->bus->match就為platform_bus_type→match,為platform_match函數(shù),該函數(shù)如下:
static int platform_match(struct device * dev, struct device_driver * drv) { struct platform_device *pdev = container_of(dev, struct platform_device, dev);return (strncmp(pdev->name, drv->name, BUS_ID_SIZE) == 0);}
是比較dev和drv的name,相同則會進入really_probe()函數(shù),從而進入自己寫的probe函數(shù)做進一步的匹配。所以dev→name和driver→drv→name在初始化時一定要填一樣的。
不同類型的驅(qū)動,其match函數(shù)是不一樣的,這個platform的驅(qū)動,比較的是dev和drv的名字,還記得usb類驅(qū)動里的match嗎?它比較的是Product ID和Vendor ID。
個人總結(jié)Platform機制的好處:
1、提供platform_bus_type類型的總線,把那些不是總線型的soc設(shè)備都添加到這條虛擬總線上。使得,總線——設(shè)備——驅(qū)動的模式可以得到普及。
2、提供platform_device和platform_driver類型的數(shù)據(jù)結(jié)構(gòu),將傳統(tǒng)的device和driver數(shù)據(jù)結(jié)構(gòu)嵌入其中,并且加入resource成員,以便于和Open Firmware這種動態(tài)傳遞設(shè)備資源的新型bootloader和kernel 接軌。
Linux內(nèi)核體系結(jié)構(gòu)因為Linux內(nèi)核是單片的,所以它比其他類型的內(nèi)核占用空間最大,復(fù)雜度也最高。這是一個設(shè)計特性,在Linux早期引起了相當(dāng)多的爭論,并且仍然帶有一些與單內(nèi)核固有的相同的設(shè)計缺陷。

為了解決這些缺陷,Linux內(nèi)核開發(fā)人員所做的一件事就是使內(nèi)核模塊可以在運行時加載和卸載,這意味著您可以動態(tài)地添加或刪除內(nèi)核的特性。這不僅可以向內(nèi)核添加硬件功能,還可以包括運行服務(wù)器進程的模塊,比如低級別虛擬化,但也可以替換整個內(nèi)核,而不需要在某些情況下重啟計算機。想象一下,如果您可以升級到Windows服務(wù)包,而不需要重新啟動……
內(nèi)核模塊如果Windows已經(jīng)安裝了所有可用的驅(qū)動程序,而您只需要打開所需的驅(qū)動程序怎么辦?這本質(zhì)上就是內(nèi)核模塊為Linux所做的。內(nèi)核模塊,也稱為可加載內(nèi)核模塊(LKM),對于保持內(nèi)核在不消耗所有可用內(nèi)存的情況下與所有硬件一起工作是必不可少的。

模塊通常向基本內(nèi)核添加設(shè)備、文件系統(tǒng)和系統(tǒng)調(diào)用等功能。lkm的文件擴展名是.ko,通常存儲在/lib/modules目錄中。由于模塊的特性,您可以通過在啟動時使用menuconfig命令將模塊設(shè)置為load或not load,或者通過編輯/boot/config文件,或者使用modprobe命令動態(tài)地加載和卸載模塊,輕松定制內(nèi)核。
第三方和封閉源碼模塊在一些發(fā)行版中是可用的,比如Ubuntu,默認情況下可能無法安裝,因為這些模塊的源代碼是不可用的。該軟件的開發(fā)人員(即nVidia、ATI等)不提供源代碼,而是構(gòu)建自己的模塊并編譯所需的.ko文件以便分發(fā)。雖然這些模塊像beer一樣是免費的,但它們不像speech那樣是免費的,因此不包括在一些發(fā)行版中,因為維護人員認為它通過提供非免費軟件“污染”了內(nèi)核。
內(nèi)核并不神奇,但對于任何正常運行的計算機來說,它都是必不可少的。Linux內(nèi)核不同于OS X和Windows,因為它包含內(nèi)核級別的驅(qū)動程序,并使許多東西“開箱即用”。希望您能對軟件和硬件如何協(xié)同工作以及啟動計算機所需的文件有更多的了解。
Linux 內(nèi)核學(xué)習(xí)經(jīng)驗總結(jié)開篇
學(xué)習(xí)內(nèi)核,每個人都有自己的學(xué)習(xí)方法,仁者見仁智者見智。以下是我在學(xué)習(xí)過程中總結(jié)出來的東西,對自身來說,我認為比較有效率,拿出來跟大家交流一下。
內(nèi)核學(xué)習(xí),一偏之見;疏漏難免,懇請指正。
為什么寫這篇博客
剛開始學(xué)內(nèi)核的時候,不要執(zhí)著于一個方面,不要專注于一個子系統(tǒng)就一頭扎到實際的代碼行中去,因為這樣的話,牽涉的面會很廣,會碰到很多困難,容易產(chǎn)生挫敗感,一個函數(shù)體中(假設(shè)剛開始的時候正在學(xué)習(xí)某個方面的某個具體的功能函數(shù))很可能摻雜著其他各個子系統(tǒng)方面設(shè)計理念(多是大量相關(guān)的數(shù)據(jù)結(jié)構(gòu)或者全局變量,用于支撐該子系統(tǒng)的管理工作)下相應(yīng)的代碼實現(xiàn),這個時候看到這些東西,紛繁蕪雜,是沒有頭緒而且很不理解的,會產(chǎn)生很多很多的疑問,(這個時候如果對這些疑問糾纏不清,刨根問底,那么事實上就是在學(xué)習(xí)當(dāng)前子系統(tǒng)的過程中頻繁的去涉足其他子系統(tǒng),這時候注意力就分散了),而事實上等了解了各個子系統(tǒng)后再回頭看這些東西的話,就簡單多了,而且思路也會比較清晰。所以,要避免 “只見樹木,不見森林”,不要急于深入到底層代碼中去,不要過早研究底層代碼。
我在大二的時候剛開始接觸內(nèi)核,就犯了這個錯誤,一頭扎到內(nèi)存管理里頭,去看非常底層的實現(xiàn)代碼,雖然也是建立在內(nèi)存管理的設(shè)計思想的基礎(chǔ)上,但是相對來說,比較孤立,因為此時并沒有學(xué)習(xí)其它子系統(tǒng),應(yīng)該說無論是視野還是思想,都比較狹隘,所以代碼中牽涉到的其它子系統(tǒng)的實現(xiàn)我都直接跳過了,這一點還算聰明,當(dāng)然也是迫不得已的。
我的學(xué)習(xí)方法
剛開始,我認為主要的問題在于你知道不知道,而不是理解不理解,某個子系統(tǒng)的實現(xiàn)采用了某種策略、方法,而你在學(xué)習(xí)中需要做的就是知道有這么一回事兒,然后才是理解所描述的策略或者方法。
根據(jù)自己的學(xué)習(xí)經(jīng)驗,剛開始學(xué)習(xí)內(nèi)核的時候,我認為要做的是在自己的腦海中建立起內(nèi)核的大體框架,理解各個子系統(tǒng)的設(shè)計理念和構(gòu)建思想,這些理念和思想會從宏觀上呈獻給你清晰的脈絡(luò),就像一個去除了枝枝葉葉的大樹的主干,一目了然;當(dāng)然,肯定還會涉及到具體的實現(xiàn)方法、函數(shù),但是此時接觸到的函數(shù)或者方法位于內(nèi)核實現(xiàn)的較高的層次,是主(要)函數(shù),已經(jīng)了解到這些函數(shù),針對的是哪些設(shè)計思想,實現(xiàn)了什么樣的功能,達成了什么樣的目的,混個臉熟的說法在這兒也是成立的。至于該主函數(shù)所調(diào)用的其它的輔助性函數(shù)就等同于枝枝葉葉了,不必太早就去深究。此時,也就初步建立起了內(nèi)核子系統(tǒng)框架和代碼實現(xiàn)之間的關(guān)聯(lián),關(guān)聯(lián)其實很簡單,比如一看到某個函數(shù)名字,就想起這個函數(shù)是針對哪個子系統(tǒng)的,實現(xiàn)了什么功能。
我認為此時要看的就是LKD3,這本書算是泛泛而談,主要就是從概念,設(shè)計,大的實現(xiàn)方法上描述各個子系統(tǒng),而對于具體的相關(guān)的函數(shù)實現(xiàn)的代碼講解很少涉及(對比于ULK3,此書主要就是關(guān)于具體函數(shù)代碼的具體實現(xiàn)的深入分析,當(dāng)然,你也可以看,但是過早看這本書,會感覺很痛苦,很枯燥無味,基本上都是函數(shù)的實現(xiàn)),很少,但不是沒有,這就很好,滿足我們當(dāng)前的需求,還避免我們過早深入到實際的代碼中去。而且本書在一些重要的點上還給出了寫程序時的注意事項,算是指導(dǎo)性建議。主要的子系統(tǒng)包括:內(nèi)存管理,進程管理和調(diào)度,系統(tǒng)調(diào)用,中斷和異常,內(nèi)核同步,時間和定時器管理,虛擬文件系統(tǒng),塊I/O層,設(shè)備和模塊。(這里的先后順序其實就是LKD3的目錄的順序)。
我學(xué)習(xí)的時候是三本書交叉著看的,先看LKD3,專于一個子系統(tǒng),主要就是了解設(shè)計的原理和思想,當(dāng)然也會碰到對一些主要函數(shù)的介紹,但大多就是該函數(shù)基于前面介紹的思想和原理完成了什么樣的功能,該書并沒有就函數(shù)本身的實現(xiàn)進行深入剖析。然后再看ULK3和PLKA上看同樣的子系統(tǒng),但是并不仔細分析底層具體函數(shù)的代碼,只是粗略地、不求甚解地看,甚至不看。因為,有些時候,在其中一本書的某個點上,卡殼了,不是很理解了,在另外的書上你可能就碰到對同一個問題的不同角度的描述,說不準(zhǔn)哪句話就能讓你豁然開朗,如醍醐灌頂。我經(jīng)常碰到這種情況。
并不是說學(xué)習(xí)過程中對一些函數(shù)體的實現(xiàn)完全就忽略掉,只要自己想徹底了解其代碼實現(xiàn),沒有誰會阻止你。我是在反復(fù)閱讀過程中慢慢深入的。比如VFS中文件打開需要對路徑進行分析,需要考慮的細節(jié)不少(.././之類的),但是其代碼實現(xiàn)是很好理解的。再比如,CFS調(diào)度中根據(jù)shedule latency、隊列中進程個數(shù)及其nice值(使用的是動態(tài)優(yōu)先級)計算出分配給進程的時間片,沒理由不看的,這個太重要了,而且也很有意思。
ULK3也會有設(shè)計原理與思想之類的概括性介紹,基本上都位于某個主題的開篇段落。但是更多的是對支持該原理和思想的主要函數(shù)實現(xiàn)的具體分析,同樣在首段,一句話綜述函數(shù)的功能,然后對函數(shù)的實現(xiàn)以1、2、3,或者a、b、c步驟的形式進行講解。我只是有選擇性的看,有時候?qū)φ罩胹ource insight打開的源碼,確認一下代碼大體上確實是按書中所描述的步驟實現(xiàn)的,就當(dāng)是增加感性認識。由于步驟中摻雜著各種針對不同實現(xiàn)目的安全性、有效性檢查,如果不理解就先跳過。這并不妨礙你對函數(shù)體功能實現(xiàn)的整體把握。
PLKA介于LKD3和ULK3之間。我覺得PLKA的作者(看照片,真一德國帥小伙,技術(shù)如此了得)肯定看過ULK,無論他的本意還是有意,總之PLKA還是跟ULK有所不同,對函數(shù)的仔細講解都做補充說明,去掉函數(shù)體中邊邊角角的情況,比如一些特殊情況的處理,有效性檢查等,而不妨礙對整個函數(shù)體功能的理解,這些他都有所交代,做了聲明;而且,就像LKD3一樣,在某些點上也給出了指導(dǎo)性編程建議。作者們甚至對同一個主要函數(shù)的講解的著重點都不一樣。這樣的話,對我們學(xué)習(xí)的人而言,有助于加深理解。另外,我認為很重要的一點就是PLKA針對的2.6.24的內(nèi)核版本,而ULK是2.6.11,LKD3是2.6.34。在某些方面PLKA比較接近現(xiàn)代的實現(xiàn)。其實作者們之所以分別選擇11或者24,都是因為在版本發(fā)行樹中,這兩個版本在某些方面都做了不小的變動,或者說是具有標(biāo)志性的轉(zhuǎn)折點(這些信息大多是在書中的引言部分介紹的,具體的細節(jié)我想不起來了)。
Intel V3,針對X86的CPU,本書自然是系統(tǒng)編程的權(quán)威。內(nèi)核部分實現(xiàn)都可以在本書找到其根源。所以,在讀以上三本書某個子系統(tǒng)的時候,不要忘記可以在V3中相應(yīng)章節(jié)找到一些基礎(chǔ)性支撐信息。
在讀書過程中,會產(chǎn)生相當(dāng)多的疑問,這一點是確信無疑的。大到搞不明白一個設(shè)計思想,小到不理解某行代碼的用途。各個方面,各種疑問,你完全可以把不理解的地方都記錄下來(不過,我并沒有這么做,沒有把疑問全部記下來,只標(biāo)記了很少一部分我認為很關(guān)鍵的幾個問題),專門寫到一張紙上,不對,一個本上,我確信會產(chǎn)生這么多的疑問,不然內(nèi)核相關(guān)的論壇早就可以關(guān)閉了。其實,大部分的問題(其中很多問題都是你知道不知道有這么一回事的問題)都可以迎刃而解,只要你肯回頭再看,書讀百遍,其義自現(xiàn)。多看幾遍,前前后后的聯(lián)系明白個七七八八是沒有問題的。我也這么做了,針對某些子系統(tǒng)也看了好幾遍,切身體會。
當(dāng)你按順序?qū)W習(xí)這些子系統(tǒng)的時候,前面的章節(jié)很可能會引用后面的章節(jié),就像PLKA的作者說的那樣,完全沒有向后引用是不可能的,他能做的只是盡量減少這種引用而又不損害你對當(dāng)前問題的理解。不理解,沒關(guān)系,跳過就行了。后面的章節(jié)同樣會有向前章節(jié)的引用,不過這個問題就簡單一些了 ,你可以再回頭去看相應(yīng)的介紹,當(dāng)時你不太理解的東西,很可能這個時候就知道了它的設(shè)計的目的以及具體的應(yīng)用。不求甚解只是暫時的。比如說,內(nèi)核各個子系統(tǒng)之間的交互和引用在代碼中的體現(xiàn)就是實現(xiàn)函數(shù)穿插調(diào)用,比如你在內(nèi)存管理章節(jié)學(xué)習(xí)了的內(nèi)存分配和釋放的函數(shù),而你是了解內(nèi)存在先的,在學(xué)習(xí)驅(qū)動或者模塊的時候就會碰到這些函數(shù)的調(diào)用,這樣也就比較容易接受,不至于太過茫然;再比如,你了解了系統(tǒng)時間和定時器的管理,再回頭看中斷和異常中bottom half的調(diào)度實現(xiàn),你對它的理解就會加深一層。
子系統(tǒng)進行管理工作需要大量的數(shù)據(jù)結(jié)構(gòu)。子系統(tǒng)之間交互的一種方式就是各個子系統(tǒng)各自的主要數(shù)據(jù)結(jié)構(gòu)通過指針成員相互引用。學(xué)習(xí)過程中,參考書上在講解某個子系統(tǒng)的時候會對數(shù)據(jù)結(jié)構(gòu)中主要成員的用途解釋一下,但肯定不會覆蓋全部(成員比較多的情況,例如task_struct),對其它子系統(tǒng)基于某個功能實現(xiàn)的引用可能解釋了,也可能沒做解釋,還可能說這個變量在何處會做進一步說明。所以,不要糾結(jié)于一個不理解的點上,暫且放過,回頭還可以看的。之間的聯(lián)系可以在對各個子系統(tǒng)都有所了解之后再建立起來。其實,我仍然在強調(diào)先理解概念和框架的重要性。
等我們完成了建立框架這一步,就可以選擇一個比較感興趣的子系統(tǒng),比如驅(qū)動、網(wǎng)絡(luò),或者文件系統(tǒng)之類的。這個時候你再去深入了解底層代碼實現(xiàn),相較于一開始就鉆研代碼,更容易一些,而且碰到了不解之處,或者忘記了某個方面的實現(xiàn),此時你完全可以找到相應(yīng)的子系統(tǒng),因為你知道在哪去找,查漏補缺,不僅完成了對當(dāng)前函數(shù)的鉆研,而且可以回顧、溫習(xí)以前的內(nèi)容,融會貫通的時機就在這里了。
《深入理解linux虛擬內(nèi)存》(2.4內(nèi)核版本),LDD3,《深入理解linux網(wǎng)絡(luò)技術(shù)內(nèi)幕》,幾乎每一個子系統(tǒng)都需要一本書的容量去講解,所以說,剛開始學(xué)習(xí)不宜對某個模塊太過深入,等對各個子系統(tǒng)都有所了解了,再有針對性的去學(xué)習(xí)一個特定的子系統(tǒng)。這時候?qū)ζ渌到y(tǒng)的援引都可以讓我們不再感到茫然、復(fù)雜,不知所云。
比如,LDD3中的以下所列章節(jié):構(gòu)造和運行模塊,并發(fā)和競態(tài),時間、延遲及延緩操作,分配內(nèi)存,中斷處理等,都屬于驅(qū)動開發(fā)的支撐性子系統(tǒng),雖說本書對這些子系統(tǒng)都專門開辟一個章節(jié)進行講解,但是詳細程度怎么能比得上PLKA,ULK3,LKD3這三本書,看完這三本書,你會發(fā)現(xiàn)讀LDD3這些章節(jié)的時候簡直跟喝白開水一樣,太隨意了,因為LDD3的講解比之LKD3更粗略。打好了基礎(chǔ),PCI、USB、TTY驅(qū)動,塊設(shè)備驅(qū)動,網(wǎng)卡驅(qū)動,需要了解和學(xué)習(xí)的東西就比較有針對性了。這些子系統(tǒng)就屬于通用子系統(tǒng),了解之后,基于這些子系統(tǒng)的子系統(tǒng)的開發(fā)—驅(qū)動(需進一步針對硬件特性)和網(wǎng)絡(luò)(需進一步理解各種協(xié)議)—相對而言,其學(xué)習(xí)難度大大降低,學(xué)習(xí)進度大大加快,學(xué)習(xí)效率大大提升。說著容易做來難。達到這樣一種效果的前提就是:必須得靜下心來,認真讀書,要看得進去,PLKA,ULK3厚得都跟磚頭塊兒一樣,令人望之生畏,如果沒有興趣,沒有熱情,沒有毅力,無論如何都是不行,因為需要時間,需要很長時間。我并不是說必須打好了基礎(chǔ)才可以進行驅(qū)動開發(fā),只是說打好了基礎(chǔ)的情況下進行開發(fā)會更輕松,更有效率,而且自己對內(nèi)核代碼的駕馭能力會更強大。這只是我個人見解,我自己的學(xué)習(xí)方式,僅供參考。
語言
PLKA是個德國人用德語寫的,后來翻譯成英文,又從英文翻譯成中文,我在網(wǎng)上書店里沒有找到它的紙質(zhì)英文版,所以就買了中文版的。ULK3和LKD3都是英文版的。大牛們寫的書,遣詞造句真的是簡潔,易懂,看原版對我們學(xué)習(xí)計算機編程的程序員來說完全不成問題,最好原汁原味。如果一本書確實翻譯地很好,我們當(dāng)然可以看中文版的,用母語進行學(xué)習(xí),理解速度和學(xué)習(xí)進度當(dāng)然是很快的,不作他想。看英文的時候不要腦子里想著把他翻譯成中文,沒必要。
API感想
“比起知道你所用技術(shù)的重要性,成為某一個特別領(lǐng)域的專家是不重要的。知道某一個具體API調(diào)用一點好處都沒有,當(dāng)你需要他的時候只要查詢下就好了。”這句話源于我看到的一篇翻譯過來的博客。我想強調(diào)的就是,這句話針應(yīng)用型編程再合適不過,但是內(nèi)核API就不完全如此。
內(nèi)核相當(dāng)復(fù)雜,學(xué)習(xí)起來很不容易,但是當(dāng)你學(xué)習(xí)到一定程度,你會發(fā)現(xiàn),如果自己打算寫內(nèi)核代碼,到最后要關(guān)注的仍然是API接口,只不過這些API絕大部分是跨平臺的,滿足可移植性。內(nèi)核黑客基本上已經(jīng)標(biāo)準(zhǔn)化、文檔化了這些接口,你所要做的只是調(diào)用而已。當(dāng)然,在使用的時候,最好對可移植性這一話題在內(nèi)核中的編碼約定爛熟于心,這樣才會寫出可移植性的代碼。就像應(yīng)用程序一樣,可以使用開發(fā)商提供的動態(tài)庫API,或者使用開源API。同樣是調(diào)用API,不同點在于使用內(nèi)核API要比使用應(yīng)用API了解的東西要多出許多。
當(dāng)你了解了操作系統(tǒng)的實現(xiàn)—這些實現(xiàn)可都是對應(yīng)用程序的基礎(chǔ)性支撐啊—你再去寫應(yīng)用程序的時候,應(yīng)用程序中用到的多線程,定時器,同步鎖機制等等等等,使用共享庫API的時候,聯(lián)系到操作系統(tǒng),從而把對該API的文檔描述同自己所了解到的這些方面在內(nèi)核中的相應(yīng)支撐性實現(xiàn)結(jié)合起來進行考慮,這會指導(dǎo)你選擇使用哪一個API接口,選出效率最高的實現(xiàn)方式。對系統(tǒng)編程頗有了解的話,對應(yīng)用編程不無益處,甚至可以說是大有好處。
設(shè)計實現(xiàn)的本質(zhì),知道還是理解
操作系統(tǒng)是介于底層硬件和應(yīng)用軟件之間的接口,其各個子系統(tǒng)的實現(xiàn)很大程度上依賴于硬件特性。書上介紹這些子系統(tǒng)的設(shè)計和實現(xiàn)的時候,我們讀過了,也就知道了,如果再深入考慮一下,為什么整體架構(gòu)要按照這種方式組織,為什么局部函數(shù)要遵循這樣的步驟處理,知其然,知其所以然,如果你知道了某個功能的實現(xiàn)是因為芯片就是這么設(shè)計的,CPU就是這么做的,那么你的疑問也就基本上到此為止了。再深究,就是芯片架構(gòu)方面的設(shè)計與實現(xiàn),對于程序員來講,無論是系統(tǒng)還是應(yīng)用程序員,足跡探究到這里,已經(jīng)解決了很多疑問,因為我們的工作性質(zhì)偏軟,而這些東西實在是夠硬。
比如,ULK3中講解的中斷和異常的實現(xiàn),究其根源,那是因為Intel x86系列就是這么設(shè)計的,去看看Intel V3手冊中相應(yīng)章節(jié)介紹,都可以為ULK3中描述的代碼實現(xiàn)方式找到注解。還有時間和定時器管理,同樣可以在Intel V3 對APIC的介紹中獲取足夠的信息,操作系統(tǒng)就是依據(jù)這些硬件特性來實現(xiàn)軟件方法定義的。
又是那句話,不是理解不理解的問題,而是知道不知道的問題。有時候,知道了,就理解了。在整個學(xué)習(xí)過程中,知道,理解,知道,理解,知道……,交叉反復(fù)。為什么開始和結(jié)尾都是知道,而理解只是中間步驟呢?世界上萬事萬物自有其規(guī)律,人類只是發(fā)現(xiàn)而已,實踐是第一位的,實踐就是知道的過程,實踐產(chǎn)生經(jīng)驗,經(jīng)驗的總結(jié)就是理論,理論源于實踐,理論才需要理解。我們學(xué)習(xí)內(nèi)核,深入研究,搞來搞去,又回到了芯片上,芯片是物質(zhì)的,芯片的功用基于自然界中物質(zhì)本有的物理和電子特性。追本溯源,此之謂也。
動手寫代碼
紙上得來終覺淺,絕知此事要躬行。只看書是絕對不行的,一定要結(jié)合課本給出的編程建議自己敲代碼。剛開始就以模塊形式測試好了,或者自己編譯一個開發(fā)版本的內(nèi)核。一臺機器的話,使用UML方式調(diào)試,內(nèi)核控制路走到哪一步,單步調(diào)試看看程序執(zhí)行過程,比書上的講解更直觀明了。一定要動手實際操作。參考書
LDD3 Linux Device Driver 3rd
LKD3 Linux Kernel Development 3rd
ULK3 Understanding the Linux Kernel 3rd
PLKA Professional Linux Kernel Architecture
UML User Mode Linux
Intel V3 Intel? 64 and IA-32 Architectures Software Developer’s Manual Volume 3 (3A, 3B & 3C): System Programming Guide
作者在寫書的時候,都是以自己的理解組織內(nèi)容,從自己的觀點看待一個主題,關(guān)注點跟作者自身有很大的關(guān)系。出書的時間有先后,后來人針對同一個主題想要出書而又不落入窠臼,最好有自己的切入方式,從自己的角度講解相關(guān)問題,這才值得出這本書,千篇一律是個掉價的行為,書就不值錢了。
盡信書不如無書。
http://lwn.net/Articles/419855/ 此處是一篇關(guān)于LKD3的書評,指出了其中的錯誤,當(dāng)你讀完的時候,不妨去找找,看一下自己在其中所描述的地方有什么特別的印象。
http://lwn.net/Articles/161190/此處是一篇對ULK3的介紹,我認為其中很關(guān)鍵的幾句話就可以給本書定位:
Many of the key control paths in the kernel are described, step by step;
一步一步地講述內(nèi)核控制路徑的實現(xiàn)。
The level of detail sometimes makes it hard to get a sense for the big picture, but it does help somebody trying to figure out how a particular function works.
對代碼講解的詳細程度有時候很難讓讀者把握住它的主旨大意,但是確實有助于讀者理解一個特定的函數(shù)到底是如何工作的。
Indeed, that is perhaps the key feature which differentiates this book. It is very much a “how it works” book, designed to help people understand the code.
事實上,這也正是本書與眾不同的地方。更像一個“如何工作”的書,幫助讀者理解代碼實現(xiàn)。
It presents kernel functions and data structures, steps the reader through them, but does not, for example, emphasize the rules for using them. UTLK is a study guide, not a programming manual.
本書描述了內(nèi)核函數(shù)和數(shù)據(jù)結(jié)構(gòu),引導(dǎo)讀者穿行于其間,但是,并沒有著重強調(diào)使用它們的法則。UTLK是一本學(xué)習(xí)指南,而不是編程手冊。
這幾句話對本書的描述非常到位?;诖?,作為指導(dǎo)性原則,我們就可以很有效率地使用它了。
看一本技術(shù)書籍,書中的序言部分絕對是首先應(yīng)該翻閱的,其次就是目錄。我發(fā)現(xiàn)在閱讀過程中我會頻繁的查看目錄,甚至是喜歡看目錄。
結(jié)尾興趣的力量是無窮的。興趣能帶來激情,如果工作可以和興趣結(jié)合到一起,工作起來才會有熱情,那么工作就不只是工作了,更是一種享受。
Linux,我的興趣,我的動力,我的方向,我的未來!
文章來源于嵌入式ARM
原文鏈接 http://www.openpcba.com/web/contents/get?id=4638&tid=15
歡迎分享轉(zhuǎn)載→http://m.avcorse.com/read-256243.html
Copyright ? 2024 有趣生活 All Rights Reserve吉ICP備19000289號-5 TXT地圖HTML地圖XML地圖