初衷:
linux核心大量使用物件導向的編碼風格。然而linux核心是完全使用c寫的。
專案使用的通訊規約也是物件導向的。
物件導向一直是一種思想,c語言也可以實現其思想。
物件導向思想:
封裝繼承
建構函式多型
封裝就是猶抱琵琶半遮面,使用結構體。
linux核心裡用到類的繼承關係,這種關係使用c語言實現就是結構體的巢狀。在核心中使用cdev結構體來描述乙個字元裝置,cdev結構體的定義如下:
使用這種方法,可以一定程度模擬c++的繼承機制,當然也有他的侷限,例如他不能如同c++中一樣直接引用其中的成員,而必須通過cdev.kobj來引用。
另一方面,這種方式也無法通過」基類」,即通過結構體裡的某個成員,訪問其他成員。
這個時候linux核心通過乙個巨集定義來實現:
用於從包含在某個結構中的指標獲得結構本身的指標。
解讀:首先定義乙個指向結構體成員的指標__mptr = (ptr),型別為const typeof(…)
而這個型別為((type*)0)->member //type:表示結構體型別 ;member:表示結構體中的成員。
下一步是將__mptr向回移動乙個offset,offsetof(type,member),則移動完畢後__mptr就指向type型別的起始位址了,最後只需將其強制型別轉換為type型別,(type*)(…)。
#define offsetof(type, member) ((size_t) &((type *)0)->member)
這個思想就是,假如結構體處於0位址,獲取其成員的位址。這個位址就相對於結構體初始位址的偏移量了。
核心提供了三個函式來註冊一組字元裝置編號,這三個函式分別是 register_chrdev_region()、alloc_chrdev_region() 和 register_chrdev()。
c++的new操作符會呼叫建構函式,對類例項進行初始化。
c語言中只有malloc函式族來分配記憶體塊,linux核心中使用kzalloc 和kmalloc ,vmalloc來申請記憶體。
kmalloc()、kzalloc()、vmalloc() 的共同特點是:
用於申請核心空間的記憶體;
記憶體以位元組為單位進行分配;
所分配的記憶體虛擬位址上連續;
kmalloc()、kzalloc()、vmalloc() 的區別是:
kzalloc 是強制清零的 kmalloc 操作;(以下描述不區分 kmalloc 和 kzalloc)
kmalloc 分配的記憶體大小有限制(128kb),而 vmalloc 沒有限制;
kmalloc 可以保證分配的記憶體實體地址是連續的,但是 vmalloc 不能保證;
kmalloc 分配記憶體的過程可以是原子過程(使用 gfp_atomic),而 vmalloc 分配記憶體時則可能產生阻塞;
kmalloc 分配記憶體的開銷小,因此 kmalloc 比 vmalloc 要快;
分析下register_chrdev_region註冊函式:(為了講解去掉了出錯處理)
int register_chrdev_region(dev_t from, unsigned count, const char *name)
return 0;
}
linux核心使用chrdevs這個指標陣列來管理所有的字元裝置驅動程式,範圍:0——255。
static struct char_device_struct *chrdevs[chrdev_major_hash_size];
最終會呼叫__register_chrdev_region(major(n), minor(n),
next - n, name)這個函式。
分析過程詳見:
類的多型特徵是linux核心經常用到的,例如file_operations利用函式指標來定義一組裝置操作函式。
在核心中C語言實現htons 函式
網路位元組順序是tcp ip中規定好的一種資料表示格式,它與具體的cpu型別 作業系統等無關,從而可以保證資料在不同主機之間傳輸時能夠被正確解釋,網路位元組順序採用big endian排序 大尾順序 方式。因為專案中需要,設定例如來自埠號為9877的資料要做些什麼處理,在上層設定了9877這個數字,...
c語言實現配重系統 核心排序
題目大意 某企業生產三種零件,三個零件可合成一種產品,但三個零件的總重量有要求,不能太重也不能太輕。輸入50組資料,每組資料報含乙個a零件乙個b零件乙個c零件。輸出符合要求的資料 格式如下 工號 a零件 工號 b零件 工號 c零件 總重 思路 先將所有的a零件按從小到大的重量排序,再將所有的b零件按...
Linux核心中hash函式的實現
linux核心中通過pid查詢程序描述符 task struct 時,用到了hash表。下面介紹一下這一部分核心中hash函式的實現。核心用pid hashfn巨集把pid轉換為表索引 kernel pid.c define pid hashfn nr,ns hash long unsigned l...