先說說為什麼要引入塊裝置驅動程式。
以flash為例,如果對flash的讀寫採用字元裝置驅動程式的那一套的話,會產生效率低下的問題。flash是以塊為單位進行操作的,假如在flash乙個塊中,要完成對扇區0和扇區1的改寫,如果按照字元裝置的方式,需要完成以下步驟:
①讀出整個塊到buffer
②修改buffer的扇區0
③擦除整個塊
④燒寫整塊
⑤讀出整個塊到buffer
⑥修改buffer的扇區1
⑦擦除整個塊
⑧燒寫整塊
但如果我們引入一些優化:
①讀出整個塊到buffer
②修改buffer的扇區0和扇區1
③擦除整個塊
④燒寫整塊
這樣我們就能夠大大提高效率。因此,塊裝置驅動程式的基本思想就出來了:先不執行讀寫,而是放入佇列;優化之後再執行。
下面介紹一下塊裝置驅動程式的框架。
--------------------------------------------- 檔案的讀寫
檔案系統: vfat, ext2, ext3, yaffs2, jffs2 (把檔案的讀寫轉換為扇區的讀寫)
-----------------ll_rw_block----------------- 扇區的讀寫
1. 把"讀寫"放入佇列
2. 呼叫佇列的處理函式(優化/調順序/合併)
塊裝置驅動程式
---------------------------------------------
硬體: 硬碟,flash
下面開始分析ll_rw_block(low level read/write block)
分析ll_rw_block
for (i = 0; i < nr; i++) ;
#define ramblock_size (1024*1024)
static
void do_ramblock_request(request_queue_t * q)
static
int ramblock_init(void)
static
void ramblock_exit(void)
module_init(ramblock_init);
module_exit(ramblock_exit);
module_license("gpl");
載入驅動之後發現:
ramblock:do_ramblock_request 1
然後就卡住了,無法繼續操作。說明確實呼叫了do_ramblock_request這個函式,但由於我們沒有對它進行進一步的處理,所以還需要完善。
static
void do_ramblock_request(request_queue_t * q)
}
以電梯排程演算法取出下乙個請求,然後結束請求並返回1表示成功。實際上我們什麼都沒有做,但這樣就不會卡住了。它會列印出如下結果:
ramblock:do_ramblock_request 1
unknown partition table
之所以提示不識別的分割槽表,是因為我們在實際上我們在do_ramblock_request裡什麼都沒有做。我們只是簡單粗暴的把請求拿出來,然後就簡單把它當成完成了。
進一步優化:
static
void do_ramblock_request(request_queue_t * q)
else
end_request(req, 1);
}
其中memcpy(void *dest, const void *src, size_t count)。
測試:
在開發板上:
1. insmod ramblock.ko
2. 格式化: mkdosfs /dev/ramblock
3. 掛接: mount /dev/ramblock /tmp/
4. 讀寫檔案: cd /tmp, 在裡面vi檔案,比如新建乙個1.txt,裡面的內容是「hello」
5. cd /; umount /tmp/,解除安裝裝置
6. cat /dev/ramblock > /mnt/ramblock.bin,把檔案的內容統統存到/mnt/ramblock.bin,相當於整個磁碟映象。
7. 在pc上檢視ramblock.bin
sudo mount -o loop ramblock.bin /mnt,可以把乙個普通檔案當作塊裝置檔案掛載,輸入ls仍然可以看到1.txt。
接下來加入列印語句,可以看到一些有意思的事情:
static
void do_ramblock_request(request_queue_t * q)
else
end_request(req, 1);
}}
還是按照上面的步驟測試,當掛載到/tmp之後,我們執行「cp /etc/inittab /tmp」:
do_ramblock_request write 6
do_ramblock_request write 7
do_ramblock_request write 8
再執行sync
do_ramblock_request write 9
do_ramblock_request write 10
其中,列印的時候會有很長的時間間隔,當輸入sync時,會完成全部操作。sync是乙個系統呼叫,是同步的意思。
從這裡我們可以看出,塊裝置的讀寫不會交叉執行,而是會進行優化,放入佇列。
static
struct block_device_operations ramblock_fops = ;
static
int ramblock_getgeo(struct block_device *bdev, struct hd_geometry *geo)
要注意的是,實際上很多磁碟已經不是這種結構了,但為了相容,必須設定虛擬的引數,這樣才能借助分割槽工具。
載入驅動之後輸入fdisk /dev/ramblock。然後輸入n新建乙個分割槽,輸入p表示主分割槽,然後輸入1表示第乙個主分割槽。
command (m for help): p
disk /dev/ramblock: 1 mb, 1048576 bytes
2 heads, 32 sectors/track, 32 cylinders
units = cylinders of 64 * 512 = 32768 bytes
device boot start
end blocks id system
command (m for help): n
command action
e extended
p primary partition (1-4)
ppartition number (1-4): 1
first cylinder (1-32, default
1): 1
last cylinder or +size
or +sizem or +sizek (1-32, default
32): 5
command (m for help): w
the partition table has been altered!
ramblock: ramblock1
這樣第乙個分割槽就好了。剩下的分割槽也這樣操作,最後別忘記輸入「w」把分割槽寫到分割槽表中。最後可以看到:
command (m for help): p
disk /dev/ramblock: 1 mb, 1048576
bytes
2 heads, 32 sectors/track, 32 cylinders
units = cylinders of
64 * 512 = 32768
bytes
device boot start end blocks id system
/dev/ramblock1 1
5144
83 linux
/dev/ramblock2 6
25640
83 linux
/dev/ramblock3 26
32224
83 linux
如果現在輸入」ls /dev/ramblock* -l」,會看到:
brw-rw
----
100254,0
jan1
00:45
/dev/ramblock
brw-rw-
---1
00254,
1jan
100:45
/dev/ramblock1
brw-rw-
---1
00254,
2jan
100:45
/dev/ramblock2
brw-rw-
---1
00254,
3jan
100:45
/dev/ramblock3
如果我們想分別格式化的時候就可以直接「fdisk /dev/ramblock2」,還可以直接掛載「mount /dev/ramblock1 /tmp/」。
驅動程式就寫到這裡,用記憶體模擬磁碟很簡單,可以想象一下,如果塊裝置也能夠像記憶體一樣訪問的話,塊裝置就會非常的簡單,但可惜的是,現在還達不到這種水平,硬體的操作太複雜了。但塊裝置本身的框架並不複雜。
裝置驅動 塊裝置驅動程式
塊裝置驅動程式提供對面向塊的裝置的訪問,這種裝置以隨機訪問的方式傳輸資料,並且資料總是具有固定大小的塊。典型的塊裝置是磁碟驅動器,也有其它型別的塊裝置。塊裝置和字元裝置有很大區別。比如塊裝置上可以掛載檔案系統,字元裝置不可以。這是隨機訪問帶來的優勢,因為檔案系統需要能按塊儲存資料,同時更需要能隨機讀...
塊裝置驅動程式
裝置描述 定義於linux genhd.h struct gendisk 裝置註冊 void add disk struct gendisk gd 裝置操作 字元裝置通過file operations結構來定義它所支援的操作。塊裝置通過struct block device operations結構...
塊裝置驅動程式
塊裝置驅動程式 1 塊裝置和字元裝置的區別 1,讀取資料的單元不同,塊裝置讀寫資料的基本單元式塊,字元裝置的基本單元是位元組。2,塊裝置可以隨機訪問,字元裝置只能順序訪問。2 linux核心中塊裝置的描述 struct gendisk 裝置操作 struct block device operati...