FreeBSD新手驱动程序加载成功,但无法创建/dev/**文件并进行调试



我正在FreeBSD 10.0上安装一个新的newbuf驱动程序。使用make编译后,驱动程序.ko文件已经创建,kldload可以成功加载。kldload返回0,我可以在kldstat输出处看到设备。当尝试使用驱动程序打开/dev/**文件时,该文件不存在。

我认为这个/dev/**文件应该由位于device_attach成员方法中的make_dev函数创建。测试kldload是否达到该附加功能;当编写printf和uprintf来调试驱动程序时,我在控制台上看不到任何输出,也看不到dmesg输出。但问题是,在device_identify和device_probe函数的开头(在本地变量定义之后)写入printf之后,我在控制台和dmesg上都看不到任何输出。

我的问题是,即使物理驱动程序有问题(未找到等),我是否应该在开始课程时看到kldload调用的device_identify成员函数的printf输出(我认为)?

我在用printf调试newbuf驱动程序时出错了吗(我还尝试了hello_world设备驱动程序,在这个驱动程序中,我可以在dmesg上获得printf的输出)?

主要是如何测试/调试这个驱动程序的kldload进程?

下面是我的驱动程序代码的一些部分(我想至少我应该看到MSG1,但我看不到):

struct mydrv_softc 
{
    device_t        dev;
};
static devclass_t mydrv_devclass;
static struct cdevsw mydrv_cdevsw = {
    .d_version  = D_VERSION,
    .d_name     = "mydrv",
    .d_flags    = D_NEEDGIANT,
    .d_open     = mydrv_open,  
    .d_close    = mydrv_close, 
    .d_ioctl    = mydrv_ioctl,
    .d_write    = mydrv_write,
    .d_read     = mydrv_read
};

static void mydrv_identify (driver_t *driver, device_t parent) {
    devclass_t dc;
    device_t child;
    printf("MSG1: The process inside the identfy function.");
    dc = devclass_find("mydrv");
    if (devclass_get_device(dc, 0) == NULL) {
        child = BUS_ADD_CHILD(parent, 0, "mydrv", -1);
    }
}
static int mydrv_probe(device_t dev) {
    printf("MSG2: The process inside the probe function.");
    mydrv_init();
    if (device_get_unit(dev) != 0)
        return (ENXIO);
    device_set_desc(dev, "FreeBSD Device Driver");
    return (0);
}
static int mydrv_attach(device_t dev) {
    struct mydrv_softc *sc;
    device_printf(dev, "MSG3: The process will make attachment.");
    sc = (struct mydrv_softc *) device_get_softc(dev);
    sc->dev = (device_t)make_dev(&mydrv_cdevsw, 0, UID_ROOT, GID_WHEEL, 0644, "mydrv_drv");
    return 0;
}
static int mydrv_detach(device_t dev) {
        struct mydrv_softc *sc;
    sc = (struct mydrv_softc *) device_get_softc(dev);
        destroy_dev((struct cdev*)(sc->dev));
    bus_generic_detach(dev);
    return 0;
}
static device_method_t mydrv_methods[] = {
    DEVMETHOD(device_identify,  mydrv_identify),
    DEVMETHOD(device_probe,     mydrv_probe),
    DEVMETHOD(device_attach,    mydrv_attach),
    DEVMETHOD(device_detach,    mydrv_detach),
    { 0, 0 }
};
static driver_t mydrv_driver = {
    "mydrv",
    mydrv_methods,
    sizeof(struct mydrv_softc),
};
DRIVER_MODULE(mydrv, ppbus, mydrv_driver, mydrv_devclass, 0, 0);

如果您在控制台上看不到printf的输出,那么您的设备函数可能不会被调用。你能给我们看一下你模块的代码吗?您使用过DRIVER_MODULE()或DEV_MODULE吗?你用的是哪辆母车?

我想printf工作得很好,但我更喜欢使用device_printf,因为它还打印设备名称,并且在查看日志或dmesg输出时会更容易。还要留下多个调试打印并检查系统上的日志文件。设备驱动程序的大多数日志都记录在/var/log/messages中。但也要检查其他日志文件。你是在虚拟机上运行代码吗?如果操作系统在虚拟机上运行,某些设备驱动程序不会在/dev中显示其设备文件。您可能应该在实际硬件上运行操作系统,以便显示设备文件。据我所知,如果你在/dev中找不到相应的设备文件,你就看不到dmesg中的输出,但正如我所提到的,你可能对日志很幸运。调试最简单的方法当然是使用printf语句。除此之外,您还可以使用在另一个系统上运行的gdb调试内核。我不熟悉确切的过程,但我知道你可以做到。谷歌搜索。

最新更新