MAR
30
2006

Hardware fun

I'm finishing my leave of absence and going back to work. Yes, doing what I wanted was great, but the pay was miserable. So I'll be going back to Trolltech. It looks like Trolltech will pay me to go to Calgary and work on Plasma with Aaron for a bit, which is just great. Plus apparently the love of my life is in Calgary. I know what you're thinking "Zack, but they have Snapple ice-tea everywhere", yes, but not Kinder Bueno's. You don't know love unless you've tried Snapple's lemon ice-tea with a kinder bueno. Let me just point out that our relationship is purely platonic.

My laptop is broken and given that I don't have absolutely any money left to get a new one my hacking time is severely limited. Fortunately for me, thanks to Benjamin Herrenschmidt and the people at Terra Soft Solutions I have a Quad-G5 which is nice. I, of course, work only on GNU/Linux so it took me a little bit of time to get the setup right, especially considering that kernel did not support quads when I got it. Again, fortunately Ben was able to hook me up with a code he and Paulus have been working on and from then on it was trivial. I'm about to sit down to check out how the sound driver is coming along because I don't work without music. One major problem is that I only have NVIDIA's pci-e cards here. Now that's a problem because NVIDIA doesn't release PPC Linux drivers. For various reasons I'd prefer not to hack on it, but I don't have money for any other card. Plus NVIDIA hardware works a little differently than what we're used to. NVIDIA has multiple harware contexts, which is nothing really new because they had it for a long time. In our infrastructure we operate with one FIFO through which command buffers are fed to the card. Technically not a huge issue, just makes it a little less than optimal for working with their hardware.

Short of political reasons, the main one I don't feel like working on acceleration support in the Open Source NVIDIA driver is that I don't have any x86 box at home. Now for those of you who never reversed engineered hardware, here's "reverse engineering 101" (meaning "writing drivers without specifications for dummies", also known as "what drives x hackers crazy" - yes! at some point many of them was sane... the pretty ones mostly... i know, i know they're all pretty):

  1. Get hardware, preferably one that doesn't work (preferably not because it's broken but because the vendor doesn't offer support for our favorite operating system)
  2. Make sure there's no specifications available (otherwise it's just masochistic and I, personally, refuse to promote that kind of spare time entertainment in my blog)
  3. Find system Z where that hardware works, meaning vendor provides driver for that system (we call it "Z" because in my extensive experience things named with Z always work beautifully)
  4. Develop a small utility for system Z that dumps state info of mapped memory regions (preferably ones that are relevant to the hardware in use, but I'm far from trying to limit your artistic skills here) and deduct register contents.
  5. Write small applications that do very specific things, in this case, for example, display uniform color triangle or a quad.
  6. Run your application and compare the regions from before and after the rendering happened.
  7. The registers that differ are somehow related to the functionality that your application was exposing. (that's also why the application needs to focus on some very specific feature, otherwise the only thing you're figuring out is how limited your intelect is)
  8. Deduce what the registers that changed are for, what values they expect when and where do they want it.
  9. Try to produce some code.
  10. This is important step - watch your machine crash, reboot and repeat.

Now as you can tell finding a system where one can trace the steps of a working driver is the crucial part of "reverse engineering" here. I can't reproduce it because I'm not a proud owner of such a system. So basically we're looking at hours of more or less educated guessing, which accounts for "writing drivers for hardware without specification - the painful way" (oh, yeah, because the previous way is "easy" and "fun"). Time during which you're bound to crash your machine every single time you try anything. This is what I was doing when I was working on Exa on my Powerbook (with ATI's RV250). After that I decided to cut my hair and go on a leave of absence. Coincidence?

Graphics hardware is very sensitive to any kind of invalid input. Well, most hardware is. A crucial step here that I forgot to mention is that between looking at the memory dumps you'll have to form a more high-level view of how the hardware works. Pretty much the only way of doing it is knowing how a lot of other hardware works, what other vendors are doing, what works and what doesn't - experience. Even after that knowing exactly what was sent to the card that made it crash doesn't mean you can figure out what to send to make it work. I'm assuming here that you're like me and simply never, ever make any mistakes in your code and all problems are simply caused by your lack of knowledge about particular piece of hardware. If you're one of those people who does happen to make mistakes then you're looking at an even more challenging task. That, plus often locking the bus and all kinds of sideeffects in between make this process not a whole lot of fun.

Comments

I'd start by getting the original driver - say, the Windows driver - and disassembling it (preferably in IDA). I mean, why wonder what a certain register is, when it's clear as day it's done before a DMA transfer is initiated?


By toastie at Thu, 03/30/2006 - 12:30

This method is explicitly forbidden by the license on pretty much all commercial drivers. In countries where companies enforce the legal side of their business doing this is not the best idea (even the first way is risky - it's all in the gray area of the law).


By zack rusin at Thu, 03/30/2006 - 15:09