draft 1, 20061206, <email@example.com>
Information for 3rd party hardware driver vendors
Overview and general information
The FreeBSD development model is quite different from the Linux development model but highly structured and produces very reliable results. This document provides an overview of the FreeBSD development model and a guideline for 3rd party hardware driver vendors to work with and to tell what to expect along the process.
FreeBSD teams, src ports doc
FreeBSD has a 'centralized' development model with a central CVS(1) based source code repository for the entire kernel and userland. From this repository all releases are created. While everyone has read access to it through the cvsup(1), anonymous cvs and cvsweb mechanisms only a defined set of devlopers have write access. These devlopers are called 'committers'. The committers are split into three groups; SRC for kernel and native userland code, PORTS for pre-packaged ports of various application packages and DOC for documentation writers. At the time of writing the groups have about X members. Within each group a further level of area expertise and specialization exists on a informal level. It is considered rude to make changes to a part that is not one own's special area of expertise without first consulting someone from the other area. In general all development happens based on consensus within one areas developers. For (very seldom) cases of deadlock the elected core team reaches out to all involved parties and brokers a compromise or reaches ultimately a final decision. The basic premise is always that all changes and system architecture are only based on their technical merits. However presenting actual and working code speaks louder than pure ideas.
A 3rd party hardware driver vendor is most likely to come into contact with the kernel developers of the SRC team first to sort out technical details. Later on the DOC and, depending on hardware associated software packages, the PORTS team.
fancy illustration here XXXX
FreeBSD release structure and policy
FreeBSD is a kernel and a matching userland application suite combined into a regular and predictable release schedule. Unlike Linux with its various distributions there is only one FreeBSD. If someone is talking about FreeBSD XYZ there is exactly one matching code base, not two or three nor any variants thereof.
FreeBSD releases are split into major and minor releases. Major releases are cut from the main development trunk every 24 month and contain all new features integrated into the system since the last major release. Minor releases are made within the same trunk as the last major release and are called STABLE releases. They contain stability improvements, bug fixes, additional hardware support and other enhancements. Paramount for the minor releases (== STABLE trunk) is stability, reliability and API/ABI compatiblity. That means a application binary or kernel module developed and compiled for a major release will continue to work on all subsequent minor releases from the same trunk. However the reverse is not true and within a trunk only forward compatibility is guaranteed but not backwards compatibility. No compatibility for API and ABI is guaranteed from one to the next major release, though an effort is made to make the upgrade process and source code changes as untroubled as possible.
Which release train to write a driver for
New features and drivers are always introduced into the main development trunk from which the next major release will be taken. This serves the purpose to have new code up to date and to provide a shakeout period to find bugs and possible problematic interactions with the rest of the system. After a certain period and sufficent proven stability new features and drivers get backported to currently active major release trunk to appear in the next minor release.
Only one major release is active at a time with a certain transition period between major releases. Once the transition to a new major release has been made the activity level on the last major release trunk goes down and no further minor releases are planned. However it continues to be supported for security and certain stability fixes for another two years since the last minor release. All major releases have clearly specified life cycles and EOL dates for planning.
3rd party drivers license and legal issues
FreeBSD itself is licensed under the BSDL with many parts under the even less restrictive modified 3 or 2-clause BSD licenses. A great effort is made to keep all parts of the kernel and base system fully under the BSD license. Deviations of this policy are not possible. The FreeBSD distribution comes with some components that are under other licenses, particularly the GPL, but such components can not be critical to the system. In other words, they must not be required if one were to want to distribute a binary working system, and components that are released under licenses incompatible with that goal will probably not be used by users wanting to make such systems.
open source drivers
Open source hardware drivers for inclusion into FreeBSD can be provided with almost any license. It is however adviseable to chose one of the OSI approved licenses instead of inventing a new one. OSI has a suitable license for almost any circumstances of a open source operating system. Chosing a well known and popular open source license heavily cuts down the legal costs of all involved parties. For the rules of inclusion into official FreeBSD releases see <later> in this chapter.
A BSD licensed open source hardware driver is the most preferred method as it ensures the broadest useability and availability for the driver and owners of this supported hardware.
closed source drivers
If a vendor doesn't want to lay open the driver source code a pre-compiled binary module in the KLD(4) format can be provided.
Some hardware requires firmware that is loaded by the device driver. Firmware is usually provided in binary form without source code. FreeBSD provides a standard way for device drivers to load firmware files from the disk drives and boot media. For the rules of inclusion into official FreeBSD releases see <later> in this chapter.
click through licenses
Click through licenses for binary drivers and/or firmware are problematic as FreeBSD system are often used on server systems without any graphical user interface which makes the traditional click though process unworkable. It is preferred to avoid the use of click though licenses. However for cases where this requirement can't be waived the FreeBSD developers are working on a generic mechanism to provide a close functional equivalent. Please contact <xxx> for specific discussion of your case.
drivers to be distributed with official FreeBSD releases
Device drivers in any format, including firmware blobs, that should be included in the GENERIC kernel and installation CDROM must be under the BSD license as well. All device drivers that should be distributed with the FreeBSD releases must be under a license that allows free distribution and redistribution.
3rd party drivers technical issues
Compared to Linux FreeBSD is a much more comfortable kernel environment to write device drivers for. FreeBSD provides general bus probing routines for all devices and extensive kernel debugging support from the start. The device driver developer can focus on the core functionality of the device instead of writing a lot of basic support functionality.
work with a src committer specialized in that area
It is adviseable to get in touch very early on with one or more committers specialized in the area the device performs functions in. These committers have extensive experience in their area can provide a lot knowledge and tipps to ensure a quick, efficient and smooth start with a greatly shortned learning curve. In certain cases an already existing driver for a different but similiar device may be used as starting point or template requiring only a modest amount of changes and adaptions.
provide test hardware to one or more committers
Providing test hardware to committers is the best way to ensure rapid development and debugging of new device drivers. Committers are generally very willing to assist in writing device drivers for which hardware and adequate documentation is provided. Also potential problem and bugs can be discoverd and resolved much quicker with direct access to the hardware in question. Remote debugging without direct access is much harder and less efficient.
give source code and documentation access (even under NDA) to one or more committers
Having an experienced committer with the ability to look at the source code and hardware documentation is extremely valuable for the same reasons as <above>. Many committers are willing, in the case of binary drivers, to sign reasonable NDAs for the source code and documentation access.
the bus attachment and device probing system
The FreeBSD kernel provides a complete driver(9) device probing and bus attachment subsystem. All popular bus systems are directly supported, PCI, PCI-Express, Cardbus...
In general a device driver is created by declaring a DRIVER_MODULE(9) instance providing a set of probe, attach and detach methods. The DEVICE_PROBE(9) method gets called for every detected device for which the driver declared PCI IDs (through devclass(9)) match. The drivers probe function then can do further checking to ensure a supported hardware to return a match or mismatch status. Upon a match the DEVICE_ATTACH(9) method gets called which then allocates the proper kernel structures and initializes the hardware into an operational state. The DEVICE_SHUTDOWN(9) and DEVICE_DETACH(9) are used for removeable devices and certain power saving modes.
the bus_dma system
The bus_dma(9) system provides a platform independent way to access memory mapped regions and registers as well as for DMA transfers from/to devices. FreeBSD supports many different CPU architecturesl, generations and platforms with widely varying capabilities. The bus_dma framework makes all this transparent to the device driver developer. The device driver has to specifiy the constrains of the device in question and bus_dma will ensure that these constrains are met. Another major functionality of bus_dma is to ensure cache coherency between the CPU, the bus, any bus bridges and the device to prevent stale data from being accessed. All memory mapped ranges and registers have to be set up through the various bus_dma* functions to ensure full compatibility. The same hold true even more so for DMA transfers. The bus_dma framework is very efficient and always uses the optimal access and transfer method the platform supports (for example dedicated IOMMUs).
bus_setup_intr(9), ithreads, ithread_create(9), ...
FreeBSD is a fully SMP capable operating system. This means that all data structures must be protected against concurrent accesses from different CPUs through mutex(9). The traditional BSD spl(9) protection mechanism is no longer viable nor available. Care has to be taken to prevent deadlocks between different locks (ordering) and CPUs which bring the kernel to a halt. This is especially critical for code run from interrupt handlers. FreeBSD provides a system called witness(9) to detect, debug and ensure the correct locking constrains.
differences between bus systems
Network drivers are the most common type of driver found in the FreeBSD kernel. Extensive infrastructure is available to support network drivers.
the ifnet structure
The ifnet(9) structure is the building block for all network interfaces and contains information on the type and supported features of the interface. It is also the entry point for all protocols transmitting over a network. First the driver has to allocate a ifnet strucutre for itself which is then attached to the networking subsystem of the kernel. ...
features supported by the kernel
vlan, checksum offloading, tso, polling, ...
the mbuf system
All network data in the kernel in managed in mbuf(9)s. Mbufs themselfs are mostly just descriptors to the actual contigous memory region but can also contain up to 200 bytes of data internally. Mbufs which only serve as descriptors are called clusters together with the memory region they refer to. Mbufs may be linked (chained) together to form larger packets. All network device drivers must be able to process packets split into a mbuf chain. Normally mbufs are directly converted into hardware DMA descriptors with the aid of the bus_dma(9) functions. ...
FreeBSD provides a couple of advanced mass storage frameworks for commonly found storage concepts.
the ATA framework
the CAM framework
direct storage driver
the GEOM framework