主题 : 简单块设备驱动问题,求教高人 复制链接 | 浏览器收藏 | 打印
zls
级别: 新手上路
UID: 55345
精华: 0
发帖: 1
金钱: 5 两
威望: 1 点
综合积分: 2 分
注册时间: 2011-09-16
最后登录: 2017-09-13
楼主  发表于: 2011-09-16 10:30

 简单块设备驱动问题,求教高人

用的是chinauinx赵磊《写一个块设备驱动》第1章的代码在mini2440上实验,目的从内存取一段,将它格式为ext3
mkfs.ext3 /dev/my_blk出现下面的错误:
/ # insmod my_blk_drv.ko
/ # mkfs.ext3 /dev/my_blk
mke2fs 1.39 (29-May-2006)
end_request: I/O error, dev my_blk, sector 0
Warning: could not erase sectoend_request: I/O error, dev my_blk, sector 0
Buffer I/O error on device my_blk, logical block 0
end_request: I/O error, dev my_blk, sector 0
end_request: I/O error, dev my_blk, sector 8
end_request: I/O error, dev my_blk, sector 16256
Buffer I/O error on device my_blk, logical block 2032
lost page write due to I/O error on my_blk
Buffer I/O error on device my_blk, logical block 2033
lost page write due to I/O error on my_blk
Buffer I/O error on device my_blk, logical block 2034
lost page write due to I/O error on my_blk
Buffer I/ror on device my_blk, logical block 2035
lost page write due to I/O error on my_blk
Buffer I/O error on device my_blk, logical block 2036
lost page write due to I/O error on my_blk
Buffer I/O error on device my_blk, logical block 2037
lost page write due to I/O error on my_blk
Buffer I/O error on device my_blk, logical block 2038
lost page write due to I/O error on my_blk
Buffer I/O error on device my_blk, logical block 2039
lost page write due to I/O error on my_blk
Buffer I/O error on device my_blk, logical block 2040
lost page write due to I/O error on my_blk
r 2: Attempt to write block from filesystem resulted in short write
Filesystem label=
OS type: Linux
Block size=1024 (log=0)
Fragment size=1024 (log=0)
1024 inodes, 8192 blocks
409 blocks (4.99%) reserved for the super user
First data block=1
1 block group
8192 blocks per group, 8192 fragments per group
1024 inodes per group

Warning: could not read block 0: Attempt to read block from filesystem resulted in short read
Warning: could not erase sector 0: Attempt to write block from filesystem resulted in short write
Writing inode tables: 0/1
Could not write 8 blocks in inode table starting at 5: Attempt to write block from filesystem resulted in short write
/ # mount /dev/my_blk /mnt/temp
end_request: I/O error, dev my_blk, sector 2
EXT3-fs: unable to read superblock
end_request: I/O error, dev my_blk, sector 0
__ratelimit: 7 callbacks suppressed
Buffer I/O error on device my_blk, logical block 0
end_request: I/O error, dev my_blk, sector 0
Buffer I/O error on device my_blk, logical block 0
Buffer I/O error on device my_blk, logical block 1
end_request: I/O error, dev my_blk, sector 8
Buffer I/O error on device my_blk, logical block 1
Buffer I/O error on device my_blk, logical block 2
end_request: I/O error, dev my_blk, sector 16
Buffer I/O error on device my_blk, logical block 2
Buffer I/O error on device my_blk, logical block 3
end_request: I/O error, dev my_blk, sector 24
Buffer I/O error on device my_blk, logical block 3
end_request: I/O error, dev my_blk, sector 0
FAT: unable to read boot sector
end_request: I/O error, dev my_blk, sector 0
FAT: unable to read boot sector
end_request: I/O error, dev my_blk, sector 0
yaffs: dev is 75497472 name is "my_blk"
yaffs: passed flags ""
yaffs: Attempting MTD mount on 72.0, "my_blk"
yaffs: dev is 75497472 name is "my_blk"
yaffs: passed flags ""
yaffs: Attempting MTD mount on 72.0, "my_blk"
mount: mounting /dev/my_blk on /mnt/temp failed: Invalid argument


