The kernel team is planning to document several aspects of kernel-level programming in a series of Newsletter articles. This will be useful to anyone who ever intends to write or directly use a driver, and will also be of general interest to those who are simply interested in knowing how the pieces of the kernel fit together.
This article provides an overview of the entire series. Future articles will focus on the various components a developer can contribute—user- and kernel-level drivers, modules, bus managers, busses, etc., and will contain helpful suggestions as to how to properly and safely integrate these pieces into the system.
As most of you know, the BeOS kernel itself consists only of core
functionality, sufficient to start the boot process and manage memory and
threads. Also built into the kernel are the ISA bus manager, the PCI bus
manager, the device file system (devfs) which manages
/dev
, the root file
system (rootfs) which handles things in
/
, and a few other odds and ends.
Since this is nowhere near enough to do anything useful, as early as the boot process the kernel uses add-ons to extend its functionality. File systems, device and bus drivers, for example, are all add-ons that are loaded by the kernel.
These kernel add-ons can be broadly classified into three categories:
device drivers—code that communicates directly with a device
modules—add-ons that export an API for use by other modules or drivers, all within kernel space
file systems—BFS, dosfs, hfs, etc. These will not be covered in this series.
Device drivers and file systems, while they add functionality to the kernel, are accessible from user space, in the sense that you can open them and address them via file descriptors. Modules, however, are kernel-only extensions, since they provide functionality for drivers and other modules. The raison d'etre of modules will become clearer below.
Note: some of this has been covered before in some detail in an article by Arve Hjønnevåg. See "Be Engineering Insights: Splitting Device Drivers and Bus Managers".
A device driver is something that actually talks to a specific device or class of devices. The communication usually involves some device-specific protocol—for example, code that specifically addresses a graphics card, an Ethernet card, or serial port is a device driver. Similarly, each piece of code that speaks to a class of devices such as SCSI disks, ATAPI devices, ATA devices, etc., is also a device driver. This code actually understands the device itself and manages it.
As explained above, modules present a uniform API for use by other modules or drivers. This is a useful way of separating out commonly used functionality from a driver.
Take the example of a SCSI device driver talking to a SCSI device. The device hangs off a SCSI bus, which in turn may be one of many busses on the system. All SCSI devices speak a common command set that is independent of the controller used to send the commands. Rather than have each SCSI driver (SCSI disk, SCSI CD, SCSI scanner, etc.) know how to deal with each of the possible types of SCSI cards, it would be nice if there were a generic interface to a SCSI card for each driver to use. This is accomplished by having one module implement each SCSI card, which then presents a generic API.
These modules are further managed by a SCSI "bus manager" module, which knows how to deal with multiple busses and present them in an encapsulated format to each driver. The bus manager's API is what the driver has to deal with, reducing its complexity a great deal. We also have USB, IDE and PCMCIA bus managers.
Another example of the use of the module architecture is a sound driver which publishes a MIDI device. MIDI functionality can be encapsulated in a module so that all sound drivers can access it, avoiding duplication in each driver.
The kernel provides basic services so that drivers and modules can function. Typically these are
Enabling and disabling interrupts.
Setting up memory for DMA, etc.
Access to other devices and modules.
The kernel also provides access at user level to devices using a "Posixy"
API. Devices can be opened by user programs through Posix calls such as
open
, read
,
write
, and ioctl
, which address the devices through file
descriptors. These calls turn into system calls in the kernel, and are
passed by devfs to the appropriate device driver, which then performs the
specified operation.
If you want to write a driver for a device, one of the first decisions you need to make is whether it should be at user or kernel level. A kernel-level driver was described above; a user-level driver does the same task by using an extant "raw" driver that knows how to handle that class of device. For example, if you wanted to write a driver for a SCSI scanner, you could write an add-on at user level that opens up the scsi raw device and send commands through scsi raw to the scanner. The alternative would be to write a conventional kernel-level driver to directly speak to the scanner.
The main advantage of operating at kernel level is speed. In this case, one less context switch is required for command completion, so the latency is lower compared to user level. In addition, if your driver needs access to some peculiar hardware, it's rather difficult to do this using a raw driver from user space.
The trade off is that it's much easier to debug at user level. You can use conventional debugging techniques and there's less chance of taking down the entire system in the process.
The above is merely a brief introduction to the topic. Stay tuned for more in-depth pieces from various members of the kernel team.
The following transcript comes from a recent interview between myself and Morgan le Be, the editor of SQUONK! Magazine. [NOTE: any resemblance to other magazines, either real or imagined, is entirely coincidental.]
A popular topic. Like the flu, it vanishes for a while, then returns as a newer, more virulent strain. But far from me to complain—I like it when Business Week and Newsweek stir up the pot. When Newsweek describes a brave new Ether in which everyday objects swim in an ocean of IP packets, I'm happy. That's because I look forward to using wireless PDAs and to programming my VCR with a mouse click from a NetPositive page somewhere in the house—or in the world. I'm happy because I see more and more opportunities for the BeOS as the mutltimedia engine in these connected applications.
Unsurprisingly, Bill Gates has views to share on the matter. He argues in the same issue of Newsweek that the PC is with us forever, the center and nexus of this brave new connected world (I paraphrase here, with no warranties expressed or implied). Apparently, his statements are in reaction to predictions that the PC will disappear, giving way to specialized, task-specific devices that do a better job for less money and less aggravation. Part of Chairman Bill's argument is that PCs will become easier to understand, with a simpler user interface. They'll provide the simplicity of a task-specific device, combined with the protean permutations we've come to love in our computers.
Yes, I like personal computers. They're useful, fun, and if you really invest enough time into making them work just right, you'll grow hair on your chest. If I understand correctly, The Chairman is promising chest alopecia some time in our future. Other people agree with him and believe that a collaboration between Intel and Microsoft will deliver us to the Promised Land of The Simple PC. From there, with a careful application of Moore's Law, The Simple PC will become The Free PC, with the marginal cost of the physical device absorbed by a service provider. Just like free cell phones.
This is a seductive strategy. But last weekend, while cleaning the shelves in my home office, I came across a Bob CD-ROM. It promised in the early 90s what The SimplePC promises now—a simple, friendly interface. The fact that it didn't work then doesn't necessarily predict that it won't work in the future. Actually, I find Windows offers a well-designed UI. But it does little to hide the growing complexity underneath. The idea that you can put an interface layer above the gas refinery, and the foul-smelling problems beneath it will never percolate to the surface is just that—an idea—a seductive one without foundation in observed behavior. This is an instance of a well-known sophism: It'll work because it would be cool if it did. That's what we thought of handwriting recognition.
I like PCs for what they do well; I agree with Microsoft's Chairman that they're irreplaceable. But they can be complemented. This isn't an either/or proposition. The Post-PC world is a misnomer—it makes good headlines, but it masks a more complex reality. Just as automobiles differentiated into all sorts of vehicles—some of which General Motors refused to acknowledge for years—everyday computing devices will continue to differentiate. In the twilight of the PC-centric era, we are moving toward a Web-centric stage and our dear PC will be one of many devices happily swimming in the ocean of IP packets.