本節我們利用前兩節所總結的內容設計乙個簡單的塊裝置驅動程式,分配一塊記憶體作為磁碟實現塊裝置的功能。
首先是一些巨集定義和全域性變數
#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函...