块设备驱动总结

来源:互联网 发布:mysql存储过程临时表 编辑:程序博客网 时间:2024/06/05 19:00

知识储备:

          块设备驱动是基于扇区(sector)来访问底层物理磁盘,基于块(block)来访问上层文件系统。扇区一般是2的n次方大小,典型为512B,内核也要求块是2的n次方大小,且块大小通常为扇区大小的整数倍,并且块大小要小于页面大小,典型大小为512B、1K或4K。

     内存和NOR型闪存的基本存储单元是bit,用户可以随机访问任何一个bit的信息。NAND型闪存的基本存储单元是页(Page)(可以看到, NAND型闪存的页就类似硬盘的扇区,硬盘的一个扇区也为512字节)。每一页的有效容量是512字节的倍数。所谓的有效容量是指用于数据存储的部分,实际上还要加上16字节的校验信息,因此我们可以在闪存厂商的技术资料当中看到“(512+16)Byte”的表示方式。目前2Gb以下容量的NAND型闪存绝大多数是(512+16)字节的页面容量,2Gb以上容量的NAND型闪存则将页容量扩大到(2048+64)字节。
 NAND型闪存以块为单位进行擦除操作。闪存的写入操作必须在空白区域进行,如果目标区域已经有数据,必须先擦除后写入,因此擦除操作是闪存的基本操作。一般每个块包含32个512字节的页,容量16KB;而大容量闪存采用2KB页时,则每个块包含64个页,容量128KB。每颗NAND型闪存的I/O接口一般是8条,每条数据线每次传输(512+16)bit信息,8条就是(512+16)×8bit,也就是前面说的512字节。

     源代码:

#include<linux/init.h>#include<linux/module.h>#include<linux/genhd.h>#include <linux/module.h>#include <linux/errno.h>#include <linux/interrupt.h>#include <linux/mm.h>#include <linux/fs.h>#include <linux/kernel.h>#include <linux/timer.h>#include <linux/genhd.h>#include <linux/hdreg.h>#include <linux/ioport.h>#include <linux/init.h>#include <linux/wait.h>#include <linux/blkdev.h>#include <linux/blkpg.h>#include <linux/delay.h>#include <linux/io.h>#include <linux/gfp.h>#include <linux/slab.h>#include <asm/system.h>#include <asm/uaccess.h>#include <asm/dma.h>//#define   DEV_MAJOR  251#define RAMDISK_SIZE (1024)static struct gendisk * mydisk;static struct request_queue *blkdev_queue;static DEFINE_SPINLOCK(ramdisk_lock);static unsigned char *ram_buff;static int DEV_MAJOR;static const struct block_device_operations rmbk_fops = {.owner= THIS_MODULE,};static void ramblock_do_request(struct request_queue * q){  struct request *req;  printk("do:ramblock_do_request\n");  req = blk_fetch_request(q);  while (req){//源或目的        unsigned long offset = blk_rq_pos(req)*512;                //目的或源        //req->buffer       // 长度        unsigned long len = blk_rq_cur_bytes(req);        if(rq_data_dir(req) == READ)memcpy(req->buffer, ram_buff+offset, len);        else                memcpy(ram_buff+offset,req->buffer,len);                  // wrap up ,0 = success, -errno =fail                if(!__blk_end_request_cur(req,0))req = blk_fetch_request(q);     }}      static int blkdev_init(void){    printk("begin\n");    // int ret;  DEV_MAJOR = register_blkdev(DEV_MAJOR,  "vmdisk");/* 注册块设备 */   /* 分配gendisk结构体*/    mydisk  =  alloc_disk(1);           blkdev_queue = blk_init_queue(ramblock_do_request,&ramdisk_lock);/* 为块设备准备一个请求队列 */    mydisk->queue =  blkdev_queue;  mydisk->major =  DEV_MAJOR;  mydisk->first_minor  =  0;  mydisk->fops =  &rmbk_fops;  sprintf(mydisk->disk_name, "vmdisk");  set_capacity(mydisk,  RAMDISK_SIZE);  ram_buff = kzalloc(RAMDISK_SIZE, GFP_KERNEL);  add_disk(mydisk);  return 0;}static void blkdev_exit(void){   printk("quit\n");    unregister_blkdev(DEV_MAJOR, "vmdisk");    del_gendisk(mydisk);    put_disk(mydisk);    blk_cleanup_queue(blkdev_queue);    kfree(ram_buff);}module_init(blkdev_init);module_exit(blkdev_exit);MODULE_LICENSE("GPL");

终端输入

FDISK的/ dev / ramdisk的进入块设备的设置

然后执行 

mkfs.vfat的/ dev / ramdisk的对分区进行格式化

接下来将其挂载到文件系统

执行命令

mount  /dev/块设备名 /ming

成功挂载


测试读写操作

LS> ming/123

cat 123



   


0 0