为了确保我理解构建UIO驱动程序的过程,我想 我会把uio_pci_generic.c的现有代码做一些更改 将它与原来的uioJ_pci_generic.c区分开来,看看我是否可以构建这个模块并将其插入到Fedora 17系统中。
这些是我对原始uio_pci_generic所做的更改以生成我的 我无法插入的测试模块uioJ_pci_generic 运行内核。请赐教(grovel,grovel,.....)
为了将我的版本与原版区分开来,我在原版中对其进行了更改:
gdev->info.name = "uio_pci_generic";
到此:
gdev->info.name = "uioJ_pci_generic";
同时更改原文:
static struct pci_driver uioJ_pci_driver = {
.name = "uio_pci_generic",
.id_table = NULL, /* only dynamic id's */
.probe = probe,
.remove = remove,
};
到:
static struct pci_driver uioJ_pci_driver = {
.name = "uioJ_pci_generic",
.id_table = NULL, /* only dynamic id's */
.probe = probe,
.remove = remove,
};
我还修改了原来的DRIVER_AUTHOR:
#define DRIVER_AUTHOR "Michael S. Tsirkin <mst@redhat.com>"
到:
#define DRIVER_AUTHOR "Neddy Seagoon <mst@redhat.com>"
还修改了原来的DRIVER_DESC:
#define DRIVER_DESC "Generic UIO driver for PCI 2.3 devices"
到:
#define DRIVER_DESC "Mother : Generic UIO driver (with comments)for PCI 2.3 devices"
以下是修改后的版本:
#include <linux/device.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/slab.h>
#include <linux/uio_driver.h>
#define DRIVER_VERSION "0.01.0"
#define DRIVER_AUTHOR "Neddy Seagoon <mst@redhat.com>"
#define DRIVER_DESC "Mother : Generic UIO driver (with comments)for PCI 2.3 devices"
struct uio_pci_generic_dev {
struct uio_info info;
struct pci_dev *pdev;
};
static inline struct uio_pci_generic_dev *
to_uio_pci_generic_dev(struct uio_info *info)
{
return container_of(info, struct uio_pci_generic_dev, info);
}
/* Interrupt handler. Read/modify/write the command register to disable
* the interrupt. */
static irqreturn_t irqhandler(int irq, struct uio_info *info)
{
static int count = 0;
pr_info("In UIO handler, count=%d\n", ++count);
struct uio_pci_generic_dev *gdev = to_uio_pci_generic_dev(info);
if (!pci_check_and_mask_intx(gdev->pdev))
return IRQ_NONE;
/* UIO core will signal the user process. */
return IRQ_HANDLED;
}
static int probe(struct pci_dev *pdev, const struct pci_device_id *id)
{
struct uio_pci_generic_dev *gdev;
int err;
err = pci_enable_device(pdev);
if (err) {
dev_err(&pdev->dev, "%s: pci_enable_device failed: %d\n",
__func__, err);
return err;
}
pr_info("probe : pci_enable_device() Success\n");
if (!pdev->irq) {
dev_warn(&pdev->dev, "No IRQ assigned to device: "
"no support for interrupts?\n");
pci_disable_device(pdev);
return -ENODEV;
}
pr_info("probe : using IRQ=%d\n", pdev->irq);
if (!pci_intx_mask_supported(pdev)) {
err = -ENODEV;
goto err_verify;
}
gdev = kzalloc(sizeof(struct uio_pci_generic_dev), GFP_KERNEL);
if (!gdev) {
err = -ENOMEM;
goto err_alloc;
}
gdev->info.name = "uioJ_pci_generic";
gdev->info.version = DRIVER_VERSION;
gdev->info.irq = pdev->irq;
gdev->info.irq_flags = IRQF_SHARED;
gdev->info.handler = irqhandler;
gdev->pdev = pdev;
err = uio_register_device(&pdev->dev, &gdev->info);
if (err)
goto err_register;
pr_info("probe : uio_register_device() Success : %d\n", err);
pci_set_drvdata(pdev, gdev);
return 0;
err_register:
pr_info("probe : uio_register_device() Failed : %d\n", err);
kfree(gdev);
err_alloc:
err_verify:
pr_info("probe : pci_disable_device()\n");
pci_disable_device(pdev);
return err;
}
static void remove(struct pci_dev *pdev)
{
struct uio_pci_generic_dev *gdev = pci_get_drvdata(pdev);
pr_info("remove()\n");
uio_unregister_device(&gdev->info);
pci_disable_device(pdev);
kfree(gdev);
}
static struct pci_driver uioJ_pci_driver = {
.name = "uioJ_pci_generic",
.id_table = NULL, /* only dynamic id's */
.probe = probe,
.remove = remove,
};
module_pci_driver(uioJ_pci_driver);
MODULE_VERSION(DRIVER_VERSION);
MODULE_LICENSE("GPL v2");
MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_DESCRIPTION(DRIVER_DESC);
以下是我构建和插入模块的步骤:
第1步:构建模块。
obj-m += uioJ_pci_generic.o
all:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
clean:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
# ls -l
-rw-r--r--. 1 james james 13943 Jun 14 11:09 uioJ_pci_generic.c
-rw-r--r--. 1 james james 13943 Jun 12 23:12 uioJ_pci_generic.c~
-rw-r--r--. 1 root root 120924 Jun 27 22:41 uioJ_pci_generic.ko
-rw-r--r--. 1 root root 415 Jun 27 22:41 uioJ_pci_generic.mod.c
-rw-r--r--. 1 root root 42288 Jun 27 22:41 uioJ_pci_generic.mod.o
-rw-r--r--. 1 root root 79592 Jun 27 22:41 uioJ_pci_generic.o
请注意,驱动程序uioJ_pci_generic不可执行,权限中没有'x'(为什么???)
步骤2:将uio目录复制到uioJ_pci_generic.ko
# cp uioJ_pci_generic.ko /lib/modules/...../drivers/uio
cp: overwrite `/lib/modules/..../drivers/uio/uioJ_pci_generic.ko'? y
# depmod -a
第3步:现在检查模块
# ls -l
total 168
-rwxr--r--. 1 root root 4792 May 7 2012 uio_aec.ko
-rwxr--r--. 1 root root 4640 May 7 2012 uio_cif.ko
-rw-r--r--. 1 root root 120924 Jun 10 13:52 uioJ_pci_generic.ko
-rwxr--r--. 1 root root 14212 May 7 2012 uio.ko
-rwxr--r--. 1 root root 4440 May 7 2012 uio_pci_generic.ko
-rwxr--r--. 1 root root 5516 May 7 2012 uio_sercos3.ko
请注意,我的uioJ_pci_generic.ko没有'x'权限,但原始版本没有。 (为什么???)
步骤4:获取uioJ_pci_generic的模块信息:
# modinfo uioJ_pci_generic
filename: /lib/modules../kernel/drivers/uio/uioJ_pci_generic.ko
description: Mother : Generic UIO driver (with comments)for PCI 2.3 devices
author: Neddy Seagoon <mst@redhat.com>
license: GPL v2
version: 0.01.0
srcversion: 7780AD87F53B831688C0CFD
depends:
vermagic: 3.3.4-5.fc17.i686.PAE SMP mod_unload 686
#
#
与原版相比:
# modinfo uio_pci_generic
filename: /lib/modules/3.3.4-5.fc17.i686.PAE/kernel/drivers/uio/uio_pci_generic.ko
description: Generic UIO driver for PCI 2.3 devices
author: Michael S. Tsirkin <mst@redhat.com>
license: GPL v2
version: 0.01.0
srcversion: 24D140D89C561428A72FF39
depends: uio
intree: Y
vermagic: 3.3.4-5.fc17.i686.PAE SMP mod_unload 686
#
注意区别:uio_pci_generic取决于uio,uioJ_pci_generic不依赖。
步骤5:插入模块
# modprobe uio
# modprobe uio_pci_generic
then I saw this in /var/log/messages:
Jun 27 23:33:46 localhost kernel: [ 3566.198890] Generic UIO driver for PCI 2.3 devices version: 0.01.0
then I tried to insert the uioJ_pci_generic version
# modprobe uioJ_pci_generic
but I saw nothing further in /var/log/messages in response to this.
如果uioJ_pci_generic模块确实正确加载了字符串 “母亲:用于PCI 2.3设备的通用UIO驱动程序(带注释)”将在/ var / log / messages中打印
标准uio_pci_generic的构建方式与我的版本不同(正确)。 构建我的uioJ_pci_generic的步骤序列有什么问题?
我很难过你! 在此先感谢您的帮助