• About Jakob Engblom and this blog
Observations from Uppsala Computer Simulation, Virtual Platforms, Embedded Programming, Multicore and More (by Jakob Engblom)

Learning Linux Device Drivers on a Virtual PowerPC

2008 November 2 12:02 / 7 Comments / Jakob

There are times when working with virtual hardware and not real hardware feels very liberating and efficient (not to mention safe). Bringing up, modifying, and extending operating systems is one obvious such case. Recently, I have been preparing an open-source-based demonstration and education systems based on embedded PowerPC machines, and teaching myself how to do Linux device drivers in the process. This really brought out the best in virtual platform use.

The final result of my efforts will be more public early next year, when the students I have put to work on my Linux-based setup come back and show me what they accomplished (or not). Until then, here are some small tidbits on how easy it is to work with kernel-level code in a virtual machine. Actually, if I had been working on real hardware, I am not that certain that I would have had anything but a bricked machine in front of me — to put it simply, flash reprogramming seems to hate me, and I have managed to fail or destroy a few embedded boards that have been unlucky enough to cross my path.

The virtual platform was really very helpful to diagnose all the mistakes I made while creating my driver and making it talk to my custom hardware.

First of all, it was dead easy to test a new version of the driver: start the simulation from a checkpoint of a booted and configured machine, load the driver into the target file-system using the Simicsfs backdoor (similar to the VmWare hostfs solution), and then insmod it. This was automated in a script that typed the needed commands on the target-command line with no manual intervention. Each iteration takes a few seconds, which is just as fast an convenient as testing a simple program directly on the host.

Diagnosing what went wrong was greatly facilitated by the simulator: did the driver access the device I had prepared for it? Were values read as expected? Obviously, there were a lot of such cases, I am not the most expert device driver programmer (yet).

Here is one particularly interesting example: I empirically learnt that the Linux kernel “readl” function is always reading data little-endian, even on a big-endian machine. You have to use “readl_be” to get the big-endian data from a big-endian device attached to a big-endian machine. I guess the behavior makes sense for reuse of drivers across architectures, but it sure confused me when my driver was reading the right register but complaining about bad contents.

The simulator showed the problem very plainly:

  • “value read is 0xabcd0101 (BE)”. Ok that looks right.
  • “register r3 contains 0x0101cdab”. Strange, looks like the wrong byte order. WHY I screamed to myself.
  • Using reverse execution to step back one instruction showed that the load instruction used was a byte-swapping 32-bit access. Aha!.
  • Go into Linux kernel headers (include/asm/io.h) to find that there were a bunch of other varieties available, and guess that readl_be() was the right solution.
  • Change device driver code, recompile, and retest. Now it worked.

I would have assumed that the book I was using as my guide, the highly-recommended Linux Device Drivers, 3rd edition” would have told me this. But it did not, as it is annoyingly tied to the horrible standard PC. It could really do with some extra chapters on drivers for PowerPC, ARM, and MIPS (to name some of the most important non-x86 architectures out there).

On the other side of the fence, I am using Virtutech DML to do the actual device, and that is working out very well. In my setup right now, I can change the device driver and the hardware it drives, recompile both, and then run an automated test script that starts from a checkpoint, inserts the hardware model in target memory, loads the device driver, and tests it in about five seconds. Very handy, and all completely automatic. The ability to load and insert hardware models on the fly during simulation is really very convenient here — I would have to have to reboot the target Linux from scratch each time I wanted to add or remove things from the virtual platform hardware setup.

To sum things up, so far, I have learnt quite a lot about doing Linux device drivers and how to setup hardware in a Linux system, and I think it would have been much harder to learn and experiment like I have done had I been stuck with physical hardware (not to mention the plain impossiblity of just inserting a  new piece of hardware in a simple way into a physical system).

It really shows that quite often, virtual hardware is “even better than the real thing”.

For fun, here is a screenshot of a complete test run of loading the device driver:

Tweet
Posted in: embedded software, ESL, teaching, virtual platforms / Tagged: DML, endianness, freescale, linux, operating systems, power architecture, Simics

