From owner-freebsd-doc@FreeBSD.ORG Mon Aug 18 05:40:17 2003 Return-Path: Delivered-To: freebsd-doc@hub.freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 982CA37B404 for ; Mon, 18 Aug 2003 05:40:17 -0700 (PDT) Received: from freefall.freebsd.org (freefall.freebsd.org [216.136.204.21]) by mx1.FreeBSD.org (Postfix) with ESMTP id 7890443FA3 for ; Mon, 18 Aug 2003 05:40:16 -0700 (PDT) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (gnats@localhost [127.0.0.1]) by freefall.freebsd.org (8.12.9/8.12.9) with ESMTP id h7ICeGUp098788 for ; Mon, 18 Aug 2003 05:40:16 -0700 (PDT) (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.12.9/8.12.9/Submit) id h7ICeGTw098787; Mon, 18 Aug 2003 05:40:16 -0700 (PDT) Resent-Date: Mon, 18 Aug 2003 05:40:16 -0700 (PDT) Resent-Message-Id: <200308181240.h7ICeGTw098787@freefall.freebsd.org> Resent-From: FreeBSD-gnats-submit@FreeBSD.org (GNATS Filer) Resent-To: freebsd-doc@FreeBSD.org Resent-Reply-To: FreeBSD-gnats-submit@FreeBSD.org, Søren Straarup Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 321EE37B401 for ; Mon, 18 Aug 2003 05:32:52 -0700 (PDT) Received: from x12.dk (xforce.dk [80.164.11.218]) by mx1.FreeBSD.org (Postfix) with ESMTP id B61E443FAF for ; Mon, 18 Aug 2003 05:32:50 -0700 (PDT) (envelope-from xride@x12.dk) Received: from x12.dk (xride@localhost [127.0.0.1]) by x12.dk (8.12.9/8.12.9) with ESMTP id h7ICWm3Y095525 for ; Mon, 18 Aug 2003 14:32:48 +0200 (CEST) (envelope-from xride@x12.dk) Received: (from xride@localhost) by x12.dk (8.12.9/8.12.9/Submit) id h7ICWmgm095524; Mon, 18 Aug 2003 14:32:48 +0200 (CEST) Message-Id: <200308181232.h7ICWmgm095524@x12.dk> Date: Mon, 18 Aug 2003 14:32:48 +0200 (CEST) From: Søren Straarup To: FreeBSD-gnats-submit@FreeBSD.org X-Send-Pr-Version: 3.113 Subject: docs/55693: Howto make a kernel module for a pseudo-device under 5.X X-BeenThere: freebsd-doc@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list Reply-To: Søren Straarup List-Id: Documentation project List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 18 Aug 2003 12:40:18 -0000 >Number: 55693 >Category: docs >Synopsis: Howto make a kernel module for a pseudo-device under 5.X >Confidential: no >Severity: serious >Priority: low >Responsible: freebsd-doc >State: open >Quarter: >Keywords: >Date-Required: >Class: update >Submitter-Id: current-users >Arrival-Date: Mon Aug 18 05:40:15 PDT 2003 >Closed-Date: >Last-Modified: >Originator: Xride >Release: FreeBSD 5.1-CURRENT i386 >Organization: >Environment: Changed the pseudo-device kernel module code, from the arch-handbook, so it will work under 5.X. --- chapter.diff begins here --- --- /usr/doc/en_US.ISO8859-1/books/arch-handbook/driverbasics/chapter.sgml Thu Aug 7 01:48:02 2003 +++ chapter.sgml Mon Aug 18 13:42:46 2003 @@ -335,6 +335,168 @@ DEV_MODULE(echo,echo_loader,NULL); + For the 5.X serie this is how the code for the pseudo-device + should look: + +/* + * Simple `echo' pseudo-device KLD + * + * Murray Stokely + */ + +/* + * Conveted to 5.X by S&oring;ren (Xride) Straarup + */ + + +#include <sys/types.h> +#include <sys/module.h> +#include <sys/systm.h> /* uprintf */ +#include <sys/errno.h> +#include <sys/param.h> /* defines used in kernel.h */ +#include <sys/kernel.h> /* types used in module initialization */ +#include <sys/conf.h> /* cdevsw struct */ +#include <sys/uio.h> /* uio struct */ +#include <sys/malloc.h> + +#define BUFFERSIZE 256 +#define CDEV_MAJOR 33 + +/* Function prototypes */ +static d_open_t echo_open; +static d_close_t echo_close; +static d_read_t echo_read; +static d_write_t echo_write; + +/* Character device entry points */ +static struct cdevsw echo_cdevsw = { + .d_open = echo_open, + .d_close = echo_close, + .d_maj = CDEV_MAJOR, + .d_name = "echo", + .d_read = echo_read, + .d_write = echo_write +}; + +typedef struct s_echo { + char msg[BUFFERSIZE]; + int len; +} t_echo; + +/* vars */ +static dev_t echo_dev; +static int count; +static t_echo *echomsg; +static int len; + + +MALLOC_DECLARE(M_ECHOBUF); +MALLOC_DEFINE(M_ECHOBUF, "echobuffer", "buffer for echo module"); + +/* + * This function acts is called by the kld[un]load(2) system calls to + * determine what actions to take when a module is loaded or unloaded. + */ + +static int +echo_loader(struct module *m, int what, void *arg) +{ + int err = 0; + + switch (what) { + case MOD_LOAD: /* kldload */ + echo_dev = make_dev(&echo_cdevsw, + 0, + UID_ROOT, + GID_WHEEL, + 0600, + "echo"); + /* kmalloc memory for use by this driver */ + /* malloc(256,M_ECHOBUF,M_WAITOK); */ + MALLOC(echomsg, t_echo *, sizeof(t_echo), M_ECHOBUF, M_WAITOK); + printf("Echo device loaded.\n"); + break; + case MOD_UNLOAD: + destroy_dev(echo_dev); + FREE(echomsg,M_ECHOBUF); + printf("Echo device unloaded.\n"); + break; + default: + err = EINVAL; + break; + } + return(err); +} + +static int +echo_open(dev_t dev, int oflags, int devtype, struct thread *p) +{ + int err = 0; + + uprintf("Opened device \"echo\" successfully.\n"); + return(err); +} + +static int +echo_close(dev_t dev, int fflag, int devtype, struct thread *p) +{ + uprintf("Closing device \"echo.\"\n"); + return(0); +} + +/* + * The read function just takes the buf that was saved via + * echo_write() and returns it to userland for accessing. + * uio(9) + */ + +static int +echo_read(dev_t dev, struct uio *uio, int ioflag) +{ + int err = 0; + int amt; + + /* How big is this read operation? Either as big as the user wants, + or as big as the remaining data */ + amt = MIN(uio->uio_resid, (echomsg->len - uio->uio_offset > 0) ? echomsg->l +en - uio->uio_offset : 0); + if ((err = uiomove(echomsg->msg + uio->uio_offset,amt,uio)) != 0) { + uprintf("uiomove failed!\n"); + } + + return err; +} + +/* + * echo_write takes in a character string and saves it + * to buf for later accessing. + */ + +static int +echo_write(dev_t dev, struct uio *uio, int ioflag) +{ + int err = 0; + + /* Copy the string in from user memory to kernel memory */ + err = copyin(uio->uio_iov->iov_base, echomsg->msg, MIN(uio->uio_iov->iov_le +n,BUFFERSIZE)); + + /* Now we need to null terminate */ + *(echomsg->msg + MIN(uio->uio_iov->iov_len,BUFFERSIZE)) = 0; + /* Record the length */ + echomsg->len = MIN(uio->uio_iov->iov_len,BUFFERSIZE); + + if (err != 0) { + uprintf("Write failed: bad address!\n"); + } + + count++; + return(err); +} + +DEV_MODULE(echo,echo_loader,NULL); + + To install this driver you will first need to make a node on your filesystem with a command such as: --- chapter.diff ends here --- >Description: >How-To-Repeat: >Fix: >Release-Note: >Audit-Trail: >Unformatted: