您的位置:首页 > 运维架构 > Linux

嵌入式Linux驱动学习之路(二十二)用内存模拟磁盘

2016-11-05 22:51 411 查看
安装驱动后,可在/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 = 2;
geo->sectors = 32;
geo->cylinders = RAMBLOCK_SIZE/2/32/512;
return 0;
}

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 = 0;
static int w_cnt = 0;
while ((req = elv_next_request(q)) != NULL)
{
/* 数据传输3要素 */
/* 源/目的 */
unsigned long offset = req->sector*512;

/* 目的 */
//req->buff

/* 长度 */
unsigned long len = req->current_nr_sectors * 512;

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, 1);/* wrap up, 0 = fail, 1 = success */
}

}

static int ramblock_init(void)
{

/* 分配一个gendisk结构体 */
ramblock_disk = alloc_disk(16);  //次设备号个数=分区个数+1

/* 设置 */
/* 分配/设置队列:提供读写能力 */
ramblock_queue = blk_init_queue(do_ramblock_request, &ramblock_lock);
/* 设置其他属性 */
major = register_blkdev(0,"ramblock");
ramblock_disk->major = major;
ramblock_disk->first_minor = 0;
sprintf(ramblock_disk->disk_name, "ramblock");
ramblock_disk->fops = &ramblock_fops;
ramblock_disk->queue = ramblock_queue;
set_capacity(ramblock_disk, RAMBLOCK_SIZE/512);

/* 硬件相关 */
ramblock_buff = kzalloc(RAMBLOCK_SIZE, GFP_KERNEL);
/* 注册 */
add_disk(ramblock_disk);

return 0;
}

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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: