块设备驱动框架

以RAM模拟一个分区为例

框架入口源文件:armblock.c

(可根据入口源文件,再按着框架到内核走一遍)

内核版本:linux_2.6.22.6     硬件平台:JZ2440

以下是驱动代码  armblock.c :

#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 <asm/system.h>
#include <asm/uaccess.h>
#include <asm/dma.h>

// ram_block_disk  独立的磁盘设备或则分区
static struct gendisk *ram_block_disk;

//定义一个request_queue 结构体
static struct request_queue *ram_block_req;

//定义一个自旋锁
static DEFINE_SPINLOCK(ramblock_lock);

//定义一个主设备号
static int major;

//磁盘大小
#define GENDISK_SIZE (1024*1024)  

//缓存起始地址
static unsigned char *gendisk_buffer;

//getgeo 获得驱动器信息
static int gendisk_getgeo(struct block_device *dev, struct hd_geometry *geo)
{
  geo->heads = 2;
  geo->cylinders = 32;
  geo->sectors = (GENDISK_SIZE/2/32/512);
  return 0;
}

static struct block_device_operations gendisk_fops=
{
   .owner = THIS_MODULE,
   .getgeo = gendisk_getgeo,
};

//请求函数
static void ram_block_req_fn(request_queue_t * q)
{
    struct request *req;
    unsigned long offset=0, len=0;

    while((req =  elv_next_request(q))!=NULL)
    {
       offset = req->sector*512;
       len = req->current_nr_sectors*512;

       if(rq_data_dir(req) == READ)  memcpy( req->buffer,gendisk_buffer+offset,len  );  //read   dest src len
        else                    memcpy( gendisk_buffer+offset, req->buffer, len ); // write

      end_request(req,1);
    }
}

static int ram_block_init(void)
{
   //申请gendisk
   ram_block_disk = alloc_disk(16);

   //设置gendisk
       //绑定请求函数
       ram_block_req = blk_init_queue(ram_block_req_fn,&ramblock_lock);
       ram_block_disk->queue = ram_block_req;
       //设置gendisk参数       注册blk
       major = register_blkdev(0, "armblock" );   /* cat /proc/devices */
       sprintf(ram_block_disk->disk_name, "armblock");
       ram_block_disk->fops  = &gendisk_fops;
       ram_block_disk->first_minor   = 0;
       ram_block_disk->major         = major;
       set_capacity(ram_block_disk, GENDISK_SIZE/512);
       gendisk_buffer = kzalloc(GENDISK_SIZE,GFP_KERNEL);    //磁盘起始地址

   //添加gendisk
   add_disk(ram_block_disk);
   return 0;
}

static void ram_block_exit(void)
{
    del_gendisk(ram_block_disk);
    put_disk(ram_block_disk);

    blk_cleanup_queue(ram_block_req);

    unregister_blkdev(major,"armblock");

    kfree(gendisk_buffer);
}

module_init(ram_block_init);
module_exit(ram_block_exit);

MODULE_LICENSE("GPL");

以下是编译驱动的Makefile:

KERN_DIR = /work/systems/kernel/linux-2/linux-2.6.22.6

all:
    make -C $(KERN_DIR) M=`pwd` modules 

clean:
    make -C $(KERN_DIR) M=`pwd` modules clean
    rm -rf modules.order

obj-m    += armblock.o

原文地址:https://www.cnblogs.com/zsy12138/p/10392758.html

时间: 2024-12-20 17:18:32

块设备驱动框架的相关文章

块设备驱动框架详解

一.正确的理解块设备驱动的概念 1.块设备和字符设备的差异 (1)块和字符是两种不同的访问设备的策略 (2)同一个设备可以同时支持块和字符两种访问策略 (3)设备本身的物理特性决定了哪一种访问策略更适合 (4)块设备本身驱动层支持缓冲区,而字符设备驱动层没有缓冲 (5)块设备驱动最适合存储设备 2.块设备驱动的特点 (1)字符设备只能顺序访问(如串口发送数据顺序),而块设备可以随机访问(不连续块访问). (2)传统的机械式块设备(如硬盘.DVD)虽然可以随机访问,但是连续访问效率更高,因此块设备

块设备驱动框架分析(二)

参考:块设备驱动之一  块设备驱动之二  块设备驱动之三 总结上一篇的块设备驱动的步骤: 1. 分配gendisk: alloc_disk static struct gendisk * ramblock_disk = alloc_disk(16); /* 次设备号个数: 分区个数+1 */2. 设置2.1 分配/设置队列: // 它提供读写能力static struct request_queue  * ramblock_queue = blk_init_queue(do_ramblock_r

