Tuesday, March 22, 2016

Introduction


I recently started a project to port drivers for the current Intel WiFi chips from Linux to Mac OS X. I can’t claim this was especially necessary: most Macs come with functional WiFi, and there are already third-party cards that are either compatible out of the box or work given appropriate drivers. Still, it’s time to learn something new, and this hits a couple of bucket list items for me — writing something in a different language, learning Linux kernel development, and doing something meaningful in the OS X/iOS programming environment. 


A bit of research turned up the following:


The Good

  • The "iwlwifi" Linux driver is just plain part of the Linux kernel sources, so it's publicly available and actively maintained
  • In order to operate, you need both hardware and firmware. During startup, you load the firmware into the hardware, and then it works. While this process arguably doesn't belong in the "good" list, the firmware is available for download. The license appears to allow you to load it on OS X, though potentially without patent coverage. That's OK as far as I'm concerned, because it's really just a hobby project.
  • Others have ported Ethernet (though not WiFi) drivers from Linux to OS X, with source code available. This means I have code for some working OS X Ethernet drivers to refer to.
  • Apple has some starter documentation on Creating a Device Driver
  • Apple's documentation refers to an IORegistryExplorer tool to browse your current hardware configuration, but I didn’t seem to receive it with Xcode. There seem to be copies available from various sources around the net. But perhaps better, there’s an open-source equivalent called IOJones.
The Bad
  • The Linux code is in C, while an OS X driver will be an IOKit kext (kernel extension), in C++. While that’s not explicitly bad, and in fact is much more compatible than if one was in Java or something, it does make for a bit of an impedance mismatch. I guess the real problem is that now I have to learn two new styles of programming at once. I've theoretically used C before, but that was maybe 20 years ago and I never did anything "real" with it.
  • The Linux and OS X APIs are different in a number of nuts and bolts type areas — macros and functions used for logging, memory allocation, synchronization, and etc. as well as the basic data structures provided. It means there are a lot of differences scattered throughout the code.
  • The iwlwifi supports devices with both the older dvm and newer mvm firmwares. I am happy to simplify by only supporting mvm for now, but in many cases the dvm code is mixed in (just disabled by #ifdef blocks if I choose not to support it).
  • Conveniently, there is a free "book" covering the Linux wireless architecture. Sadly, most text other than descriptions of specific structs was never written, and it looks to have been abandoned more than five years ago. The wireless wiki looks more promising, although it's not completely up to date either. Comments in the source code it is, then.
  • Published books are available covering both OS X and Linux kernel and driver development (e.g. 1 2 3). However, they all seem to be several releases out of date.
The Ugly
  • While all the Linux APIs are public, Apple has not released a wireless API. There are APIs available for PCI devices and Ethernet devices, but not wireless. My guess is that they figure the demand for third-party wireless devices is low, and their code is probably a bit messy; not worth cleaning up and documenting for external release. This has a couple of implications:
    • Just plain more work because all the generic wireless plumbing has to be implemented as well as the driver itself
    • Besides the driver itself, the project will ultimately need to include a user-space API and tools to display and prioritize available wireless networks, choose one, specify and store the security key, and etc.
    • Once finished, the device will appear as a generic Ethernet device instead of as a native wireless device in System Preferences / Network, and will not use the wireless menu bar control to change WiFi networks.
    • As an example, Realtek has created their own app for devices using their USB wireless chips. It’s bad — overcomplicated and annoying to use. It comes with a dysfunctional menu bar icon. It wants the main app to be on all the time. Yuck!
Bottom line, this is going to be a challenging project. But it should be good for learning.


3 comments:

  1. You can download IORegistryExplorer from https://developer.apple.com/downloads/ in Hardware IO Tools.
    I have intel ac 7260 wifi card and I'm really interested in your work

    ReplyDelete
  2. some osx wireless driver source
    http://gtdriver.binaervarianz.de/sources.php (core only, full source can't download)
    https://github.com/kemenaran/iwidarwin (old intel wireless card port)

    ReplyDelete
  3. Whatsup man!. Looks like you are off the shelf now. haha

    ReplyDelete