塊裝置驅動程式的引入和簡單應用

2021-07-27 03:54:23 字數 4953 閱讀 5130

先說說為什麼要引入塊裝置驅動程式。

以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...