diff --git a/en_US.ISO8859-1/books/arch-handbook/driverbasics/chapter.sgml b/en_US.ISO8859-1/books/arch-handbook/driverbasics/chapter.sgml
index 29cf0a05cb..52d27534ad 100644
--- a/en_US.ISO8859-1/books/arch-handbook/driverbasics/chapter.sgml
+++ b/en_US.ISO8859-1/books/arch-handbook/driverbasics/chapter.sgml
@@ -1,362 +1,379 @@
-
- Writing FreeBSD Device Drivers
-
- This chapter was written by Murray Stokely with selections from
- a variety of sources including the intro(4) man page by Joerg
- Wunsch.
-
-
- Introduction
-
- This chapter provides a brief introduction to writing device
- drivers for FreeBSD. A device in this context is a term used
- mostly for hardware-related stuff that belongs to the system,
- like disks, printers, or a graphics display with its keyboard.
- A device driver is the software component of the operating
- system that controls a specific device. There are also
- so-called pseudo-devices where a device driver emulates the
- behaviour of a device in software without any particular
- underlying hardware. Device drivers can be compiled into the
- system statically or loaded on demand through the dynamic
- kernel linker facility `kld'.
-
- Most devices in a Unix-like operating system are
- accessed through device-nodes, sometimes also called special
- files. These files are usually located under the directory
- /dev in the file system hierarchy. Until
- devfs is fully integrated into FreeBSD, each device node must
- be created statically and independent of the existence of the
- associated device driver. Most device nodes on the system are
- created by running MAKEDEV.
-
- Device drivers can roughly be broken down into two
- categories; character and network device drivers.
-
-
-
- Dynamic Kernel Linker Facility - KLD
- The kld interface allows system administrators to
- dynamically add and remove functionality from a running
- system. This allows device driver writers to load their new
- changes into a running kernel without constantly rebooting to
- test changes.
-
- The kld interface is used through the following
- administrator commands :
-
- kldload - loads a new kernel
+
+ Writing FreeBSD Device Drivers
+
+ This chapter was written by &.murray with selections
+ from a variety of sources including the intro(4) man page by Joerg
+ Wunsch.
+
+
+ Introduction
+ This chapter provides a brief introduction to writing device
+ drivers for FreeBSD. A device in this context is a term used
+ mostly for hardware-related stuff that belongs to the system,
+ like disks, printers, or a graphics display with its keyboard.
+ A device driver is the software component of the operating
+ system that controls a specific device. There are also
+ so-called pseudo-devices where a device driver emulates the
+ behaviour of a device in software without any particular
+ underlying hardware. Device drivers can be compiled into the
+ system statically or loaded on demand through the dynamic kernel
+ linker facility `kld'.
+
+ Most devices in a Unix-like operating system are accessed
+ through device-nodes, sometimes also called special files.
+ These files are usually located under the directory
+ /dev in the file system hierarchy. Until
+ devfs is fully integrated into FreeBSD, each device node must be
+ created statically and independent of the existence of the
+ associated device driver. Most device nodes on the system are
+ created by running MAKEDEV.
+
+ Device drivers can roughly be broken down into two
+ categories; character and network device drivers.
+
+
+
+
+ Dynamic Kernel Linker Facility - KLD
+
+ The kld interface allows system administrators to
+ dynamically add and remove functionality from a running system.
+ This allows device driver writers to load their new changes into
+ a running kernel without constantly rebooting to test
+ changes.
+
+ The kld interface is used through the following
+ administrator commands :
+
+
+ kldload - loads a new kernel
module
- kldunload - unloads a kernel
+ kldunload - unloads a kernel
module
- kldstat - lists the currently loadded
+ kldstat - lists the currently loadded
modules
-
-
+
+
+
+ Skeleton Layout of a kernel module
- Skeleton Layout of a kernel module
/*
* KLD Skeleton
* Inspired by Andrew Reiter's Daemonnews article
*/
#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 */
/*
* Load handler that deals with the loading and unloading of a KLD.
*/
static int
skel_loader(struct module *m, int what, void *arg)
{
int err = 0;
switch (what) {
case MOD_LOAD: /* kldload */
uprintf("Skeleton KLD loaded.\n");
break;
case MOD_UNLOAD:
uprintf("Skeleton KLD unloaded.\n");
break;
default:
err = EINVAL;
break;
}
return(err);
}
/* Declare this module to the rest of the kernel */
DECLARE_MODULE(skeleton, skel_loader, SI_SUB_KLD, SI_ORDER_ANY);
-
- Makefile
- FreeBSD provides a makefile include that you can use
- to quickly compile your kernel addition.
- SRCS=skeleton.c
+
+ Makefile
+
+ FreeBSD provides a makefile include that you can use to
+ quickly compile your kernel addition.
+
+ SRCS=skeleton.c
KMOD=skeleton
.include <bsd.kmod.mk>
-
- Simply running make with
- this makefile will create a file
- skeleton.ko that can be loaded into
- your system by typing :
-
-&prompt.root kldload -v ./skeleton.ko
+ Simply running make with this makefile
+ will create a file skeleton.ko that can
+ be loaded into your system by typing :
+ &prompt.root
+ kldload -v ./skeleton.ko
-
-
-
-
-
- Accessing a device driver
- Unix provides a common set of system calls for user
- applications to use. The upper layers of the kernel dispatch
- these calls to the corresponding device driver when a user
- accesses a device node. The /dev/MAKEDEV
- script makes most of the device nodes for your system but if
- you are doing your own driver development it may be necessary
- to create your own device nodes with mknod
-
-
-
- Creating static device nodes
- The mknod command requires four
- arguments to create a device node. You must specify the
- name of this device node, the type of device, the major number
- of the device, and the minor number of the device.
-
-
-
- Dynamic device nodes
- The device filesystem, or devfs, provides access to the
+
+
+
+
+
+ Accessing a device driver
+
+ Unix provides a common set of system calls for user
+ applications to use. The upper layers of the kernel dispatch
+ these calls to the corresponding device driver when a user
+ accesses a device node. The /dev/MAKEDEV
+ script makes most of the device nodes for your system but if you
+ are doing your own driver development it may be necessary to
+ create your own device nodes with mknod
+
+
+
+ Creating static device nodes
+
+ The mknod command requires four
+ arguments to create a device node. You must specify the name
+ of this device node, the type of device, the major number of
+ the device, and the minor number of the device.
+
+
+
+ Dynamic device nodes
+
+ The device filesystem, or devfs, provides access to the
kernel's device namespace in the global filesystem namespace.
This eliminates the problems of potentially having a device
driver without a static device node, or a device node without
- an installed device driver. Devfs is still a work in progress,
- but it is already working quite nice.
-
-
-
-
-
- Character Devices
- A character device driver is one that transfers data
- directly to and from a user process. This is the most common
- type of device driver and there are plenty of simple examples
- in the source tree.
- 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.
+ an installed device driver. Devfs is still a work in
+ progress, but it is already working quite nice.
+
+
+
+
+
+ Character Devices
+
+ A character device driver is one that transfers data
+ directly to and from a user process. This is the most common
+ type of device driver and there are plenty of simple examples in
+ the source tree.
+
+ 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.
+
/*
* Simple `echo' pseudo-device KLD
*
* Murray Stokely
*/
#define MIN(a,b) (((a) < (b)) ? (a) : (b))
#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
/* Function prototypes */
d_open_t echo_open;
d_close_t echo_close;
d_read_t echo_read;
d_write_t echo_write;
/* Character device entry points */
static struct cdevsw echo_cdevsw = {
echo_open,
echo_close,
echo_read,
echo_write,
noioctl,
nopoll,
nommap,
nostrategy,
"echo",
33, /* reserved for lkms - /usr/src/sys/conf/majors */
nodump,
nopsize,
D_TTY,
-1
};
typedef struct s_echo {
char msg[BUFFERSIZE];
int len;
} t_echo;
/* vars */
static dev_t sdev;
static int len;
static int count;
static t_echo *echomsg;
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 */
sdev = 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(sdev);
FREE(echomsg,M_ECHOBUF);
printf("Echo device unloaded.\n");
break;
default:
err = EINVAL;
break;
}
return(err);
}
int
echo_open(dev_t dev, int oflags, int devtype, struct proc *p)
{
int err = 0;
uprintf("Opened device \"echo\" successfully.\n");
return(err);
}
int
echo_close(dev_t dev, int fflag, int devtype, struct proc *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)
*/
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.
*/
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 */
*(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 :
+ To install this driver you will first need to make a node on
+ your filesystem with a command such as :
+
&prompt.root mknod /dev/echo c 33 0
-With this driver loaded you should now be able to type something
- like :
+
+ With this driver loaded you should now be able to type
+ something like :
+
&prompt.root echo -n "Test Data" > /dev/echo
&prompt.root cat /dev/echo
Test Data
- Real hardware devices in the next chapter..
- Additional Resources
-
- Real hardware devices in the next chapter..
+
+ Additional Resources
+
+ Dynamic
Kernel Linker (KLD) Facility Programming Tutorial -
Daemonnews October 2000
- How
to Write Kernel Drivers with NEWBUS - Daemonnews July
2000
-
-
-
-
-
- Network Drivers
- Drivers for network devices do not use device nodes in
- ord to be accessed. Their selection is based on other
- decisions made inside the kernel and instead of calling
- open(), use of a network device is generally introduced by
- using the system call socket(2).
- man ifnet(), loopback device, Bill Pauls drivers, etc..
-
-
-
+
+
+
+
+
+ Network Drivers
+
+ Drivers for network devices do not use device nodes in order
+ to be accessed. Their selection is based on other decisions
+ made inside the kernel and instead of calling open(), use of a
+ network device is generally introduced by using the system call
+ socket(2).
+
+ man ifnet(), loopback device, Bill Paul's drivers,
+ etc..
+
+
+
+
diff --git a/en_US.ISO8859-1/books/developers-handbook/driverbasics/chapter.sgml b/en_US.ISO8859-1/books/developers-handbook/driverbasics/chapter.sgml
index 29cf0a05cb..52d27534ad 100644
--- a/en_US.ISO8859-1/books/developers-handbook/driverbasics/chapter.sgml
+++ b/en_US.ISO8859-1/books/developers-handbook/driverbasics/chapter.sgml
@@ -1,362 +1,379 @@
-
- Writing FreeBSD Device Drivers
-
- This chapter was written by Murray Stokely with selections from
- a variety of sources including the intro(4) man page by Joerg
- Wunsch.
-
-
- Introduction
-
- This chapter provides a brief introduction to writing device
- drivers for FreeBSD. A device in this context is a term used
- mostly for hardware-related stuff that belongs to the system,
- like disks, printers, or a graphics display with its keyboard.
- A device driver is the software component of the operating
- system that controls a specific device. There are also
- so-called pseudo-devices where a device driver emulates the
- behaviour of a device in software without any particular
- underlying hardware. Device drivers can be compiled into the
- system statically or loaded on demand through the dynamic
- kernel linker facility `kld'.
-
- Most devices in a Unix-like operating system are
- accessed through device-nodes, sometimes also called special
- files. These files are usually located under the directory
- /dev in the file system hierarchy. Until
- devfs is fully integrated into FreeBSD, each device node must
- be created statically and independent of the existence of the
- associated device driver. Most device nodes on the system are
- created by running MAKEDEV.
-
- Device drivers can roughly be broken down into two
- categories; character and network device drivers.
-
-
-
- Dynamic Kernel Linker Facility - KLD
- The kld interface allows system administrators to
- dynamically add and remove functionality from a running
- system. This allows device driver writers to load their new
- changes into a running kernel without constantly rebooting to
- test changes.
-
- The kld interface is used through the following
- administrator commands :
-
- kldload - loads a new kernel
+
+ Writing FreeBSD Device Drivers
+
+ This chapter was written by &.murray with selections
+ from a variety of sources including the intro(4) man page by Joerg
+ Wunsch.
+
+
+ Introduction
+ This chapter provides a brief introduction to writing device
+ drivers for FreeBSD. A device in this context is a term used
+ mostly for hardware-related stuff that belongs to the system,
+ like disks, printers, or a graphics display with its keyboard.
+ A device driver is the software component of the operating
+ system that controls a specific device. There are also
+ so-called pseudo-devices where a device driver emulates the
+ behaviour of a device in software without any particular
+ underlying hardware. Device drivers can be compiled into the
+ system statically or loaded on demand through the dynamic kernel
+ linker facility `kld'.
+
+ Most devices in a Unix-like operating system are accessed
+ through device-nodes, sometimes also called special files.
+ These files are usually located under the directory
+ /dev in the file system hierarchy. Until
+ devfs is fully integrated into FreeBSD, each device node must be
+ created statically and independent of the existence of the
+ associated device driver. Most device nodes on the system are
+ created by running MAKEDEV.
+
+ Device drivers can roughly be broken down into two
+ categories; character and network device drivers.
+
+
+
+
+ Dynamic Kernel Linker Facility - KLD
+
+ The kld interface allows system administrators to
+ dynamically add and remove functionality from a running system.
+ This allows device driver writers to load their new changes into
+ a running kernel without constantly rebooting to test
+ changes.
+
+ The kld interface is used through the following
+ administrator commands :
+
+
+ kldload - loads a new kernel
module
- kldunload - unloads a kernel
+ kldunload - unloads a kernel
module
- kldstat - lists the currently loadded
+ kldstat - lists the currently loadded
modules
-
-
+
+
+
+ Skeleton Layout of a kernel module
- Skeleton Layout of a kernel module
/*
* KLD Skeleton
* Inspired by Andrew Reiter's Daemonnews article
*/
#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 */
/*
* Load handler that deals with the loading and unloading of a KLD.
*/
static int
skel_loader(struct module *m, int what, void *arg)
{
int err = 0;
switch (what) {
case MOD_LOAD: /* kldload */
uprintf("Skeleton KLD loaded.\n");
break;
case MOD_UNLOAD:
uprintf("Skeleton KLD unloaded.\n");
break;
default:
err = EINVAL;
break;
}
return(err);
}
/* Declare this module to the rest of the kernel */
DECLARE_MODULE(skeleton, skel_loader, SI_SUB_KLD, SI_ORDER_ANY);
-
- Makefile
- FreeBSD provides a makefile include that you can use
- to quickly compile your kernel addition.
- SRCS=skeleton.c
+
+ Makefile
+
+ FreeBSD provides a makefile include that you can use to
+ quickly compile your kernel addition.
+
+ SRCS=skeleton.c
KMOD=skeleton
.include <bsd.kmod.mk>
-
- Simply running make with
- this makefile will create a file
- skeleton.ko that can be loaded into
- your system by typing :
-
-&prompt.root kldload -v ./skeleton.ko
+ Simply running make with this makefile
+ will create a file skeleton.ko that can
+ be loaded into your system by typing :
+ &prompt.root
+ kldload -v ./skeleton.ko
-
-
-
-
-
- Accessing a device driver
- Unix provides a common set of system calls for user
- applications to use. The upper layers of the kernel dispatch
- these calls to the corresponding device driver when a user
- accesses a device node. The /dev/MAKEDEV
- script makes most of the device nodes for your system but if
- you are doing your own driver development it may be necessary
- to create your own device nodes with mknod
-
-
-
- Creating static device nodes
- The mknod command requires four
- arguments to create a device node. You must specify the
- name of this device node, the type of device, the major number
- of the device, and the minor number of the device.
-
-
-
- Dynamic device nodes
- The device filesystem, or devfs, provides access to the
+
+
+
+
+
+ Accessing a device driver
+
+ Unix provides a common set of system calls for user
+ applications to use. The upper layers of the kernel dispatch
+ these calls to the corresponding device driver when a user
+ accesses a device node. The /dev/MAKEDEV
+ script makes most of the device nodes for your system but if you
+ are doing your own driver development it may be necessary to
+ create your own device nodes with mknod
+
+
+
+ Creating static device nodes
+
+ The mknod command requires four
+ arguments to create a device node. You must specify the name
+ of this device node, the type of device, the major number of
+ the device, and the minor number of the device.
+
+
+
+ Dynamic device nodes
+
+ The device filesystem, or devfs, provides access to the
kernel's device namespace in the global filesystem namespace.
This eliminates the problems of potentially having a device
driver without a static device node, or a device node without
- an installed device driver. Devfs is still a work in progress,
- but it is already working quite nice.
-
-
-
-
-
- Character Devices
- A character device driver is one that transfers data
- directly to and from a user process. This is the most common
- type of device driver and there are plenty of simple examples
- in the source tree.
- 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.
+ an installed device driver. Devfs is still a work in
+ progress, but it is already working quite nice.
+
+
+
+
+
+ Character Devices
+
+ A character device driver is one that transfers data
+ directly to and from a user process. This is the most common
+ type of device driver and there are plenty of simple examples in
+ the source tree.
+
+ 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.
+
/*
* Simple `echo' pseudo-device KLD
*
* Murray Stokely
*/
#define MIN(a,b) (((a) < (b)) ? (a) : (b))
#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
/* Function prototypes */
d_open_t echo_open;
d_close_t echo_close;
d_read_t echo_read;
d_write_t echo_write;
/* Character device entry points */
static struct cdevsw echo_cdevsw = {
echo_open,
echo_close,
echo_read,
echo_write,
noioctl,
nopoll,
nommap,
nostrategy,
"echo",
33, /* reserved for lkms - /usr/src/sys/conf/majors */
nodump,
nopsize,
D_TTY,
-1
};
typedef struct s_echo {
char msg[BUFFERSIZE];
int len;
} t_echo;
/* vars */
static dev_t sdev;
static int len;
static int count;
static t_echo *echomsg;
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 */
sdev = 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(sdev);
FREE(echomsg,M_ECHOBUF);
printf("Echo device unloaded.\n");
break;
default:
err = EINVAL;
break;
}
return(err);
}
int
echo_open(dev_t dev, int oflags, int devtype, struct proc *p)
{
int err = 0;
uprintf("Opened device \"echo\" successfully.\n");
return(err);
}
int
echo_close(dev_t dev, int fflag, int devtype, struct proc *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)
*/
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.
*/
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 */
*(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 :
+ To install this driver you will first need to make a node on
+ your filesystem with a command such as :
+
&prompt.root mknod /dev/echo c 33 0
-With this driver loaded you should now be able to type something
- like :
+
+ With this driver loaded you should now be able to type
+ something like :
+
&prompt.root echo -n "Test Data" > /dev/echo
&prompt.root cat /dev/echo
Test Data
- Real hardware devices in the next chapter..
- Additional Resources
-
- Real hardware devices in the next chapter..
+
+ Additional Resources
+
+ Dynamic
Kernel Linker (KLD) Facility Programming Tutorial -
Daemonnews October 2000
- How
to Write Kernel Drivers with NEWBUS - Daemonnews July
2000
-
-
-
-
-
- Network Drivers
- Drivers for network devices do not use device nodes in
- ord to be accessed. Their selection is based on other
- decisions made inside the kernel and instead of calling
- open(), use of a network device is generally introduced by
- using the system call socket(2).
- man ifnet(), loopback device, Bill Pauls drivers, etc..
-
-
-
+
+
+
+
+
+ Network Drivers
+
+ Drivers for network devices do not use device nodes in order
+ to be accessed. Their selection is based on other decisions
+ made inside the kernel and instead of calling open(), use of a
+ network device is generally introduced by using the system call
+ socket(2).
+
+ man ifnet(), loopback device, Bill Paul's drivers,
+ etc..
+
+
+
+
diff --git a/en_US.ISO_8859-1/books/developers-handbook/driverbasics/chapter.sgml b/en_US.ISO_8859-1/books/developers-handbook/driverbasics/chapter.sgml
index 29cf0a05cb..52d27534ad 100644
--- a/en_US.ISO_8859-1/books/developers-handbook/driverbasics/chapter.sgml
+++ b/en_US.ISO_8859-1/books/developers-handbook/driverbasics/chapter.sgml
@@ -1,362 +1,379 @@
-
- Writing FreeBSD Device Drivers
-
- This chapter was written by Murray Stokely with selections from
- a variety of sources including the intro(4) man page by Joerg
- Wunsch.
-
-
- Introduction
-
- This chapter provides a brief introduction to writing device
- drivers for FreeBSD. A device in this context is a term used
- mostly for hardware-related stuff that belongs to the system,
- like disks, printers, or a graphics display with its keyboard.
- A device driver is the software component of the operating
- system that controls a specific device. There are also
- so-called pseudo-devices where a device driver emulates the
- behaviour of a device in software without any particular
- underlying hardware. Device drivers can be compiled into the
- system statically or loaded on demand through the dynamic
- kernel linker facility `kld'.
-
- Most devices in a Unix-like operating system are
- accessed through device-nodes, sometimes also called special
- files. These files are usually located under the directory
- /dev in the file system hierarchy. Until
- devfs is fully integrated into FreeBSD, each device node must
- be created statically and independent of the existence of the
- associated device driver. Most device nodes on the system are
- created by running MAKEDEV.
-
- Device drivers can roughly be broken down into two
- categories; character and network device drivers.
-
-
-
- Dynamic Kernel Linker Facility - KLD
- The kld interface allows system administrators to
- dynamically add and remove functionality from a running
- system. This allows device driver writers to load their new
- changes into a running kernel without constantly rebooting to
- test changes.
-
- The kld interface is used through the following
- administrator commands :
-
- kldload - loads a new kernel
+
+ Writing FreeBSD Device Drivers
+
+ This chapter was written by &.murray with selections
+ from a variety of sources including the intro(4) man page by Joerg
+ Wunsch.
+
+
+ Introduction
+ This chapter provides a brief introduction to writing device
+ drivers for FreeBSD. A device in this context is a term used
+ mostly for hardware-related stuff that belongs to the system,
+ like disks, printers, or a graphics display with its keyboard.
+ A device driver is the software component of the operating
+ system that controls a specific device. There are also
+ so-called pseudo-devices where a device driver emulates the
+ behaviour of a device in software without any particular
+ underlying hardware. Device drivers can be compiled into the
+ system statically or loaded on demand through the dynamic kernel
+ linker facility `kld'.
+
+ Most devices in a Unix-like operating system are accessed
+ through device-nodes, sometimes also called special files.
+ These files are usually located under the directory
+ /dev in the file system hierarchy. Until
+ devfs is fully integrated into FreeBSD, each device node must be
+ created statically and independent of the existence of the
+ associated device driver. Most device nodes on the system are
+ created by running MAKEDEV.
+
+ Device drivers can roughly be broken down into two
+ categories; character and network device drivers.
+
+
+
+
+ Dynamic Kernel Linker Facility - KLD
+
+ The kld interface allows system administrators to
+ dynamically add and remove functionality from a running system.
+ This allows device driver writers to load their new changes into
+ a running kernel without constantly rebooting to test
+ changes.
+
+ The kld interface is used through the following
+ administrator commands :
+
+
+ kldload - loads a new kernel
module
- kldunload - unloads a kernel
+ kldunload - unloads a kernel
module
- kldstat - lists the currently loadded
+ kldstat - lists the currently loadded
modules
-
-
+
+
+
+ Skeleton Layout of a kernel module
- Skeleton Layout of a kernel module
/*
* KLD Skeleton
* Inspired by Andrew Reiter's Daemonnews article
*/
#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 */
/*
* Load handler that deals with the loading and unloading of a KLD.
*/
static int
skel_loader(struct module *m, int what, void *arg)
{
int err = 0;
switch (what) {
case MOD_LOAD: /* kldload */
uprintf("Skeleton KLD loaded.\n");
break;
case MOD_UNLOAD:
uprintf("Skeleton KLD unloaded.\n");
break;
default:
err = EINVAL;
break;
}
return(err);
}
/* Declare this module to the rest of the kernel */
DECLARE_MODULE(skeleton, skel_loader, SI_SUB_KLD, SI_ORDER_ANY);
-
- Makefile
- FreeBSD provides a makefile include that you can use
- to quickly compile your kernel addition.
- SRCS=skeleton.c
+
+ Makefile
+
+ FreeBSD provides a makefile include that you can use to
+ quickly compile your kernel addition.
+
+ SRCS=skeleton.c
KMOD=skeleton
.include <bsd.kmod.mk>
-
- Simply running make with
- this makefile will create a file
- skeleton.ko that can be loaded into
- your system by typing :
-
-&prompt.root kldload -v ./skeleton.ko
+ Simply running make with this makefile
+ will create a file skeleton.ko that can
+ be loaded into your system by typing :
+ &prompt.root
+ kldload -v ./skeleton.ko
-
-
-
-
-
- Accessing a device driver
- Unix provides a common set of system calls for user
- applications to use. The upper layers of the kernel dispatch
- these calls to the corresponding device driver when a user
- accesses a device node. The /dev/MAKEDEV
- script makes most of the device nodes for your system but if
- you are doing your own driver development it may be necessary
- to create your own device nodes with mknod
-
-
-
- Creating static device nodes
- The mknod command requires four
- arguments to create a device node. You must specify the
- name of this device node, the type of device, the major number
- of the device, and the minor number of the device.
-
-
-
- Dynamic device nodes
- The device filesystem, or devfs, provides access to the
+
+
+
+
+
+ Accessing a device driver
+
+ Unix provides a common set of system calls for user
+ applications to use. The upper layers of the kernel dispatch
+ these calls to the corresponding device driver when a user
+ accesses a device node. The /dev/MAKEDEV
+ script makes most of the device nodes for your system but if you
+ are doing your own driver development it may be necessary to
+ create your own device nodes with mknod
+
+
+
+ Creating static device nodes
+
+ The mknod command requires four
+ arguments to create a device node. You must specify the name
+ of this device node, the type of device, the major number of
+ the device, and the minor number of the device.
+
+
+
+ Dynamic device nodes
+
+ The device filesystem, or devfs, provides access to the
kernel's device namespace in the global filesystem namespace.
This eliminates the problems of potentially having a device
driver without a static device node, or a device node without
- an installed device driver. Devfs is still a work in progress,
- but it is already working quite nice.
-
-
-
-
-
- Character Devices
- A character device driver is one that transfers data
- directly to and from a user process. This is the most common
- type of device driver and there are plenty of simple examples
- in the source tree.
- 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.
+ an installed device driver. Devfs is still a work in
+ progress, but it is already working quite nice.
+
+
+
+
+
+ Character Devices
+
+ A character device driver is one that transfers data
+ directly to and from a user process. This is the most common
+ type of device driver and there are plenty of simple examples in
+ the source tree.
+
+ 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.
+
/*
* Simple `echo' pseudo-device KLD
*
* Murray Stokely
*/
#define MIN(a,b) (((a) < (b)) ? (a) : (b))
#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
/* Function prototypes */
d_open_t echo_open;
d_close_t echo_close;
d_read_t echo_read;
d_write_t echo_write;
/* Character device entry points */
static struct cdevsw echo_cdevsw = {
echo_open,
echo_close,
echo_read,
echo_write,
noioctl,
nopoll,
nommap,
nostrategy,
"echo",
33, /* reserved for lkms - /usr/src/sys/conf/majors */
nodump,
nopsize,
D_TTY,
-1
};
typedef struct s_echo {
char msg[BUFFERSIZE];
int len;
} t_echo;
/* vars */
static dev_t sdev;
static int len;
static int count;
static t_echo *echomsg;
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 */
sdev = 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(sdev);
FREE(echomsg,M_ECHOBUF);
printf("Echo device unloaded.\n");
break;
default:
err = EINVAL;
break;
}
return(err);
}
int
echo_open(dev_t dev, int oflags, int devtype, struct proc *p)
{
int err = 0;
uprintf("Opened device \"echo\" successfully.\n");
return(err);
}
int
echo_close(dev_t dev, int fflag, int devtype, struct proc *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)
*/
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.
*/
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 */
*(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 :
+ To install this driver you will first need to make a node on
+ your filesystem with a command such as :
+
&prompt.root mknod /dev/echo c 33 0
-With this driver loaded you should now be able to type something
- like :
+
+ With this driver loaded you should now be able to type
+ something like :
+
&prompt.root echo -n "Test Data" > /dev/echo
&prompt.root cat /dev/echo
Test Data
- Real hardware devices in the next chapter..
- Additional Resources
-
- Real hardware devices in the next chapter..
+
+ Additional Resources
+
+ Dynamic
Kernel Linker (KLD) Facility Programming Tutorial -
Daemonnews October 2000
- How
to Write Kernel Drivers with NEWBUS - Daemonnews July
2000
-
-
-
-
-
- Network Drivers
- Drivers for network devices do not use device nodes in
- ord to be accessed. Their selection is based on other
- decisions made inside the kernel and instead of calling
- open(), use of a network device is generally introduced by
- using the system call socket(2).
- man ifnet(), loopback device, Bill Pauls drivers, etc..
-
-
-
+
+
+
+
+
+ Network Drivers
+
+ Drivers for network devices do not use device nodes in order
+ to be accessed. Their selection is based on other decisions
+ made inside the kernel and instead of calling open(), use of a
+ network device is generally introduced by using the system call
+ socket(2).
+
+ man ifnet(), loopback device, Bill Paul's drivers,
+ etc..
+
+
+
+