博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【驱动】第7课、块设备驱动之学习笔记
阅读量:5132 次
发布时间:2019-06-13

本文共 5547 字,大约阅读时间需要 18 分钟。

主   机:VMWare--Ubuntu-16.04.2-x64-100ask

开发板:Mini2440--256M NandFlash,   2M NorFlash,   64M SDRAM,   LCD-TD35;

    bootlorder:u-boot1.16,        Kernel:2.6.22.6;
编译器:arm-linux-gcc-3.4.5


目录

  

  

  


【课堂笔记】

框架:
app: open,read,write "1.txt"
--------------------------------------------- 文件的读写
文件系统: vfat, ext2, ext3, yaffs2, jffs2 (把文件的读写转换为扇区的读写)
-----------------ll_rw_block----------------- 扇区的读写
1. 把"读写"放入队列
2. 调用队列的处理函数(优化/调顺序/合并)
块设备驱动程序
---------------------------------------------
硬件: 硬盘,flash

【编程】
参考:
drivers\block\xd.c
drivers\block\z2ram.c
目的:分配一块内存,用这块内存作为块设备模拟硬盘;
一、驱动框架
1、分配一个gendisk结构体;
2、设置
2.1分配/设置一个队列:request_queue_t, 提供(块设备的)读写能力;
blk_init_queue();
2.2设置gendisk其他信息/属性(6项),比如:主设备号,次设备首号,名字,操作函数,容量,队列;
3、硬件操作:为块设备读写操作分配内存;
4、注册gendisk结构体;
add_disk(ramblock_disk);
5、操作函数所在fops结构体;

函数分配与回滚:

ramblock_disk = alloc_disk(16); 对应 put_disk(ramblock_disk); del_gendisk(ramblock_disk);
q = blk_init_queue(); 对应 blk_cleanup_queue(q);
register_blkdev(0, "ramblock"); 对应unregister_blkdev(major, "ramblock");

二、硬件相关的操作

1、硬件操作:为块设备读写操作分配内存;
2、在读写操作队列处理函数:do_xx_request()中,对读/写队列进行处理,然后结束队列;

三、定义操作函数中,块设备的几何信息;

  fops = {...     .getgeo = ramblock_getgeo,}

【测试】

1、块设备驱动,实验找不到mkdosfs命令?
答:开发板的文件系统缺少mkdosfs可执行文件!
2、硬件操作分配的内存 ramblock_buf = kzalloc(RAMBLOCK_SIZE, GFP_KERNEL),是为块设备读写操作分配的数据缓冲区,
还是为块设备本身分配的内存?
答:是为块设备本身分配的内存,为队列里读/写操作分配的数据缓冲区是struct request *req->buffer;该数据缓冲区貌
似是内核自己分配的,没有让驱动开发者手动分配!
3、网络文件系统上的ramblock9.ko没有删除直接用新文件上传覆盖时,测试(不正常):
Device Boot Start End Blocks Id System
/dev/ramblock1 1 5 288 83 Linux
Partition 1 has different physical/logical endings:
phys=(260, 1, 0) logical=(4, 1, 64)
Partition 1 does not end on cylinder boundary

Command (m for help): n

用rm命令手动删除该ramblock9.ko文件,然后再从服务器cp该文件到单板网络文件系统测试(正常):

Device Boot Start End Blocks Id System
/dev/ramblock1 1 5 144 83 Linux

Command (m for help):

总结:已经是第二次遇到这个问题了,文件并没有随着最新时间的相同文件的上传而被覆盖,相反旧文件覆盖了新文件或者没更新旧文件!
这是为什么呢?

 

 

 

【源码】

ramblock9.c

