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

安装驱动后,可在/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驱动学习之路(二十三)NAND FLASH驱动程序


下一篇:嵌入式Linux驱动学习之路(二十)USB设备驱动