Rocky Hotas
2024-04-06 20:27:12 UTC
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);
--
Posted automagically by a mail2news gateway at muc.de e.V.
Please direct questions, flames, donations, etc. to news-***@muc.de
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);
--
Posted automagically by a mail2news gateway at muc.de e.V.
Please direct questions, flames, donations, etc. to news-***@muc.de