历史上的今天
今天是: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块设备驱动程序的编写驱动之用内存模拟磁盘
史海拾趣
|
我想问下用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 ...… 查看全部问答> |
|
1 序言 GPRS(General Packet Radio Service,通用分组无线业务)的出现充分利用了现有的GSM网络,不仅适用于间断的、突发性的或频繁的、少量的数据传输,也适用于偶尔的大数据量传输。它使移动通信与数据网络合二为一,它利用“分组交换”(Packet S ...… 查看全部问答> |
|
原来用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 ...… 查看全部问答> |
|
今天弄了一天的GPIO复用功能。。。书上说要配置GPIOPCTL寄存器。我翻了好久发现只要库函数中的void GPIOPinConfigure(uint32_t ui32PinConfig) 这个函数涉及到了这个寄存器。。。。。。可是,可是,可是!!!!!!这个函数的参数该写什么啊?? ...… 查看全部问答> |




