Driver Development Presentation at WalterCon 2006
This is a transcription of the Driver Development Presentation given by Axel Dörfler at WalterCon 2006. The slides in HTML format can be downloaded from here. A video of the presentation is also available for download.
Contents
1. Device File System
Weakly typed directory hierarchy:
- there is no /dev/eth0, instead, all network devices are in /dev/net/
- all drivers in a subdirectory usually follow the same API, however this is not enforced
- drivers can support multiple APIs by publishing more than one device
- the name of the driver does not need to have any relation to where or what is published, even though you shouldn't abuse this to avoid confusion
For development:
- use
rescan <driver name>to make sure the system reloads your driver after a recompilation - for the rescanning to work as expected, the driver must be located in the drivers/bin/ directory - this is the only reason why it's usually not a good idea to put the driver into drivers/dev/
- Rescanning will only work if no device published by the driver is currently in use
System boot in BeOS:
- The boot loader needs to load all drivers needed to let the kernel access the boot file system
- Only the drivers found in certain well known directories are loaded:
- drivers/dev/
- drivers/dev/disk/
- All other drivers are loaded on demand: an application (for example, the media server) looks for devices in /dev/audio, and the devfs will then load all of the drivers it finds in that directory.
System boot in Haiku:
- It's yet to be determined how exactly the boot loader will do its job
- If possible, it will use hardware detection to identify which driver need to be loaded so that the kernel can boot further
2. Modules
- BeOS supports 3 different types of kernel add-ons:
- drivers
- file systems
- modules
- Haiku's file systems are standard modules; BeOS file systems are not supported
- Haiku's new device system uses modules only, too, but BeOS drivers are still supported for compatibility
- There can be several exported modules per add-on:
module_info *modules[] = { (module_info *)&scsi_for_sim_module, (module_info *)&scsi_bus_module, (module_info *)&scsi_device_module, (module_info *)&scsi_bus_raw_module, NULL };
- The module name is determined by its path - plus an additional arbitrary identifier:
- Name:
"bus_managers/scsi/bus/v1" - Path: bus_managers/scsi
- Free Identifier:
bus/v1
- Name:
- To use a module, you have to get it first:
device_manager_info *gManager; status_t status = get_module(B_DEVICE_MANAGER_MODULE_NAME, (module_info **)&gManager); if (status < B_OK) { ... }
- The
gManagervariable points to the requested module if the above call was successful; the module's exported functions can be used - After usage, you have to put the module away again using
put_module()so that the system knows that it may unload the module again to save memory
- Haiku extension: Dependencies
locked_pool_interface *gLockedPool; device_manager_info *gManager; module_dependency module_dependencies[] = { {B_DEVICE_MANAGER_MODULE_NAME, (module_info **)&gManager}, {LOCKED_POOL_MODULE_NAME, (module_info **)&gLockedPool}, {} };
- These dependencies are automatically resolved when loading the module - the referenced modules are directly available via the provided variables
- They will be put away after your module has been uninitialized
3. Device Types
The sub directory determines the function and API of a device:
- network drivers are in /dev/net
- disk drivers are in /dev/disk/
- audio drivers are in /dev/audio/; there are further sub directories which specify the exact function and API, for example old for the R3 style sound interface, or multi for the never finished multi audio interface
- graphics drivers are in /dev/graphics/, TV and similar drivers can be found in /dev/video/
API? What API?
- all devices export the same C API
- the special type depending API is completely exported via the general purpose
ioctl()call
ioctl() pitfalls
- You have to make sure the passed in arguments are valid!
- You have to make sure any pointers are valid - and stay valid during execution
- There is no publicly documented way to do the above in BeOS; in Haiku, you have to use
user_memcpy()to copy any incoming data before use in the kernel - Any application can send any control codes - make extra double sure you can't cause crashes this way
- BeOS does not preserve the optional length argument when given
Network device drivers
- Private definitions in ether_driver.h
- The ETHER_INIT parameters can safely be ignored (they are always 0 for Haiku)
- The BONE extensions ETHER_GETIFTYPE, and ETHER_GETLINKSTATE will be supported by Haiku as well
- ETHER_HASIOVECS might not be supported - in that case, a replacement for this mechanism will be implemented (important for speedy Gigabit ethernet)
- More or less good example implementations:
rtl8169for a Gigabit driver,sis900for a 10/100MBit driver
Audio device drivers
- Obsolete R3 definitions in sound.h - this is not supported by Haiku yet
- R5's multi audio interface was never completely finished or documented (for example, recording never worked)
- Haiku's current multi audio implementation is not completely compatible, and is therefore called
hmulti_audiofor the time being - Example for the old R3 API:
sonic_vibes,usb_audio,sis7018 - Example for Be's multi audio API:
ich97- this will likely be converted to the new Haiku API, though - Example for Haiku's current multi audio API would be:
auich
Graphics device drivers (1/2)
- Special breed because the interface is mostly free
- The only call is B_GET_ACCELERANT_SIGNATURE to identify the accelerant to be used by the
app_server - The real app_server API to be implemented is defined in add-ons/graphics/Accelerant.h
- The interface as defined in GraphicsCard.h is deprecated and won't be supported in Haiku
Graphics device drivers (2/2)
- Haiku will extend the existing API (in a back- and upwards compatible way), but it's not yet finalized. For example, 32 bit mouse cursors with transparency will be used in Haiku
- Example implementation to look at:
intel_extreme- the exception here is theB_PROPOSE_MODEhook which should be better be used from a different driver at the time of this writing
4. Interrupts
- An interrupt will be enabled when you install a dedicated handler:
status = install_io_interrupt_handler(info.pci->u.h0.interrupt_line, &my_interrupt_handler, (void
