1. 程式人生 > >20179203 《Linux內核原理與分析》第十周作業

20179203 《Linux內核原理與分析》第十周作業

計時 使用 數據 一個個 類型 原則 聲明 標識 變量

第17章 設備與模塊

一、設備類型

1. Linux及Unix系統:

塊設備
字符設備
網絡設備

2.塊設備:

通常縮寫為blkdev,它是可尋址的,尋址以塊為單位,塊大小隨設備不同而不同;塊設備通常支持重定位操作,也就是對數據的隨機訪問。
塊設備是通過稱為“塊設備節點”的特殊文件來訪問的,井且通常被掛載為文件系統。

3.字符設備:

通常縮寫為cdev,它是不可尋址的,僅提供數據的流式訪問,就是一個個字符,或者一個個字節。
字符設備的例子有鍵盤、鼠標、打印機,還有大部分偽設備。字符設備是通過稱為“字符設備節點”的特殊文件來訪問的。與塊設備不同,應用程序通過直接訪問設備節點與字符設備交互。

4.網絡設備:

最常見的類型有時也以以太網設備稱呼,它提供了對網絡〈例如Internet)的訪問,這是通過-個物理適配器和一種特定的協議進行的
網絡設備打破了Unix的“所有東西都是文件”的設計原則,它不是通過設備節點來訪問,而是通過套接字API這樣的特殊接口來訪問。

5.偽設備:

大部分設備驅動是表示物理設備的,但並不是所有設備驅動都表示物理設備。有些設備驅動是虛擬的,僅提供訪問內核功能而已。我們稱為“偽設備”。

常見的如:

內核隨機數發生器(通過/dev/random和/dev/urandom 訪問)
空設備(通過/dev/null 訪問)
零設備(通過/dev/zero 訪問)
滿設備(通過/dev/full 訪問)
內存設備(通過/dev/mem 訪問)

二、模塊

1. 概述:

Linux 內核是模塊化組成的,它允許內核在運行時動態地向其中插入或從中刪除代碼。這些代碼(包括相關的子例程、數據、函數人口和函數出口)被一並組合在一個單獨的二進制鏡像中,即所謂的可裝載內核模塊中,或簡稱為模塊。
支持模塊的好處是基本內核鏡像可以盡可能地小,因為可選的功能和驅動程序可以利用模塊形式再提供。模塊允許我們方便地刪除和重新載入內核代碼,也方便了調試工作。而且當熱插拔新設備時,可通過命令載入新的驅動程序。
模塊的所有初始化函數必須符合形式:int my _ init (void);
退出函數必須符合形式:void my_exit (void);

2.構建與安裝

安裝編譯的模塊: make modules_install

產生依賴關系信息,而且在每次啟動時更新。
產生內核依賴關系的信息,root用戶可運行命令:depmod
只為新模塊生成依賴信息,不生成所有的依賴關系,root用戶可運行命令:depmod -A
模塊依賴關系信息存放在/lib/modules/version/modules.dep文件中。

載入,root用戶可運行命令:insmod module .ko

在內核via modprobe中插入模塊,root用戶可運行命令:zmodprobe module[module parameters] (參數 module 指定了需要載入的模塊各稱)。

從內核中卸載模塊,root用戶可運行命令:modprobe -r modules

三、設備模型

  • 1.kobject:
    設備模型的核心部分。其中struct kobject 結構體表示,定義於頭文件<linux/k,ρ1lij四t.b>中。通常是嵌入其他結構中的。

  • 2.ktype:
    kobject 對象被關聯到一種特殊的類型:ktype。由kobj_type 結構體表示,定義於頭文件<linux/kobject.h>中。為了描述一族kobject 所具有的普遍特性。

  • 3.kset:
    在Linux 內核中,只有少數一些的ktype,卻有多個kset。由kset 結構體表示,定義於頭文件<linux/kobject.h>中:

  • 4.kobject、ktype、kset關系:
    kobject,讓那些包含它的結構具有了kobject 的特性。ktype 定義了一些kobject 相關的默認特性。kset 提供了兩個功能:第一,其中嵌入的kobj創作為kobject 組的基類。第二, kset 將相關的kobject 集合在一起。

  • 5.管理和操作kobject:
    kobject 通過函數koject_init 進行初始化,該函數定義在文件<linux/kobject.h>中:void kobject_init(struct kobject kobj, struct kobj_type ktype);第一個參數就是需要初始化的kobject 對象;調用初始化函數前, kobject 必須清空;未被清空,調用memset() 即可:memset(kobj, 0, sizeof (*kobj ) );應該調用kobject_createO 創建koject。

  • 6.計數:
    kobject的主要功能:提供了一個統一的引用計數系統。初始化後,kobject的引用計數設置為1;引用計數不為零,該對象就會繼續保留在內存中。引用計數跌到零時,對象可被撤銷,相關內存也被釋放。koject 的引用計數是通過kref結構體實現,該結構體定義在頭文件<linux/kref.h>中。