7 Thoughts on “Learning Linux Device Drivers on a Virtual PowerPC”

  1. Simon Kågström on 2008 November 4 at 22:31 said:

    I might have mentioned it before, but Eclipse really shines when writing code for the Linux kernel. I’m quite amazed that it manages to lookup the proper definition of all those *very* nasty Linux macros, but it does. Recommended if you haven’t tried it.

    Then there is the thing with Linux: There are typically multiple ways of doing the same thing, and not always clear which one is correct. For your readl example, I tend to use in_be32/in_le32 instead depending on what endianness I’m after. It’s explicit at least.

    I also before did some horrible hack to get some files into sysfs (/sys). I now know how to do it properly, and the end result is beautiful, but again not something which immediately obvious.

    Developing on real hardware, especially U-boot, is OK as long as you can reflash the board via a JTAG interface :-)

  2. Jakob on 2008 November 9 at 21:26 said:

    I am now trying to use Eclipse… we’ll see how it goes. Followed Simon’s instructions at http://simonkagstrom.livejournal.com/31079.html?view=19559#t19559 , think I got things right.

    Maybe that will help me figure out how IRQs get locked in the PowerPC architecture — seems to have to be registered for use in the device tree blob or something like that. And how to convince the kernel to accept an arbitrary number of cores, and not just two.

  3. Jakob on 2008 November 9 at 21:44 said:

    > I also before did some horrible hack to get some files into sysfs (/sys). I now know how to do it properly, and the end result is beautiful, but again not something which immediately obvious.

    Would like to see this if you can share the code…

  4. Pingback: Observations from Uppsala » Blog Archive » Shaking a Linux Device Driver a Virtual Platform

  5. Simon Kågström on 2008 November 10 at 13:21 said:

    Sure, a good resource is for example lis302dl.c from the openmoko project:

    http://git.openmoko.org/?p=kernel.git;a=blob;f=drivers/input/misc/lis302dl.c;h=f743a241d87817a15bd748f0f911f7ff0a746946;hb=stable

    You would have something like

    static ssize_t set_wakeup(struct device *dev, struct device_attribute *attr,
    const char *buf, size_t count)
    {
    …
    return count;
    }

    static ssize_t show_wakeup(struct device *dev,
    struct device_attribute *attr, char *buf)
    {
    return snprintf(…);
    }

    static DEVICE_ATTR(wakeup, S_IRUGO | S_IWUSR, show_wakeup, set_wakeup);

    static struct attribute *lis302dl_sysfs_entries[] = {
    &dev_attr_wakeup.attr,
    NULL
    };

    static struct attribute_group lis302dl_attr_group = {
    .name = NULL,
    .attrs = lis302dl_sysfs_entries,
    };

    whatever_probe(…)
    {
    …
    rc = sysfs_create_group(&lis->dev->kobj, &lis302dl_attr_group);
    …
    }

    Adding new sysfs files is now easy to do by adding them to the _entries array and adding a show and/or set function to implement it. This works for all common and simple cases. If you need to sleep on the sysfs file, I think you might need to use the lower-level interfaces.

    // Simon

  6. Pingback: Observations from Uppsala » Blog Archive » Gary Stringham on Hardware Interface Design vs Virtual Platforms

  7. Pingback: Observations from Uppsala » Tying a Thread to a Processor in Linux

Leave a Reply Cancel reply

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

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Post Navigation

← Previous Post
Next Post →

Recent Posts

  • A Few Electrons too Many
  • Wind River Blog: Visuality NQ CIFS Server on Simics
  • Everything in the Cloud?
  • Wind River Blog: TCF and Simics
  • Off-Topic: Moving Bad Piggies Save Games
  • Two Cores, Four Cores, Eight Cores – Mobile Variety
  • Bliss: Failing to Pivot for Ideology
  • Wind River Blog and Movie: Demo of Simics Debugging
  • Simulation vs Reality in Schlock Mercenary
  • Programming like Lego
  • Does ISA Matter for Performance?
  • Wind River Blog: Debugging Simics using Simics
  • Wind River Blog: Simics and Flying Piggies
  • Dragons can be Useful – when AT Models Make Sense
  • Logging (Some More Thoughts)

