From nobody Sat Apr 06 20:39:26 2024 X-Original-To: freebsd-hackers@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4VBnSR0nKDz5HKDH for ; Sat, 6 Apr 2024 20:45:59 +0000 (UTC) (envelope-from wlosh@bsdimp.com) Received: from mail-ej1-x62a.google.com (mail-ej1-x62a.google.com [IPv6:2a00:1450:4864:20::62a]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (2048 bits) client-digest SHA256) (Client CN "smtp.gmail.com", Issuer "GTS CA 1D4" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4VBnSQ3LXnz4Xqp for ; Sat, 6 Apr 2024 20:45:58 +0000 (UTC) (envelope-from wlosh@bsdimp.com) Authentication-Results: mx1.freebsd.org; none Received: by mail-ej1-x62a.google.com with SMTP id a640c23a62f3a-a51addddbd4so160684266b.0 for ; Sat, 06 Apr 2024 13:45:58 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bsdimp-com.20230601.gappssmtp.com; s=20230601; t=1712436353; x=1713041153; darn=freebsd.org; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:from:to:cc:subject:date:message-id:reply-to; bh=WpnJbSX3L4dvFURo+NNQxR6rjlpAIaMYmExj0O6bLJk=; b=eO+DuNRMbgYxGo4JxKsiAEs498pDsKaY+xuYSHNOVMXXdgEiqijtFnhgGXk/yD4bzt tJc9LbQ6jL20/8fnLyImpv/EGeQ4gNYyYqIIBHdn0UkPxM5SCJfqgHUBlADzJ3+59vIl XQA4vLNWzv14M+b6Agi3e+nhKVJ4MK/l4MtJ07dAV0x6F96tKjrUpurG89eqJDhHFg3o p7174AtzWUSLDSleKcbgSOdM2jVQhKQ8T+ypKnh4bH26kPzCaEADEI6oomjLk5s7pVRo 7luEpLU5T+MXuLZ3STopSkZLpONiwaVWAmsbLajvT+YImgjJBaVTFQ83siVZMgYKp7JE E12g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1712436353; x=1713041153; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=WpnJbSX3L4dvFURo+NNQxR6rjlpAIaMYmExj0O6bLJk=; b=BWxNexPILT1y1j/xyHg80YXi717WgAXbPmfOjWwYxdiwnaj04PvTEJfqtZMQjKYZEQ CfgEf1GAVk2l/l/mj4eP+S/DKR3D/GNGvWmu46/jT1ftTkri4xJIOHgJN8EzzY9M33IZ tZUBi4Z2tLSRLJJTln5XiGYn8jODqh8APrcpPWv4mCeplp6D0a6/UiOJKwwIkTok+32Y G9Da46Jtx6IajQXGqS08tF5vP1vGwBZLej0PoYRcxaND0bD7LiS4zfvWg3LyvhLcJrfd 2ivC/xgFGDcFqpf0SR0giZN+a5AgZ+1erp4mUEbBV+cXFaTKrnQeHW7OwebapOIPvw8V cofw== X-Gm-Message-State: AOJu0Yy9tpW8kyzkfaieMMtaMI0sB3pgeYlnz1I65evAG1aSbIYD8KxG PpzO21zjTOZ/54453mCIVeW5d4K1JLDikplYwWo8Twul0pTUFiJgnG1Kh+2rsX0gL14ag8Bjwu3 qc2S7nHAivgckfMqudfsPzWn9UAO/W/tHROmOWYSbfoyyjXAJ X-Google-Smtp-Source: AGHT+IGqgPU1fMsf6qVBBGqCRFzzDzpLuXCZSq2HOEgv6UMgpEX+S20cUDk35fd4Qw0xgzXMoclyjqUenfxCw9IThjk= X-Received: by 2002:a17:907:d92:b0:a51:c1e0:2ba9 with SMTP id go18-20020a1709070d9200b00a51c1e02ba9mr1217581ejc.11.1712435978743; Sat, 06 Apr 2024 13:39:38 -0700 (PDT) List-Id: Technical discussions relating to FreeBSD List-Archive: https://lists.freebsd.org/archives/freebsd-hackers List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-freebsd-hackers@freebsd.org MIME-Version: 1.0 References: In-Reply-To: From: Warner Losh Date: Sat, 6 Apr 2024 14:39:26 -0600 Message-ID: Subject: Re: Kernel module: return a number from a device To: Rocky Hotas Cc: FreeBSD Hackers Content-Type: multipart/alternative; boundary="00000000000036ce4a06157392a6" X-Spamd-Bar: ---- X-Rspamd-Pre-Result: action=no action; module=replies; Message is reply to one we originated X-Spamd-Result: default: False [-4.00 / 15.00]; REPLY(-4.00)[]; ASN(0.00)[asn:15169, ipnet:2a00:1450::/32, country:US] X-Rspamd-Queue-Id: 4VBnSQ3LXnz4Xqp --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 wr= ote: > Hello! > I'm trying to write a simple kernel module, using as a model the example > in > > > > 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 > #include > #include > #include > #include > #include > #include > #include > #include > > 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
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).

