Re: Kernel module: return a number from a device
- In reply to: Rocky Hotas : "Kernel module: return a number from a device"
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Sat, 06 Apr 2024 20:39:26 UTC
When this happens, hit ^t (control t). That will give a traceback of the call stack which may help you track down where it is hanging (most likely something is sleeping waiting for an event). Warner On Sat, Apr 6, 2024, 2:27 PM Rocky Hotas <rockyhotas@tilde.team> wrote: > Hello! > I'm trying to write a simple kernel module, using as a model the example > in > > <https://docs.freebsd.org/en/books/arch-handbook/driverbasics/> > > I am a newbie. My module should be simpler than the one in the link: it > should just create a read-only /dev/rolld file; each time it is read > by the user (for example through `cat'), the file should provide a > random number mod d_size. So, the "output" should always be 1 character. > > I modified the echo kernel module presented in the link. My module > can successfully be loaded into the kernel and the device is created, > but if I run as a user `cat /dev/rolld': > > $ cat /dev/rolld > Opened device "rolld" successfully. > > and it hangs, giving no more output and without generating an error. > > May be this due to the fact that uiomove receives a pointer &random_out, > which is a pointer to a uint32_t instead of for example a char? (And if > this is the issue, how to convert a uint32_t to char inside the kernel?) > > Or is there some other error that I made? > > I paste my code below. > > Bye! > > Rocky > > > > #include <sys/types.h> > #include <sys/systm.h> > #include <sys/param.h> > #include <sys/module.h> > #include <sys/kernel.h> > #include <sys/conf.h> > #include <sys/uio.h> > #include <sys/malloc.h> > #include <sys/libkern.h> > > static d_open_t rolld_open; > static d_close_t rolld_close; > static d_read_t rolld_read; > > static struct cdevsw rolld_cdevsw = { > .d_version = D_VERSION, > .d_open = rolld_open, > .d_close = rolld_close, > .d_read = rolld_read, > .d_name = "rolld", > }; > > /* vars */ > static struct cdev *rolld_dev; > static uint32_t d_size = 6; > > static int > rolld_loader(struct module *m __unused, int what, void *arg __unused) > { > int error = 0; > > switch (what) { > case MOD_LOAD: /* kldload */ > error = make_dev_p(MAKEDEV_CHECKNAME | MAKEDEV_WAITOK, > &rolld_dev, > &rolld_cdevsw, > 0, > UID_ROOT, > GID_WHEEL, > 0444, > "rolld"); > if (error != 0) > break; > > printf("Roll device loaded.\n"); > break; > case MOD_UNLOAD: > destroy_dev(rolld_dev); > printf("Roll device unloaded.\n"); > break; > default: > error = EOPNOTSUPP; > break; > } > return (error); > } > > static int > rolld_open(struct cdev *dev __unused, int oflags __unused, int devtype > __unused, > struct thread *td __unused) > { > int error = 0; > > uprintf("Opened device \"rolld\" successfully.\n"); > return (error); > } > > static int > rolld_close(struct cdev *dev __unused, int fflag __unused, int devtype > __unused, > struct thread *td __unused) > { > uprintf("Closing device \"rolld\".\n"); > return (0); > } > > static int > rolld_read(struct cdev *dev __unused, struct uio *uio, int ioflag __unused) > { > uint32_t random_out; > uint32_t random_item; > int error; > > random_item = arc4random(); > random_out = random_item % d_size; > > if ((error = uiomove(&random_out, 1, uio)) != 0) > uprintf("uiomove failed!\n"); > > return (error); > } > > DEV_MODULE(rolld, rolld_loader, NULL); > >