Linux塊裝置驅動(三)程式設計

2021-08-29 20:15:07 字數 2730 閱讀 7285

本節我們利用前兩節所總結的內容設計乙個簡單的塊裝置驅動程式,分配一塊記憶體作為磁碟實現塊裝置的功能。

首先是一些巨集定義和全域性變數

#define ramdisk_size		(1024*1024)

#define sector_size 512

static int major;

struct ramdisk_dev ;

struct ramdisk_dev *ramdisk;

我們定義了乙個名為ramdisk_dev的結構描述該塊裝置,buffer指向訪問資料記憶體,lock是控制訪問佇列的自旋鎖,gd就是核心的gendisk結構體。巨集定義ramdisk_size為整個磁碟的容量,sector_size為每個扇區的大小。

入口和出口函式

static struct block_device_operations ramdisk_fops = ;

static int __init ramdisk_init(void)

ramdisk = kmalloc(sizeof(struct ramdisk_dev), gfp_kernel);

if (!ramdisk)

goto unregister;

memset(ramdisk, 0, sizeof(struct ramdisk_dev));

ramdisk->buffer = vmalloc(ramdisk_size);

if (ramdisk->buffer == null)

goto unregister;

spin_lock_init(&ramdisk->lock);

ramdisk->gd = alloc_disk(16);

if (ramdisk->gd == null)

goto vfree;

ramdisk->gd->major = major;

ramdisk->gd->first_minor = 0;

ramdisk->gd->fops = &ramdisk_fops;

ramdisk->gd->queue = blk_init_queue(ramdisk_request, &ramdisk->lock);

if (ramdisk->gd->queue == null)

goto vfree;

sprintf(ramdisk->gd->disk_name, "ramdisk0");

set_capacity(ramdisk->gd, ramdisk_size / 512);

add_disk(ramdisk->gd);

return 0;

vfree:

vfree(ramdisk->buffer);

unregister:

unregister_blkdev(major, "sbd");

return -enomem;

}module_init(ramdisk_init);

static void vmem_disk_exit(void)

if (ramdisk->buffer)

vfree(ramdisk->buffer);

unregister_blkdev(major, "ramdisk");

kfree(ramdisk);

}module_exit(vmem_disk_exit);

入口函式初始化乙個ramdisk_dev,並初始化其中的gendisk結構體,出口函式釋放分配的資源。

block_device_operations中成員函式的實現,這裡只實現getgeo函式,設定磁頭,磁柱,扇區資訊

static int ramdisk_getgeo(struct block_device *bdev, struct hd_geometry *geo)

最後就是處理請求函式的實現了

static void ramdisk_request(struct request_queue *q)

}__blk_end_request_all(req, 0);

}}

請求處理函式提取出每個請求,再遍歷每個請求的每個bio,再遍歷每個bio的bio_vec。

處理每個bio的過程: 

通過bio->bvec-iter->bi_sector得到要操作哪個扇區;

提取每個bio_vec;

處理每個bio_vec: 需要三個要素,請求的快取位址,塊裝置的讀寫起始位址,傳輸資料的位元組數

傳輸資料的位元組數:用bio_cur_bytes()得到。

接下來就是複製資料了,最後算出下乙個bio_vec在哪個扇區,用傳輸資料的位元組數除以扇區容量,表示這次操作佔了幾個扇區,再累加到當前扇區編號就得到下次操作所在的扇區。

編譯通過後載入驅動,可以在/dev目錄下看到這個塊裝置:

再將其格式化為ext2檔案系統:mkfs.ext2 /dev/ramdisk0

接下來就可以掛載使用了,我們先建立乙個ramdisk目錄,將其掛載到該目錄上:

使用df指令檢視:

可以看到這個磁碟已經成功掛載可以使用了。 

Linux塊裝置驅動

塊裝置提供塊裝置提供裝置的訪問,裝置的訪問,可以隨機的以固定大小的塊傳輸資料,例如我們最為常見的磁碟裝置,當然塊裝置和字元裝置有較大差別,塊裝置有自己的驅動介面。簡單來說,核心決定乙個塊是固定的4096 位元組,當然該值可以隨著依賴檔案系統的變化而改變。塊裝置驅動採用register blkdev向...

linux驅動之塊裝置驅動

塊裝置驅動的系統架構 塊裝置註冊過程 1,註冊裝置塊驅動程式 register blkdev 2,初始化請求佇列 blk init queue 3,指明扇區的大小 blk queue logical block size dev queue,sect size 4,申請乙個gendisk結構,初始化...

LINUX塊裝置驅動 1

編寫塊裝置驅動的關鍵步驟 1 呼叫register blkdev申請或註冊主裝置號及裝置名稱,詳見核心原始碼中該函式的注釋。不過下面這篇文章裡並未用到這一步 2 呼叫blk init queue函式建立並初始化乙個 request queue 結構,該函式需要乙個用來處理請求的do request函...