<?xml version="1.0" encoding="utf-8"?>
<!-- If you are running a bot please visit this policy page outlining rules you must respect. http://www.livejournal.com/bots/ -->
<feed xmlns="http://www.w3.org/2005/Atom" xmlns:lj="http://www.livejournal.com">
  <id>urn:lj:livejournal.com:atom1:lukego</id>
  <title>Luke's Weblog</title>
  <subtitle>I only hack it so that I can brag about it here</subtitle>
  <author>
    <name>Luke Gorrie</name>
  </author>
  <link rel="alternate" type="text/html" href="http://lukego.livejournal.com/"/>
  <link rel="self" type="text/xml" href="http://lukego.livejournal.com/data/atom"/>
  <updated>2009-11-16T13:39:15Z</updated>
  <lj:journal userid="11934870" username="lukego" type="personal"/>
  <link rel="service.feed" type="application/x.atom+xml" href="http://lukego.livejournal.com/data/atom" title="Luke's Weblog"/>
  <link rel="hub" href="http://pubsubhubbub.appspot.com/"/>
  <entry>
    <id>urn:lj:livejournal.com:atom1:lukego:26836</id>
    <link rel="alternate" type="text/html" href="http://lukego.livejournal.com/26836.html"/>
    <link rel="self" type="text/xml" href="http://lukego.livejournal.com/data/atom/?itemid=26836"/>
    <title>EUC 2009</title>
    <published>2009-11-16T11:31:51Z</published>
    <updated>2009-11-16T13:39:15Z</updated>
    <category term="erlang"/>
    <content type="html">&lt;a href="http://pics.livejournal.com/lukego/pic/0002yax8/"&gt;&lt;img src="http://pics.livejournal.com/lukego/pic/0002yax8" width="156" height="135" border="0" align="right" /&gt;&lt;/a&gt;
The &lt;a href="http://www.erlang-factory.com/conference/ErlangUserConference2009"&gt;Erlang User Conference&lt;/a&gt; in Stockholm was a lot of fun! Thank you
everybody at Erlang Training and Consulting for the excellent organisation.
&lt;p&gt;
My favourite talk of the day was Patrik Nyblom on the development of SMP support in the BEAM
virtual machine. He was entertaining andalso inspiring: that is some
really hot technology that our programs are sitting on. I'm reminded
of Klacke's talk in London last year: Erlang programmers
&lt;i&gt;do&lt;/i&gt; have a more powerful tool than everybody else and &lt;i&gt;now&lt;/i&gt;
is the time to make the most of it.
&lt;p&gt;
Kostis Sagonas's presentation of the latest Dialyzer developments was
great too. I'm one of those opinionated bastards who doesn't care much
about standardized programming styles and this tends to put me at odds
with people writing linting tools. This time I had no room to
complain: the tool is entirely optional, the motivating examples of
bugs it can find were very easy to relate to, and it's been developed
and maintained as a production tool for many years now. Great
marketing!
&lt;p&gt;
Some of the other talks really lacked motivating examples for me. I'm
sure it's fun to write cloud-hosted databases and map-reduce
frameworks, but what problem does it solve for me? The SQL people have
long since fallen into the trap of "if all you have is a hammer,
everything looks like a nail." NoSQL might be the same.
&lt;p&gt;
I dined a bit too well with friends on the nights leading up to the conference and so I missed the first talks about Nitrogen and advanced parse-transform hackery, which is a pity because I heard they were some of the best.
&lt;p&gt;
The whole week in Stockholm has been a really great time. I'm writing
this on my short flight back to Switzerland at the moment and feeling
very glad to live in the neighbourhood again. Now back to Erlang hacking..</content>
  </entry>
  <entry>
    <id>urn:lj:livejournal.com:atom1:lukego:26577</id>
    <link rel="alternate" type="text/html" href="http://lukego.livejournal.com/26577.html"/>
    <link rel="self" type="text/xml" href="http://lukego.livejournal.com/data/atom/?itemid=26577"/>
    <title>ECLM 2009</title>
    <published>2009-09-16T22:30:34Z</published>
    <updated>2009-09-16T22:30:34Z</updated>
    <category term="openfirmware"/>
    <category term="lisp"/>
    <category term="eclm"/>
    <content type="html">&lt;a href="http://pics.livejournal.com/lukego/pic/0002xswz/"&gt;&lt;img src="http://pics.livejournal.com/lukego/pic/0002xswz/s320x240" width="120" height="106" border="0" align="right" /&gt;&lt;/a&gt;
