Writing the device drivers for a machine can be either the easiest or the hardest part of a port, depending on how much documentation is available for the machine's hardware.
In BSD there is no strict definition of the role of a device driver, but in general a driver should do the very least necessary to interface to the hardware. The designer of a device driver (and, in fact, any kernel module) should ask himself what features of the driver belong in the kernel and which belong in a user program. Although this decision is easy for some programs ( e.g., X Windows or a serial port driver), some kernel modules have arguments for being in both places. For example, SL/IP (the Serial Line Internet Protocol) is implemented in the kernel in BSD, but one might ask whether all users should carry the weight of a module used only by a few people and that could be implemented almost as efficiently as a daemon. File systems, especially seldom used ones, could similarly be implemented as user-level daemons called by the kernel.
On the Macintosh, the video display is implemented as a bitmap and there is no hardware support for fonts. Our video driver (ITE) got quite large with support for fast font drawing, different font sizes, different video cards, different display sizes, VT220 emulation, mouse pointer, cut and paste, virtual terminals, scroll-back, etc. After a long argument among members of the team, it was finally decided that this driver, being similar in spirit to a windowing program, did not belong in the kernel. All the code (except the very basic support for a small font and VT220) was removed and put in a program called dt (for desktop), which users could run after having logged in. This gave users all the features they had when the code was in the kernel, and it allowed the code to be swapped out if necessary, to be configured at run-time, to be more easily developed and debugged, and to use more memory for its scroll-back pool. It was a clear win to move it out, although this was not so evident when it was first implemented in the kernel. Any addition to the kernel should be scrutinized and justified in order to avoid kernel bloat, because the speed gained by linking it in is rarely needed.
The following subsections are presented roughly in the order that their drivers should be written.