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
--00000000000036ce4a06157392a6 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable 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=E2=80=AFPM Rocky Hotas <rockyhotas@tilde.team> wr= ote: > 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 =3D { > .d_version =3D D_VERSION, > .d_open =3D rolld_open, > .d_close =3D rolld_close, > .d_read =3D rolld_read, > .d_name =3D "rolld", > }; > > /* vars */ > static struct cdev *rolld_dev; > static uint32_t d_size =3D 6; > > static int > rolld_loader(struct module *m __unused, int what, void *arg __unused) > { > int error =3D 0; > > switch (what) { > case MOD_LOAD: /* kldload */ > error =3D make_dev_p(MAKEDEV_CHECKNAME | MAKEDEV_WAITOK, > &rolld_dev, > &rolld_cdevsw, > 0, > UID_ROOT, > GID_WHEEL, > 0444, > "rolld"); > if (error !=3D 0) > break; > > printf("Roll device loaded.\n"); > break; > case MOD_UNLOAD: > destroy_dev(rolld_dev); > printf("Roll device unloaded.\n"); > break; > default: > error =3D EOPNOTSUPP; > break; > } > return (error); > } > > static int > rolld_open(struct cdev *dev __unused, int oflags __unused, int devtype > __unused, > struct thread *td __unused) > { > int error =3D 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 __unuse= d) > { > uint32_t random_out; > uint32_t random_item; > int error; > > random_item =3D arc4random(); > random_out =3D random_item % d_size; > > if ((error =3D uiomove(&random_out, 1, uio)) !=3D 0) > uprintf("uiomove failed!\n"); > > return (error); > } > > DEV_MODULE(rolld, rolld_loader, NULL); > > --00000000000036ce4a06157392a6 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable <div dir=3D"auto">When this happens, hit ^t (control t). That will give a t= raceback of the call stack which may help you track down where it is hangin= g (most likely something is sleeping waiting for an event).<div dir=3D"auto= "><br></div><div dir=3D"auto">Warner=C2=A0</div></div><br><div class=3D"gma= il_quote"><div dir=3D"ltr" class=3D"gmail_attr">On Sat, Apr 6, 2024, 2:27= =E2=80=AFPM Rocky Hotas <rockyhotas@tilde.team> wrote:<br></div><bloc= kquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #cc= c solid;padding-left:1ex">Hello!<br> I'm trying to write a simple kernel module, using as a model the exampl= e<br> in<br> <br> =C2=A0<<a href=3D"https://docs.freebsd.org/en/books/arch-handbook/driver= basics/" rel=3D"noreferrer noreferrer" target=3D"_blank">https://docs.freeb= sd.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 cha= racter.<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=C2=A0 =C2=A0 =C2=A0 rolld_open;<br> static d_close_t=C2=A0 =C2=A0 =C2=A0rolld_close;<br> static d_read_t=C2=A0 =C2=A0 =C2=A0 rolld_read;<br> <br> static struct cdevsw rolld_cdevsw =3D {<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 .d_version =3D D_VERSION,<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 .d_open =3D rolld_open,<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 .d_close =3D rolld_close,<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 .d_read =3D rolld_read,<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 .d_name =3D "rolld",<br> };<br> <br> /* vars */<br> static struct cdev *rolld_dev;<br> static uint32_t d_size =3D 6;<br> <br> static int<br> rolld_loader(struct module *m __unused, int what, void *arg __unused)<br> {<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 int error =3D 0;<br> <br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 switch (what) {<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 case MOD_LOAD:=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 /* kldload */<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 error =3D make_dev_= p(MAKEDEV_CHECKNAME | MAKEDEV_WAITOK,<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 &= rolld_dev,<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 &= rolld_cdevsw,<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 0,<br= > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 UID_R= OOT,<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 GID_W= HEEL,<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 0444,= <br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 "= ;rolld");<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if (error !=3D 0)<b= r> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 break;<br> <br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 printf("Roll d= evice loaded.\n");<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 break;<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 case MOD_UNLOAD:<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 destroy_dev(rolld_d= ev);<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 printf("Roll d= evice unloaded.\n");<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 break;<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 default:<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 error =3D EOPNOTSUP= P;<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 break;<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 }<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 return (error);<br> }<br> <br> static int<br> rolld_open(struct cdev *dev __unused, int oflags __unused, int devtype __un= used,<br> =C2=A0 =C2=A0 struct thread *td __unused)<br> {<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 int error =3D 0;<br> <br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 uprintf("Opened device \"rolld\"= successfully.\n");<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 return (error);<br> }<br> <br> static int<br> rolld_close(struct cdev *dev __unused, int fflag __unused, int devtype __un= used,<br> =C2=A0 =C2=A0 struct thread *td __unused)<br> {<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 uprintf("Closing device \"rolld\"= ;.\n");<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 return (0);<br> }<br> <br> static int<br> rolld_read(struct cdev *dev __unused, struct uio *uio, int ioflag __unused)= <br> {<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 uint32_t random_out;<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 uint32_t random_item;<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 int error;<br> <br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 random_item =3D arc4random();<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 random_out =3D random_item % d_size;<br> <br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 if ((error =3D uiomove(&random_out, 1, uio)= ) !=3D 0)<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 uprintf("uiomo= ve failed!\n");<br> <br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 return (error);<br> }<br> <br> DEV_MODULE(rolld, rolld_loader, NULL);<br> <br> </blockquote></div> --00000000000036ce4a06157392a6--
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?CANCZdfqAUWqp_s8ULhi9A97jrMCxA1CAXJKmUJ307=PSpekKug>