1 /*  2  * 2019-01-10  3  * 目的: 分配一块内存,用这块内存做块设备模拟硬盘;  4  */  5 #include 
6 #include
7 #include
8 #include
9 #include
10 #include
11 #include
12 #include
13 #include
14 #include
15 #include
16 #include
17 #include
18 #include
19 #include
20 #include
21 22 #include
23 #include
24 #include
25 26 #define RAMBLOCK_SIZE (1024*1024) 27 MODULE_LICENSE("GPL"); 28 29 static struct gendisk *ramblock_disk; 30 static request_queue_t *ramblock_queue; 31 static DEFINE_SPINLOCK(ramblock_lock); 32 static int major; 33 static unsigned char *ramblock_buf; 34 35 /* 读写操作请求队列处理函数 */ 36 static void do_ramblock_request(request_queue_t *q) 37 { 38 struct request *req; 39 while((req = elv_next_request(q)) != NULL) 40 { 41 /* 数据传输三要素: 源,长度,目的地 */ 42 unsigned long offset = req->sector*512; /* 写入为目的地,读出为源 */ 43 unsigned long len = req->current_nr_sectors*512; 44 if(rq_data_dir(req) == READ) 45 { 46 memcpy(req->buffer, ramblock_buf + offset, len); 47 } 48 else 49 { 50 memcpy(ramblock_buf + offset, req->buffer, len); 51 } 52 53 end_request(req, 1); 54 } 55 } 56 57 static int ramblock_getgeo(struct block_device *bdev, struct hd_geometry *geo) 58 { 59 geo->heads = 2; 60 geo->cylinders = 32; 61 geo->sectors = RAMBLOCK_SIZE/2/32/512; 62 return 0; 63 } 64 65 static struct block_device_operations ramblock_fops = { 66 .owner = THIS_MODULE, 67 .getgeo = ramblock_getgeo, 68 }; 69 70 static int ramblock_init(void) 71 { 72 int err; 73 /* 1.分配一个gendisk结构体 */ 74 ramblock_disk = alloc_disk(16); 75 if(!ramblock_disk) 76 { 77 printk(KERN_ERR "Unable to allocate ramblock_disk gendisk!\n"); 78 err = -ENOMEM; 79 goto err_fail1; 80 } 81 /* 2.配置该结构体 */ 82 /* 2.1分配/设置一个队列: 提供读写能力 */ 83 ramblock_queue = blk_init_queue(do_ramblock_request, &ramblock_lock); 84 if(!ramblock_queue) 85 { 86 printk(KERN_ERR "Unable to prepare ramblock_queue request queue!\n"); 87 err = -ENOMEM; 88 goto err_fail2; 89 } 90 /* 2.2其他属性: 主设备号,次设备首号,操作函数,队列,名字,容量等 */ 91 major = register_blkdev(0, "ramblock"); 92 if(!major) 93 { 94 printk(KERN_ERR "Unable to register ramblock block device!\n"); 95 err = -EBUSY; 96 goto err_fail3; 97 } 98 ramblock_disk->major = major; 99 ramblock_disk->first_minor = 0;100 sprintf(ramblock_disk->disk_name, "ramblock");101 ramblock_disk->fops = &ramblock_fops;102 ramblock_disk->queue = ramblock_queue;103 set_capacity(ramblock_disk, RAMBLOCK_SIZE/512); //容量: 扇区数目;104 /* 3.硬件相关的配置 */105 ramblock_buf = kzalloc(RAMBLOCK_SIZE, GFP_KERNEL);106 if(!ramblock_buf)107 {108 printk(KERN_ERR "Unable to allocate ramblock_buf buffer!\n");109 err = -ENOMEM;110 goto err_fail4;111 }112 /* 4.注册该结构体 */113 add_disk(ramblock_disk);114 return 0;115 err_fail4:116 kfree(ramblock_buf);117 err_fail3:118 unregister_blkdev(major, "ramblock");119 err_fail2:120 blk_cleanup_queue(ramblock_queue);121 err_fail1:122 put_disk(ramblock_disk);123 del_gendisk(ramblock_disk);124 return err;125 }126 127 static void ramblock_exit(void)128 {129 unregister_blkdev(major, "ramblock");130 blk_cleanup_queue(ramblock_queue);131 put_disk(ramblock_disk);132 del_gendisk(ramblock_disk);133 kfree(ramblock_buf);134 }135 136 module_init(ramblock_init);137 module_exit(ramblock_exit);

 

Makefile:

1 ifneq ($(KERNELRELEASE),) 2     obj-m := ramblock9.o 3 else 4     KERN_DIR ?= /home/book/workbook/mini2440/systems/linux-2.6.22.6 5  6     PWD = $(shell pwd) 7 all: 8     $(MAKE) -C $(KERN_DIR) M=$(PWD) modules 9 clean:10     $(MAKE) -C $(KERN_DIR) M=$(PWD) modules clean11     rm -rf modules.order12 13 endif

 

转载于:https://www.cnblogs.com/xiaohujian/p/10252345.html

你可能感兴趣的文章
浅谈HTTP中Get与Post的区别
查看>>
struts1与struts2的区别
查看>>
【HANA系列】SAP HANA XS使用Odata标志全解析
查看>>
使用Nginx的proxy_cache缓存功能取代Squid(转)
查看>>
浅谈深拷贝与浅拷贝
查看>>
Difference Between Vector and Deque in C++
查看>>
Leetcode: Pascal's Triangle II
查看>>
[转]安装Sql Server 2008 Profiler
查看>>
度度熊想去商场买一顶帽子,商场里有N顶帽子,有些帽子的价格可能相同。度度熊想买一顶价格第三便宜的帽子,问第三便宜的帽子价格是多少?...
查看>>
使用Sigar做后台服务器管理时,遇到的linux上的问题
查看>>
[转载]apache rewrite规则
查看>>
ubuntu创建wifi热点(android可识别)亲测可用
查看>>
CreateaJointCurve.txt
查看>>
Android进阶:ListView性能优化异步加载图片 使滑动效果流畅
查看>>
iOS :Object-C 语言merge两个字典对象
查看>>
artDialog ( v 6.0.2 ) content 参数引入页面 html 内容
查看>>
ckeditor:基本使用方法
查看>>
20189217 2018-2019-2 《密码与安全新技术专题》第五周作业
查看>>
Spring Cloud 之 Eureka.
查看>>
发些好文链接
查看>>