历史上的今天
返回首页

历史上的今天

今天是:2024年10月11日(星期五)

正在发生

2018年10月11日 | OK6410块设备驱动之用内存模拟磁盘

2018-10-11 来源:eefocus

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


推荐阅读

史海拾趣

Capital Advanced Technologies公司的发展小趣事

品质管理是CAT发展的重要保障。公司建立了严格的质量管理体系,从原材料采购到产品制造、检验、包装等各个环节都进行严格的品质控制。CAT还注重与客户的沟通与协作,及时了解客户需求,为客户提供个性化的解决方案和优质的售后服务。这些举措使得CAT赢得了客户的广泛信赖和长期合作。

EUPEC [eupec GmbH]公司的发展小趣事

EUPEC,全称欧洲电力半导体与电子公司(European Semiconductors and Electronics Company),成立于1990年。它是由西门子和德国另一家大型电器公司AEG生产电力半导体器件的两个部门合并而成。这次合并标志着EUPEC正式进入电力半导体领域,凭借其强大的技术背景和丰富的行业经验,EUPEC迅速在市场中占据了一席之地。

Global Communications公司的发展小趣事
利用微处理器或数字信号处理器(DSP)等数字设备,将温度传感器检测到的温度信号进行数字化处理后,通过算法计算出相应的补偿量,并控制晶体振荡器的输出频率或相位。这种方法具有高度的灵活性和准确性,但成本相对较高。
西安航天民芯公司的发展小趣事

在宇航领域,动力电池管理芯片的性能要求极高。西安航天民芯凭借其在集成电路设计领域的深厚积累,成功研发出全国第一颗宇航级动力电池管理芯片。这一突破不仅打破了国外垄断的局面,也为中国宇航事业的发展做出了重要贡献。

CML公司的发展小趣事

CML公司成立于1968年,那是一个半导体技术刚刚起步的年代。公司创始人们洞察到单芯片解决方案的巨大潜力,决心打破当时标准组件组装的常规,着手创建创新的单芯片产品。初创时期,CML面临着资金短缺、技术瓶颈以及市场竞争等多重挑战。然而,正是在这样的环境下,CML凭借对技术的执着和对市场的敏锐洞察,成功推出了首款产品——频率敏感开关。这款产品凭借其卓越的性能和稳定性,迅速在消费产品市场赢得了口碑,为CML的发展奠定了坚实的基础。

ABCO公司的发展小趣事

ABCO公司深知产品质量是企业生存的根本。因此,公司建立了一套严格的质量管理体系,从原材料采购到产品生产、检测、出厂等各个环节都进行严格把控。同时,公司还注重持续改进,不断优化生产流程,提高生产效率,确保产品质量始终保持在行业前列。

问答坊 | AI 解惑

关于51单片机用T2作波特率发生器

我想问下用T2作单片机串口波特率发生器时,TH2,TL2,T2CON该如何赋值?这样对吗?void main(){ TMOD=0x02;  SCON=0x50;  TCON=0x01;  IE=0x93;  T2CON=0x30;  RCAP2H=RCAP2L=-11059200/2/32/9600;  TH0=TL0=-250;&nb ...…

查看全部问答>

基于STC单片机与GPRS的图文LED屏

1 序言 GPRS(General Packet Radio Service,通用分组无线业务)的出现充分利用了现有的GSM网络,不仅适用于间断的、突发性的或频繁的、少量的数据传输,也适用于偶尔的大数据量传输。它使移动通信与数据网络合二为一,它利用“分组交换”(Packet S ...…

查看全部问答>

有毒气体报警器毕业设计

有没有全套的啊,原理图也行,求各位高手帮忙,小弟快急死了…

查看全部问答>

IGBT保护原理分析

IGBT保护原理分析,供大家分享!…

查看全部问答>

WINCE6 使用 TFAT的问题?

原来用FAT系统在掉电或RESET情况下,存在数据丢失,文件系统被破坏的问题。 现在准备升级使用TFAT,另外CE6中增加了EXFAT File System,准备使用TFAT+EXFAT的方式。 有没有用过的兄弟知道这样使用需要如何设置,是不是在Storage Manager下选择了 ...…

查看全部问答>

PlaySound()与WaveOutWrite()有什么区别?

PlaySound()与WaveOutWrite()有什么区别? PlaySound()是否是WaveOutWrite()的上层函数?也就是事实上PlaySound也是调用了WaveOutWrite()? 那么,到底是用哪个层次的函数来播放声音好呢? 另外,PlaySound()的第一个参数可以使文件的路径名也可 ...…

查看全部问答>

█ █ █富人和穷人的十二个致命差异█ █ █

1.自我认知     穷人:很少想到如何去赚钱和如何才能赚到钱,认为自己一辈子就该这样,不相信会有什么改变。富人:骨子里就深信自己生下来不是要做穷人,而是要做富人,他有强烈的赚钱意识,这已是他血液里的东西,他会想尽一切办 ...…

查看全部问答>

将2700系列的SCPI应用转换为3700系列的系统开关/万用表系统脚本应用

多年来,仪器制造商已经在用“可编程仪器标准指令”或SCPI控制测量仪器系统的可编程测试和测量设备。SCPI为控制测试和测量仪器提供了一种统一、一致的语言。不论制造商还是仪器类型,都能使用相同的指令和响应控制SCPI设备中相应的仪器功能。 &n ...…

查看全部问答>

TIVA WARE库 bug

今天弄了一天的GPIO复用功能。。。书上说要配置GPIOPCTL寄存器。我翻了好久发现只要库函数中的void GPIOPinConfigure(uint32_t ui32PinConfig) 这个函数涉及到了这个寄存器。。。。。。可是,可是,可是!!!!!!这个函数的参数该写什么啊?? ...…

查看全部问答>