- add example FreeBSD 5.X driver submitted by S<F8>ren (Xride) Straarup
(driver tested on i386 and sparc64 platforms) - minor formatting fixes (add <example></example>) - minor spelling/grammar fixes Approved: blackend (mentor)
This commit is contained in:
parent
0a49fed78d
commit
c6674adc3d
Notes:
svn2git
2020-12-08 03:00:23 +00:00
svn path=/head/; revision=18238
1 changed files with 167 additions and 4 deletions
|
@ -174,7 +174,12 @@ KMOD=skeleton
|
|||
|
||||
<para>This simple example pseudo-device remembers whatever values
|
||||
you write to it and can then supply them back to you when you
|
||||
read from it.</para>
|
||||
read from it. Two versions are shown, one for &os; 4.X and
|
||||
one for &os; 5.X.</para>
|
||||
|
||||
<example>
|
||||
<title>Example of a Sample Echo Pseudo-Device Driver for
|
||||
&os; 4.X</title>
|
||||
|
||||
<programlisting>/*
|
||||
* Simple `echo' pseudo-device KLD
|
||||
|
@ -334,9 +339,167 @@ echo_write(dev_t dev, struct uio *uio, int ioflag)
|
|||
}
|
||||
|
||||
DEV_MODULE(echo,echo_loader,NULL);</programlisting>
|
||||
</example>
|
||||
|
||||
<para>To install this driver you will first need to make a node on
|
||||
your filesystem with a command such as:</para>
|
||||
<example>
|
||||
<title>Example of a Sample Echo Pseudo-Device Driver for
|
||||
&os; 5.X</title>
|
||||
|
||||
<programlisting>/*
|
||||
* Simple `echo' pseudo-device KLD
|
||||
*
|
||||
* Murray Stokely
|
||||
*
|
||||
* Converted to 5.X by Sø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;
|
||||
|
||||
MALLOC_DECLARE(M_ECHOBUF);
|
||||
MALLOC_DEFINE(M_ECHOBUF, "echobuffer", "buffer for echo module");
|
||||
|
||||
/*
|
||||
* This function 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(<literal>&</literal>echo_cdevsw,
|
||||
0,
|
||||
UID_ROOT,
|
||||
GID_WHEEL,
|
||||
0600,
|
||||
"echo");
|
||||
/* kmalloc memory for use by this driver */
|
||||
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->len - 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_len,BUFFERSIZE));
|
||||
|
||||
/* Now we need to null terminate, then record the length */
|
||||
*(echomsg->msg + MIN(uio->uio_iov->iov_len,BUFFERSIZE)) = 0;
|
||||
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);</programlisting>
|
||||
</example>
|
||||
|
||||
<para>To install this driver on &os; 4.X you will first need to
|
||||
make a node on your filesystem with a command such as:</para>
|
||||
|
||||
<screen>&prompt.root; <userinput>mknod /dev/echo c 33 0</userinput></screen>
|
||||
|
||||
|
@ -347,7 +510,7 @@ DEV_MODULE(echo,echo_loader,NULL);</programlisting>
|
|||
&prompt.root; <userinput>cat /dev/echo</userinput>
|
||||
Test Data</screen>
|
||||
|
||||
<para>Real hardware devices in the next chapter..</para>
|
||||
<para>Real hardware devices are described in the next chapter.</para>
|
||||
|
||||
<para>Additional Resources
|
||||
<itemizedlist>
|
||||
|
|
Loading…
Reference in a new issue