安装驱动后,可在/dev/目录下发现已经生成了相应的设备文件。

格式化设备:mkdosfs /dev/ramblock。

    挂载设备。

    读写设备 。

驱动程序代码:

/*************************************************************************
> File Name: ramblock.c
> Author:
> Mail:
> Created Time: 2016年11月05日 星期六 22时17分28秒
************************************************************************/
#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> #define RAMBLOCK_SIZE (1024*1024) struct gendisk *ramblock_disk;
static request_queue_t *ramblock_queue; static DEFINE_SPINLOCK(ramblock_lock); static int major; static unsigned char *ramblock_buff;
static int ramblock_getgeo(struct block_device *bdev, struct hd_geometry *geo)
{
/* 容量 = heads*sectors*cylinders*512 */
geo->heads = ;
geo->sectors = ;
geo->cylinders = RAMBLOCK_SIZE///;
return ;
} static struct block_device_operations ramblock_fops = {
.owner= THIS_MODULE,
.getgeo = ramblock_getgeo,
}; static void do_ramblock_request(request_queue_t * q)
{
struct request *req;
static int r_cnt = ;
static int w_cnt = ;
while ((req = elv_next_request(q)) != NULL)
{
/* 数据传输3要素 */
/* 源/目的 */
unsigned long offset = req->sector*; /* 目的 */
//req->buff /* 长度 */
unsigned long len = req->current_nr_sectors * ; if(rq_data_dir(req)==READ)
{
memcpy(req->buffer,ramblock_buff+offset, len);
printk("read %d\n",r_cnt++);
}
else
{
memcpy(ramblock_buff+offset, req->buffer, len);
printk("write %d\n",w_cnt++);
} end_request(req, );/* wrap up, 0 = fail, 1 = success */
} } static int ramblock_init(void)
{ /* 分配一个gendisk结构体 */
ramblock_disk = alloc_disk(); //次设备号个数=分区个数+1 /* 设置 */
/* 分配/设置队列:提供读写能力 */
ramblock_queue = blk_init_queue(do_ramblock_request, &ramblock_lock);
/* 设置其他属性 */
major = register_blkdev(,"ramblock");
ramblock_disk->major = major;
ramblock_disk->first_minor = ;
sprintf(ramblock_disk->disk_name, "ramblock");
ramblock_disk->fops = &ramblock_fops;
ramblock_disk->queue = ramblock_queue;
set_capacity(ramblock_disk, RAMBLOCK_SIZE/); /* 硬件相关 */
ramblock_buff = kzalloc(RAMBLOCK_SIZE, GFP_KERNEL);
/* 注册 */
add_disk(ramblock_disk); return ;
} static void ramblock_exit(void)
{
unregister_blkdev(major,"ramblock");
del_gendisk(ramblock_disk);
put_disk(ramblock_disk);
blk_cleanup_queue(ramblock_queue);
kfree(ramblock_buff);
} module_init(ramblock_init);
module_exit(ramblock_exit);
MODULE_LICENSE("GPL");

sd

嵌入式Linux驱动学习之路(二十二)用内存模拟磁盘的更多相关文章

  1. 嵌入式Linux驱动学习之路(二十五)虚拟网卡驱动程序

    一.协议栈层次对比 设备无关层到驱动层的体系结构 1).网络协议接口层向网络层协议提供提供统一的数据包收发接口,不论上层协议为ARP还是IP,都通过dev_queue_xmit()函数发送数据,并通过 ...

  2. 嵌入式Linux驱动学习之路(二十四)Nor Flash驱动程序

    Nor Flash和Nand Flash的不同: 类型 NOR Flash  Nand Flash  接口 RAM-like,引脚多 引脚少 容量 小(1M.2M...) 大(512M.1G) 读 简 ...

  3. 嵌入式Linux驱动学习之路(二十)USB设备驱动

    USB在接入系统的时候,以0的设备ID和主机通信,然后由主机为其分配新的ID. 在主机端,D+和D-都是下拉接地的.而设备端的D-接上拉时,表明此设备为高速设备:12M/s. D+接上拉时则是全速设备 ...

  4. 嵌入式Linux驱动学习之路(十二)按键驱动-poll机制

    实现的功能是在读取按键信息的时候,如果没有产生按键,则程序休眠在read函数中,利用poll机制,可以在没有退出的情况下让程序自动退出. 下面的程序就是在读取按键信息的时候,如果5000ms内没有按键 ...

  5. 嵌入式Linux驱动学习之路(二十六)DM9000C网卡驱动程序

    基于DM9000C的原厂代码修改dm9000c的驱动程序. 首先确认内存的基地址 iobase. 确定中断号码. 打开模块的初始化函数定义. 配置内存控制器的相应时序(结合DM9000C.C的手册). ...

  6. 嵌入式Linux驱动学习之路(二十三)NAND FLASH驱动程序

    NAND FLASH是一个存储芯片. 在芯片上的DATA0-DATA7上既能传输数据也能传输地址. 当ALE为高电平时传输的是地址. 当CLE为高电平时传输的是命令. 当ALE和CLE都为低电平时传输 ...

  7. 嵌入式Linux驱动学习之路(十八)LCD驱动

    驱动代码: /************************************************************************* > File Name: lcd ...

  8. 嵌入式Linux驱动学习之路(十六)输入子系统

    以前写的一些输入设备的驱动都是采用字符设备处理的.问题由此而来,Linux开源社区的大神们看到了这大量输入设备如此分散不堪,有木有可以实现一种机制,可以对分散的.不同类别的输入设备进行统一的驱动,所以 ...

  9. 嵌入式Linux驱动学习之路(十五)按键驱动-定时器防抖

    在之前的定时器驱动程序中,我们发现在连续按下按键的时候,正常情况下应该是一次按下对应一次松开.而程序有时候会显示是两次按下,一次松开.这个问题是因为在按下的时候,因为是机械按键,所以电压信号会产生一定 ...

随机推荐

  1. (Spring4 json入门)Spring4+SpringMVC+页面数据发送与接收(json格式)

    jar包(Maven仓库): Spring4 jar包(Maven仓库): 在测试过程中我查看了网上的一些教程,但是那些教程都是在Spring3环境下的,Spring3和Spring4解析json需要 ...

  2. php实现设计模式之 桥接模式

    <?php /** 桥接模式:将抽象部分与实现部分分离,使它们都可以独立的变化. * * 在软件系统中,某些类型由于自身的逻辑,它具有两个或多个维度的变化,桥接模式就是应对这种多维度的变化 */ ...

  3. ATM跨行取款的清算方式

    ATM跨行取款和POS机是类似的,因为没有商户参与,所以不需要收单清算,过程更为简单. 回到文章最开头的例子:你拿着一张工行卡去建行的ATM取了100元,这个跨行业务在CNAPS体系中的过程如下: 你 ...

  4. 关于arcgis engine的注记显示与关闭问题

    1.注记的添加需要拿到IGeoFeatureLayer接口下的AnnotationProperties属性,转为IAnnotationLayerPropertiesCollection接口,并创建一个 ...

  5. SharePoint 2013 工作流设计之Designer 使用“可视化视图”

    SharePoint 2013增强了工作流功能,而Designer里面也添加了可视化设计视图,也就是类似Visio的设计视图(需要Visio 2013支持),下面我们简单介绍下,在可视化视图下,使用工 ...

  6. 【转载】ReactiveX 的理念和特点

    原作者地址:http://www.open-open.com/lib/view/open1440166491833.html ReactiveX是Reactive Extensions的缩写,一般简写 ...

  7. iOS开发工程师面试题(二)

    1.手写冒泡跟插入排序 冒泡排序来源于生活常识,相当于把数组竖起来,轻的向上,重的向下.void bubbleSort(int[] unsorted) { ; i < unsorted.Leng ...

  8. linux 学习随笔-系统日常管理常用命令

    1:W 查看系统整体负载,无法查看具体负载,比如内存,磁盘  23:25:20 up 13 min,  2 users,  load average: 0.00, 0.01, 0.01 USER   ...

  9. Java暗箱操作之for-each

    对于我们常用的ArrayList等容器类,经常需要一个一个遍历里面的元素,从而对各个元素执行对应的操作. 像我代码写多了,通常的做法是用传统的,类似于数组遍历的方法,即在for循环中设置一个int变量 ...

  10. mysqldump: Got error: 1142: SELECT, LOCK TABLES command denied to user 'root'@'localhost' for table 'accounts' when using LOCK TABLES

    AutoMySQLBackup备份时,出现mysqldump: Got error: 1142: SELECT, LOCK TABLES command denied to user 'root'@' ...