×
单片机 > 单片机程序设计 > 详情

OK6410块设备驱动之用内存模拟磁盘

发布时间:2020-06-03 发布时间:
|

ramblock.c源码:

// 参考drivers/block/xd.c,z2ram.c

#include "linux/major.h"

#include "linux/vmalloc.h"

#include "linux/init.h"

#include "linux/module.h"

#include "linux/blkdev.h"

#include "linux/bitops.h"

#include "linux/hdreg.h"

 

#define RAMBLOCK_SIZE 0x100000

static struct gendisk *ramblock_disk;

static struct request_queue *ramblock_queue;

static int major;

static unsigned char *ramblock_buf;

static DEFINE_SPINLOCK(ramblock_lock);

static int ramblock_getgeo(struct block_device *dev, struct hd_geometry *geo)

{

    // 容量 = heads * cylinders * sectors *512 

    geo->heads     = 2;

    geo->cylinders = 128;

    geo->sectors   = RAMBLOCK_SIZE / 2 / 128 / 512;

    return 0;

}

static struct block_device_operations ramblock_fops =

{

    .owner      = THIS_MODULE,

    .getgeo     = ramblock_getgeo,

};

static void do_ramblock_request(struct request_queue *q)

{

    static int r_cnt = 0;

    static int w_cnt = 0;

    struct request *req;

    

    //printk("do_ramblock_request %d\n", ++cnt);

    

    while ((req = elv_next_request(q)) != NULL) 

    {

        // 数据传输3要素: 源,目的,长度 

        // 源/目的 

        unsigned long offset = req->sector * 512;

        // 目的/源: req->buffer 

        // 长度 

        unsigned long len = req->current_nr_sectors * 512;

        if (rq_data_dir(req) == READ)

        {

            //printk("do_ramblock_request read %d\n", ++r_cnt);

            memcpy(req->buffer, ramblock_buf+offset, len);

        }

        else

        {

            //printk("do_ramblock_request write %d\n", ++w_cnt);

            memcpy(ramblock_buf+offset, req->buffer, len);

        }

        end_request(req, 1);  // 1 - 成功 

    }

}

static int ramblock_init(void)

{

    // 0. register_blkdev : cat /proc/devices 

    major = register_blkdev(0, "ramblock");

    

    // 1. 分配gendisk 

    ramblock_disk = alloc_disk(2);   // 0-整个磁盘, 1-第1个分区 

    // 2. 设置 

    // 2.1 设置队列: 提供读写的能力 

    ramblock_queue = blk_init_queue(do_ramblock_request, &ramblock_lock);

    ramblock_disk->queue = ramblock_queue;

    // 2.2 设置属性: 比如容量,主设备号,第1个次设备号,操作函数等 

    ramblock_disk->major       = major;

    ramblock_disk->first_minor = 0;  // (major,0),(major,1),...,(major,15) 

    ramblock_disk->fops = &ramblock_fops;

    set_capacity(ramblock_disk, RAMBLOCK_SIZE / 512);

    sprintf(ramblock_disk->disk_name, "ramblock");

    // 3. 硬件相关操作 

    ramblock_buf = vmalloc(RAMBLOCK_SIZE);

    // 4. 注册 

    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);

}

module_init(ramblock_init);

module_exit(ramblock_exit);

MODULE_LICENSE("GPL");

=====================================================================

Makefile文件:

KERN_DIR = /home/linux-3.0.1

all:

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

clean:

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

    rm -rf modules.order

obj-m += ramblock.o

=====================================================================

测试详情参考:JZ2440块设备驱动程序的编写驱动之用内存模拟磁盘



『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
采用AT89C2051的数字可调稳压电源单片机源程序