Warner=C2=A0

On Sat, Apr 6, 2024, 2:27= =E2=80=AFPM Rocky Hotas <rockyhotas@tilde.team> wrote:
Hello!
I'm trying to write a simple kernel module, using as a model the exampl= e
in

=C2=A0<https://docs.freeb= sd.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 cha= racter.

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=C2=A0 =C2=A0 =C2=A0 rolld_open;
static d_close_t=C2=A0 =C2=A0 =C2=A0rolld_close;
static d_read_t=C2=A0 =C2=A0 =C2=A0 rolld_read;

static struct cdevsw rolld_cdevsw =3D {
=C2=A0 =C2=A0 =C2=A0 =C2=A0 .d_version =3D D_VERSION,
=C2=A0 =C2=A0 =C2=A0 =C2=A0 .d_open =3D rolld_open,
=C2=A0 =C2=A0 =C2=A0 =C2=A0 .d_close =3D rolld_close,
=C2=A0 =C2=A0 =C2=A0 =C2=A0 .d_read =3D rolld_read,
=C2=A0 =C2=A0 =C2=A0 =C2=A0 .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)
{
=C2=A0 =C2=A0 =C2=A0 =C2=A0 int error =3D 0;

=C2=A0 =C2=A0 =C2=A0 =C2=A0 switch (what) {
=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 */
=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,
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 &= rolld_dev,
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 &= rolld_cdevsw,
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 0, =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 UID_R= OOT,
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 GID_W= HEEL,
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 0444,=
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 "= ;rolld");
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if (error !=3D 0) =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;

=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 printf("Roll d= evice loaded.\n");
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 break;
=C2=A0 =C2=A0 =C2=A0 =C2=A0 case MOD_UNLOAD:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 destroy_dev(rolld_d= ev);
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 printf("Roll d= evice unloaded.\n");
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 break;
=C2=A0 =C2=A0 =C2=A0 =C2=A0 default:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 error =3D EOPNOTSUP= P;
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 break;
=C2=A0 =C2=A0 =C2=A0 =C2=A0 }
=C2=A0 =C2=A0 =C2=A0 =C2=A0 return (error);
}

static int
rolld_open(struct cdev *dev __unused, int oflags __unused, int devtype __un= used,
=C2=A0 =C2=A0 struct thread *td __unused)
{
=C2=A0 =C2=A0 =C2=A0 =C2=A0 int error =3D 0;

=C2=A0 =C2=A0 =C2=A0 =C2=A0 uprintf("Opened device \"rolld\"= successfully.\n");
=C2=A0 =C2=A0 =C2=A0 =C2=A0 return (error);
}

static int
rolld_close(struct cdev *dev __unused, int fflag __unused, int devtype __un= used,
=C2=A0 =C2=A0 struct thread *td __unused)
{
=C2=A0 =C2=A0 =C2=A0 =C2=A0 uprintf("Closing device \"rolld\"= ;.\n");
=C2=A0 =C2=A0 =C2=A0 =C2=A0 return (0);
}

static int
rolld_read(struct cdev *dev __unused, struct uio *uio, int ioflag __unused)=
{
=C2=A0 =C2=A0 =C2=A0 =C2=A0 uint32_t random_out;
=C2=A0 =C2=A0 =C2=A0 =C2=A0 uint32_t random_item;
=C2=A0 =C2=A0 =C2=A0 =C2=A0 int error;

=C2=A0 =C2=A0 =C2=A0 =C2=A0 random_item =3D arc4random();
=C2=A0 =C2=A0 =C2=A0 =C2=A0 random_out =3D random_item % d_size;

=C2=A0 =C2=A0 =C2=A0 =C2=A0 if ((error =3D uiomove(&random_out, 1, uio)= ) !=3D 0)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 uprintf("uiomo= ve failed!\n");

=C2=A0 =C2=A0 =C2=A0 =C2=A0 return (error);
}

DEV_MODULE(rolld, rolld_loader, NULL);

--00000000000036ce4a06157392a6--