天天看點

linux核心資料類型,Linux核心資料類型.doc

Linux核心資料類型

Linux裝置驅動程式學習(7)-核心的資料類型

來源: ChinaUnix部落格  日期: 2008.10.13 21:03 (共有0條評論) 我要評論Linux裝置驅動程式學習(7)-核心的資料類型 由于前面的學習中有用到 第十一章 核心資料結構類型 的知識,是以我先看了。要點如下: 将linux 移植到新的體系結構時,開發者遇到的若幹問題都與不正确的資料類型有關。堅持使用嚴格的資料類型與使用 -Wall -Wstrict-prototypes 進行編譯可能避免大部分的 bug。核心資料使用的資料類型主要分為 3 個類型: 标準 C 語言類型、确定大小的類型與特定核心對象的類型。 标準 C 語言類型 當需要“一個2位元組填充符”或“用一個4位元組字串來代表某個東西”,就不能使用标準C語言類型,因為在不同的體系結構,C語言的資料類型所占的空間大小不同。後面的datasize 程式實驗展示了使用者空間各種 C的資料類型在目前平台所占空間的大小。而且有的構架,核心空間與使用者空間的C資料類型所占空間大小也可能不同。kdatasize子產品顯示了目前子產品的核心空間C 資料類型所占空間大小。盡管概念上位址是指針,但使用一個無符号整型可以更好地實作記憶體管理; 核心把實體記憶體看成一個巨型數組, 記憶體位址就是該數組的索引。 我們可以友善地對指針取值,但直接處理記憶體位址時,我們幾乎從不會以這種方式對他取值。使用一個整數類型避免了這種取值,是以避免了 bug。是以,利用至少在 Linux 目前支援的所有平台上,指針與長整型始終是相同大小的這一事實,核心中記憶體位址常常是 unsigned long。C99 标準定義了 intptr_t 與 uintptr_t 類型,它們是能夠儲存指針值的整型變量。但沒在 2.6 核心中幾乎沒使用。 确定大小的類型 當需要知道你定義的資料的大小時,可以使用核心提供的下列資料類型(所有的資料聲明在 , 被包含在??): u8; u16; u32; u64; 若一個使用者空間程式需要使用這些類型,可在符号前加一個雙下劃線: __u8與其它類型是獨立于 __KERNEL__ 定義的。這些類型是 Linux 特定的,它們妨礙了移植軟體到其他的 Unix 機器。新的編譯器系統支援 C99-标準 類型,如 uint8_t 與 uint32_t。若考慮移植性,使用這些類型比 Linux特定的變體要好。 接口特定的類型(_t 類型) 核心中最常用的資料類型由它們自己的 typedef聲明,阻止了任何移植性問題。“接口特定(interface-specific)”由某個庫定義的一種資料類型,以便為了某個特定的資料結構提供接口。很多 _t 類型在??中定義。注意:近來已經很少定義新的接口特定的類型。有許多核心開發者已經不再喜歡使用 typedef 語句,他們甯願看到代碼中直接使用的真實類型資訊。很多老的接口特定類型在核心中保留,他們不會很快消失。即使沒有定義接口特定類型,也應該始終是用與核心其他部分保持一緻、适當的資料類型。隻要驅動使用了這種“定制”類型的函數,但又不遵照約定,編譯器會發出警告,這時使用 -Wall 編譯器選項并小心去除所有的警告,就可以确信代碼的可移植性了。_t 類型的主要問題是:列印它們時,常常不容易選擇正确的 printk 或 printf 格式。列印接口特定的資料的最好方法是:将其強制轉換為可能的最大類型(常常是 long 或 unsigned long ) 并用相應的格式列印。 其他移植性問題 移植的一個通正常則是:避免使用顯式的常量值,要使用預處理宏使常量值參數化。時間間隔當處理時間間隔時,不要假定每秒的jiffies個數,不是每個 Linux 平台都以固定的速度運作.當計算時間間隔時,要使用 HZ ( 每秒的定時器中斷數 ) 來标定你的時間。s3c2410的HZ值預設為200。頁大小當使用記憶體時,記住一個記憶體頁是 PAGE_SIZE 位元組, 不是 4KB。相關的宏定義是 PAGE_SIZE 與 PAGE_SHIT(包含将一個位址移位來獲得它的頁号的位數),在 中定義。如果使用者空間程式需要這些資訊,可以使用 getpagesize 庫函數。若一個驅動需要 16 KB 來暫存資料,一個可移植得解決方法是 get_order: #include asm/p