此处以编译smartpqi驱动为示例。以V10服务器系统为编译测试环境,驱动下载链接:https://storage.microsemi.com/en-us/speed/raid/aac/linux/smartpqi_src_v2.1.12-055_tgz.php
1、解压源码
# tar -zxf smartpqi_src_v2.1.12-055.tgz
2、安装源码包
# cd srcrpm/
# rpm -ivh smartpqi-2.1.12-055.src.rpm
3、编译源码
# cd /root/rpmbuild/SPECS
# rpmbuild -bp smartpqi-src.spec
# cd ../BUILD/
# make
4、构建rpm包
# cd ../SPECS/
#rpmbuild -ba
构建完成的包位于RPMS目录中
5、安装验证
#rpm -ivh smartpqi-2.1.12-055.ky10.x86_64.rpm
遇到的问题处理:
问题1:
错误:问题来源: /root/rpmbuild/SOURCES/smartpqi-2.1.12-055.ky10.tar.bz2: 没有那个文件或目录
只需要修改源码包的名字即可
#cd ../SOURCES/
#mv smartpqi-2.1.12-055.tar.bz2 smartpqi-2.1.12-055.ky10.tar.bz2
问题2:
/root/rpmbuild/BUILD/src/smartpqi_init.c:7173:11: 错误:从不兼容的指针类型初始化 [-Werror=incompatible-pointer-types]
.ioctl = pqi_ioctl,
^~~~~~~~~
/root/rpmbuild/BUILD/src/smartpqi_init.c:7173:11: 附注:(在‘pqi_driver_template.ioctl’的初始化附近)
此处报错得知驱动代码中的数据类型不对,我们可以查看系统内核头文件中源码定义
#vim /root/rpmbuild/BUILD/src/smartpqi_init.c +7173
static struct scsi_host_template pqi_driver_template = {
.module = THIS_MODULE,
.name = DRIVER_NAME_SHORT,
.proc_name = DRIVER_NAME_SHORT,
.queuecommand = PQI_SCSI_QUEUE_COMMAND,
.scan_start = pqi_scan_start,
.scan_finished = pqi_scan_finished,
.this_id = -1,
.eh_device_reset_handler = pqi_eh_device_reset_handler,
.ioctl = pqi_ioctl,
.slave_alloc = pqi_slave_alloc,
.slave_configure = pqi_slave_configure,
.sdev_attrs = pqi_sdev_attrs,
.shost_attrs = pqi_shost_attrs,
};
接下来去内核中搜索该函数的代码情况
# grep -rni "struct scsi_host_template {" /usr/src/
结果如下:
/usr/src/kernels/xxxx/include/scsi/scsi_host.h:51:struct scsi_host_template {
#vim /usr/src/kernels/xxxx/include/scsi/
scsi_host.h +51
可以看到ioctl的声明如下:
int (*ioctl)(struct scsi_device *dev, unsigned int cmd,
void __user *arg);
再次搜索驱动源码中pqi_ioctl 的函数定义及参数情况
#grep -rni "pqi_ioctl" /root/rpmbuild/BUILD/src/
结果如下:
/root/rpmbuild/BUILD/src/smartpqi_init.c:6648:static int pqi_ioctl(struct scsi_device *sdev, IOCTL_INT cmd, void __user *arg)
/root/rpmbuild/BUILD/src/smartpqi_init.c:7173: .ioctl = pqi_ioctl,
#vim /root/rpmbuild/BUILD/src/smartpqi_init.c +6648
可以看到该函数的实现中,cmd参数的类型与内核源码不匹配,因此修改该参数的类型即可
static int pqi_ioctl(struct scsi_device *sdev, IOCTL_INT cmd, void __user *arg)
{
int rc;
struct pqi_ctrl_info *ctrl_info;
ctrl_info = shost_to_hba(sdev->host);
switch (cmd) {
case CCISS_DEREGDISK:
case CCISS_REGNEWDISK:
case CCISS_REGNEWD:
rc = pqi_scan_scsi_devices(ctrl_info);
break;
case CCISS_GETPCIINFO:
rc = pqi_getpciinfo_ioctl(ctrl_info, arg);
break;
case CCISS_GETDRIVVER:
rc = pqi_getdrivver_ioctl(arg);
break;
case CCISS_PASSTHRU:
rc = pqi_passthru_ioctl(ctrl_info, arg);
break;
default:
rc = -EINVAL;
break;
}
return rc;
}
修改后为static int pqi_ioctl(struct scsi_device *sdev, unsigned int cmd, void __user *arg)
...
问题3:
执行rpmbuild -bb 构建软件包过程中还是会有问题2的报错,因为原始的源码中我们未修改,因此需要修改/root/rpmbuild/SOURCES/smartpqi-2.1.12-055.ky10.tar.bz2 包中的代码
#cd /root/rpmbuild/SOURCES/
#mkdir temp
#tar -xf smartpqi-2.1.12-055.ky10.tar.bz2 -C temp
#cd temp
#grep -rni "pqi_ioctl(" .
结果如下:
./src/smartpqi_init.c:6648:static int pqi_ioctl(struct scsi_device *sdev, unsigned int cmd, void __user *arg)
#vim src/smartpqi_init.c +6648
修改完成重新打包
#
问题4:
处理文件:smartpqi-debuginfo-2.1.12-055.ky10.x86_64
错误:空 %file 文件 /root/rpmbuild/BUILD/smartpqi-2.1.12/debugfiles.list
RPM 构建错误:
空 %file 文件 /root/rpmbuild/BUILD/smartpqi-2.1.12/debugfiles.list
需要先修改smartpqi-src.spec (使用命令vim smartpqi-src.spec编辑,添加%global debug_package %{nil})
修改后内容如下
...
# prep ############
%global debug_package %{nil}
%prep
echo prep %{version}-%{release}
%setup -c -b 0
cp %_sourcedir/Module.supported src/Module.supported
...