Linux设备驱动框架设计

引子 Linux操作系统的一大优势就是支持数以万计的芯片设备,大大小小的芯片厂商工程师都在积极地向Linux kernel提交设备驱动代码.能让这个目标得以实现,这背后隐藏着一个看不见的技术优势:Linux内核提供了一套易于扩展和维护的设备驱动框架.Linux内核本身提供一套设备驱动模型,此模型提供了Linux内核对设备的一般性抽象描述,包括设备的电源管理.对象生命周期管理.用户空间呈现等等.在设备模型的帮助下,设备驱动开发工程师从设备的一般性抽象中解脱出来.但是每个设备的具体功能实现还需要大量

块设备驱动之内存模拟硬盘

转载请注明出处:http://blog.csdn.net/ruoyunliufeng/article/details/25240899 一.块设备驱动框架 app:      open,read,write "hello.txt" ---------------------------------------------  文件的读写 文件系统: vfat, ext2, ext3, yaffs2, jffs2      (把文件的读写转换为扇区的读写) ----------------

linux块设备驱动---概念与框架(转)

基本概念   块设备(blockdevice) --- 是一种具有一定结构的随机存取设备,对这种设备的读写是按块进行的,他使用缓冲区来存放暂时的数据,待条件成熟后,从缓存一次性写入设备或者从设备一次性读到缓冲区. 字符设备(Character device) ---是一个顺序的数据流设备,对这种设备的读写是按字符进行的,而且这些字符是连续地形成一个数据流.他不具备缓冲区,所以对这种设备的读写是实时的. 扇区(Sectors):任何块设备硬件对数据处理的基本单位.通常,1个扇区的大小为512byt

块设备驱动之NAND FLASH驱动程序

转载请注明出处:http://blog.csdn.net/ruoyunliufeng/article/details/25240909 一.框架总结 二.硬件原理 相比于nor flash,我们可以清楚的看出引脚少了很多,主要是输入输出引脚进行了复用.现在我说下各引脚的用途. a.LDATA0~LDATA7这8个引脚为输入输出引脚.命令.地址.数据的传输都是由这8个引脚实现的(引脚复用,节约引脚). b.RnB:此引脚用来判忙.因为命令.数据.地址发出去和收到时候不能立刻就完成,需要一个时间.此

块设备驱动

在Linux下,驱动设备有字符设备驱动.块设备驱动和网络设备驱动三种,之前学习了字符设备驱动,现在开始学习块设备驱动.首先来比较看这两种设备驱动有何不通,为什么要分割成不同类型的驱动.举一个例子说明引入块设备驱动的必要: 假如按照字符设备一样的框架去构造驱动,如图: 则需要频繁地对存储设备进行擦除,如果使用另一种框架构思(块设备思想): 对比之下,对于这样的存储设备,则引入块设备显然使得操作的效果大为提高.由此可知块设备的特点就是:把请求放入队列,优化后执行. 字符设备与块设备I/O操作的区别:

Linux块设备驱动详解

<机械硬盘> a:磁盘结构 -----传统的机械硬盘一般为3.5英寸硬盘,并由多个圆形蝶片组成,每个蝶片拥有独立的机械臂和磁头,每个堞片的圆形平面被划分了不同的同心圆,每一个同心圆称为一个磁道,位于最外面的道的周长最长称为外道,最里面的道称为内道,通常硬盘厂商会将圆形蝶片最靠里面的一些内道(速度较慢,影响性能)封装起来不用:道又被划分成不同的块单元称为扇区,每个道的周长不同,现代硬盘不同长度的道划分出来的扇区数也是不相同的,而磁头不工作的时候一般位于内道,如果追求响应时间,则数据可存储在硬盘的

Linux块设备驱动

推荐书:<Linux内核源代码情景分析> 1.字符设备驱动和使用中等待某一事件的方法①查询方式②休眠唤醒,但是这种没有超时时间③poll机制,在休眠唤醒基础上加一个超时时间④异步通知,异步通知实际上就是发信号⑤输入子系统,这样比较通用 2.块设备相对于字符设备驱动逻辑的变化①对于硬盘对读写的优化假如要读磁头0的扇区0,然后写磁头1的扇区0,然后读磁头0的扇区1,若像字符设备那样,就会机械山跳转2次,效率低.优化:先不执行,放入队列,优化后再执行,这里的优化是指调整顺序. ②对于flash假如要