character and block - best representation of devices?
Posted: Mon Jan 07, 2008 12:26 am
When the Unix device specification was first written, devices could either be accessed in two ways:
As a block of data: Which works fine for disk drivers, disk partitions, or anything that can be represented as a chunk of data.
As a stream of characters: Which suits text terminals, keyboards, and line printers.
I like this idea, since by using only a few sets of calls (read, write, seek) one may access any device in a consistent interface.
However, in a modern and more complex system (specifically in my micro-kernel environment), I do not see how this abstraction can suit every device.
For example, consider a graphics device. Using the Unix philosophy, this device can be represented as a block device, giving linear access to the frame buffer. But, in doing so, how would you handle things like flipping the buffer and setting the resolution?
The same problem could apply to a sound device. You could represent this using character device to constantly stream raw sound into the device. But how do you set the bit-rate, how do you change the volume, set if the data is a uncompressed, compressed, or MIDI stream?
There are many move examples of this, such as setting the burn speed and ejecting the tray of an optical drive.
The best possible way I have thought about getting around this is using multiple character and block device to represent one physical device. Using the example of a graphics device, you could use a block device to represent the frame buffer and a character device used to send special commands to the device. But, in doing so you are creating two virtual devices to represent one physical device.
The problem could become a lot more extreme. If a sound device supports 6 independent channels used for surround sound, each channel would need to be represented by a different character device. To control the volume and bit-rate of each channel, you would need another character device per channel. That equals 12 character devices representing one sound card! (Although there might be advantages of representing each channel individually, that is not the point of this argument).
I am looking for an driver-abstraction/interface where each physical device can be represented by a single virtual device though a consistent interface. Is this possible using the *nix character/block philosophy, or maybe using an yet-implemented 3rd device type? Or am I looking for a completely different paradigm?
As a block of data: Which works fine for disk drivers, disk partitions, or anything that can be represented as a chunk of data.
As a stream of characters: Which suits text terminals, keyboards, and line printers.
I like this idea, since by using only a few sets of calls (read, write, seek) one may access any device in a consistent interface.
However, in a modern and more complex system (specifically in my micro-kernel environment), I do not see how this abstraction can suit every device.
For example, consider a graphics device. Using the Unix philosophy, this device can be represented as a block device, giving linear access to the frame buffer. But, in doing so, how would you handle things like flipping the buffer and setting the resolution?
The same problem could apply to a sound device. You could represent this using character device to constantly stream raw sound into the device. But how do you set the bit-rate, how do you change the volume, set if the data is a uncompressed, compressed, or MIDI stream?
There are many move examples of this, such as setting the burn speed and ejecting the tray of an optical drive.
The best possible way I have thought about getting around this is using multiple character and block device to represent one physical device. Using the example of a graphics device, you could use a block device to represent the frame buffer and a character device used to send special commands to the device. But, in doing so you are creating two virtual devices to represent one physical device.
The problem could become a lot more extreme. If a sound device supports 6 independent channels used for surround sound, each channel would need to be represented by a different character device. To control the volume and bit-rate of each channel, you would need another character device per channel. That equals 12 character devices representing one sound card! (Although there might be advantages of representing each channel individually, that is not the point of this argument).
I am looking for an driver-abstraction/interface where each physical device can be represented by a single virtual device though a consistent interface. Is this possible using the *nix character/block philosophy, or maybe using an yet-implemented 3rd device type? Or am I looking for a completely different paradigm?