Linux-2.6.32 下 块设备驱动的编写 与 相关问题解决
来源:互联网 发布:莫知我哀 影九 小说 编辑:程序博客网 时间:2024/05/20 17:23
在LDD3书中,其中的有些块设备操作函数已经在Linux-2.6.32有了很大的变动,需要自己重新根据新定义的一些函数进行适当的移植,以解决编译时报出的各种错误,
主要时在do_request请求处理函数中修改,笔者修改的结果如下:
static void ubuntu_do_ramblock_requset(struct request_queue *q)
{ static int cnt = 0; struct request *req; int err =0; printk("do_ramblock_request %d\n", ++cnt); req = blk_fetch_request(q); while (req) { if ((req->cmd_type != REQ_TYPE_FS)) { printk (KERN_NOTICE "Skip non-CMD request\n"); __blk_end_request_all(req, -EIO); continue; } sbull_transfer( req,blk_rq_pos(req), blk_rq_cur_sectors(req), req->buffer, rq_data_dir(req)); done: if (!__blk_end_request_cur(req, err)) req = blk_fetch_request(q); }}
其中 sbull_transfer( req,blk_rq_pos(req), blk_rq_cur_sectors(req), req->buffer, rq_data_dir(req)); 如下:
static void sbull_transfer( struct request *req,unsigned long sector, unsigned long nsect, char *buffer, int write){ unsigned long offset = sector*KERNEL_SECTOR_SIZE; unsigned long nbytes = nsect*KERNEL_SECTOR_SIZE; if ((offset + nbytes) > get_capacity(req->rq_disk)*KERNEL_SECTOR_SIZE) { printk (KERN_NOTICE "Beyond-end write (%ld %ld)\n", offset, nbytes); return; } if (write) memcpy(ubuntu_ramblock_buf + offset, req->buffer, nbytes); elsememcpy(req->buffer,ubuntu_ramblock_buf + offset , nbytes);}
以上在LDD3书的基础上修改后,就可以通过编译了。
然而,将编写好的驱动放到开发板(mini2440)上运行的时候,格式化时没有出现问题,但是,挂载块设备的时候却报出了如下错误:
# mount /dev/ramblock /mnt yaffs: dev is 266338304 name is "ramblock"yaffs: passed flags ""yaffs: Attempting MTD mount on 254.0, "ramblock"yaffs: dev is 266338304 name is "ramblock"yaffs: passed flags ""yaffs: Attempting MTD mount on 254.0, "ramblock"FAT: utf8 is not a recommended IO charset for FAT filesystems, filesystem will be case sensitive!mount: mounting /dev/ramblock on /mnt failed: Invalid argument
解决办法:
在内核源码linux - 2.6.32 中配置内核
File Systems --->
DOS/FAT/NT Filesystems --->
(utf8) Default iocharset for FAT
改为
(cp936) Default iocharset for FAT
即可完美解决该问题
现附上源代码,供大家参考
/*²Î¿¼ xd.c ºÍ z2ram.c */#include <linux/module.h>#include <linux/errno.h>#include <linux/interrupt.h>#include <linux/mm.h>#include <linux/fs.h>#include <linux/kernel.h>#include <linux/timer.h>#include <linux/genhd.h>#include <linux/hdreg.h>#include <linux/ioport.h>#include <linux/init.h>#include <linux/wait.h>#include <linux/blkdev.h>#include <linux/blkpg.h>#include <linux/delay.h>#include <linux/io.h>#include <asm/system.h>//#include <asm/uaccess .h>#include <asm/dma.h>#include <linux/genhd.h>#include <linux/blkdev.h>#include <linux/buffer_head.h>/* invalidate_bdev */#include <linux/bio.h>static struct gendisk * ubuntu_disk;static struct request_queue * ubuntu_ramblock_queue;static DEFINE_SPINLOCK(ubuntu_ramblock_lock);static int major; //¿éÉ豸µÄÖ÷É豸ºÅstatic unsigned char *ubuntu_ramblock_buf; //ÉêÇëµÄÄÚ´æµØÖ·static const struct block_device_operations ubuntu_ramblock_fops = {.owner= THIS_MODULE,//.getgeo = xd_getgeo, //»ñµÃÇý¶¯Æ÷µÄÓ²¼þÎûÎû};#define UBUNTU_RAMBLOCL_SIZE (1024*1024) // 1 M#define KERNEL_SECTOR_SIZE 512static void sbull_transfer( struct request *req,unsigned long sector, unsigned long nsect, char *buffer, int write){ unsigned long offset = sector*KERNEL_SECTOR_SIZE; unsigned long nbytes = nsect*KERNEL_SECTOR_SIZE; if ((offset + nbytes) > get_capacity(req->rq_disk)*KERNEL_SECTOR_SIZE) { printk (KERN_NOTICE "Beyond-end write (%ld %ld)\n", offset, nbytes); return; } if (write) memcpy(ubuntu_ramblock_buf + offset, req->buffer, nbytes); elsememcpy(req->buffer,ubuntu_ramblock_buf + offset , nbytes);}static void ubuntu_do_ramblock_requset(struct request_queue *q){static int cnt = 0;struct request *req;int err =0;printk("do_ramblock_request %d\n", ++cnt);/*while ((req = elv_next_request(q)) != NULL) {end_request(req, 1);}*/req = blk_fetch_request(q); //´Ó¶ÓÁÐÖлñÈ¡Ò»¸öÇëÇówhile (req) { if ((req->cmd_type != REQ_TYPE_FS)) { printk (KERN_NOTICE "Skip non-CMD request\n"); __blk_end_request_all(req, -EIO); continue; }/*Êý¾Ý´«ÊäÈýÒªËØ*//*Ô´/Ä¿µÄ*//*unsigned long start = blk_rq_pos(req) * 512; //ÉÈÇøÊý*512 =×Ö½ÚÊý/*Ä¿µÄ/Ô´*///req->buffer/*³¤¶È*//*unsigned long len = blk_rq_cur_bytes(req) * 512;*/ sbull_transfer( req,blk_rq_pos(req), blk_rq_cur_sectors(req), req->buffer, rq_data_dir(req));/*´«Êä*//*if (rq_data_dir(req) == READ)memcpy(req->buffer,ubuntu_ramblock_buf + start , len);elsememcpy(ubuntu_ramblock_buf + start, req->buffer, len);*/done:if (!__blk_end_request_cur(req, err))req = blk_fetch_request(q);}}static int ubuntu_ram_block_init(void){/*print banner*/printk("/***** ubuntu_ram_block_init driver*****/\n");printk("/**** guoyu @ncu linux 2.6.32******* /\n");printk("/******* 2012/5/22 ***********/\n");/*1.·ÖÅägendisk ½á¹¹Ìå*/ubuntu_disk= alloc_disk(16); //´ËÉ豸ºÅ¸öÊý:·ÖÇøÊý +1 ,¼´±íʾ¸ÃÉ豸ÓÐ15¸ö·ÖÇø/*2. ÉèÖÃ*//*2.1 Ϊgendisk·ÖÅäºÍÉèÖÃÇëÇó¶ÓÁÐ:Ìṩ¶ÁдÄÜÁ¦*/ubuntu_ramblock_queue = blk_init_queue(ubuntu_do_ramblock_requset, &ubuntu_ramblock_lock); //ΪÇëÇó¶ÓÁÐÉèÖÃÇëÇó´¦Àíº¯Êý/*2.2 ÆäËûgendiskÉèÖÃ*/major = register_blkdev(0, "ubuntu_ramblock");// Óë×Ö·ûÉ豸µÄ×¢²áº¯Êý±È//¸Ãº¯ÊýÍË»¯ÁË£¬Ö»·µ»ØÒ»¸ö//¿ÉʹÓõÄÖ÷É豸ºÅ//ÔÚcat /proc/devicesÏ¿ÉÒÔ¿´µ½µÄÉ豸ÃûºÍÖ÷É豸ºÅubuntu_disk->major = major;ubuntu_disk->first_minor = 0; //µÚÒ»¸ö·ÖÇøsprintf(ubuntu_disk->disk_name, "ubuntu_ramblock");ubuntu_disk->fops = &ubuntu_ramblock_fops;ubuntu_disk->queue = ubuntu_ramblock_queue;set_capacity( ubuntu_disk, UBUNTU_RAMBLOCL_SIZE / 512); //ÒÔÉÈÇøµÄ´óС¼ÆË㣬ÿ512×Ö½ÚΪһ¸öÉÈÇø/*ΪÉ豸·ÖÅäÄÚ´æµØÖ·*/ubuntu_ramblock_buf = kzalloc(UBUNTU_RAMBLOCL_SIZE, GFP_KERNEL);/*×¢²á*/add_disk(ubuntu_disk); return 0;}static void ubuntu_ram_block_exit(void){unregister_blkdev(major, "ubuntu_ramblock");del_gendisk(ubuntu_disk);put_disk(ubuntu_disk);blk_cleanup_queue(ubuntu_ramblock_queue);}#define DRIVER_VERSION "v1.0"#define DRIVER_AUTHOR "Guoyu <cgsz1992@163.com>"#define DRIVER_DESC "USB HID Boot Protocol mouse driver"module_init(ubuntu_ram_block_init);module_exit(ubuntu_ram_block_exit);MODULE_AUTHOR(DRIVER_AUTHOR);MODULE_DESCRIPTION(DRIVER_DESC);MODULE_LICENSE("GPL");
- Linux-2.6.32 下 块设备驱动的编写 与 相关问题解决
- 块设备驱动编写
- Linux块设备驱动(1)---块驱动中相关的结构体及其操作
- linux下的块设备驱动(一)
- linux下的块设备驱动(二)
- Linux驱动编写(块设备驱动代码)
- linux驱动编写之十六(块驱动设备初识)
- Linux块设备驱动(四)————块设备的数据结构与相关操作及I/O调度器
- Linux块设备驱动的模块加载与卸载
- 块设备驱动编写总结
- 块设备驱动编写总结
- 块设备驱动编写总结
- 块设备驱动编写总结
- Linux下SPI从设备驱动的编写
- Linux下SPI从设备驱动的编写
- Linux下SPI从设备驱动的编写
- Linux块设备驱动
- Linux块设备驱动
- android中 phone类的分析
- 需求规格说明书
- C#抽象类与接口的异同
- 八卦
- play
- Linux-2.6.32 下 块设备驱动的编写 与 相关问题解决
- 一个简单的UDP广播例子(含C/S)
- TCP
- [mysql] mysql 数据库timestamp直接转换为unix秒数的函数UNIX_TIMESTAMP
- java画图板
- 常见异常处理
- oracle :%TYPE 和 %ROWTYPE
- js 常用100句 精典操作
- linux学习笔记(1)-安装小企鹅输入法