附块驱动代码:#include <linux/vmalloc.h>
#include <linux/genhd.h>
#include <linux/blkdev.h>
#include <linux/buffer_head.h> /*invalidate_bdev */
#include <linux/bio.h>

#define SIMP_BLKDEV_BYTES (16*256*1024)

static struct gendisk *my_blk_disk;
static struct request_queue *my_blk_queue;
unsigned charmy_blk_data[SIMP_BLKDEV_BYTES];
//my_blk_do_request函数负责处理块设备请求,但它不能由驱动自己调用,只有当内核认为是时候让驱动处理对设备的读写操作时才调用它
static void my_blk_do_request(structrequest_queue *q) {
struct request *req;
while ((req = blk_fetch_request(q)) != NULL) { //elv_next_request (已被blk_fetch_request取代)来获得队列中第一个未完成的请求
//现在不能直接获取request结构的sector和current_nr_sector;而是通过函数blk_rq_pos和blk_rq_cur_sectors获得
if ((blk_rq_pos(req)+ blk_rq_cur_sectors(req)) << 9 >SIMP_BLKDEV_BYTES) {
printk(KERN_ERR "my_blk: bad request: block=%llu, count=%u\n",
(unsigned longlong)blk_rq_pos(req), blk_rq_cur_sectors(req));
blk_end_request_all(req, 0); //将请求从请求队列中剥离
continue;
}

switch (rq_data_dir(req)) { //这个宏从请求中抽取传送的方向; 一个 0 返回值表示从设备中读, 非 0 返回值表示写入设备.
case READ:
memcpy(req->buffer, my_blk_data + (blk_rq_pos(req)<< 9),blk_rq_cur_sectors(req) << 9);
blk_end_request_all(req, 1); /*1表示通知成功完成这个请求*/
break;
  
case WRITE:
memcpy(my_blk_data + (blk_rq_pos(req)<< 9), req->buffer,blk_rq_cur_sectors(req) << 9);
blk_end_request_all(req, 1);
break;
  /* No default because rq_data_dir(req) is 1bit */
default:
break;
}
}
}

static struct block_device_operationsmy_blk_fops = {
.owner = THIS_MODULE,
};

static int __init my_blk_init(void)
{
int ret;

my_blk_queue = blk_init_queue(my_blk_do_request, NULL);
if (!my_blk_queue) {
ret = -ENOMEM;
goto err_init_queue;
}

  my_blk_disk = alloc_disk(1); //在添加设备之前我们需要申请这个设备的资源,这用到了alloc_disk()函数
if (!my_blk_disk) {
ret = -ENOMEM;
goto err_alloc_disk;
}
  /*请求队列初始化*/
  strcpy(my_blk_disk->disk_name,"my_blk");
my_blk_disk->major = COMPAQ_SMART2_MAJOR; //抢COMPAQ_SMART2_MAJOR的设备号
my_blk_disk->first_minor = 0;
my_blk_disk->fops = &my_blk_fops;
my_blk_disk->queue = my_blk_queue;
set_capacity(my_blk_disk, SIMP_BLKDEV_BYTES>>9); //在gendisk结构中保存设备容量(用512字节扇区为单位)
  
add_disk (my_blk_disk); //用add_disk()函数向系统中添加这个块设备
  return 0;
  
  err_alloc_disk:
  blk_cleanup_queue(my_blk_queue);
err_init_queue:
return ret;
}

static void __exit my_blk_exit(void)
{
del_gendisk (my_blk_disk);
  put_disk(my_blk_disk); //在卸载模块的代码中加一个行清理函数
  blk_cleanup_queue(my_blk_queue);
}

module_init(my_blk_init);
module_exit(my_blk_exit);