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块设备驱动程序的编写驱动之用内存模拟磁盘


关键字:OK6410  块设备驱动  内存  模拟磁盘 引用地址:OK6410块设备驱动之用内存模拟磁盘

上一篇:OK6410块设备驱动内存模拟nor_flash
下一篇:OK6410之USB设备驱动程序

推荐阅读

从工业革命时期开始,机器就开始替代机械化重复的体力劳动。通常这些机器运作时,人类需要与其保持一个安全距离。然而,越来越多的研究人员开始思考,如何让机器接近人类、与人协作、甚至可以向人类学习。 近日,开发了一套训练机器人的系统,教机器人如何通过观察人类活动来行动。研究人员用 s 给不同物体打上标签,并开发了一组程序,让机器人先感...
一、串行通信的通信方式1.同步通信:带时钟同步信号传输,有一根线是同步时钟。例如SPI(全双功)、IIC(半双工)通信接口2.异步通信:不带时钟同步信号,必须约定好波特率。例如UART(全双功)二、STM32的串口通信接口UART:通用异步收发器。USART:通用同步异步收发器。STM32F10x系列包含3个USART和2个UART。都是TTL电平交叉相连即可与PC机可以使用USB-T...
10月7日凌晨,苹果正式官宣将在北京时间10月14日凌晨1点召开新品发布会,届时全新的iPhone 12系列手机即将与我们见面。根据最新消息来看,除iPhone 12外,苹果还将在此次新品发布会上为我们带来多款新产品,其中就包含了小尺寸的HomePod mini。HomePod mini据外媒报道称,HomePod mini是一个全新的品类,它将与几年前发布的HomePod并存。与此前发布的...
ST提供的固件库给我们很大的方面,但我十分不喜欢使用固件库因为它不简洁等一些原因,所以自己不断琢磨怎么用汇编和C语言编写自己想要的程序。以定时器TMI1上溢中断的产生为例总结一下这种方法。硬件条件是:外部晶振使用HIE=6MHz;目标是:定时器每10S进中断一次使LED闪烁。首先要知道这个中断(TIM1上溢事件)的中断向量地址在哪?汇编部分就是编写一个跳...

史海拾趣

问答坊 | AI 解惑

CCS3.3 81版的升级包

比较大,分成几个部分 …

查看全部问答∨

培训资料

本帖最后由 paulhyde 于 2014-9-15 09:16 编辑 忘了从哪里找的了  …

查看全部问答∨

变压器发明简史

变压器是根据电磁感应定律,将交流电变换为同频率、不同电压交流电的非旋转式电机。因此,变压器是随着电磁感应现象的发现而诞生,经过许多科学家不断完善、改进而形成的。? 1  变压器的雏形—感应线圈 ………

查看全部问答∨

基于虚拟仪器的电路故障诊断(大连理工硕士论文)

本帖最后由 paulhyde 于 2014-9-15 09:34 编辑 模拟电路故障诊断一直以来都是十分必要且有意义的,已成为热门的研究课题。传统的模拟电路故障诊断的方法也有很多种,但是它们一般都是用于诊断开路、短路这种硬故障的,难以发现在电路中的各个元器 ...…

查看全部问答∨

急问:VHDL在编译顶层电路图的错误问题?

错误如下:Tri-state node must be driven by a TRI buffer, but is driven by primitive ROM代码如下: LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; ENTITY MODE_CONTROL IS PORT(      FZ,FC:IN STD_LOGIC;   & ...…

查看全部问答∨

打印机USB口数据的发送和接受,有报酬!

需要做一个与斑马打印机USB口通信的接口,实现数据的接收和发送,功能比较单一,但需要提供全部的源代码。 报酬在2000-3000之间,最好是在北京地区的人员承接。 联系方式:159-1093-1116…

查看全部问答∨

关于LPC2378在keil中的中断问题

根据ADS的例程编写的中断,但是在keil中调试,发现怎么也进不去中断,还会提示说找不到IRQEnable()函数,求助高手给解答一下,是启动文件的问题吗?还是keil要使能IRQ中断不是采用这种方法?…

查看全部问答∨

太阳能LED节能灯原理及荧光粉技术改善方案

太阳能LED灯节能性的产生原理   太阳能光伏发电LED照明系统组成高效节能的太阳能光伏发电LED照明系统包括太阳能电池组、DC-DC变换器、最大功率跟踪MPPTfMaximumpowerpointtracking)控制、储存电能的蓄电池组和LED照明控制、LED光源等部分。   ...…

查看全部问答∨

如何保证串口唤醒STOP模式不丢失数据

请教大家,如何保证串口唤醒STOP模式时不丢失数据?发送数据端不是自己控制的,无法通过发无效的数据来唤醒STM32。…

查看全部问答∨

三星SCX-3206W打印机试用感受,与大家分享一下

今天终于体验到了传送中的无线打印是什么感觉了,哈哈。来与大家分享一下。本人由于工作原因,基本上每天都一直在和打印机打交道,所以一直对最新的打印机比较关注,上次去中关村的时候,听朋友说,最近要出一款新的一体机,集打印扫描于一体,而且 ...…

查看全部问答∨
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
随便看看

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved