LDD3示例代码sbull编译问题

本文记录了在内核2.6.39下编译2.6.10版LDD3示例代码sbull驱动时遇到的若干问题及解决方案,包括内核函数和结构的变动,如函数定义删除、函数参数变化等。通过针对性地修改代码,解决了编译警告和错误,但在安装模块时仍遇到killed的问题,进一步分析发现函数指针类型不匹配,修复后成功编译。最后提供了测试和运行sbull驱动的步骤。
摘要由CSDN通过智能技术生成
编译块设备驱动程序实例代码sbull遇到的问题

示例代码版本为 2.6.10,编译时的内核版本为2.6.39。内核中许多函数和结构发生变化,造成了编译问题,记录如下:


  • error: unknown type name ‘request_queue_t’
    原因:新版内核中已经没有request_queue_t的定义
    解决方法:可在代码所在文件添加如下定义:
    typedef struct request_queue request_queue_t;

  • error: implicit declaration of function ‘elv_next_request’
    原因:在新版本中已经将elv_next_requestblk_fetch_request替代。参考网址
    解决方法:在相应代码处替换即可。

  • error: implicit declaration of function ‘blk_fs_request’
    原因:在 新版本中已经没有blk_fs_request函数来判断命令类型。
    解决方法:可将判断语句改为:req->cmd_type != REQ_TYPE_FS

  • error: implicit declaration of function end_request
    原因:新版本内核中void end_request(struct request *req, int succeeded)已不存在。
    解决方法:可用void __blk_end_request_all(struct request *rq, int error);替代。

  • error: ‘struct request’ has no member named ‘sector’
    error: ‘struct request’ has no member named ‘current_nr_sectors’
    原因:新版本内核,struct request中删除了成员sectorcurrent_nr_sectors
    解决方法 :采用如下两个函数作相应代换:blk_rq_pos(req)blk_rq_cur_sectors(req)

  • error: implicit declaration of function ‘bio_cur_sectors’
    原因:新版本内核中 ‘bio_cur_sectors’已经删除。
    解决方法:与 2.610和2.6.39代码对照可知,可使用bio_cur_bytes(bio) / KERNEL_SECTOR_SIZE代替该函数。

  • error: implicit declaration of function ‘rq_for_each_bio’
    原因:新版本中改为了__rq_for_each_bio
    解决方法:修改之。

  • error: implicit declaration of function ‘end_that_request_first’
    error: implicit declaration of function ‘blkdev_dequeue_request’
    error: implicit declaration of function ‘end_that_request_last’
    原因:新版本中以上三个函数已经不存在。
    解决方法:参考网址代替将
sectors_xferred = sbull_xfer_request(dev, req);
if (! end_that_request_first(req, 1, sectors_xferred)) {
   
   blkdev_dequeue_request(req);
   end_that_request_last(req);
}

改为

sbull_xfer_request(dev, req);
if (!__blk_end_request_cur(req, 0)) {
   
	blk_start_request(req);
 	blk_fetch_request(q);
}

但是在我这边运行不了,以下为亲测可用代码,只是可以正常运行,不知其中原理 :

sbull_xfer_request(dev, req);
__blk_end_request_all(req, 0);

  • error: too many arguments to function ‘bio_endio’
    原因:新版本内核该函数参数改为两个,少了中间那个参数。
    解决方法:将中间那个参数去掉。

  • error: implicit declaration of function ‘blk_queue_hardsect_size’
    原因:与 2.610和2.6.39代码对照可知, 可由blk_queue_logical_block_size代替。
    解决方法:修改之。

  • 编译之后,有一个warning,"blk_put_queue" [/root/examples/sbull/sbull.ko] undefined!
    原因:新版本未定义该函数,可以使用kobject_put(&(dev->queue)->kobj);代替。
    解决方法:修改之 。

  • 修改上述错误后,便可编译成功,但是在安装模块时会提示killed。
  • 原因:观察编译时的输出:

    warning: initialization from incompatible pointer type [enabled by default] 警告:从不兼容的指针类型初始化[默认启用],有好几个函数指针类型均不匹配。查看新的内核版本代码struct block_device_operations结构:
struct block_device_operations {
   
 int (*open) (struct block_device *, fmode_t);
 int (*release) (struct gendisk *, fmode_t);
 int (*ioctl) (struct block_device *, fmode_t, unsigned, unsigned long);
 int (*compat_ioctl) (struct block_device *, fmode_t, unsigned, unsigned long);
 int (*direct_access) (struct block_device *, sector_t,
      void **, unsigned long *);
 unsigned int (*check_events) (struct gendisk *disk,
          unsigned int clearing);
 /* ->media_changed() is DEPRECATED, use ->check_events() instead */
 int (*media_changed) (struct gendisk *);
 void (*unlock_native_capacity) (struct gendisk *);
 int (*revalidate_disk) (struct gendisk *);
 int (*getgeo)(struct block_device *, struct hd_geometry *);
 /* this callback is with swap_lock and sometimes page table lock held */
 void (*swap_slot_free_notify) (struct block_device *, unsigned long);
 struct module *owner;
};

解决方法:将代码中相关函数改为对应定义的类型,并修改代码。 并且新版本结构中国包含getgeo函数,从而不再需要在ioctl函数实现HDIO_GETGEO命令。具体修改方法可见所附代码。


接下来即可进行测试。

  • ll /dev | grep sbull
  • 分区:fdisk /dev/sbull
  • 格式化,指定文件系统:mkfs.ext4 /dev/sbull
  • 挂载:mount /dev/sbull /mnt
  • 查看磁盘物理分区信息:cat /proc/partitions
  • 查看磁盘分区占用情况:df -ahT

参考网址:


sbull.c:

/*
 * Sample disk driver, from the beginning.
 */

//#include <linux/config.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/init.h>

#include <linux/sched.h>
#include <linux/kernel.h>	/* printk() */
#
  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值