Question

I am installing a new newbuf driver on FreeBSD 10.0 . After compiling with make the driver.ko file has been created and than kldload can load successfully. kldload returns 0 and I can see the device at the kldstat output. When attempt to use the driver opening the /dev/** file, the file is not exist.

I think that this /dev/** file should be created by make_dev function which is located in device_attach member method. To test if the kldload reaches this attaching function; when write printf and uprintf to debug the driver, I can not see any output at console nor dmesg output. But the problem is after writing printf at beginnings (after local variable definitions) of device_identify and device_probe functions, I can't see any output again at console nor dmesg.

My question is that even if the physical driver has problem (not located etc.), should I see the ouput of printf at the device_identify member function which is called by kldload at starting course (I think)?

Do I have a mistake when debugging newbuf driver with printf (I also tried a hello_world device driver and at this driver I can take output of printf at dmesg)?

Mainly how can I test/debug this driver's kldload processes?

Below some parts of my driver code (I think at least I should see MSG1, but I can not see):

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);
Was it helpful?

Solution

If you don't see your printf's output on your console then your device functions will probably not be called. Can you show us your module's code? Have you used DRIVER_MODULE() or DEV_MODULE()? What parent bus are you using?

OTHER TIPS

I guess printf works fine, but I prefer to use device_printf as it also prints the device name, and will be easier when looking through logs or dmesg output. Also leave multiple debug prints and check the log files on your system. Most logs for the device drivers are logged in /var/log/messages. But check other log files too. Are you running your code on a virtual machine? Some device drivers don't show up their device files in /dev if the OS is running on a virtual machine. You should probably run your OS on actual hardware for the device file to show up. As far as I know, you can't see the output in dmesg if you cannot find the corresponding device file in /dev but you may have luck with logs as I mentioned. The easiest way to debug is of course using the printf statements. Other than this, you can debug the kernel using gdb running on another system. I am not familiar with the exact process but I know you can do this. Google it.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top