塊裝置快速體驗:塊裝置是指只能以塊為單位進行訪問的裝置,塊大小一般是512個位元組的整數倍。常見的塊裝置包括硬體,sd卡,光碟等。有同學會說,加入我需要通過硬碟訪問1個位元組的資料,難道無法訪問嗎?注意這裡的512個位元組是指對硬體裝置的最小訪問單元,對應用層訪問資料的大小沒有限制。
下面開始體驗一下塊裝置:
將下面的**儲存後並編寫模組的makefile(參考前幾課的**)。
#include #include #include #include #include /* printk() */
#include /* kmalloc() */
#include /* everything... */
#include /* error codes */
#include #include /* size_t */
#include /* o_accmode */
#include /* hdio_getgeo */
#include #include #include #include #include /* invalidate_bdev */
#include module_license("dual bsd/gpl");
static int major = 0;
static int sect_size = 512;
static int nsectors = 1024;
/** the internal representation of our device.
*/struct blk_dev;
struct blk_dev *dev;
/** handle an i/o request, in sectors.
*/static void blk_transfer(struct blk_dev *dev, unsigned long sector,
unsigned long nsect, char *buffer, int write)
if (write)
memcpy(dev->data + offset, buffer, nbytes);
else
memcpy(buffer, dev->data + offset, nbytes);}/*
* the ****** form of the request function.
*/static void blk_request(struct request_queue *q)}}
/** transfer a single bio.
*/static int blk_xfer_bio(struct blk_dev *dev, struct bio *bio)
return 0; /* always "succeed" */}/*
* transfer a full request.
*/static int blk_xfer_request(struct blk_dev *dev, struct request *req)
return nsect;}/*
* the device operations structure.
*/static struct block_device_operations blk_ops = ;
/** set up our internal device.
*/static void setup_device()
dev->queue = blk_init_queue(blk_request, null);
if (dev->queue == null)
goto out_vfree;
blk_queue_logical_block_size(dev->queue, sect_size);
dev->queue->queuedata = dev;
/** and the gendisk structure.
*/dev->gd = alloc_disk(1);
if (! dev->gd)
dev->gd->major = major;
dev->gd->first_minor = 0;
dev->gd->fops = &blk_ops;
dev->gd->queue = dev->queue;
dev->gd->private_data = dev;
sprintf (dev->gd->disk_name, "simp_blk%d", 0);
set_capacity(dev->gd, nsectors*(sect_size/sect_size));
add_disk(dev->gd);
return;
out_vfree:
if (dev->data)
vfree(dev->data);
}static int __init blk_init(void)
dev = kmalloc(sizeof(struct blk_dev), gfp_kernel);
if (dev == null)
goto out_unregister;
setup_device();
return 0;
out_unregister:
unregister_blkdev(major, "sbd");
return -enomem;
}static void blk_exit(void)
if (dev->queue)
blk_cleanup_queue(dev->queue);
if (dev->data)
vfree(dev->data);
unregister_blkdev(major, "blk");
kfree(dev);
}module_init(blk_init);
module_exit(blk_exit);
編譯並安裝:
#make
#insmod ******-blk.ko
檢視驅動檔案:
#ls /dev/simp_blkdev0
可以看到這個裝置是b開頭的,代表block,塊裝置,然後把它初始化為ext3檔案系統
#mkfs.ext3 /dev/simp_blk0
把快裝置掛載到指定目錄,比如新建乙個/mnt/blk目錄,然後掛載:
#mkdir –p /mnt/blk
#mount /dev/simp_blk0 /mnt/blk
對這個目錄進行讀寫,在拷貝過程中會有警告,提示空間不足:
#cp /etc/init.d/* /mnt/blk
檢視這個塊裝置,
#ls /mnt/blk
解除安裝這個裝置
#umount /mnt/blk
再次檢視,裡面的檔案應該沒有了:
#ls /mnt/blk
我們先看看整體的構架:
使用者在訪問塊裝置的時候首先應用的是虛擬檔案系統,vfs是對各種具體檔案系統的一種封裝 ,為使用者程式訪問檔案提供統一的介面。它遮蔽了各種檔案系統的差異性:
第二個層面是catch,學過作業系統的應該知道,catch裡面儲存了需要經常訪問的檔案,用於加快訪問速度。
第三個層次是檔案系統層,他實現到實體地址的對映,並且計算出當前需要訪問多少個塊裝置,這些裝置的位址分別是多少。
第四個層次是通用塊層,它把對bock的訪問做成bio的結構,bio結構是linux系統對塊裝置訪問的通用結構。
第五個層次是io排程層,比如說電梯排程等等(具體檢視作業系統相關的知識)
第六個層次是驅動層,用於實現對物理裝置的讀寫。
linux flash裝置驅動
儲存裝置市面上常見的有nandflash,norflash,emmc這三類 1.1 nandflash nand flash式東芝在1989年的國際固態電路研討會 isscc 上發表的,要在nandflash上面讀寫資料,要外部加主控和電路設計。nand flash具有較快的抹寫時間,而且每個儲存單...
Linux FLASH驅動設計二
塊裝置驅動系統分析 功能 把記憶體劃出512k,然後利用驅動程式做成塊裝置進行相應的訪問。include include include include include printk include kmalloc include everything.include error codes inc...
LINUX塊裝置驅動 1
編寫塊裝置驅動的關鍵步驟 1 呼叫register blkdev申請或註冊主裝置號及裝置名稱,詳見核心原始碼中該函式的注釋。不過下面這篇文章裡並未用到這一步 2 呼叫blk init queue函式建立並初始化乙個 request queue 結構,該函式需要乙個用來處理請求的do request函...