Date: Sat, 6 Apr 2024 14:39:26 -0600 From: Warner Losh <imp@bsdimp.com> To: Rocky Hotas <rockyhotas@tilde.team> Cc: FreeBSD Hackers <freebsd-hackers@freebsd.org> Subject: Re: Kernel module: return a number from a device Message-ID: <CANCZdfqAUWqp_s8ULhi9A97jrMCxA1CAXJKmUJ307=PSpekKug@mail.gmail.com> In-Reply-To: <oghsl7sgcl6p6ym3wwa3w56hn52cdophcr4jxau4ronxevy4ar@ux223whjcthj> References: <oghsl7sgcl6p6ym3wwa3w56hn52cdophcr4jxau4ronxevy4ar@ux223whjcthj>
next in thread | previous in thread | raw e-mail | index | archive | help
[-- Attachment #1 --] 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); > > [-- Attachment #2 --] <div dir="auto">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).<div dir="auto"><br></div><div dir="auto">Warner </div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Sat, Apr 6, 2024, 2:27 PM Rocky Hotas <rockyhotas@tilde.team> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hello!<br> I'm trying to write a simple kernel module, using as a model the example<br> in<br> <br> <<a href="https://docs.freebsd.org/en/books/arch-handbook/driverbasics/" rel="noreferrer noreferrer" target="_blank">https://docs.freebsd.org/en/books/arch-handbook/driverbasics/</a>><br> <br> I am a newbie. My module should be simpler than the one in the link: it<br> should just create a read-only /dev/rolld file; each time it is read<br> by the user (for example through `cat'), the file should provide a<br> random number mod d_size. So, the "output" should always be 1 character.<br> <br> I modified the echo kernel module presented in the link. My module<br> can successfully be loaded into the kernel and the device is created,<br> but if I run as a user `cat /dev/rolld':<br> <br> $ cat /dev/rolld <br> Opened device "rolld" successfully.<br> <br> and it hangs, giving no more output and without generating an error.<br> <br> May be this due to the fact that uiomove receives a pointer &random_out,<br> which is a pointer to a uint32_t instead of for example a char? (And if<br> this is the issue, how to convert a uint32_t to char inside the kernel?)<br> <br> Or is there some other error that I made?<br> <br> I paste my code below.<br> <br> Bye!<br> <br> Rocky<br> <br> <br> <br> #include <sys/types.h><br> #include <sys/systm.h><br> #include <sys/param.h><br> #include <sys/module.h><br> #include <sys/kernel.h><br> #include <sys/conf.h><br> #include <sys/uio.h><br> #include <sys/malloc.h><br> #include <sys/libkern.h><br> <br> static d_open_t rolld_open;<br> static d_close_t rolld_close;<br> static d_read_t rolld_read;<br> <br> static struct cdevsw rolld_cdevsw = {<br> .d_version = D_VERSION,<br> .d_open = rolld_open,<br> .d_close = rolld_close,<br> .d_read = rolld_read,<br> .d_name = "rolld",<br> };<br> <br> /* vars */<br> static struct cdev *rolld_dev;<br> static uint32_t d_size = 6;<br> <br> static int<br> rolld_loader(struct module *m __unused, int what, void *arg __unused)<br> {<br> int error = 0;<br> <br> switch (what) {<br> case MOD_LOAD: /* kldload */<br> error = make_dev_p(MAKEDEV_CHECKNAME | MAKEDEV_WAITOK,<br> &rolld_dev,<br> &rolld_cdevsw,<br> 0,<br> UID_ROOT,<br> GID_WHEEL,<br> 0444,<br> "rolld");<br> if (error != 0)<br> break;<br> <br> printf("Roll device loaded.\n");<br> break;<br> case MOD_UNLOAD:<br> destroy_dev(rolld_dev);<br> printf("Roll device unloaded.\n");<br> break;<br> default:<br> error = EOPNOTSUPP;<br> break;<br> }<br> return (error);<br> }<br> <br> static int<br> rolld_open(struct cdev *dev __unused, int oflags __unused, int devtype __unused,<br> struct thread *td __unused)<br> {<br> int error = 0;<br> <br> uprintf("Opened device \"rolld\" successfully.\n");<br> return (error);<br> }<br> <br> static int<br> rolld_close(struct cdev *dev __unused, int fflag __unused, int devtype __unused,<br> struct thread *td __unused)<br> {<br> uprintf("Closing device \"rolld\".\n");<br> return (0);<br> }<br> <br> static int<br> rolld_read(struct cdev *dev __unused, struct uio *uio, int ioflag __unused)<br> {<br> uint32_t random_out;<br> uint32_t random_item;<br> int error;<br> <br> random_item = arc4random();<br> random_out = random_item % d_size;<br> <br> if ((error = uiomove(&random_out, 1, uio)) != 0)<br> uprintf("uiomove failed!\n");<br> <br> return (error);<br> }<br> <br> DEV_MODULE(rolld, rolld_loader, NULL);<br> <br> </blockquote></div>
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?CANCZdfqAUWqp_s8ULhi9A97jrMCxA1CAXJKmUJ307=PSpekKug>
