搜尋「blk_init_queut()」參考「drivers\block\xd.c」和「drivers\block\z2ram.c」兩個檔案。
看乙個驅動程式從「入口函式」開始看。
處理函式》放到佇列》放到gendisk
其他屬性()>>gengdisk
最終效果,檔案系統通過處理函式來實現相應的功能.
塊裝置驅動框架
之前分析把「檔案讀寫」轉成「扇區讀寫」,對「扇區的讀寫」會放入個佇列裡面:
把「buffer_head」構造為「bio」,把「bio」放入到佇列裡面,呼叫佇列裡面的「q->make_request_fn」函式,這個「make_request_fn」構造請求的函式有預設的函式
「__make_request」。
當我們初始化佇列時,給我們提供了乙個預設構造請求的函式「__make_request」。當它把這個「請求」放入到「佇列」之後,以後會用這個佇列裡的「q->request_fn()」來處理。這個「request_fn()」就等於「blk_init_queue_node()」函式傳進來的引數「形參1:request_fn_proc *rfn」。這個形參 1 會賦給「request_fn」,最後就是我們要定義的乙個處理請求的函式。request_queue_t *blk_init_queue(request_fn_proc *rfn, spinlock_t *lock)-->blk_init_queue_node(rfn, lock, -1);-->blk_queue_make_request(q, __make_request);提供了預設構造請求的函式。對於我們這裡這個把記憶體模擬成硬碟的驅動來說,最終會是我們這裡定義的
「do_rambloc_request」來處理請求。
塊裝置驅動程式編寫步驟
a. 使用alloc_disk分配gendisk結構體
b. 設定gendisk
b.1 blk_init_queue(分配/設定)佇列request_queue_t
b.2 設定gendisk其他資訊
// 它提供屬性: 如容量
c. 註冊: add_disk
具體流程
設定其他屬性
0alloc_disk():
1主裝置號
2第乙個次裝置號是什麼 和 塊裝置的名字。
3,fops :操作函式。即使是空的操作函式,這個 fops 也要提供。(經過實驗,即使這個函式裡什麼也沒有(如沒有".ioctl"和".getgeo"),也要提供這個結構體。不然會出錯。)
4容量:設定容量時,是以扇區為單位
5設定佇列:
6註冊:add_disk().
7設定處理函式()
注意 : 對於乙個塊裝置,次裝置號為「0」時,表示整個磁碟。如「/dev/sda」。次裝置號「1,
2,、」表示是磁碟的第幾個 主 分割槽。次裝置號從 5 開始是「擴充套件分割槽」
static struct gendisk *ramblock_disk;
static struct request_queue *ramblock_queue;
/*獲得主裝置號*/
ramblock_disk = alloc_disk(16) //次裝置號個數/分割槽個數+1
ramblock_queue = blk_init_queue(do_ramblock_request, &ramdisk_lock)
ramblock_disk->queue = ramblock_queue;
塊裝置驅動之記憶體模擬硬碟
一.塊裝置驅動框架 與字元裝置相比什麼差別 1.塊裝置僅僅能以塊為單位接受輸入和返回輸出。而字元裝置則以位元組為單位。大多數裝置是字元裝置,由於它們不須要緩衝並且不以固定塊大小進行操作。2.塊裝置對於i o請求有相應的緩衝區。因此它們能夠選擇以什麼順序進行響應,字元裝置無需緩衝且被直接讀寫。對於儲存...
Linux塊裝置驅動之記憶體模擬塊裝置
用記憶體代替塊裝置的總結,相對來簡單得多,對記憶體操作想必大家都很熟悉,直接分配一塊記憶體就可以直接讀寫操作了 參考 drivers block xd.c drivers block z2ram.c define ramblock size 1024 1024 乙個扇區是512位元組 static ...
編寫塊裝置驅動之記憶體模擬磁碟
可以參考一下核心裡面的檔案 在核心裡面收索blk init queue 然後就會發現xd.c和z2ram.c 大概看一眼,看乙個去驅動程式從入口開始看,這裡有個register blkdev註冊塊裝置驅動,跟我們字元裝置相比少了乙個fops,註冊塊裝置已經退化了,它只不過是cat prok devi...