I had an excellent time at &lt;a href="http://weitz.de/eclm2009/"&gt;ECLM&lt;/a&gt;. It's always my favourite conference -
diverse hackers, two dinners to one day of talks, great atmosphere.
I'd like to have seen more faces - Christophe Rhodes, Tim Daly, Tony
Martinez, Marc Battyani to name a few - but you can't have everybody.
Thanks a million Edi &amp; Arthur for making this happen, and see you in
Amsterdam for ECLM 2010 :-)
&lt;p&gt;
My favourite was Dimitri Simon's delightful talk about &lt;a href="http://www.piano.aero/"&gt;Piano&lt;/a&gt;. He's spent his career writing
a program that's great for aeroplane engineers like himself, he
developed it using a program that he loves (MCL), and it's maintained
with help from the many nice people in the room (Clozure, Edi,
Lispworks). He's a one-man company and his licenses start at £50,000.
What's not to smile about?
&lt;p&gt;
Paul Tarvydas and David McClain each gave forceful talks with a "this
is how real engineering is done" flavour, but I wasn't entirely convinced. Do
you really need a Lisp-based clone of Erlang with homebrew
cryptography to admin routers and farm out calculations? Or a visual
digital circuit design environment to mail-merge commercial brochures?
They seemed like brilliant and accomplished people with too much opportunity
to over-engineer their programs.
&lt;p&gt;
Dan Weinreb's talk was an enjoyable taste of Lisp programming in the
large. The impression I got was that things are going quite well and
their system is coming together nicely. One later reflection though:
whereas Lisp was a &lt;a href="http://www.paulgraham.com/carl.html"&gt;famous win&lt;/a&gt; for their
fare search engine, it seemed like more of a mixed bag for their
Oracle-Lisp-Java reservation system. I feel for them being unable to
separately compile their source files, for example. I look forward
to future reports.
&lt;p&gt;
I made a four-minute lightning presentation about &lt;a href="http://www.openfirmware.info/Open_Firmware"&gt;Openfirmware&lt;/a&gt;. I
had three things to say: if you want to experiment with
low-level programming on a well-engineered self-contained platform, it's easy with Openfirmware on OLPC. If you want to port your Lisp system (or other program) onto a
platform that's free of the C/POSIX/Unix legacy, Openfirmware is easy for that too - the only primitive you need is to call Forth's &lt;code&gt;APPLY&lt;/code&gt; and then all the drivers are yours.
And if you have an operating system of your own (like Movitz) and you
want some cheap device drivers, you can write an &lt;a href="http://en.wikipedia.org/wiki/Open_Firmware"&gt;IEEE 1275
Openfirmware&lt;/a&gt; FCODE interpreter and reuse a whole stack of portable
ones from Openfirmware. (And if you don't care about any of those
things, well, four minutes isn't a very long time.)</content>
  </entry>
  <entry>
    <id>urn:lj:livejournal.com:atom1:lukego:26307</id>
    <link rel="alternate" type="text/html" href="http://lukego.livejournal.com/26307.html"/>
    <link rel="self" type="text/xml" href="http://lukego.livejournal.com/data/atom/?itemid=26307"/>
    <title>Europe, Switzerland, OLPC, Boston, Canada, etc</title>
    <published>2009-09-07T20:22:25Z</published>
    <updated>2009-09-07T20:27:53Z</updated>
    <category term="switzerland"/>
    <content type="html">&lt;a href="http://pics.livejournal.com/lukego/pic/0002wcsy/"&gt;&lt;img src="http://pics.livejournal.com/lukego/pic/0002wcsy/s320x240" width="160" height="120" border="0" align="right" /&gt;&lt;/a&gt;
I've been busy: briefly catching up with lots of friends around
Europe, clearing Swiss immigration, exploring Switzerland by bike and
by foot, working with &lt;a href="http://howsoftwareisbuilt.com/2008/03/27/interview-with-mitch-bradley-firmware-olpc/"&gt;Mitch&lt;/a&gt; on the OLPC-1.5 rev-A2/B1 firmware, meeting interesting people
in Boston, going to a great wedding in Canada, and so on.
&lt;p&gt;
The highlight has been a quick &lt;a href="http://maps.google.com/maps?f=d&amp;amp;source=s_d&amp;amp;saddr=pfaffikon+sz&amp;amp;daddr=vulpera&amp;amp;hl=en&amp;amp;geocode=&amp;amp;mra=ls&amp;amp;dirflg=w&amp;amp;sll=46.810869,9.943314&amp;amp;sspn=0.260819,0.576096&amp;amp;ie=UTF8&amp;amp;ll=46.959636,9.558105&amp;amp;spn=1.040375,2.304382&amp;amp;t=h&amp;amp;z=9"&gt;cycle
tour&lt;/a&gt; from near Zürich (Pfäffikon) through Davos and Flüela Pass to
Vulpera near the Austrian/Italian borders. Hiked some beautiful mountains, picked lots of wild berries, and got introduced to &lt;a href="http://en.wikipedia.org/wiki/Kaiserschmarrn"&gt;Kaiserschmarrn&lt;/a&gt; at a friendly alp.
&lt;p&gt;
I'm extremely happy with my new touring setup: a
Specialized road bike, a Deuter &lt;a href="http://www.outdoorgb.com/p/deuter_superbike_18_4_ltr/"&gt;Superbike&lt;/a&gt;
backpack, a waterproof sleeping bag from REI ("just add forest"
one-piece camping kit), and bugger all else. France, Germany, Austria, Italy: I'll ride to you soon :-)
&lt;p&gt;
Current agenda: &lt;a href="http://weitz.de/eclm2009/"&gt;ECLM&lt;/a&gt; on the weekend and then finding a more permanent home
than &lt;a href="http://twitter.com/jesnellm"&gt;Juho&lt;/a&gt;'s couch in Zürich.</content>
  </entry>
  <entry>
    <id>urn:lj:livejournal.com:atom1:lukego:26030</id>
    <link rel="alternate" type="text/html" href="http://lukego.livejournal.com/26030.html"/>
    <link rel="self" type="text/xml" href="http://lukego.livejournal.com/data/atom/?itemid=26030"/>
    <title>Code snippet of the day</title>
    <published>2009-08-22T02:58:43Z</published>
    <updated>2009-08-22T02:58:43Z</updated>
    <category term="forth"/>
    <content type="html">A Forth assembler word that happened to cross my path today:&lt;br /&gt;&lt;pre&gt;
code expand-rect  ( src dst w h --- )
   dx  pop              \ Height of source image in pixels
   4 [sp] edi xchg
   8 [sp] esi xchg
   begin
      0 [sp]  cx mov   \ Width of source image in pixels
      begin
         op: ax lods                \ Get a pixel
         op: ax d# 2400 [edi] mov   \ Write to next line
         op: ax stos                \ Write to this line + increment
         op: ax d# 2400 [edi] mov   \ Write to next line
         op: ax stos                \ Write to this line + increment
      loopa
      d# 2400 # edi add             \ Skip the next output line - already written
      edx dec
   0= until
   eax pop   \ Discard source width
   edi pop   \ Restore EDI
   esi pop   \ Restore ESI
c;
&lt;/pre&gt;&lt;br /&gt;Posted just 'cause it's nice to have a little asm in life.</content>
  </entry>
  <entry>
    <id>urn:lj:livejournal.com:atom1:lukego:25634</id>
    <link rel="alternate" type="text/html" href="http://lukego.livejournal.com/25634.html"/>
    <link rel="self" type="text/xml" href="http://lukego.livejournal.com/data/atom/?itemid=25634"/>
    <title>Bottom-Up System Design Ltd</title>
    <published>2009-07-30T19:51:15Z</published>
    <updated>2009-07-30T19:51:15Z</updated>
    <category term="europe"/>
    <category term="bupsys"/>
    <content type="html">I'm back in Europe! I've started a company to continue my diverse hacktivities.
&lt;p&gt;
&lt;center&gt;&lt;a href="http://www.bupsys.com/"&gt;&lt;img border="1" src="http://www.bupsys.com/business-card.png" align="center"&gt;&lt;/a&gt;&lt;/center&gt;
&lt;p&gt;
Fancy a beer in Zürich? I'll be back after a couple of weeks in east-coast US and Canada. Drop me a line :-)</content>
  </entry>
  <entry>
    <id>urn:lj:livejournal.com:atom1:lukego:25461</id>
    <link rel="alternate" type="text/html" href="http://lukego.livejournal.com/25461.html"/>
    <link rel="self" type="text/xml" href="http://lukego.livejournal.com/data/atom/?itemid=25461"/>
    <title>Travels</title>
    <published>2009-07-22T23:44:30Z</published>
    <updated>2009-07-22T23:53:15Z</updated>
    <category term="travel"/>
    <category term="erlang"/>
    <category term="lisp"/>
    <category term="beer"/>
    <content type="html">I'm headed to Stockholm next week, and Boston the week after. I'd be happy to have the traditional tuesday Man in the Moon pub night in Stockholm if anybody's in town, and Xach's already put the word out that Lispers should come for dinner at the Cambridge Brewing Company on friday august 7th (6pm).
&lt;p&gt;
See you soon. :-)</content>
  </entry>
  <entry>
    <id>urn:lj:livejournal.com:atom1:lukego:25169</id>
    <link rel="alternate" type="text/html" href="http://lukego.livejournal.com/25169.html"/>
    <link rel="self" type="text/xml" href="http://lukego.livejournal.com/data/atom/?itemid=25169"/>
    <title>Magic numbers</title>
    <published>2009-07-22T23:34:14Z</published>
    <updated>2009-07-22T23:51:56Z</updated>
    <category term="olpc"/>
    <category term="forth"/>
    <category term="firmware"/>
    <content type="html">Today I wrote some device driver code of precisely the sort I'm always complaining about -- containing seemingly opaque magic numbers that have no relevance to the operating system and "should have been" built into the hardware:
&lt;pre&gt;
   h# 25 to node
   h# 290a8 cmd \ high-pass filter, semi-manual mode, 600Hz cutoff
   h# 34001 cmd \ speaker power 1 dB gain
   h# 38001 cmd \ over-current / short-circuit protection, 2.6A threshold
   h# 39019 cmd \ temperature protection at 130C
   h# 42011 cmd \ over-temperature shutdown of class-D