第19章 可移植性

一、可移植操作系統

有些操作系統在設計時把可移植性作為頭等大事之一,盡可能減少涉及與機器相關的代碼。匯編代碼少之又少,這樣做就是利用代碼性能優化能力換取代碼的可移植性。Minix,NetBSD和許多研究用的系統就是這種高度可移植的操作系統。
還有一些操作系統完全不顧及可移植性,盡最大可能追求代碼的性能表現,盡可能多的使用匯編代碼,這樣就是利用代碼的可移植性換取代碼的性能優化能力。這樣的系統比可移植的系統更難維護。DOS和Windows95就是這樣的操作系統。

二、字長和數據類型

ANSIC標準規定,一個char的長度一定是1字節;盡管沒有規定int類型的長度是32位,但在Linux當前支持的體系結構中,它都是32位的。short類型也類似,在當前所有支持的體系結構中,雖然沒有明文規定,但是它都是16位的。絕對不應該假定指針和long的長度,在linux當前支持的體系結構中,它們可以在32位和64位中變化。對於不同的體系結構long的長度不同,決不應該假設sizeof(int)=sizeof(long)。類似的,也不要假設指針和int長度相等。

三、本章感受

要想寫出移植性好、簡潔、合適的內核代碼,要註意以下兩點:

  • 1.編碼盡量選取最大公因子:假定任何事情都可能發生,任何潛在的約束都可能存在。編碼盡量選取最小公約數:不要假定給定的內核特性是可用的,僅僅需要最小的體系結構功能。

  • 2.編寫可移植性的代碼需要考慮很多問題:字長、數據類型、填充、對齊、字節次序、符號、字節順序、頁大小以及處理器的加載/存儲排序等。對於絕大多數的內核開發者來說,可能主要考慮的問題就是保證正確使用數據類型。

第20章 補丁,開發和社區

本章重點介紹了Linux編碼風格:

  • 縮進——縮進風格是用制表位每次縮進8個字符長度。
  • switch語句——switch語句下屬的case標記應該縮進到和switch聲明對齊,這樣有助於減少8個字符的tab鍵帶來的排版縮進。
  • 空格——Linux編碼風格規定,空格放在關鍵字周圍,函數名和圓括號之間無空格。
  • 花括號——內核選定的風格是左括號緊跟在語句的最後,與語句在相同的一行。而右括號要新起一行,作為該行的第一個字符。
  • 每行代碼的長度——源代碼中要盡可能地保證每行代碼長度不超過80個字符,因為這樣做可能使代碼最合適在標準的80*24的終端上顯示。
  • 命名規範——命名中不允許使用駱駝拼寫法、Studly Caps或者其他混合的大小寫字符。
  • 函數——根據經驗,函數的代碼長度不應該超過兩屏,局部變量不應超過10個。一個函數應該功能單一而且實現精確。
  • 註釋——一般情況下應該描述的是你的代碼要做什麽和為什麽要這樣做,而不是具體通過什麽方式實現的。
  • typedef——使用typedef要謹慎,只有在確實需要的時候再使用它。
  • 多用現成的東西——請勿閉門造車。內核本身就提供了字符串操作函數,壓縮函數和一個鏈表接口,所以請使用他們。
  • 在源碼中減少使用ifdef——不贊成在源碼中使用ifdef預處理指令。
  • 結構初始化——結構初始化的時候必須在他的成員前加上結構標識符。
  • 代碼的事後修正——indent是一個在大多數Linux系統中都能找到的好工具,它可以按照指定的方式對源代碼進行格式化 。

20179203 《Linux內核原理與分析》第十周作業