Linux-2.6.32|Linux-2.6.32 下 块设备驱动的编写 与 相关问题解决


在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( structrequest *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); else memcpy(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|Linux-2.6.32 下 块设备驱动的编写 与 相关问题解决】在内核源码linux - 2.6.32 中配置内核


File Systems --->
DOS/FAT/NT Filesystems--->
(utf8) Default iocharset for FAT
改为
(cp936) Default iocharset for FAT
即可完美解决该问题

现附上源代码,供大家参考
/*2??? xd.c oí z2ram.c */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include //#include #include #include #include #include /* invalidate_bdev */ #include static struct gendisk * ubuntu_disk; static struct request_queue * ubuntu_ramblock_queue; static DEFINE_SPINLOCK(ubuntu_ramblock_lock); static int major; //?ééè±?μ??÷éè±?o?static unsigned char *ubuntu_ramblock_buf; //éê??μ??ú′?μ??·static const struct block_device_operations ubuntu_ramblock_fops = { .owner = THIS_MODULE, //.getgeo = xd_getgeo,//??μ??y?ˉ?÷μ?ó2?t???? }; #define UBUNTU_RAMBLOCL_SIZE(1024*1024)//1 M#define KERNEL_SECTOR_SIZE 512 static void sbull_transfer( structrequest *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); else memcpy(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); //′ó?óáD?D??è?ò??????ó while (req) {if ((req->cmd_type != REQ_TYPE_FS)) { printk (KERN_NOTICE "Skip non-CMD request\n"); __blk_end_request_all(req, -EIO); continue; }/*êy?Y′?ê?èyòa??*/ /*?′/??μ?*/ /*unsigned long start = blk_rq_pos(req) * 512; //éè??êy*512 =×??úêy/*??μ?/?′*/ //req->buffer/*3¤?è*/ /* 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); else memcpy(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 @nculinux 2.6.32******* /\n"); printk("/******* 2012/5/22***********/\n"); /*1.·???gendisk ?á11ì?*/ ubuntu_disk= alloc_disk(16); //′?éè±?o???êy:·???êy +1 ,?′±íê???éè±?óD15??·??? /*2. éè??*/ /*2.1 ?agendisk·???oíéè?????ó?óáD:ìá1??áD′?üá|*/ ubuntu_ramblock_queue = blk_init_queue(ubuntu_do_ramblock_requset, &ubuntu_ramblock_lock); //?a???ó?óáDéè?????ó′|àíoˉêy /*2.2 ????gendiskéè??*/ major = register_blkdev(0, "ubuntu_ramblock"); // ó?×?·?éè±?μ?×¢2áoˉêy±è //??oˉêyí??ˉá?£???·μ??ò??? //?éê1ó?μ??÷éè±?o? //?úcat /proc/devices???éò??′μ?μ?éè±???oí?÷éè±?o? 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); //ò?éè??μ?′óD?????£???512×??ú?aò???éè?? /*?aéè±?·????ú′?μ??·*/ ubuntu_ramblock_buf = kzalloc(UBUNTU_RAMBLOCL_SIZE, GFP_KERNEL); /*×¢2á*/ 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 " #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");



    推荐阅读