MinGW cross-compilation adventure.

I just finished porting a Windows driver (actually 3) to use the MinGW build environment.

Due to the Windows Device Driver Kit (DDK) being under a somewhat opaque license, we could not get legal clearance to release binaries of our GPLed code compiled with the DDK. This was bad because I, being the open-source kinda guy I am, had based my work on a pretty substantial GPLed codebase. *Surely* the DDK license couldn’t be so restrictive to prevent all binaries bsed on GPL source! Well maybe it is and maybe it isn’t. When it’s not clear, legal says no.

Not good. It looked like we were going to have to somehow pull out the work I had done and rewrite the rest of the code from scratch to be GPL-free so we could release binaries legally following the DDK’s EULA.

It was in the process of estimating the work involved that I happened to talk to Jamey Sharp at a local Linux beering. We were each talking about our work and it turned out that he was in the same boat as me, a Linux dev who through some strange quirk was working on Windows drivers. But he wasn’t using the DDK, he was using MinGW, which is a port of GCC to compile Windows binaries.

Sometime later he was kind enough to come over and show me his setup and makefile, and sure enough it worked. So, we *could* use the GPLed code if we just distributed DDK-free binaries.

Once on that path, it still did take me a while to get the driver building. One nice thing about trying to get a different build env going is that you have something that works (although you can’t distribute it 🙂

I got it compiling by modifying the driver to have function definitions etc. that MinGW lacked. But it wouldn’t link. Sigh. I was using functions that were not in MinGW’s import libraries, and could not get around this by fudging it in my driver; I had to fix MinGW. This is a big fear of mine every time I use a piece of open-source software — if your code has a Foo dependency and Foo is broken, you pretty much have to be willing to start hacking Foo if you want it fixed. (Sure you can file a bug, but obviously nobody cares about your bug except you or it would be fixed, right?)

Once I dived into MinGW (actually w32api) it was straightforward to fix. Many of my changes to get the driver compiling actually belonged in the MinGW header. There were also functions omitted from the import libraries. (Import libs tell the linker how to link to the actual shared libraries that will be present at runtime.) These were defined in .DEF files, and all it needed to know was for each function, how many bytes were its arguments? Easy, once I knew what to do. (Nothing hard, just if one doesn’t do this thing regularly, you forget how it all fits together.)

So for anyone who wants to write Windows kernel code without the DDK, it can be done. Some tips:

  • Debian/Ubuntu includes mingw cross-compiler
  • Don’t use KMDF/WDF, MinGW doesn’t support it
  • Sprinkle all callback functions with DDKAPI, so they use stdcall calling method (the compiler will complain, makes it easy.) including DriverEntry().
  • Add -DDBG to enable KdPrint()s
  • Inline asm will need to be rewritten
  • Recent GCC doesn’t have __FUNCTION__, and DDK doesn’t have __func__, so plan on wrapping with your own macros for tracing and handling this difference based on #ifdef __MINGW32__. I’m a big fan of gcc’s preprocessor, the variable-argument macros are pretty nice.
  • WinDBG needs .pdb files to set breakpoints and step through code, MinGW doesn’t generate these, so KdPrint() is your friend
  • You can’t link with libc yet sometimes you need snprintf. I pulled in Linux’s snprintf code to fill this gap, yay GPL!
  • MinGW is 32-bit only right now. For 64-bit binaries, plan on becoming a serious MinGW contributor for a while!
  • Here’s how my makefile build cmd ended up: i586-mingw32msvc-gcc $(CFLAGS) -o [email protected] -shared -Wl,–entry,[email protected] -nostartfiles -nostdlib $^ -lntoskrnl -lhal -lndis
  • For reference, see the Xen GPLPV repo. More help is always welcome.

Hopefully this blog post will contain enough keywords to be helpful to someone in the future 🙂

8 thoughts on “MinGW cross-compilation adventure.

  1. anonymous

    Why in particular an Open Source piece of software? Surely it should be a fear with every piece of software you use? Unless, of course, you buy a support contract… which you can do for either… so… I guess I don’t really understand your point…

  2. anonymous

    Sorry, I don’t get the problem.

    Aren’t most drivers compiled using the DDK? Why would it be a problem to release the binaries (like everybody else?)

    As for using MinGW, that’s great (and much better- in a OSS way -than using the DDK) Too bad the DDK comes with lots of docs, etc

    And also, Windows driver development sucks a lot compared to linux driver development…

  3. strdup

    Hey I agree, my take from reading the DDK license was that you could build binaries of GPLed source, but if you did so you could not base your driver off the tiniest shred of the DDK’s plentiful sample code (as this would get some of their code out in the wild under a license they didn’t like.)

    This was not the view of the lawyers. My explanations to the contrary, they were not comfortable okaying this. So yes, if it’s true that there was no legal risk then using MinGW is not needed… but using MinGW removes the DDK license uncertainty from the equation entirely, which can be very important sometimes.

    I don’t know if the DDK license’s intention was FUD, but that was the result.

  4. anonymous

    There are other issues here. Microsoft doesn’t support drivers built with any tools other than the ones that ship in the WDK — even including other Visual C++ versions. If you find a bug and call for support, they won’t talk to you until you reproduce it with the WDK build tools.

    The fact that the WDK is available for free makes me wonder why anyone would go to all of this trouble.

    By the way, Visual C++ also supports variadic macros.

    – Tim Roberts

  5. anonymous

    The MS compiler doesn’t grok variadic macros and other useful GCC specific features. This could be enough to justify the effort.

    And this was an exciting exercise just for the sake of the art 🙂


  6. macmeyers

    And again, lawyers argue that even if you win it’s not worth the risk or expense, and that you should settle and pay a few thousand dollars.

Leave a Reply

Your email address will not be published. Required fields are marked *