Categories

  • appearances (30)
  • articles (21)
  • blogging (10)
  • books (6)
  • business issues (31)
  • computer architecture (35)
  • conferences (34)
  • EDA (50)
    • ESL (35)
  • embedded (78)
    • embedded software (57)
    • embedded systeme (50)
  • general research (6)
  • history (32)
    • general history (7)
    • history of computing (26)
  • off-topic (94)
    • biking (5)
    • board games (1)
    • computer games (3)
    • desktop software (35)
    • food and drink (1)
    • funny (12)
    • gadgets (24)
    • Politics (3)
    • popular culture (5)
    • trains (5)
    • transportation (10)
    • travel (10)
    • websites (3)
  • parallel computing (92)
    • multicore computer architecture (51)
    • multicore debug (22)
    • multicore software (65)
  • programming (107)
  • review (8)
  • security (19)
  • teaching (7)
  • testing (9)
  • uncategorized (12)
  • virtual things (128)
    • computer simulation technology (68)
    • virtual machines (17)
    • virtual platforms (97)
    • virtualization (14)
  • Wind River Blog (39)

Tags

ARM blog commentary Cadence Checkpointing clock-cycle models Communications of the ACM computer architecture conference cycle accuracy debugging DML Domain-specific languages embedded freescale G900 heterogeneous homogeneous IBM Intel iPod lego linux mobile phones multicore off-topic office 2007 operating systems p4080 podcast commentary power architecture rant research reverse debugging reverse execution S4D SiCS Multicore days Simics simulation software tools Sun SystemC video virtualization Vista Windows

1

  • F-Secure Blog

Blogs and news

  • Andras Vajda's blog (on multicore)
  • Embedded in Academia (John Regehr)
  • Grant Martin
  • Jack Ganssle
  • My Wind River Blog
  • Security Now podcast
  • Secworks (Joachim Strömbergson)
  • Simon Kågström
  • Synopsys View from the Top
  • Worse Than Failure

Archives

  • May 2013 (1)
  • April 2013 (1)
  • March 2013 (4)
  • February 2013 (1)
  • January 2013 (3)
  • December 2012 (2)
  • November 2012 (2)
  • October 2012 (1)
  • September 2012 (6)
  • August 2012 (4)
  • July 2012 (4)
  • June 2012 (3)
  • May 2012 (4)
  • April 2012 (2)
  • March 2012 (3)
  • February 2012 (1)
  • January 2012 (6)
  • December 2011 (2)
  • November 2011 (3)
  • October 2011 (4)
  • September 2011 (5)
  • August 2011 (4)
  • July 2011 (3)
  • June 2011 (4)
  • May 2011 (7)
  • April 2011 (1)
  • March 2011 (3)
  • February 2011 (5)
  • January 2011 (1)
  • December 2010 (4)
  • November 2010 (3)
  • October 2010 (5)
  • September 2010 (5)
  • August 2010 (5)
  • July 2010 (6)
  • June 2010 (5)
  • May 2010 (3)
  • April 2010 (4)
  • March 2010 (3)
  • February 2010 (4)
  • January 2010 (7)
  • December 2009 (6)
  • November 2009 (6)
  • October 2009 (7)
  • September 2009 (6)
  • August 2009 (7)
  • July 2009 (11)
  • June 2009 (5)
  • May 2009 (10)
  • April 2009 (7)
  • March 2009 (8)
  • February 2009 (9)
  • January 2009 (12)
  • December 2008 (8)
  • November 2008 (9)
  • October 2008 (9)
  • September 2008 (10)
  • August 2008 (13)
  • July 2008 (12)
  • June 2008 (8)
  • May 2008 (9)
  • April 2008 (10)
  • March 2008 (7)
  • February 2008 (8)
  • January 2008 (5)
  • December 2007 (5)
  • November 2007 (7)
  • October 2007 (7)
  • September 2007 (12)
  • August 2007 (9)
  • July 2007 (2)
© Copyright 2013 - Observations from Uppsala
Infinity Theme by DesignCoral / WordPress