Settings

Theme

Writing a device driver for Unix V6

mveg.es

133 points by vegesm 4 years ago · 9 comments

Reader

yjftsjthsd-h 4 years ago

Absolutely fantastic:) I've rather fallen into the trap of thinking of kernel code, including drivers, as being some sort of deep magic beyond human comprehension, but this makes it seem utterly straightforward; map a chunk of memory in the "hardware", map the memory in the OS, wire it up, use that to communicate. Is this how it works on newer OSs (*BSD, Linux, Illumos)? Are there equivalent tutorials for any modern FOSS *nix?

  • Nzen 4 years ago

    I don't know if there are tutorials, but I enjoyed Ben Cox's writeup [0] about making a driver for a vga / webcam he had bought. The osdev wiki links to this 2006 [1] sample driver project. Maybe you can find more, depending on what you want to interface with.

    [0] https://blog.benjojo.co.uk/post/userspace-usb-drivers

    [1] https://sourceforge.net/projects/glider-kernel/files/EDI%20H...

    • matheusmoreira 4 years ago

      This writeup was immensely useful for me. Had all the information and pointers I needed to get started. My user space USB driver was significantly simpler, just control reports, but I don't know what I would have done if I hadn't found this article.

    • omgitsabird 4 years ago

      yeah, there is a lot more in the last 16 years...

      i too suffer from immediate references to tell me i know nothing, but we are all the same, reading the same stuff, even right here...

  • gmueckl 4 years ago

    A device driver is program code like any other, so there's no way it can be magic. Whether it's simple or complex depends on a couple of things. Some hardware maps registers into memory and you communicate it by reading from/writing to these addresses. This is very common in simpler architectures like microcontrollers. Other times, your hardware is attached to shared system busses like PCI or USB and you need to go through driver layers for them. Of course, there's the occasional bit of quirky hardware that requires that the driver does some odd things, but even that isn't magic if you understand the device hardware.

    I think the biggest source of complexity for device drivers is the expectations that come with the design of the operating system the driver should run on. If there are e.g. strong expectations that device drivers don't block for certain operations or keep certain locks for extended amounts of time, then the driver may gain a lot of complexity from trying to play nice. Modern optimized desktop and server operating system are somewhat guilty of forcing that kind of complexity onto device drivers.

  • antoinealb 4 years ago

    At my previous job I had to write a device driver for a (simple) I2C device. I already had experience writing drivers for microcontrollers, but to move to Linux I found it was pretty simple to take the code for an existing device that was similar to what I wanted to do and use it as a reference. If you look at the code for a simple serial port [1], with the knowledge gained in the article, you would probably figure out what are the different parts.

    [1] https://github.com/torvalds/linux/blob/master/drivers/tty/se...

  • matheusmoreira 4 years ago

    > 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 comprehension

    There 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?

    • yjftsjthsd-h 4 years ago

      > It boggles my mind to this day, why couldn't they have done that in hardware?

      Software is cheaper and more flexible, I suppose.

  • johnny22 4 years ago

    there are entire books and tutorials about writing drivers for linux, or even how to do a mini OS from scratch. So many i can't even remember them all.

Keyboard Shortcuts

j
Next item
k
Previous item
o / Enter
Open selected item
?
Show this help
Esc
Close modal / clear selection