/* 参考: * drivers\block\xd.c * drivers\block\z2ram.c */#include#include#include#include#include#include#include#include#include#include#include#include#include#include#include#include#include#include#includestatic struct gendisk *ramblock_disk;static request_queue_t *ramblock_queue;static int major;static DEFINE_SPINLOCK(ramblock_lock);#define RAMBLOCK_SIZE (1024*1024)static unsigned char *ramblock_buf;static int ramblock_getgeo(struct block_device *bdev, struct hd_geometry *geo){/* 容量=heads*cylinders*sectors*512 */geo->heads = 2;geo->cylinders = 32;geo->sectors = RAMBLOCK_SIZE/2/32/512;return 0;}static struct block_device_operations ramblock_fops = {.owner= THIS_MODULE,.getgeo= ramblock_getgeo,};static void do_ramblock_request(request_queue_t * 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) {/* 数据传输三要素: 源,目的,长度 *//* 源/目的: */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);}}static int ramblock_init(void){/* 1. 分配一个gendisk结构体 */ramblock_disk = alloc_disk(16); /* 次设备号个数: 分区个数+1 *//* 2. 设置 *//* 2.1 分配/设置队列: 提供读写能力 */ramblock_queue = blk_init_queue(do_ramblock_request, &ramblock_lock);ramblock_disk->queue = ramblock_queue;/* 2.2 设置其他属性: 比如容量 */major = register_blkdev(0, "ramblock"); /* cat /proc/devices */ramblock_disk->major = major;ramblock_disk->first_minor = 0;sprintf(ramblock_disk->disk_name, "ramblock");ramblock_disk->fops = &ramblock_fops;set_capacity(ramblock_disk, RAMBLOCK_SIZE / 512);/* 3. 硬件相关操作 */ramblock_buf = kzalloc(RAMBLOCK_SIZE, GFP_KERNEL);/* 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);kfree(ramblock_buf);}module_init(ramblock_init);module_exit(ramblock_exit);MODULE_LICENSE("GPL");框架:app: open,read,write "1.txt"--------------------------------------------- 文件的读写文件系统: vfat, ext2, ext3, yaffs2, jffs2 (把文件的读写转换为扇区的读写)-----------------ll_rw_block----------------- 扇区的读写 1. 把"读写"放入队列 2. 调用队列的处理函数(优化/调顺序/合并) 块设备驱动程序 ---------------------------------------------硬件: 硬盘,flash分析ll_rw_block for (i = 0; i struct buffer_head *bh = bhs[i]; submit_bh(rw, bh); struct bio *bio; // 使用bh来构造bio (block input/output) submit_bio(rw, bio); // 通用的构造请求: 使用bio来构造请求(request) generic_make_request(bio); __generic_make_request(bio); request_queue_t *q = bdev_get_queue(bio->bi_bdev); // 找到队列 // 调用队列的"构造请求函数" ret = q->make_request_fn(q, bio); // 默认的函数是__make_request __make_request // 先尝试合并 elv_merge(q, &req, bio); // 如果合并不成,使用bio构造请求 init_request_from_bio(req, bio); // 把请求放入队列 add_request(q, req); // 执行队列 __generic_unplug_device(q); // 调用队列的"处理函数" q->request_fn(q); 怎么写块设备驱动程序呢?1. 分配gendisk: alloc_disk2. 设置2.1 分配/设置队列: request_queue_t // 它提供读写能力 blk_init_queue2.2 设置gendisk其他信息 // 它提供属性: 比如容量3. 注册: add_disk参考:drivers\block\xd.cdrivers\block\z2ram.c测试3th,4th:在开发板上:1. insmod ramblock.ko2. 格式化: mkdosfs /dev/ramblock3. 挂接: mount /dev/ramblock /tmp/4. 读写文件: cd /tmp, 在里面vi文件5. cd /; umount /tmp/6. cat /dev/ramblock > /mnt/ramblock.bin7. 在PC上查看ramblock.bin sudo mount -o loop ramblock.bin /mnt测试5th:1. insmod ramblock.ko2. ls /dev/ramblock*3. fdisk /dev/ramblock 01-20 20:21