&lt;/pre&gt;
and, for once, I actually see why this is the (firmware) device driver's responsibility.
&lt;p&gt;
You see, this code is performing pre-setup of a Conexant HDAudio Codec chip to suit the physical peculiarities of the OLPC 1.5's motherboard and other components. The chip itself has no prior knowledge of the machine it's being used in, so some other component has to provide it with useful information like the power of the speakers, their frequency range, the maximum safe level of current, and so on. And so I've adopted these "magic numbers" into my firmware code quite happily -- it's information peculiar to this PC/motherboard and so the firmware is the place to put it.
&lt;p&gt;
Here's some more amusing code that's in the firmware: telling the audio chip what it's many and varied pins are connected to on the motherboard, so that it can repeat this information to Linux's audio driver. Once more -- this information can't be baked into the chip, because it's specific to the use of that chip on this particular motherboard.
&lt;pre&gt;
: port-a  ( -- u )  19 config(  1/8" green left hp-out jack     )config  ;
: port-b  ( -- u )  1a config(  1/8" pink left mic-in jack      )config  ;
: port-c  ( -- u )  1b config(  builtin front mic-in            )config  ;
: port-d  ( -- u )  1c config(  unused line-out                 )config  ;
: port-e  ( -- u )  1d config(  unused line-out                 )config  ;
: port-f  ( -- u )  1e config(  1/8" pink left line-in jack     )config  ;
: port-g  ( -- u )  1f config(  builtin front speaker           )config  ;
: port-h  ( -- u )  20 config(  unused spdiff-out               )config  ;
: port-i  ( -- u )  22 config(  unused spdiff-out               )config  ;
: port-j  ( -- u )  23 config(  unused mic-in                   )config  ;
&lt;/pre&gt;
I wonder if anyone will make use of this knowledge of what colour the audio jacks are!
&lt;p&gt;
So I've somewhat improved my mental model of the appropriate ways to factor information between chips, boards, firmwares, and operating systems.
&lt;p&gt;
That doesn't mean I'm happy about seeing this kind of information pass over USB. I'd still like to see gadgets designed for simple on-the-wire protocols, as we do on the internet, and take responsibility for as much of their own configuration as possible. I wonder whether I'll change my mind when I start building USB gadgets.. :-)</content>
  </entry>
  <entry>
    <id>urn:lj:livejournal.com:atom1:lukego:24833</id>
    <link rel="alternate" type="text/html" href="http://lukego.livejournal.com/24833.html"/>
    <link rel="self" type="text/xml" href="http://lukego.livejournal.com/data/atom/?itemid=24833"/>
    <title>Brickproofing</title>
    <published>2009-06-04T04:12:46Z</published>
    <updated>2009-06-04T04:29:33Z</updated>
    <category term="fpga"/>
    <category term="olpc"/>
    <content type="html">&lt;a href="http://pics.livejournal.com/lukego/pic/0002tbr0/"&gt;&lt;img src="http://pics.livejournal.com/lukego/pic/0002tbr0/s320x240" width="135" height="180" border="0" align="right" /&gt;&lt;/a&gt;
I &lt;a href="http://en.wikipedia.org/wiki/Brick_(electronics)"&gt;bricked&lt;/a&gt; my
OLPC XO the other week by flashing bad stuff onto the SPI FLASH.
That's the 1MB flash chip that the XO boots from -- it's supposed to
contain the &lt;a href="http://wiki.laptop.org/go/Embedded_controller"&gt;Embedded
Controller&lt;/a&gt; software image and Openfirmware, but when either of those
is messed up then the machine won't function and can't fix itself.
&lt;p&gt;
So Mitch sent me a DIY
debricking kit: a replacement SPI FLASH chip with working firmware and
some &lt;a href="http://www.curiousinventor.com/store/product/102"&gt;ChipQuick&lt;/a&gt;
to remove the old chip with. My dad and I heated up a soldering iron and eventually managed to make the transplant. That was fun! But I wouldn't want to do it that way every time :-)
&lt;p&gt;
&lt;a href="http://pics.livejournal.com/lukego/pic/0002s5d4/"&gt;&lt;img src="http://pics.livejournal.com/lukego/pic/0002s5d4/s320x240" width="160" height="120" border="0" align="right" /&gt;&lt;/a&gt;
Thankfully my new XO-1.5 boots from something much cooler than an SPI
FLASH chip: an &lt;a href="http://www.artecgroup.com/flexyice"&gt;Artec
FlexyICE&lt;/a&gt; ROM emulator attached to the &lt;a href="http://en.wikipedia.org/wiki/Low_Pin_Count"&gt;LPC bus&lt;/a&gt;. The ROM
emulator is seriously cool - it's an FPGA with two interfaces: LPC
towards the XO, impersonating a ROM chip, and USB-serial towards my
Macbook, receiving new firmware images that I'm creating. It's also open-source hardware
and ships with its ~2500 line VHDL sources.
&lt;p&gt;
I've wanted to have FPGAs in my life for quite a while now. This feels like a step in the right direction. :-)</content>
  </entry>
  <entry>
    <id>urn:lj:livejournal.com:atom1:lukego:24633</id>
    <link rel="alternate" type="text/html" href="http://lukego.livejournal.com/24633.html"/>
    <link rel="self" type="text/xml" href="http://lukego.livejournal.com/data/atom/?itemid=24633"/>
    <title>Taipei</title>
    <published>2009-06-04T02:25:32Z</published>
    <updated>2009-06-04T03:19:37Z</updated>
    <category term="olpc"/>
    <category term="forth"/>
    <content type="html">&lt;a href="http://pics.livejournal.com/lukego/pic/0002rtzz/"&gt;&lt;img src="http://pics.livejournal.com/lukego/pic/0002rtzz/s320x240" width="160" height="120" border="0" align="right" /&gt;&lt;/a&gt;
So I was lucky enough to join in the &lt;a href="http://olpc.tv/2009/06/01/olpc-xo-15-in-taipei-part-1-john-watlington/"&gt;OLPC XO 1.5 bringup&lt;/a&gt; at Quanta in
Taipei. This was great fun: I wrote an Openfirmware HDAudio driver
and we used it to test and debug parts of the main board. I got to watch people doing
cool things with soldering irons, oscilloscopes, LPC ROM emulators,
and other implements of destruction. Mitch debugged the memory controller interactively using a Forth that fits strictly in cache - that's a nice trick.
&lt;p&gt;
Bringups are fun! I would do another :-)</content>
  </entry>
  <entry>
    <id>urn:lj:livejournal.com:atom1:lukego:24446</id>
    <link rel="alternate" type="text/html" href="http://lukego.livejournal.com/24446.html"/>
    <link rel="self" type="text/xml" href="http://lukego.livejournal.com/data/atom/?itemid=24446"/>
    <title>Forth school</title>
    <published>2009-05-21T23:59:42Z</published>
    <updated>2009-05-22T00:00:45Z</updated>
    <category term="olpc"/>
    <category term="forth"/>
    <content type="html">&lt;a href="http://pics.livejournal.com/lukego/pic/0002q670/"&gt;&lt;img src="http://pics.livejournal.com/lukego/pic/0002q670/s320x240" width="160" height="120" border="0" align="right" /&gt;&lt;/a&gt;
I went to &lt;a href="http://wiki.laptop.org/go/Forth_Lessons"&gt;Forth school&lt;/a&gt; with &lt;a href="http://howsoftwareisbuilt.com/2008/03/27/interview-with-mitch-bradley-firmware-olpc/"&gt;Mitch Bradley&lt;/a&gt; yesterday. Here are a few cool new things I learned:
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;many&lt;/b&gt;: The word &lt;code&gt;many&lt;/code&gt; repeats execution of the current line until a key is pressed.
&lt;pre&gt;
ok ." luke rules" cr  many
luke rules
luke rules
luke rules
&lt;keypress&gt;
ok see many
: many   
   key? 0= if    
      0 &amp;gt;in ! 
   then  
; 
&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;quine&lt;/b&gt;: Since we can introspect the input stream it's easy to write a program that prints itself to stdout.
&lt;pre&gt;
ok ( this is a quine ) source type
( this is a quine ) source type
&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;patch&lt;/b&gt;: The word &lt;code&gt;patch&lt;/code&gt; is a simple way to make binary patches to Forth words.
&lt;pre&gt;
ok : foo 1 + ;           
ok see foo
: foo   
   1 + 
; 
ok 41 foo .
42 

ok patch - + foo
ok see foo
: foo   
   1 - 
; 
ok 43 foo .
42 

ok patch 5 1 foo
ok see foo
: foo   
   5 - 
; 
ok 47 foo .
42 
ok 
&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;
I love Forth.</content>
  </entry>
  <entry>
    <id>urn:lj:livejournal.com:atom1:lukego:24085</id>
    <link rel="alternate" type="text/html" href="http://lukego.livejournal.com/24085.html"/>
    <link rel="self" type="text/xml" href="http://lukego.livejournal.com/data/atom/?itemid=24085"/>
    <title>Catchup</title>
    <published>2009-05-18T09:16:03Z</published>
    <updated>2009-05-18T09:41:53Z</updated>
    <category term="jaoo"/>
    <category term="olpc"/>
    <content type="html">&lt;a href="http://pics.livejournal.com/lukego/pic/0002p6aw/"&gt;&lt;img src="http://pics.livejournal.com/lukego/pic/0002p6aw/s320x240" width="160" height="120" border="0" align="right" /&gt;&lt;/a&gt;
Exciting things lately - visited people along the east coast of
Australia, went to JAOO in Brisbane, bricked my OLPC XO by
installing a bad firmware, my dad and I unbricked it by soldering on a
replacement SPI FLASH chip containing good firmware (thanks
Mitch!), now getting to put my Forth where my mouth is and fly
over to Taipei to &lt;strike&gt;get in the way of&lt;/strike&gt; help with &lt;a href="http://wiki.laptop.org/go/XO1.5_Bringup"&gt;OLPC 1.5 hardware
bringup&lt;/a&gt;.&lt;p&gt;But who can be bothered blogging day-to-day events in the age of &lt;a href="http://twitter.com/lukego"&gt;twitter&lt;/a&gt;?</content>
  </entry>
  <entry>
    <id>urn:lj:livejournal.com:atom1:lukego:23858</id>
    <link rel="alternate" type="text/html" href="http://lukego.livejournal.com/23858.html"/>
    <link rel="self" type="text/xml" href="http://lukego.livejournal.com/data/atom/?itemid=23858"/>
    <title>PS/2 Mouse Decoding</title>
    <published>2009-05-01T09:35:59Z</published>
    <updated>2009-05-01T09:52:21Z</updated>
    <category term="mouse"/>
    <category term="drivers"/>
    <content type="html">Me and Ian Piumarta have been playing around with PS/2 mouse drivers and partly in Erlang. We came up with a neat way to parse the 3-byte report from a mouse that describes its position-change and button states. Here's the &lt;a href="http://computer-engineering.org/index.php?title=PS/2_Mouse_Interface"&gt;PS/2 mouse report format&lt;/a&gt;:
&lt;p&gt;
&lt;table border="1" cellpadding="4"&gt;
&lt;tr&gt;
&lt;th&gt; &lt;/th&gt;&lt;th&gt; Bit 7 &lt;/th&gt;&lt;th&gt; Bit 6 &lt;/th&gt;&lt;th&gt; Bit 5 &lt;/th&gt;&lt;th&gt; Bit 4 &lt;/th&gt;&lt;th&gt; Bit 3 &lt;/th&gt;&lt;th&gt; Bit 2 &lt;/th&gt;&lt;th&gt; Bit 1 &lt;/th&gt;&lt;th&gt; Bit 0

&lt;/th&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;th&gt; Byte1
&lt;/th&gt;&lt;td&gt; Yoverflow &lt;/td&gt;&lt;td&gt; Xoverflow &lt;/td&gt;&lt;td&gt; Ysign &lt;/td&gt;&lt;td&gt; Xsign &lt;/td&gt;&lt;td&gt; 1 &lt;/td&gt;&lt;td&gt; MiddleBtn &lt;/td&gt;&lt;td&gt; RightBtn &lt;/td&gt;&lt;td&gt; LeftBtn

&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;th&gt; Byte2
&lt;/th&gt;&lt;td align="center" colspan="8"&gt; X movement
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;th&gt; Byte3
&lt;/th&gt;&lt;td align="center" colspan="8"&gt; Y movement
&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;p&gt;
This turns out to be pretty neat to decode with Erlang's bit syntax:
&lt;pre&gt;
%% Decode a 3-byte PS/2 mouse report.
%% Return: {Xdelta, Ydelta, LeftButton, MiddleButton, RightButton}
decode_report(&amp;lt;&amp;lt;YO:1,XO:1,YS:1,XS:1,1:1,MMB:1,RMB:1,LMB:1,X:8,Y:8&amp;gt;&amp;gt;) -&amp;gt;
    {&amp;lt;&amp;lt;DX:10/signed&amp;gt;&amp;gt;,&amp;lt;&amp;lt;DY:10/signed&amp;gt;&amp;gt;} = {&amp;lt;&amp;lt;XS:1,XO:1,X:8&amp;gt;&amp;gt;, &amp;lt;&amp;lt;YS:1,YO:1,Y:8&amp;gt;&amp;gt;},
    {DX, DY, LMB, MMB, RMB}.
&lt;/pre&gt;
The DX and DY values are really 10-bit signed numbers, with the top two bits placed in the header byte, and the bit syntax has no trouble converting 10 bits from funky sources into signed numbers.
&lt;p&gt;
Here's a test function:
&lt;pre&gt;
test_decode_report() -&amp;gt;
    {42+256, 42-512, 1, 0, 1} = decode_report(&amp;lt;&amp;lt;2#01101011, 42, 42&amp;gt;&amp;gt;).
&lt;/pre&gt;</content>
  </entry>
  <entry>
    <id>urn:lj:livejournal.com:atom1:lukego:23690</id>
    <link rel="alternate" type="text/html" href="http://lukego.livejournal.com/23690.html"/>
    <link rel="self" type="text/xml" href="http://lukego.livejournal.com/data/atom/?itemid=23690"/>
    <title>My first experience with Mercurial</title>
    <published>2009-04-30T22:34:49Z</published>
    <updated>2009-04-30T22:34:49Z</updated>
    <content type="html">&lt;pre&gt;
~$ hg
Traceback (most recent call last):
  File "/usr/local/bin/hg", line 18, in &lt;module&gt;
    mercurial.util.set_binary(fp)
  File "/Library/Python/2.5/site-packages/mercurial/demandimport.py",
  line 74, in __getattribute__
    self._load()
  File "/Library/Python/2.5/site-packages/mercurial/demandimport.py",
  line 46, in _load
    mod = _origimport(head, globals, locals)
  File "/Library/Python/2.5/site-packages/mercurial/util.py",
  line 33, in &lt;module&gt;
    _encoding = locale.getlocale()[1]
  File "/System/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/locale.py",
  line 460, in getlocale
    return _parse_localename(localename)
  File "/System/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/locale.py",
  line 373, in _parse_localename
    raise ValueError, 'unknown locale: %s' % localename
ValueError: unknown locale: UTF-8
&lt;/pre&gt;</content>
  </entry>
  <entry>
    <id>urn:lj:livejournal.com:atom1:lukego:23379</id>
    <link rel="alternate" type="text/html" href="http://lukego.livejournal.com/23379.html"/>
    <link rel="self" type="text/xml" href="http://lukego.livejournal.com/data/atom/?itemid=23379"/>
    <title>lively.el 0.1</title>
    <published>2009-04-20T13:52:17Z</published>
    <updated>2009-04-20T13:52:17Z</updated>
    <content type="html">Long time no Emacs hack!
&lt;pre&gt;
;;; lively.el version 0.1 --- interactively updating text
;;; Copyright 2009 Luke Gorrie &amp;lt;luke@bup.co.nz&amp;gt;
;;;
;;; Go to the end of any of the following lines and run `M-x lively'
;;;   Current time:      (current-time-string)
;;;   Last command:      last-command
;;;   Open buffers:      (length (buffer-list))
;;;   Unix processes:    (lively-shell-command "ps -a | wc -l")
;;;
;;; then the code will be replaced by its formatted result -- and
;;; periodically updated. You can create little dashboards.
;;; Use `M-x lively-stop' to restore order.
;;;
;;; Based on the Squeak hack by Scott Wallace.

(require 'cl)

(defvar lively-overlays nil "List of all overlays representing lively text.")
(defvar lively-timer    nil "Idle timer for updating lively text.")
(defvar lively-interval 0.25 "Idle time before lively text update in seconds.")

(defun lively ()
  "Make the expression before point lively."
  (interactive)
  (lively-region (save-excursion (backward-sexp) (point)) (point)))

(defun lively-region (start end)
  "Make the region lively."
  (interactive "r")
  (when (null lively-timer)
    (lively-init-timer))
  (push (make-overlay start end) lively-overlays))

(defun lively-update ()
  "Update the display of all visible lively text."
  (interactive)
  (dolist (o lively-overlays)
    (when (get-buffer-window (overlay-buffer o))
      (condition-case err
          (lively-update-overlay o)
        (error (message "Error in lively expression: %S" err)
               (lively-delete-overlay o))))))

(defun lively-delete-overlay (o)
  (delete-overlay o)
  (setq lively-overlays (remove o lively-overlays)))

(defun lively-update-overlay (o)
  "Evaluate the lively code for O and update its display text."
  (with-current-buffer (overlay-buffer o)
    (let ((expr (buffer-substring (overlay-start o) (overlay-end o))))
      (overlay-put o 'display (format "%s" (eval (read expr)))))))

(defun lively-init-timer ()
  "Setup background timer to update lively text."
  (setq lively-timer (run-with-timer 0 lively-interval 'lively-update)))

(defun lively-stop ()
  "Remove all lively regions in Emacs."
  (interactive)
  (when lively-timer (cancel-timer lively-timer))
  (setq lively-timer nil)
  (mapc 'delete-overlay lively-overlays)
  (setq lively-overlays nil))

;;; Nice to have:

(defun lively-shell-command (command)
  "Execute COMMAND and return the output, sans trailing newline."
  (let ((result (shell-command-to-string command)))
    (substring result 0 (1- (length result)))))
&lt;/pre&gt;</content>
  </entry>
  <entry>
    <id>urn:lj:livejournal.com:atom1:lukego:23061</id>
    <link rel="alternate" type="text/html" href="http://lukego.livejournal.com/23061.html"/>
    <link rel="self" type="text/xml" href="http://lukego.livejournal.com/data/atom/?itemid=23061"/>
    <title>USB</title>
    <published>2009-04-07T07:26:44Z</published>
    <updated>2009-04-07T07:26:44Z</updated>
    <content type="html">Here's what I've discovered about some kinds of USB device:

&lt;ul&gt;

&lt;li&gt;&lt;b&gt;Keyboard and mouse&lt;/b&gt;: they support a simplified bootstrap
mode that's very simple to deal with. Here's a driver for the common
parts of bootstrap-mode keyboard and mouse:
&lt;pre&gt;
USBHID : USBDevice ()

USBHID init: devicename
[
  super init: (OFW open: devicename).
  self setConfiguration: 1.
  self setBootstrapProtocol.
]

USBHID setBootstrapProtocol
[
  self controlSetIndex: 0 value: 0
       requestType: (DR_HIDD bitOr: DR_OUT) request: SET_PROTOCOL
]

USBHID setIdle: ms
[
  self controlSetIndex: 0 value: (ms // 4 &amp;lt;&amp;lt; 8)
       requestType: (DR_HIDD bitOr: DR_OUT) request: SET_IDLE
]

USBHID selftest
[
  self init.
  1000 timesRepeat: [ self readReport ifNotNilDo: [ :e | e println]. ]
]
&lt;/pre&gt;

and here's a subclass that knows how to turn the reports into mouse events:

&lt;pre&gt;
USBMouse : USBHID ()

USBMouse init         [ self init: '/mouse' ]
USBMouse init: device [ super init: device. self setIdle: 0 ]

USBMouse readReport   [ ^MouseEvent fromUSB: (self intrIn: 1) ]

MouseEvent fromUSB: report
[
  self := self new.
  left  := (report first bitAnd: 1) ~~ 0.
  right := (report first bitAnd: 2) ~~ 0.
  dx := report second.
  dy := report third.
  "Treat bit 8 as sign."
  (dx bitAnd: 0x80) ~~ 0 ifTrue: [ dx := dx - 256 ].
  (dy bitAnd: 0x80) ~~ 0 ifTrue: [ dy := dy - 256 ].
]
&lt;/pre&gt;
The keyboard is similar: it reports the set of keys (identified by scancode) that are currently pressed, and uses a fixed mapping from scancodes onto key identifiers.
&lt;p&gt;
I regret that I haven't come back to look at the full-blown USB Human Input Device protocol yet!
&lt;/li&gt;

&lt;li&gt;&lt;b&gt;Ethernet&lt;/b&gt;: In theory the &lt;a href="http://en.wikipedia.org/wiki/USB_communications_device_class"&gt;USB
Communications Device Class&lt;/a&gt; specifies the high-level interface for
ethernet-like network adapters, but &lt;a href="http://www.linux-usb.org/usbnet/"&gt;in practice&lt;/a&gt; most
USB-ethernet dongles seem to be built from an &lt;a href="http://www.asix.com.tw/products.php?op=pIt...01&amp;amp;PLine=71"&gt;ASIX
USB-ethernet chip&lt;/a&gt;. For example, the Apple USB-ethernet dongle is
internally an ASIX 88772A.
&lt;p&gt;
ASIX chips aren't compatible with the
USB CDC standard, they use their own &lt;a href="http://www.asix.com.tw/FrootAttach/datasheet/AX88x72A_Simplified_Datasheet_v106.pdf"&gt;custom
protocol&lt;/a&gt; instead. The protocol is simple but it's lower-level
than CDC: you're sometimes peeking and poking registers instead of exchanging
messages.
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Display&lt;/b&gt;:
My previous posts (&lt;a href="http://lukego.livejournal.com/22764.html"&gt;first&lt;/a&gt;, &lt;a href="http://lukego.livejournal.com/22799.html"&gt;second&lt;/a&gt;) describe the USB-VGA adapter I found. I'm unhappy with this device: taking a notoriously closed graphics chip and blindly bridging its PCI bus onto USB is really kludgy. The components don't even seem to be particularly cheap (Octopart suggests $15 for the USB-PCI bridge chip) so I suppose the intention was to save development money by not having to program the dongle. I'd be happier if they'd spent the same money on an ARM- or FPGA- based dongle and programmed it to do the job gracefully, but that's me being a naive software guy.
&lt;/li&gt;
&lt;/ul&gt;
I'm finding driver writing frustratingly slow going. I'm used to a very experimental and exploratory programming style, but that's not very effective because when you make a mistake the devices won't tell you where! This reminds me of talking to &lt;a href="http://adywicaksono.wordpress.com/2008/05/21/understanding-gsm-0348/"&gt;SIM cards&lt;/a&gt; and &lt;a href="http://lukego.livejournal.com/6154.html"&gt;web services&lt;/a&gt;. I'm looking for a smarter working style.</content>
  </entry>
  <entry>
    <id>urn:lj:livejournal.com:atom1:lukego:22799</id>
    <link rel="alternate" type="text/html" href="http://lukego.livejournal.com/22799.html"/>
    <link rel="self" type="text/xml" href="http://lukego.livejournal.com/data/atom/?itemid=22799"/>
    <title>Cheating</title>
    <published>2009-03-26T02:29:17Z</published>
    <updated>2009-03-26T02:48:55Z</updated>
    <content type="html">&lt;a href="http://pics.livejournal.com/lukego/pic/0002k969/"&gt;&lt;img src="http://pics.livejournal.com/lukego/pic/0002k969/s320x240" width="180" height="240" border="0" align="right" /&gt;&lt;/a&gt;

So the USB2VGA dongle isn't much fun to program -- especially since I haven't found a spec for the SiS315 graphics chip. I started out by porting very tedious Linux code like this:

&lt;pre&gt;
ret |= SETIREGAND(SISCR, 0x5b, 0xdf);
ret |= SETIREG(SISSR, 0x05, 0x86);
ret |= SETIREGOR(SISSR, 0x20, 0x01);

ret |= SETREG(SISMISCW, 0x67);

for (i = 0x06; i &amp;lt;= 0x1f; i++) {
	ret |= SETIREG(SISSR, i, 0x00);
}
for (i = 0x21; i &amp;lt;= 0x27; i++) {
	ret |= SETIREG(SISSR, i, 0x00);
}
&lt;/pre&gt;

and after a while I reached the important realisation that these hundreds of numbers that you need to send the dongle in order to boot it are completely &lt;i&gt;boring&lt;/i&gt;.
&lt;p&gt;
There's no sense in filling up source files with boring numbers, so I changed strategy. I recorded what Linux sends over USB to make the dongle boot and checked whether I could just blindly replay exactly the same traffic. This turned out to be easy and fun!
&lt;p&gt;
&lt;ol&gt;
&lt;li&gt;Capture USB traffic while plugging in the dongle:
&lt;pre&gt;
tcpdump -w trace.pcap -ni usb0
&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;Open the trace in &lt;code&gt;wireshark&lt;/code&gt; and &lt;code&gt;Print&lt;/code&gt; as ascii like this:
&lt;pre&gt;
Frame 3 (14 bytes on wire, 14 bytes captured)
USB URB
    URB id: 0x00000000de478380
    URB type: URB_SUBMIT ('S')
    URB transfer type: URB_BULK (3)
    Endpoint: 0x0e
    Device: 3
    URB bus id: 1
    Device setup request: not present ('-')
    Data: present (0)
    URB status: Operation now in progress (-EINPROGRESS) (-115)
    URB length [bytes]: 6
    Data length [bytes]: 6
    [Response in: 4]
    [bInterfaceClass: Unknown (0xffff)]
    Application Data: 420044D00000
&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;Filter and massage the printed trace:
&lt;pre&gt;
#!/usr/bin/env awk -f
/Endpoint:/                     { ep = "" }
/Endpoint: 0x0[de]/             { ep = strtonum($2) }
/Application Data:/ &amp;&amp; ep != "" { printf("SND %.2x %s\n", ep, $3); }
&lt;/pre&gt;
to resemble a script:
&lt;pre&gt;
SND 0d 1F002403000004000000
SND 0d 1F006403000004000000
SND 0d 1F008403000004000000
SND 0d 1F000001000000070000
SND 0d 0F0004000000
...
&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;Write a traffic-replaying interpreter for the trace in (for example) Forth:
&lt;pre&gt;
d# 128 constant /buffer
/buffer dma-alloc value buffer   \ buffer in DMA-friendly memory.

0 value line
: SND ( "endpoint" "data" -- )
   line 1+ to line
   get-hex#                      ( endpoint )
   safe-parse-word decode-hex    ( endpoint adr len )
   dup &amp;gt;r                        ( r: len )
   buffer swap                   ( endpoint adr buffer len )
   cmove                         ( endpoint )
   buffer r&amp;gt; rot                 ( adr len endpoint )
   bulk-out ?dup if
      ." usb error on write = " .  ." line " line . abort
   then
;
&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
Then plug the dongle into my OLPC XO and execute the Forth code in Openfirmware and -- &lt;i&gt;drumroll&lt;/i&gt; -- the dongle boots! I see the contents of the framebuffer appear on my monitor. Cool!
&lt;/li&gt;
&lt;/ol&gt;
Poking around a little more at the Forth prompt reveals that the screen is initialized to 800x600 in 16bpp RGB-565 mode. I can either settle for that or make a new trace of Xorg initializing some specific display mode of my liking.
&lt;p&gt;
Beats writing it by hand :-)</content>
  </entry>
  <entry>
    <id>urn:lj:livejournal.com:atom1:lukego:22764</id>
    <link rel="alternate" type="text/html" href="http://lukego.livejournal.com/22764.html"/>
    <link rel="self" type="text/xml" href="http://lukego.livejournal.com/data/atom/?itemid=22764"/>
    <title>Opening dongles</title>
    <published>2009-03-22T07:21:49Z</published>
    <updated>2009-03-22T07:21:49Z</updated>
    <content type="html">&lt;a href="http://pics.livejournal.com/lukego/pic/0002hkbh/"&gt;&lt;img src="http://pics.livejournal.com/lukego/pic/0002hkbh/s320x240" width="180" height="240" border="0" align="right" /&gt;&lt;/a&gt;

I'm writing a driver for my &lt;i&gt;StarTech.com USB 2.0 to VGA
Display Adapter&lt;/i&gt;. I have a Linux driver for reference, but it isn't
obvious what specifications that's based on. The cool thing is that if we take the screws out of the dongle we can learn quite a
bit about how it works just by googling the part numbers printed on
the chips!
&lt;p&gt;
There are three big chips on the circuit board:
&lt;ul&gt;
&lt;li&gt;EM638325TS-6G: This is RAM -- the framebuffer will be here. (The
framebuffer has to be in the dongle -- USB isn't fast enough
to feed SVGA.)&lt;/li&gt;

&lt;li&gt;Graphics: There's a chip hidden behind a metal shield, but on the
PCB we can see it connected to the RAM and the VGA port, so it's the
video chip. The Linux sources suggest it's a SiS315(E) and I don't see
any reason to doubt.&lt;/li&gt;

&lt;li&gt;NET2280 REV1-LF: PCI-USB bridge. AHA!&lt;/li&gt;&lt;/ul&gt;
 So that's how it works --
they've taken three off-the-shelf components (RAM, PCI-Video, PCI-USB
bridge) and put them onto a custom printed circuit board together and
that's all it took to make the dongle. The rest is up to software:
the driver has to talk to the PCI-Video chip through the USB-PCI tunnel.
&lt;p&gt;
I like this world below the OS -- firmware, chips, microcontrollers,
circuit boards, FPGAs, Verilog, etc. I'm very happy to have the chance to explore it :-)</content>
  </entry>
  <entry>
    <id>urn:lj:livejournal.com:atom1:lukego:22500</id>
    <link rel="alternate" type="text/html" href="http://lukego.livejournal.com/22500.html"/>
    <link rel="self" type="text/xml" href="http://lukego.livejournal.com/data/atom/?itemid=22500"/>
    <title>cgc.fth</title>
    <published>2009-03-17T04:48:25Z</published>
    <updated>2009-03-17T04:48:25Z</updated>
    <category term="forth"/>
    <content type="html">&lt;a href="http://pics.livejournal.com/lukego/pic/0002gqxd/"&gt;&lt;img src="http://pics.livejournal.com/lukego/pic/0002gqxd/s320x240" width="160" height="120" border="0" align="right" /&gt;&lt;/a&gt;
I wrote my &lt;a href="http://github.com/lukego/fwd/tree/master"&gt;first
garbage collector&lt;/a&gt; on the trip from California to New Zealand! It's
a &lt;a href="http://en.wikipedia.org/wiki/Garbage_collection_(computer_science)#Precise_vs._conservative_and_internal_pointers"&gt;conservative
collector&lt;/a&gt; written in Forth. I need to teach it how to find the
root set for C programs before I can try it on the application I have
in mind, but I'm not in the mood to do that right now so I just blog
it as a small hack for the moment.
&lt;p&gt;
Forth tips would be welcome. :-)</content>
  </entry>
  <entry>
    <id>urn:lj:livejournal.com:atom1:lukego:22266</id>
    <link rel="alternate" type="text/html" href="http://lukego.livejournal.com/22266.html"/>
    <link rel="self" type="text/xml" href="http://lukego.livejournal.com/data/atom/?itemid=22266"/>
    <title>Dunedin, Otago</title>
    <published>2009-03-09T21:36:49Z</published>
    <updated>2009-03-09T21:36:49Z</updated>
    <content type="html">&lt;a href="http://pics.livejournal.com/lukego/pic/0002fa8c/"&gt;&lt;img src="http://pics.livejournal.com/lukego/pic/0002fa8c/s320x240" width="160" height="106" border="0" align="right" /&gt;&lt;/a&gt;

I'll be writing device drivers from Dunedin, New Zealand from next week until easter. I'd love to meet some like-minded programmers thereabouts so please drop me a line on &lt;code&gt;lukego@gmail.com&lt;/code&gt; if you fancy a coffee or know of an interesting event!
&lt;p&gt;
I have &lt;code&gt;xoos&lt;/code&gt; talking to my USB mouse and keyboard with the bootstrap-protocol and that was easy enough. I'm working in a non-public repository right now so I'll post the code later when more is working.</content>
  </entry>
  <entry>
    <id>urn:lj:livejournal.com:atom1:lukego:21794</id>
    <link rel="alternate" type="text/html" href="http://lukego.livejournal.com/21794.html"/>
    <link rel="self" type="text/xml" href="http://lukego.livejournal.com/data/atom/?itemid=21794"/>
    <title>grep</title>
    <published>2009-02-26T21:04:43Z</published>
    <updated>2009-02-26T21:04:43Z</updated>
    <content type="html">Hey I think I found a bug in the grep on Ubuntu!

&lt;pre&gt;
﻿﻿﻿$ echo -ne '         U GC_init\n0000000a t TTFont___5fdebugName\n' &amp;gt; f
$ cat f
         U GC_init
0000000a t TTFont___5fdebugName
$ cat f | grep -w T               # This gets it WRONG!
0000000a t TTFont___5fdebugName
$ cat f | grep -w T | grep -w T   # but this is right!
$ grep --version
GNU grep 2.5.3
&lt;/pre&gt;

How exciting!</content>
  </entry>
  <entry>
    <id>urn:lj:livejournal.com:atom1:lukego:21706</id>
    <link rel="alternate" type="text/html" href="http://lukego.livejournal.com/21706.html"/>
    <link rel="self" type="text/xml" href="http://lukego.livejournal.com/data/atom/?itemid=21706"/>
    <title>Erlounge San Francisco</title>
    <published>2009-02-24T04:34:32Z</published>
    <updated>2009-02-24T04:36:25Z</updated>
    <content type="html">See you at &lt;a href="http://sferlounge.com/"&gt;sferlounge&lt;/a&gt; in San Francisco on thursday!</content>
  </entry>
  <entry>
    <id>urn:lj:livejournal.com:atom1:lukego:21434</id>
    <link rel="alternate" type="text/html" href="http://lukego.livejournal.com/21434.html"/>
    <link rel="self" type="text/xml" href="http://lukego.livejournal.com/data/atom/?itemid=21434"/>
    <title>New Openfirmware tricks</title>
    <published>2009-02-21T05:00:50Z</published>
    <updated>2009-02-23T19:24:38Z</updated>
    <category term="openfirmware"/>
    <category term="forth"/>
    <content type="html">&lt;a href="http://pics.livejournal.com/lukego/pic/0002e994/"&gt;&lt;img src="http://pics.livejournal.com/lukego/pic/0002e994/s320x240" width="160" height="93" border="0" align="right" /&gt;&lt;/a&gt;
I'm hacking on XOOS again! Now it's my vehicle to explore USB.
&lt;p&gt;
To make life better I've optimized my XOOS edit-compile-boot
loop: now I type 'make' on my Macbook and four seconds later the new
operating system has loaded and started executing on my XO.
&lt;p&gt;
Here are the tricks I learned, mostly from Mitch Bradley, as I went along:

&lt;ul&gt;
&lt;li&gt;Openfirmware accepts gzipped operating systems. For me the time to compress/decompress is well worth the savings over the network.&lt;/li&gt;

&lt;li&gt;Boot a new OS without resetting the hardware: &lt;pre&gt;ok 0 to already-go?  boot&lt;/pre&gt;&lt;/li&gt;

&lt;li&gt;You can move configuration variables (as in &lt;code&gt;printenv&lt;/code&gt; and &lt;code&gt;setenv&lt;/code&gt;) into NVRAM to have them preserved between boots. To do this you need to rebuild Openfirmware (type &lt;code&gt;make&lt;/code&gt; in &lt;code&gt;cpu/x86/pc/olpc/build/&lt;/code&gt;) after uncommenting this line from &lt;code&gt;cpu/x86/pc/olpc/config.fth&lt;/code&gt;:
&lt;pre&gt;
\ create use-flash-nvram
&lt;/pre&gt;

You should use Openfirmware version Q2E33 for the fix in SVN rev r1111. Otherwise you may see verifier-errors that make it look like your firmware is corrupted when in fact it isn't.
&lt;/li&gt;

&lt;li&gt;Once NVRAM is enabled you can store your own little Forth
extras in there. Type &lt;code&gt;nvedit&lt;/code&gt; to edit your
&lt;code&gt;nvramrc&lt;/code&gt; (CTRL-X to exit) and use &lt;code&gt;setenv use-nvramrc? true&lt;/code&gt; to make it run automatically on boot. 
&lt;/li&gt;

&lt;li&gt;Use a static IP address on the XO.
&lt;pre&gt;ok setenv ip-address 10.0.0.42&lt;/pre&gt;&lt;/li&gt;

&lt;li&gt;I setup the XO to automatically boot a new operating system build
the moment it's ready. First I wrote in my &lt;code&gt;nvramrc&lt;/code&gt; a
Forth command to keep on attempting to download and boot an OS until
it succeeds:

&lt;pre&gt;
: rerun ( -- )
  begin
    " " ['] boot-load catch nip
  0= until
  go
;
&lt;/pre&gt;

and then I very forcefully made OFW call &lt;code&gt;rerun&lt;/code&gt; every time it becomes idle, e.g. when my operating system finishes executing and returns. The hook I used was overriding the word for printing the Forth prompt:
&lt;pre&gt;
ok ' rerun is prompt
&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;I didn't want the XO to busy-loop trying boot all the time, so I tell it to boot from a CGI script on my Macbook's webserver:

&lt;pre&gt;ok setenv boot-device http:\\10.0.0.1\cgi-bin\os&lt;/pre&gt;

The CGI script waits until the OS image is created, sends it over to
Openfirmware, and then deletes it. That way each request returns the next image.
Here's the script:
&lt;pre&gt;
#!/bin/sh
os="/tmp/os"
until test -f $os; do sleep 1; done
echo "Content-Type: application/octet-stream"
echo "Content-Length: $(ls -l $os | awk '{print $5}')"
echo
cat $os
rm $os
&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;</content>
  </entry>
  <entry>
    <id>urn:lj:livejournal.com:atom1:lukego:21033</id>
    <link rel="alternate" type="text/html" href="http://lukego.livejournal.com/21033.html"/>
    <link rel="self" type="text/xml" href="http://lukego.livejournal.com/data/atom/?itemid=21033"/>
    <title>Back on the hack</title>
    <published>2009-02-16T00:18:51Z</published>
    <updated>2009-02-16T00:18:51Z</updated>
    <content type="html">&lt;a href="http://pics.livejournal.com/lukego/pic/0002det7/"&gt;&lt;img src="http://pics.livejournal.com/lukego/pic/0002det7/s320x240" width="90" height="120" border="0" align="right" /&gt;&lt;/a&gt;

I'm hanging out in Los Angeles and thinking hard about programming again. What I want
in life is a computer that feels like it's my own -- running hardware
and software that I understand and like. Not a lot to ask!
&lt;p&gt;
I'm imagining a USB-based computer now. The idea is simple: a
computer that's just a CPU with a USB port, an operating system with
only a USB driver, and the rest as plain ol' high-level software.
&lt;p&gt;
I'm currently at the starting stage of reading USB Complete, looking
for an expedient programming language &amp; platform for USB exploration,
and toying around with my incredibly sexy new toy: a &lt;a href="http://www.gumstix.com/"&gt;Gumstix Overo&lt;/a&gt;.
&lt;p&gt;
In other news I'm one healthy bastard after an amazing 2000km bike
ride through Laos and exploration of Angkor Wat.</content>
  </entry>
  <entry>
    <id>urn:lj:livejournal.com:atom1:lukego:20954</id>
    <link rel="alternate" type="text/html" href="http://lukego.livejournal.com/20954.html"/>
    <link rel="self" type="text/xml" href="http://lukego.livejournal.com/data/atom/?itemid=20954"/>
    <title>Laos by bike</title>
    <published>2009-01-23T08:26:37Z</published>
    <updated>2009-01-23T09:10:11Z</updated>
    <category term="holiday"/>
    <category term="asia"/>
    <category term="laos"/>
    <content type="html">&lt;a href="http://pics.livejournal.com/lukego/pic/0002cp2z/"&gt;&lt;img src="http://pics.livejournal.com/lukego/pic/0002cp2z/s320x240" width="160" height="120" border="0" align="right" /&gt;&lt;/a&gt;
My accomplice and I have now biked around 1150km from Thailand to the Laos capital (Chiang Rai - Chiang Kong - Nam Thong - Luang Namtha - Nom Kiaw - Luang Prabang - Vientiane) and then expressed our way by night bus down to Paksi in the south to spend the last two weeks exploring the Bolaven plateau, 4000 Islands of the Meekong Delta, and Ankor Wat in Cambodia. The verdict is in: bike touring is an excellent way to see a country.
&lt;p&gt;
We made it to the Thai border on the first day covering 100km of deceptively easy flat going on good roads followed by 20km of up-and-down hills in fading daylight on the approach to Chiang Kong. The next morning we took a taxi boat a couple of hundred meters across the Meekong and through the Laos border in time for an excellent Laos lunch: a fried noodle and noodle soup, with a huge bowl of fresh herbs to mix in by the hands-full (mint, coriander, lime, etc). Then, not understanding why the guides recommend a boat trip up or down the Meekong, we hopped on the bikes and charged straight through the very-bloody-steep mountains for a couple of days to Luang Namtha.
&lt;p&gt;
On the way through we spent a night in a little village called Nam Thong: highly recommendable! The people were really in awe of &lt;i&gt;farang&lt;/i&gt; here and everywhere we walked we were followed by wide eyes and gaping mouths of the local children, but all the same it was fun to follow the piglets around and chat with the dogs. We ate dinner with our hosts: a basket of sticky rice, a tasty soup, and a bbq fish. The Lao style of eating is to pull out a lump of sticky rice, mold it into a ball with your fingers, and then dip and scoop some meat and sauce onto it and eat it. Really fun! And practical because you don't get sauce all over your fingers :-)
&lt;p&gt;
Highlights further along the way have been relaxing on the riverbanks at Nom Kiow, indulging in pizza and french wine in Luang Prabang, &lt;a href="http://thaireland.ie/blog/day19/day_19.html"&gt;meeting&lt;/a&gt; some &lt;a href="http://www.thaireland.ie/"&gt;crazy irishmen&lt;/a&gt; by a hot spring, and the amazing scenery of limestone formations on the way into Vang Vieng.</content>
  </entry>
  <entry>
    <id>urn:lj:livejournal.com:atom1:lukego:20626</id>
    <link rel="alternate" type="text/html" href="http://lukego.livejournal.com/20626.html"/>
    <link rel="self" type="text/xml" href="http://lukego.livejournal.com/data/atom/?itemid=20626"/>
    <title>Gone bikin'</title>
    <published>2009-01-05T01:49:59Z</published>
    <updated>2009-01-05T01:50:29Z</updated>
    <content type="html">I'm bicycling through Laos for the next month. I'll catch up on emails when I get back!</content>
  </entry>
</feed>
