| > Is this how it works on newer OSs It can be. Not all devices will use memory-mapped I/O. USB devices, for example, use message passing. Messages are packets called USB Request Blocks, or URBs. https://www.kernel.org/doc/html/latest/driver-api/usb/URB.ht... A USB device driver is just a program that sends and receives theses messages. There are standardized device classes which enable generic drivers. Human interface devices, for example, will most likely be handled by a generic driver which can deal with any device of that class. Hardware manufacturers can still add custom functionality on top of a standard interface, usually through control messages. A USB keyboard with LEDs, for example. All the key events are handled by generic drivers, I only had to figure out the LED control interface. I used wireshark to reverse engineer it. Captured the USB traffic, saw a lot of control packets and correlated all of them with the proprietary manufacturer software's functions. With this data, it was simple to write a user space Linux driver for my keyboard. https://wiki.wireshark.org/USB The manufacturer's program would send a control message containing a payload, essentially bytes instructing the hardware what to do. For example, to set the color of a specific LED, my program sends this buffer to the hardware: const unsigned char report[] = {
0xCC, /* Some kind of prefix? Always present in all payloads. */
0x01, /* Set LED color command. */
led, /* LED index, some keys have multiple LEDs. */
r, g, b, /* RGB8 color of the LED. */
0x7F /* Some kind of suffix? Always present in all payloads. */
};
hid_send_feature_report(keyboard, report, sizeof(report));
To turn off all LEDs and clear all configuration: const unsigned char report[] = {
0xCC,
0x00, 0x0C,
0x00, 0x00, 0x00,
0x7F
};
> I've rather fallen into the trap of thinking of kernel code, including drivers, as being some sort of deep magic beyond human comprehensionThere certainly is a lot of deep magic. Often because dealing with hardware is an ugly business. I've read Linux drivers which actually work around literal defects in the hardware. For example, I remember a bit of special code for a button that inexplicably sent two press events every time it was pushed. I wouldn't even have known that was the case were it not for the extremely helpful comments left by the developer. In my case, I discovered the proprietary driver from the manufacturer was intercepting all of my keystrokes in order to support a special mode where LEDs light up when you press a key. It boggles my mind to this day, why couldn't they have done that in hardware? |
Software is cheaper and more flexible, I suppose.