【Tiny6410 And Linux】—(5.1)—RamDisk 驱动实现(内核缺省的处理函数 __make_request())——代码
来源:互联网 发布:于赓哲 知乎 编辑:程序博客网 时间:2024/05/23 01:19
电脑总算是修好了!
但是 JBL 音响又 TMD 出了问题!
真心不逗!
~~
1、驱动程序
①、blk.c
#include <linux/module.h>#include <linux/moduleparam.h>#include <linux/init.h>#include <linux/sched.h>#include <linux/kernel.h>/* printk() */#include <linux/slab.h>/* kmalloc() */#include <linux/fs.h>/* everything... */#include <linux/errno.h>/* error codes */#include <linux/timer.h>#include <linux/types.h>/* size_t */#include <linux/fcntl.h>/* O_ACCMODE */#include <linux/hdreg.h>/* HDIO_GETGEO */#include <linux/kdev_t.h>#include <linux/vmalloc.h>#include <linux/genhd.h>#include <linux/blkdev.h>#include <linux/buffer_head.h>/* invalidate_bdev */#include <linux/bio.h>#include <linux/major.h>#include <linux/version.h>#define SIMP_BLKDEV_DEVICEMAJORCOMPAQ_SMART2_MAJOR#define SIMP_BLKDEV_DISKNAME "_Justin"#define SIMP_BLKDEV_BYTES (16 * 1024 * 1024)static struct request_queue *simp_blkdev_queue;static struct gendisk *simp_blkdev_disk;unsigned char simp_blkdev_data[SIMP_BLKDEV_BYTES];/* * simp_blkdev_make_request */static int simp_blkdev_make_request(struct request_queue *q, struct bio *bio){struct request *req;/* 在 2.6.38 的内核没有这个函数,那又要怎么调用 * 还有就是 struct request 的变量差距好大! */while((req = elv_next_request(q)) != NULL){if((req->sector + req->current_nr_sectors) << 9> SIMP_BLKDEV_BYTES){printk(KERN_ERR SIMP_BLKDEV_DISKNAME": bad request: block = %llu, count = %u\n",(unsigned long long)req->sector,req->current_nr_sectors);end_request(req, 0);continue;}/* * rq_data_dir 是一个 macro! * #define rq_data_dir(rq) ((rq)->cmd_flags & 1) */switch(rq_data_dir(req)){case READ:memcpy(req->buffer,simp_blkdev_data + (req->sector << 9),req->current_nr_sectors << 9);end_request(req, 1);break;case WRITE:memcpy(simp_blkdev_data + (req->sector << 9),req->buffer,req->current_nr_sectors << 9);end_request(req, 1);break;default:/* No default because rq_data_dir(req) 1 bit */break;}}}/* * block_device_operations */struct block_device_operations simp_blkdev_fops = { .owner = THIS_MODULE,};/* * simp_blkdev_init */static int __init simp_blkdev_init(void){ int ret;/* 初始化请求队列 */ simp_blkdev_queue = blk_init_queue(simp_blkdev_make_request,NULL); if(!simp_blkdev_queue) { ret = -ENOMEM; goto err_init_queue; }/* 分配一个 gendisk 结构 */ simp_blkdev_disk = alloc_disk(1); if (!simp_blkdev_disk) { ret = -ENOMEM; goto err_alloc_disk; }/* 填充 gendisk 主要结构成员 */ strcpy(simp_blkdev_disk->disk_name, SIMP_BLKDEV_DISKNAME); simp_blkdev_disk->major = SIMP_BLKDEV_DEVICEMAJOR; simp_blkdev_disk->first_minor = 0; simp_blkdev_disk->fops = &simp_blkdev_fops; simp_blkdev_disk->queue = simp_blkdev_queue;/* 设置容量,其实说白了就是一个转换 */ set_capacity(simp_blkdev_disk, SIMP_BLKDEV_BYTES >> 9);/* 向内核注册块设备驱动 */ add_disk(simp_blkdev_disk); return 0;err_alloc_disk: blk_cleanup_queue(simp_blkdev_queue);err_init_queue: return ret;}/* * simp_blkdev_exit */static void __exit simp_blkdev_exit(void){ del_gendisk(simp_blkdev_disk);/* 删除 gendisk 结构 */ put_disk(simp_blkdev_disk);/* 释放一个该对象的引用 */ blk_cleanup_queue(simp_blkdev_queue);/* 清理请求队列 */}module_init(simp_blkdev_init);module_exit(simp_blkdev_exit);
②、Makefile
这里一定要注意了:
这是基于 X86 平台的驱动,所以跟基于 ARM 平台的驱动是有区别的,主要是编译器和平台不一样!
ifneq ($(KERNELRELEASE),)obj-m := blk.oelseKDIR := /lib/modules/2.6.27.62/buildall:make -C $(KDIR) M=$(PWD) modulesclean:rm -f *.ko *.o *.mod.o *.mod.c *.symvers *.orderendif
2、实验结果
通过以下步骤来实现!
1) insmod blk.ko
2) mkdir -p /mnt/blk
3) mkfs.ext3 /dev/_Justin
4) mount /dev/_Justin /mnt/blk
5) ls /mnt/dev/
6) umount /mnt/dev
7) rmmod blk
如图所示:
- 【Tiny6410 And Linux】—(5.1)—RamDisk 驱动实现(内核缺省的处理函数 __make_request())——代码
- 【Tiny6410 And Linux】—(5.1)—RamDisk 驱动实现(内核缺省的处理函数 __make_request())——原理
- 【Tiny6410 And Linux】—(5.2)—RamDisk 驱动实现(自己绑定 make_request_fn() )——代码
- 【Tiny6410 And Linux】—(5.2)—RamDisk 驱动实现(自己绑定 make_request_fn() )——原理
- 【Tiny6410 And Linux】—(2.4)—实现 input 模型按键驱动——代码
- 【Tiny6410 And Linux】—(2.1)—platform 总线、设备、驱动——代码
- 【Tiny6410 And Linux】—(6.1)—LCD 驱动测试程序——代码
- 【Tiny6410 And Linux】—(2.4)—实现 input 模型按键驱动——原理
- 【Tiny6410 And Linux】—(2.3)—使用工作队列处理按键中断——代码
- 【Tiny6410 And Linux】——基于 platform 总线的按键驱动——代码
- 【Tiny6410 And Linux】—(6.2)—LCD 驱动测试程序(BMP 显示位图)——代码
- 【Tiny6410 And Linux】—(2.1)—platform 总线、设备、驱动——原理
- 【Tiny6410 And Linux】—(6.1)—LCD 驱动测试程序——原理
- 【Tiny6410 And Linux】—(2.2)—Linux 中断处理——原理
- 【Tiny6410 And Linux】—(2.3)—使用工作队列处理按键中断——原理
- 【Tiny6410 And Linux】—(1.1)—kobject——代码
- 【Tiny6410 And Linux】—(1.2)—kset——代码
- 【Tiny6410 And Linux】—(1.3)—bus 设备模型——代码
- 在IPhone/IPad上建立反弹后门
- Makefile 隐式规则
- 代理服务器内部的实现方法(Windows 2000 Server)
- sourcesafe设置默认的用户名
- 详细解说 STL 排序(Sort)_C++ Programmer's Cookbook
- 【Tiny6410 And Linux】—(5.1)—RamDisk 驱动实现(内核缺省的处理函数 __make_request())——代码
- 内存分配方式
- 我也来学习一下sudo
- CC2530 AD转换那点事
- iphone开发与苹果榜单等相关功能
- c++一道学生类题目
- byte数组和结构体相互转换
- 用Photoshop制作2寸照片方法
- SHELL编程之变量