【Android驱动】块设备---笔记

缓冲,I/O调度,请求队列等都是与块设备驱动相关的概念。

1.块设备I/O特点。字符设备和块设备I/O上的诧异。
2.Linux块设备驱动结构。数据结构,函数,关系。
3.块设备驱动模块的加载与卸载,打开/释放/ioctl
4.块设备I/O操作所依赖的请求,bio处理方法。
5.Linux下的块设备例子。

-------------------------
块设备与字符设备区别:

1.字符设备以字符串为单位读写,块设备以固定块大小进行操作。
2.块设备对于I/O请求有缓冲区,读写顺序可以调整。读写连续的扇区,存储速度更快。
3.字符设备顺序读写,块设备随机访问。

---------------
块设备驱动结构:
file_operation ---> block_device_operations块设备操作的集合。

//打开和释放
int(*open)(struct block_device*, fmode_t);
void(*release)(struct gendisk*, fmode_t);

// I/O控制
int(*ioctl)(struct block_device*, fmode_t, unsigned, unsigned long);
int(*compat_ioctl)(struct block_device*, fmode_t, unsigned, unsigned, unsigned long);

//介质改变
int (*media_changed)(struct gendisk *gd);
unsigned int (*check_events)(struct gendisk *disk, unsigned int clearing);

//使介质有效
int (*revalidate_disk)(struct gendisk *gd);

//5.获得驱动器信息,hd_geometry结构体包含磁头,扇区,柱面等信息
int (*getgeo)(struct block_device *, struct hd_geometry *);

-------------------
块设备注册和初始化阶段
    register_blkdev()    注册到内核,申请设备号, 返回主设备号。
    unregister_blkdev()
    
int register_blkdev(unsigned int major, const char* name);
int unregister_blkdev(unsigned int major, const char *name);

--------------
static int xxx_init(void)
{
    if(register_blkdev(XXX_MAJOR, "xxx"))
    {
        err = -EIO;
        goto out;
    }
    
    xxx_queue = blk_init_queue(xxx_request, xxx_lock);
    if(!xxx_queue)
        goto out_queue;
        
    blk_queue_max_hw_sectors(xxx_queue, 255);
    blk_queue_logcal_block_size(xxx_queue, 512);
    
    xxx_disks->major = XXX_MAJOR;
    xxx_disks->first_minor = 0;
    xxx_disks->fops = &xxx_op;
    xxx_disks->queue = xxx_queue;
    sprintf(xxx_disks->disk_name, "xxx%d", i);
    set_capacity(xxx_disks, xxx_size * 2);
    add_disk(xxx_disks);
    
    return 0;
    out_queue:unregister_blkdev(XXX_MAJOR, "xxx");
    out:put_disk(xxx_disks);
    blk_cleanup_queue(xxx_queue);
    
    return -ENOMEME;
}

清除请求队列,使用blk_cleanup();
删除对gendisk的引用,使用put_disk()
删除对块设备的引用,注销块设备驱动,使用unregister_blkdev();

static int mmc_blk_ioctl(struct block_device *bdev, fmode_t mode, unsigne int cmd, unsigned long arg)
{
    int ret = -EINVAL;
    if(cmd == MMC_IOC_CMD)
        ret = mmc_blk_ioctl_cmd(bdev, (struct mmc_ioc_cmd __user*)arg);
        
    return ret;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值