我正在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调试内核。我不熟悉确切的过程,但我知道你可以做到。谷歌搜索。