<?xml version="1.0" encoding="iso-8859-1"?> <rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:admin="http://webns.net/mvcb/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:content="http://purl.org/rss/1.0/modules/content/">

<channel>
<title>Lost Art of Computer Programming</title>
<link>http://www.cucy.net/lacp/</link>
<description>The Travels of an Accidental Programmer</description>
<dc:language>en-us</dc:language>
<dc:creator>curt@cbrune.com</dc:creator>
<dc:rights>Copyright 2012</dc:rights>
<dc:date>2006-06-01T08:24:44-08:00</dc:date>
<admin:generatorAgent rdf:resource="http://www.movabletype.org/?v=5.13-en" />
<admin:errorReportsTo rdf:resource="mailto:curt@cbrune.com"/>
<sy:updatePeriod>hourly</sy:updatePeriod>
<sy:updateFrequency>1</sy:updateFrequency>
<sy:updateBase>2000-01-01T12:00+00:00</sy:updateBase>


<item>
<title>Talking Dirty with GDB and SSH Tunneling</title>
<link>http://www.cucy.net/lacp/archives/000024.html</link>
<description> Ever debugged a program remotely and felt like telling your computer where to go and how to get there? Hopelessly adding calls to printf() and recompiling as a steady string of explectatives flow from your over-caffeinated brain waves. Fear not! Help is on the way. Read on to learn...</description>
<guid isPermaLink="false">24@http://www.cucy.net/lacp/</guid>
<content:encoded><![CDATA[<p>
Ever debugged a program remotely and felt like telling your computer where to go and how to get there?  Hopelessly adding calls to <code>printf()</code> and recompiling as a steady string of explectatives flow from your over-caffeinated brain waves.
</p>
<p>Fear not!  Help is on the way.  Read on to learn how to use gdbserver and ssh tunnelling to debug remote processes.
</p>
<p>
<center>
<a href="/lacp/img/network3.png"><img src="/lacp/img/network3-small.png"></a><br>
Click to enlarge
</center>
</p>
<p>
 In embedded systems development making do with less is the name of
 the game &ndash;  less CPU power, less physical RAM and less peristant
 storage (if any!) to name a few.  Debugging a misbehaving process in
 this environment can be challenging, but a little ingenuity coupled
 with plenty of
 <a href="http://www.fsf.org/licensing/essays/free-sw.html">free
  software</a> eases the problem.
</p>
<p>
 In this article I will explain how to use <a href="http://www.gnu.org/software/gdb/">GDB</a>
 for debugging remote processes running on embedded systems from our desktop workstation.
</p>

<p>
  For the purposes of this article the embedded system is a RPX_Lite
  from <a href="http://www.embeddedplanet.com/">EmbeddedPlanet</a>,
  which I discussed in a <a href="http://www.cucy.net/lacp/archives/000011.html">previous article</a>.  This board has a blindingly fast (not) 80MHz 823e  
  PowerPC processor with 16MB of RAM. It's pretty cute, a 3 inch square
  that includes ethernet, USB, serial and a PCMCIA slot. Just right for
  experimenting.
</p>
<p>
</p>
<h3>Major Differences</h3>
<p>
While many differences exist between desktops and embedded systems
running GNU/Linux, the biggest difference is size and power.  Embedded
systems have very specific design goals limiting the overall power
consumption and physical dimensions.  This leads to the use of low
power CPUs, limited physical RAM and little or no persistant storage
devices.
</p>
<p>
The next major difference is the CPU architecture &ndash; embedded systems
often use low power CPUs that are not x86 based.  To compile programs
from your x86 based desktop you need "cross-compilation tools", which
run on your local desktop, but generate excutable code for the target
architecture.  In this article I will be cross-compiling for the
PowerPC architecture.
</p>
<p>
The last major difference is perspective.  You will be debugging a
process that is executing on a remote CPU not your local workstation.
This requires a slightly different mindset then traditional
debugging.  
</p>
<p>
</p>
<h3>ELF and Binutil Background</h3>
<p>
Before getting to the nuts and bolts here's a quick review about how
executable code and debugging information is stored in an <a
href="http://www.cs.ucdavis.edu/~haungs/paper/node10.html">ELF</a>
binary.  Most modern *NIX systems use the the ELF format for
executables and shared libraries.
</p>
<p>
On a GNU/Linux system a family of utilities called <a
href="http://www.gnu.org/software/binutils/">binutils</a> exists for
examining and manipulating ELF objects.  In a cross-compiling
development environment the usual tool names like <code>gcc</code>, <code>gdb</code> and all
the binutils will have a prefix that describes the target
architecture.
</p>
<p>
In this article I'm targeting the PowerPC 823e and the
tool prefix is "ppc_8xx-".  I am using the wonderful <a href="http://www.denx.de/wiki/DULG/ELDK">Embedded Linux Development Kit (ELDK)</a>, which has complete toolchains for the PowerPC.
</p>
<p>
Let's play around with some of the binutils using a simple "Hello
World" application:
</p>
<pre>
  #include <stdio.h>

  int main(void) {
    
    printf("Hello World\n");

    return 0;

  }</pre>
<p>
First let's compile the program with debugging symbols using the <code>-g</code>
option.
</p>
<pre>
  ppc_8xx-gcc -g -o hello hello.c</pre>
<p>
Note I used the cross compiler, <code>ppc_8xx-gcc</code>, to compile the program
for the PowerPC 823e target.
</p>
<p>
On my system the resulting binary size is 20632 bytes.
</p>
<p>
  To see what symbols the binary contains use the <code>nm</code> binary utility.
Remember I'm using the PowerPC version of nm, ppc_8xx-nm.
</p>
<pre>
   coz:~/articles/rgdb$ ppc_8xx-nm hello
   10010868 D _DYNAMIC
   10010948 T _GLOBAL_OFFSET_TABLE_
   [... stuff deleted]
   1001085c W data_start
   10000408 t frame_dummy
   1000048c T main
   100109d4 b object.2
   10010860 d p.0
            U printf@@GLIBC_2.0
   
The interesting lines for us are near the bottom:
   1000048c T main
            U printf@@GLIBC_2.0</pre>
<p>
The first line shows the address of the main() function is 1000048c.
"T" means the text section, which is an old term for the section where
the code resides.  The next line shows that printf() is an
unresolved symbol and will be loaded from a shared library at run time.
</p>
<p>
Interesting.
</p>
<p>
The ELF format defines sections where various information
about the executable is stored.  The most interesting sections are:
</p>
<p>
  <ul>
    <li>text -- where the executable code lives</li>
    <li>data -- where global variables live</li>
    <li>rodata -- where global "read only" constants live</li>
  </ul>
</p>
<p>
In addition several other sections also are present,
including sections containing the debugging information.  To see all
the sections and their sizes use the <code>objdump</code> binutil with the <code>-h</code>
option to display section headers.
</p>
<pre>
  coz:~/articles/rgdb$ ppc_8xx-objdump -h hello
  
  hello:     file format elf32-powerpc
  
  Sections:
  Idx Name          Size      VMA       LMA       File off  Algn
    0 .interp       0000000d  10000114  10000114  00000114  2**0
                    CONTENTS, ALLOC, LOAD, READONLY, DATA
    1 .note.ABI-tag 00000020  10000124  10000124  00000124  2**2
                    CONTENTS, ALLOC, LOAD, READONLY, DATA
    2 .hash         00000030  10000144  10000144  00000144  2**2
                    CONTENTS, ALLOC, LOAD, READONLY, DATA
    3 .dynsym       00000070  10000174  10000174  00000174  2**2
                    CONTENTS, ALLOC, LOAD, READONLY, DATA
    4 .dynstr       0000007a  100001e4  100001e4  000001e4  2**0
                    CONTENTS, ALLOC, LOAD, READONLY, DATA
    5 .gnu.version  0000000e  1000025e  1000025e  0000025e  2**1
                    CONTENTS, ALLOC, LOAD, READONLY, DATA
    6 .gnu.version_r 00000020  1000026c  1000026c  0000026c  2**2
                    CONTENTS, ALLOC, LOAD, READONLY, DATA
    7 .rela.dyn     0000000c  1000028c  1000028c  0000028c  2**2
                    CONTENTS, ALLOC, LOAD, READONLY, DATA
    8 .rela.plt     00000030  10000298  10000298  00000298  2**2
                    CONTENTS, ALLOC, LOAD, READONLY, DATA
    9 .init         00000028  100002c8  100002c8  000002c8  2**2
                    CONTENTS, ALLOC, LOAD, READONLY, CODE
   10 .text         00000528  100002f0  100002f0  000002f0  2**2
                    CONTENTS, ALLOC, LOAD, READONLY, CODE
   11 .fini         00000020  10000818  10000818  00000818  2**2
                    CONTENTS, ALLOC, LOAD, READONLY, CODE
   12 .rodata       00000024  10000838  10000838  00000838  2**2
                    CONTENTS, ALLOC, LOAD, READONLY, DATA
   13 .sdata2       00000000  1000085c  1000085c  0000085c  2**2
                    CONTENTS, ALLOC, LOAD, READONLY, DATA
   14 .data         00000008  1001085c  1001085c  0000085c  2**2
                    CONTENTS, ALLOC, LOAD, DATA
   15 .eh_frame     00000004  10010864  10010864  00000864  2**2
                    CONTENTS, ALLOC, LOAD, DATA
   16 .dynamic      000000c8  10010868  10010868  00000868  2**2
                    CONTENTS, ALLOC, LOAD, DATA
   17 .ctors        00000008  10010930  10010930  00000930  2**2
                    CONTENTS, ALLOC, LOAD, DATA
   18 .dtors        00000008  10010938  10010938  00000938  2**2
                    CONTENTS, ALLOC, LOAD, DATA
   19 .jcr          00000004  10010940  10010940  00000940  2**2
                    CONTENTS, ALLOC, LOAD, DATA
   20 .got          00000014  10010944  10010944  00000944  2**2
                    CONTENTS, ALLOC, LOAD, CODE
   21 .sdata        00000000  10010958  10010958  00000958  2**2
                    CONTENTS, ALLOC, LOAD, DATA
   22 .sbss         00000000  10010958  10010958  00000958  2**0
                    ALLOC
   23 .plt          00000078  10010958  10010958  00000958  2**2
                    ALLOC, CODE
   24 .bss          0000001c  100109d0  100109d0  00000958  2**2
                    ALLOC
   25 .comment      0000016e  00000000  00000000  00000958  2**0
                    CONTENTS, READONLY
   26 .debug_aranges 00000020  00000000  00000000  00000ac6  2**0
                    CONTENTS, READONLY, DEBUGGING
   27 .debug_pubnames 00000040  00000000  00000000  00000ae6  2**0
                    CONTENTS, READONLY, DEBUGGING
   28 .debug_info   00001f81  00000000  00000000  00000b26  2**0
                    CONTENTS, READONLY, DEBUGGING
   29 .debug_abbrev 00000271  00000000  00000000  00002aa7  2**0
                    CONTENTS, READONLY, DEBUGGING
   30 .debug_line   00000232  00000000  00000000  00002d18  2**0
                    CONTENTS, READONLY, DEBUGGING
   31 .debug_frame  0000003c  00000000  00000000  00002f4c  2**2
                    CONTENTS, READONLY, DEBUGGING
   32 .debug_str    00000041  00000000  00000000  00002f88  2**0
                    CONTENTS, READONLY, DEBUGGING</pre>    
<p>
WOW!  That's a lot of sections and many of them contain debug
information.  These sections can add quite a bit of size to an
executable and none of it is essential to running the program.  The
information is only useful when trying to debug.
</p>
<p>
  Aside: the <code>ctors</code> and <code>dtors</code> sections are for "constructors" and
"destructors", like those used for static C++ objects.
</p>
<p>
In order to save as much space as possible on an embedded system we
often strip off all the non-essential information from the ELF
sections.  The binutil <code>strip</code> does just this.
</p>
<pre>
   coz:~/articles/rgdb$ ppc_8xx-strip hello</pre>
<p>
Now the size of my executable is 4092 bytes, a reduction of 16540
bytes.  That is over an 80% reduction &ndash; awesome!  But it comes at a
price.  Without the debug sections debugging will be impossible...
</p>
<p>
Sort of.  More on that later.  
</p>
<p>
</p>
<h3>Remote Debugging With GDB</h3>
<p>
So now we have a stripped application that we can execute on our
embedded system.  But what if it is crashing and we want to debug it?
A couple of obsticles sit in our way.
</p>
<p>
First, the target system has limited storage so we did not bother to
put a cross-compiled version of GDB on it.  On my development
workstation the GDB executable is 9973975 bytes, nearly 10 megabytes.
Clearly that won't leave much room for anything else if I only have
16MB total on the embedded system.
</p>
<p>
What to do?
</p>
<p>
The answer is to use <a href="http://sources.redhat.com/gdb/current/onlinedocs/gdb_18.html#SEC163">gdbserver</a>, a small footprint server that
implements the low level features of GDB.
</p>
<p>
Consider the following diagram &ndash; using TCP the feature-rich GDB on my
workstation connects to the light-weight gdbserver running on the
embedded system.  Most of the heavy lifting is done by the GDB on my
workstation, while gdbserver deals with the low level interactions.
</p>
<p>
<center>
<a href="/lacp/img/network.png"><img src="/lacp/img/network-small.png"></a><br>
Click to enlarge
</center>
</p>
<p>
On my system gdbserver is only 59303 bytes, a considerable improvement
over the size of the full GDB program.
</p>
<p>
In the following examples my workstation, <code>coz</code>, has the IP address of
10.0.0.10 and the embedded system, <code>gw</code>, has an IP address of 10.0.0.20 as
shown in the above diagram.
</p>
<p>
The first step is to attach the gdbserver to a process on the target
system.  You can have gdbserver start a program and attach to it
immediately or you can attach to an already running process using the
process ID (<code>pid</code>).  The last argument you need to specify is the TCP port
that gdbserver will listen on.  Here's the syntax:
</p>
<pre>
   gdbserver host:2222 PROGRAM [ARGS...]
   gdbserver host:2222 --attach PID</pre>
<p>
In the above examples the gdbserver would listen on port 2222.  Using
gdbserver to launch our hello world application on the embedded system
looks like this:
</p>
<pre>
   gdbserver host:2222 hello
   Process hello created; pid = 23125
   Listening on port 2222</pre>
<p>
The prompt does not comeback as the gdbserver is now blocking, waiting
for connections on port 2222.
</p>
<p>
The next step is to start the main GDB program on your workstation and
connect to the gdbserver process.  In order for the main GDB debug my
program it needs to examine the "unstripped" version of executable
that contains all of the debugging symbols.  The simplest thing to is
to <code>chdir</code> to the directory containing the unstripped executable and
start the cross compiled version of the gdb, like this:
</p>
<pre>
   coz:~$ cd ~/articles/rgdb
   coz:~/articles/rgdb$ ppc_8xx-gdb
   GNU gdb Yellow Dog Linux (5.2.1-4b_4)
   Copyright 2002 Free Software Foundation, Inc.
   GDB is free software, covered by the GNU General Public License, and you are
   welcome to change it and/or distribute copies of it under certain conditions.
   Type "show copying" to see the conditions.
   There is absolutely no warranty for GDB.  Type "show warranty" for details.
   This GDB was configured as "--host=i386-redhat-linux --target=ppc-linux".
   (gdb)</pre>
<p>
To "tell" GDB to read the symbols from the unstripped executable use
  the GDB <code>file</code> command like this:
</p>
<pre>
   (gdb) file hello
   Reading symbols from /home/curt/articles/rgdb/hello...done.</pre>
<p>
If your application uses shared libraries and most real world
applications do, then you also need to tell GDB where to locate these
libraries.  These need to be the unstripped versions of these
libraries so that GDB can tell you more info.
</p>
<p>
Set the GDB "solib-search-search-path" variable so that GDB can find
the shared libraries used by your application, like this:
</p>
<pre>
   (gdb) set solib-search-path  [path to libraries]</pre>
<p>
If your application has a lot of shared libraries spread all over your
source tree (and most real world ones do) then here's a little trick
for the solib-search-path variable.  Create one directory and populate
it with symlinks to all of your shared libraries.  Then you need only
specify this one directory when setting the solib-search-path
variable.  Comes in handy.
</p>
<p>
Now we are ready to connect to the gdbserver running on the embedded
system.  We use the <code>target remote</code> command from the main GDB command
prompt, like this:
</p>
<pre>
   (gdb) target remote 10.0.0.20:2222
   Remote debugging using 10.0.0.20:2222
   0x10000120 in ?? ()</pre>
<p>
On the embedded system console you should see this output:
</p>
<pre>
   Remote debugging from host 10.0.0.10</pre>
<p>
Now we are connected and the program being debugged is currently
paused.  Now would be a good time to set some break points and then
continue running the program.  Here's an example:
</p>
<pre>
   (gdb) b main
   Breakpoint 1 at 0x1000048c: file hello.c, line 4.
   (gdb) continue
   Continuing.
   
   Breakpoint 1, main () at hello.c:4
   4		printf("Hello World\n");</pre>
<p>
And there we are!  We are remotely debugging the stripped executable.
Pretty cool, huh?  I love it!  You can now use all your favourite GDB
commands and techniques to debug.
</p>
<p>
Personally I like running GDB from within <a href="http://www.gnu.org/software/emacs/">Emacs</a>, but your tastes may
vary.  You can use any GDB front-end you want for remote debugging.
Very nice.
</p>
<p>
</p>
<h3>SSH Tunneling and GDB</h3>
<p>
Suppose you have the network topology shown in the following diagram
and you want to debug a process running on the host <code>wonkel</code>.  In this
topology the host <code>gw</code> is dual homed with one interface on the
10.0.0.0/24 network and one on the 192.168.1.0/24 network.  The host
<code>wonkel</code> is also on the 192.168.1.0 network, while your workstation is
on the 10.0.0.0 network.
</p>
<p>
<center>
<a href="/lacp/img/network2.png"><img src="/lacp/img/network2-small.png"></a><br>
Click to enlarge
</center>
</p>
<p>
The diagram also depicts a serial console connection from <code>coz</code> to
<code>wonkel</code> &ndash; serial UART connections are very common on embedded systems
for debug purposes, a back door for when the network connection is not
working.  Even though they are a bit slow, UARTs are cheap, reliable
and easy to configure.  A serial console is usually the first bit of
hardware tested out when bringing up a new board.
</p>
<p>
The problem here is that no routable network path exists from <code>coz</code> to
<code>wonkel</code> &ndash; <code>gw</code> cannot act as a gateway and forward packets in the normal
manner.
</p>
<p>
What to do?  I'll be honest &ndash; a lot solutions present themselves.
You could configure <a href="http://www.netfilter.org/">iptables</a> on <code>gw</code> to forward packets from <code>coz</code> to
<code>wonkel</code>.  That works fine if you have root access to <code>gw</code>.
</p>
<p>
Another method is to use the port forwarding capabilities of your old
friend, <a href="http://www.openssh.com/">ssh</a>.  The trick here is
to forward connections on a local <code>coz</code> port to a port on <code>wonkel</code> &ndash; as a
side benefit the traffic on the tunneled port is also encrypted by the
SSH protocol.
</p>
<p>
Via the serial console you can login to <code>wonkel</code> and perform basic
commands.  Using the serial console start the gdbserver on <code>wonkel</code>,
just like the previous example:
</p>
<pre>
   gdbserver host:2222 hello
   Process hello created; pid = 23125
   Listening on port 2222</pre>
<p>
Now we need to create an SSH tunnel from <code>coz</code> to <code>wonkel</code> via <code>gw</code>.  Here's
the command to do that:
</p>
<pre>
   ssh -L 4000:wonkel:2222 curt@gw</pre>
<p>
  This opens a listening TCP socket on the local host, <code>coz:4000</code>.
Whenever a connection is made to this socket it is forwarded to the
sshd process on <code>gw</code>, which then opens a connection to <code>wonkel:2222</code>.
This is shown in the following diagram.
</p>
<p>
<center>
<a href="/lacp/img/network3.png"><img src="/lacp/img/network3-small.png"></a><br>
Click to enlarge
</center>
</p>
<p>
Now we can start GDB on <code>coz</code> like before, but this time the "target
host" command use localhost:4000, like this:
</p>
<pre>
   (gdb) target remote localhost:4000
   Remote debugging using localhost:4000
   0x10000120 in ?? ()</pre>
<p>
This connection is tunneled via <code>gw</code> to <code>wonkel:2222</code>.  On the <code>wonkel</code>
serial console you should see:
</p>
<pre>
   Remote debugging from host 192.168.1.20</pre>
<p>
Note <code>wonkel</code> thinks the debug request is coming from <code>gw</code>, not <code>coz</code>.
</p>
<p>
Now you can proceed to debug as before.
</p>
<p>
I hope you have found this intro to remote debugging and ssh
tunnelling useful.  All comments are welcome.
</p>
<p>
Happy hacking!
</p>
<p>
-Curt
</p>
<p>
---------------------<br>
No commercial products were harmed in the writing of this article
</p>
<p>
</p>
<p>
</p>
<a href="http://www.cucy.net/cgi-bin/mt/mt-tb.cgi?__mode=view&entry_id=24" onclick="OpenTrackback(this.href); return false">TrackBack (0)</a> | <a href="http://www.cucy.net/lacp/archives/000024.html#comments" title="Comment on: Talking Dirty with GDB and SSH Tunneling">Comments (1)</a></p>]]></content:encoded>
<dc:subject>General</dc:subject>
<dc:date>2006-06-01T08:24:44-08:00</dc:date>
</item>

<item>
<title>Lifestyle Routing</title>
<link>http://www.cucy.net/lacp/archives/000023.html</link>
<description><![CDATA[ Even with the best of maps and instruments, we can never fully chart our journeys. &ndash; Gail Pool The questions worth asking have not answers worth knowing, but rather they engender journeys worth taking. &ndash; Curt Brune This article describes the motivations behind and the inner workings of a...]]></description>
<guid isPermaLink="false">23@http://www.cucy.net/lacp/</guid>
<content:encoded><![CDATA[    <blockquote>
      Even with the best of maps and instruments, we can never fully chart
      our journeys.<br>
      &ndash; Gail Pool 
    </blockquote>
    <blockquote>
      The questions worth asking have not answers worth knowing, but
      rather they engender journeys worth taking.<br>
      &ndash; Curt Brune
    </blockquote>
    <p>
      This article describes the motivations behind and the inner workings of a "IP address to Google Map"
      mash-up application I wrote recently called <a
      href="http://www.cucy.net/map/georoute.html">Geo IP Route</a>.  Read on!.
   </p>
    <p>
      What should I do?<br>
      Where should I go?<br>
      Am I sure this is the right direction?<br>
      What if I had chosen a different path?<br>
    </p>
   <p>
      Most of us have asked ourselves these types of questions at one
      time or another.  It's only natural to ponder the meaning of our
      existence and wonder aloud at the complexity of the universe.
    </p>
    <p>
      Like all good questions these questions apply to many different
      levels of our existance, from superficial daily decisions to
      subdermal compromises of family and career to the innermost
      vexing decisions regarding ethics and morality.
    </p>
    <p>
      Off hand the questions arising from routine daily decision
      making are of little interest to me.  "Don't sweat the small
      stuff," someone once said.  Good advice as life is too short.
      Make decisions, take action and keep moving forward.
    </p>
    <p>
      No, I find the subtle, difficult questions much more
      intriguing.  As these decisions lie closer to our core being,
      the effects of minor course corrections dramatically
      influence the route we travel.  While it's true destinations
      help focus your energy, upon arrival the journey gives more
      insight to where you are then the destination itself.
    </p>
    <p>
      I would like to share with you one of my recent existential
      programming journeys.  Along the way I ponder questions, fiddle
      with <a
      href="http://www.die.net/doc/linux/man/man8/traceroute.8.html">traceroute</a>
      and <a href="http://en.wikipedia.org/wiki/Geocoding">geocoding</a>. As
      I've written <a
      href="http://www.cucy.net/lacp/archives/000011.html">previously</a>  
      the best way to get going to is to have a project to work on.
      With the project in hand we can sharpen the saw and get to work.
    </p>
    <p>
      Here's a snapshot of the final application:
    </p>
    <center>
      <a href="http://www.cucy.com/sd/georoute-blog-big.jpg"><img
      border="0"
      src="http://www.cucy.com/sd/georoute-blog-small.jpg"></a> 
    </center>
    <p>
      Read on for more ...
    </p>
    <h3>Charting Your Route</h3>
    <p>
      I wanted to do something new, something new to me and to you.
      Also I wanted to do something different from my day job
      (embedded system design and programming).  For the something
      different I wanted to learn how to make web pages with
      interactive maps using the <a
      href="http://www.google.com/apis/maps/">Google Maps API</a>.
    </p>
    <p>
      If you have been following along you know I have a <a
      href="http://www.cucy.net/lacp/archives/000001.html">history</a>
      of working with GIS and digital map applications.  I had never
      played with online map applications though.
    </p>
    <p>
      Now the <i>something new to me and you</i> was going to be
      difficult.  Mapping APIs are great, but what are you going to
      put on the map?  To put items on a map you first need their
      latitude and longitude, otherwise known as geocoding.  Where
      could I get geocodes of something <b>interesting</b>?  For free
      of course.
    </p>
    <p>
      After much head scratching I decided it would be cool to map the
      Internet routers used for various transactions.  If you are
      familiar with <a
      href="http://www.die.net/doc/linux/man/man8/traceroute.8.html">traceroute</a>
      you know exactly what I was thinking.
    </p>
    <p>
      I wanted to make sure what I was doing didn't already
      exist.  I did a Google search for "traceroute geocoding" &ndash; much to
      my dismay several sites came up.  Only one seemed relevant, in
      fact it was pretty much exactly what I was thinking of doing.
      Somewhat long faced I clicked on the link to check out the
      application.  Much to my delight the application was
      non-existant, the link provided didn't work.  I was still in
      business.
    </p>
    <p>
      This project had several challenges that had to be surmounted in
      order to succeed.
    </p>
    <p>
      The first trick was to convert the <a
      href="http://en.wikipedia.org/wiki/Internet_protocol_suite">Internet
      Protocol</a> (IP) addresses into latitude and longitude
      coordinates.  I had a couple of ideas on how to do this.
    </p>
    <p>
      The second trick was learning the <a
	href="http://www.google.com/apis/maps/">Google Maps API</a> and
      various bits of <a
	href="http://en.wikipedia.org/wiki/Javascript">javascript</a> to
      glue it all together.  While this seemed straightforward at
	first plenty of surprises were lurking to insure an eventful journey.
    </p>
    <p>
      With destination in hand, the navigation charts arrayed before
      me I was ready to embark on the journey.
    </p>
    <h3>IPv4 to Latitude and Longitude</h3>
    <p>
      How to do this?  <a href="http://www.ip2location.com/">Companies
	sell</a> databases that map IP addresses to latitude and
      longitude, along with a subscription service to keep the
      database up to date.  That would likely be the mostly accurate
      way to go, but that would take all the fun out of it.  Plus I
      don't have money to pay for it. 
    </p>
    <p>
      I harkened back to my experience which traditional geocoding,
      where the latitude/longitude (lat/long) is derived from a street address.
      Maybe a I could transform IP addresses to street addresses and
      then to lat/long.  How could I get street addresses from IP
      addresses?
    </p>
    <p>
      Given that this was a for-fun-not-for-profit project 100%
      accurracy was not required, so I decided to use the <a
	href="http://www.whois.net/">whois</a> database to look up the
      administrative contact for given IP addresses.  This was not the
      final solution I used for the finished application, but it was a
      start.  Starting is key to any journey! 
    </p>
    <p>
      Clearly using whois was not going to tell me the exact location
      of the server in question, but it would tell me the location of
      the organization that ran the server.  Good enough.
    </p>
    <p>
      The following is the abbreviated whois output for <a
	href="http://www.linuxdevices.com/">LinuxDevices.com</a>.  First I
      looked up the IP address for www.linuxdevices.com and then fed
      that IP address into the whois command, using the <a
	href="http://www.arin.net/">whois.arin.net</a> whois sever.
    </p>

<pre>
linux:$ whois -h whois.arin.net + 216.218.185.154
...
OrgName:    Hurricane Electric 
OrgID:      HURC
Address:    760 Mission Court
City:       Fremont
StateProv:  CA
PostalCode: 94539
Country:    US
...
</pre>
    
    <p>
      <a href="http://www.he.net">Hurricane Electric</a> is a co-lo in the San
      Jose, CA area.  This is likely where the servers for
      LinuxDevices.com reside.  Considering all the places the server
      could have been, this narrows it down considerably.
    </p>
    <p>
      OK, great so I have the street address given an IP address.  Now
      what?
    </p>
    <p>
      I need a geo-coder.  <a href="http://geocoder.us/">Free
	geocoders</a> exist as web services, which are convienent, but
      also introduce latency as the query is serviced by a third-party.
      I didn't want to introduce more latency &ndash; I was already querying
      the whois database.
    </p>
    <p>
      I wanted to do the geo-coding locally on my own server.  Luckly
      the <a href="http://www.census.gov/geo/www/tiger/">U.S. Census
	Bureau</a> makes its Tiger Line data freely available for download.
      A nifty perl module, <a
	href="http://search.cpan.org/~sderle/Geo-Coder-US/">Geo::Coder::US</a>,
      provides an interface to this database.  
    </p>
    <p>
      I was now in business &ndash; I could turn an IP address into a
      location on the map.  While not optimal it got me going so I could
      move on to the next challenge, using the mapping APIs and making
      something worth looking at.
    </p>

    <h3>Google Maps and Javascript</h3>

    <p>
      Dear reader if you know next to nothing about Javascript then I knew
      less than you when I embarked on this adventure.  Sure I had
      programmed a bunch in various language, but never javascript.  I
      needed a good reference to get up to speed.
    </p>
    <p>
      I found the <a href="http://www.w3schools.com/js/default.asp">W3
      Schools Javascript Tutorial</a> to be an excellent on-line reference.
      It is really, really helpful with nice working examples.  Go
      there and read up.
    </p>
    <p>
      The <a href="http://www.google.com/apis/maps/">Google Maps
      API</a> is well documented and pretty straight forward to use.
      My applicatin required two basic mapping features
    </p>
    <p>

      <ul>
	<li> Draw a map, centered on a lat/long at a particular zoom
	  level.</li>
	<li> Put icons on the map at particular locations.</li>
      </ul>

    </p>
    <p>
      Most mapping applications do little more than this.  The Google
      APIs made this a relatively easy task.
    </p>
    <p>
      In my application the user sends a series of IP addresses to my
      server, where I turn those IP address in to lat/long locations
      and send them back to the user's browser.  The highlight for me
      was the using XML to send the data back to the browser.
    </p>
    <p>
      The Google API provides a really <a
      href="http://www.google.com/apis/maps/documentation/#GXml_code_">nice
      XML parser</a> making it simple to marshall arguments
      between web applications.  What a time saver!  Totally cool.
    </p>
    <p>
      Another cool thing for me was using anonymous Javascript
      functions for asynchronous HTTP query/response handling.
      First an HTTP request is made and an anonymous function is
      registered as the response handling function.  Later the
      response is handled asynchronously by the registered function.
      It was cool using an anonymous function for this &ndash;
      reminded me of the <a
      href="http://en.wikipedia.org/wiki/Lambda_calculus">lambda
      functions</a> of LISP. 
    </p>
    <h3>Iteration and Closure</h3>
    <blockquote>
      We are what we repeatedly do. Excellence then is not an act but a
      habit.<br>
      &ndash; Aristotle
    </blockquote>
    <blockquote>
      Perfection is achieved, not when there is nothing more to add,
      but when there is nothing left to take away.<br>
      &ndash; Antoine de Saint Exupery (1900 - 1944) 
    </blockquote>
    <p>
      Just like writing an essay, creating good computer programs
      usually benefit from one or more development iterations &ndash;
      quickly putting down the first draft captures the fleeting flashes
      of insight bouncing around your ideas.  Subsequent drafts smooth out the
      rough spots, refine the algorithms, shorten the code paths
      and delete the cruft.
    </p>
    <p>
      Earlier I alluded that the final version of my application did
      not stick with the whois/geocoding method for turning IP
      addresses into lat/long coordinates.  During development I found
      a more satisfying method.
    </p>
    <p>
      The first enhancement was to realize that someone else was
      already offering a free service for U.S. and U.K IP addresses.
      Go check out <a href="http://www.hostip.info/">hostip.info</a>.
      This solved the problem for two large countries, but what about
      the rest of the world?
    </p>
    <p>
      Well that was going to be tricky.  In the end I knew the
      application did not need to be perfect, but only provide an
      estimate for the path that packets took across the Internet.
    </p>
    <p>
      The hostip.info query fails whenever it does not have a location
      for an IP address &ndash; it can sometimes fail even for
      U.S. and U.K. addresses that it does not know about.  When it
      fails, however, it does tell you the country that the IP address
      is in.
    </p>
    <p>
      If the country is the U.S. then I fall back on the my original
      whois/geocode method, which works OK.  For other countries I use
      the lat/long of the capital city of the country.  So the resuls
      are not perfect, but the spirit of where the packets are going is
      preserved.  I used the list of world capital lat/longs found <a
      href="http://www.mapsofworld.com/utilities/world-latitude-longitude.htm">here</a>. 
    </p>
    <h3>Until Next Time</h3>
    <p>
      Well I hope you have enjoyed this journey &ndash; good travels!
    </p>
    <p>
      Oh, I almost forgot &ndash; please check out my <a
      href="http://www.cucy.net/map/georoute.html">Geo IP Route</a> application.
    </p>
<a href="http://www.cucy.net/cgi-bin/mt/mt-tb.cgi?__mode=view&entry_id=23" onclick="OpenTrackback(this.href); return false">TrackBack (0)</a> | <a href="http://www.cucy.net/lacp/archives/000023.html#comments" title="Comment on: Lifestyle Routing">Comments (1)</a></p>]]></content:encoded>
<dc:subject>General</dc:subject>
<dc:date>2005-12-18T14:48:20-08:00</dc:date>
</item>

<item>
<title>Das U-Boot: The Universal Boot Loader</title>
<link>http://www.cucy.net/lacp/archives/000022.html</link>
<description> Exciting new embedded Linux devices are appearing at an astonishing rate. From tiny 3 inch &quot;Gumstix&quot; boards to PDAs and smart-phones embedded Linux is everywhere. Installing and booting Linux on these wildly varying boards is quite a chore. Without a good boot loader these machines are just complicated hunks...</description>
<guid isPermaLink="false">22@http://www.cucy.net/lacp/</guid>
<content:encoded><![CDATA[    <p>
Exciting new embedded Linux devices are appearing at an astonishing
rate. From tiny 3 inch "Gumstix" boards to PDAs and smart-phones
embedded Linux is everywhere. Installing and booting Linux on these
wildly varying boards is quite a chore. Without a good boot loader
these machines are just complicated hunks of silicon with nothing to
do. That's where <a href="http://sourceforge.net/projects/u-boot/">Das U-Boot</a>, a Free Software universal boot loader,
steps in.
    </p>
    <p>
A boot loader, sometimes referred to as a boot monitor, is a small
piece of software that executes soon after powering up a computer. On
your desktop Linux PC you may be familiar with lilo or grub, which
resides on the master boot record (MBR) of your hard drive. After the
PC BIOS performs various system initializations it executes the boot
loader located in the MBR. The boot loader then passes system
information to the kernel and then executes the kernel. For instance
the boot loader tells the kernel which hard drive partition to mount
as root.
    </p>
    <p>
In an embedded system the role of the boot loader is more complicated
since these systems do not have a BIOS to perform the initial system
configuration. The low level initialization of microprocessors,
memory controllers and other board specific hardware varies from board
to board and CPU to CPU. These initializations must be performed
before a Linux kernel image can execute.
    </p>
    <p>
At a minimum an embedded loader provides the following features:
    </p>
    <ul>
      <li> Initializing the hardware, especially the memory controller.</li>

      <li> Providing boot parameters for the Linux kernel.</li>

      <li> Starting the Linux kernel.</li>
    </ul>

    <p>
Additionally, most boot loaders also provide "convenience" features that
simplify development:
    </p>
    <ul>
      <li> Reading and writing arbitrary memory locations.</li>

      <li> Uploading new binary images to the board's RAM via a serial line or Ethernet</li>

      <li> Copying binary images from RAM to FLASH memory.</li>
    </ul>
    </p>
    <table>
      <tbody>
        <tr>
          <td>
            <h3>Das U-Boot</h3>
	    <p>
Das U-Boot is a GPL'ed cross-platform boot loader shepherded by
project leader Wolfgang Denk and backed by an active developer and
user community. U-Boot provides out-of-the-box support for hundreds of
embedded boards and a wide variety of CPUs including PowerPC, ARM,
XScale, MIPS, Coldfire, NIOS, Microblaze and x86. You can easily
configure U-Boot to strike the right balance between a rich feature
set and a small binary footprint.
	    </p>
	    <p>
U-Boot has its origins in the 8xxROM project, a boot loader for 8xx
PowerPC systems by Magnus Damm. When bringing that project to
Sourceforge in 2000 the current project leader, Wolfgang Denk, renamed
the project PPCBoot since Sourceforge did not allow project names to
begin with a digit.
	    </p>
	    <p>
The openness and utility of PPCBoot fanned the flames of its
popularity, driving developers to port PPCBoot to new
architectures. By September 2002 PPCBoot supported four different ARM
processors and the name PPCBoot was becoming quaint. In November 2002
the PPCBoot team retired the project, which led directly to the
surfacing of "Das U-Boot".
	    </p>
	    <p>
The strength of the Free Software development process is clearly
evident in the success of U-Boot. The four freedoms expressed by the
FSF's <a href="http://www.fsf.org/philosophy/free-sw.html">Free Software Definition</a> directly fuel U-Boot's impressive
progress and wide spread deployment.
	    </p>
	    <p>
You can jump start your next embedded Linux project using U-Boot to
take care of the low-level board initializations, allowing you to
focus on the core of your embedded application. Downloading images and
flashing kernels should be the least of your worries. If the need
arises, however, you have the source code can can add support for new
hardware or add a special feature.
	    </p>
	    <p>
            <h3>Prerequisites</h3>
	    <p>
Before building and installing U-Boot you need a cross-development
tool chain for your target architecture. The term tool chain is a bit
squishy, but generally means a C/C++ compiler, an assembler, a
linker/loader, associated binary utilities and header files for a
specific architecture, like PowerPC or ARM. Collectively these
programs are called a tool chain.
	    </p>
	    <p>
You are probably familiar with the tool chain on your desktop Linux
PC. That tool chain runs on an x86 platform and generates binaries
for an x86 platform. A cross-development tool chain executes on one
CPU architecture, but generates binaries for a different architecture.
In my case the host architecture is x86 while the target architecture
is ARM and PowerPC. Sometimes this process is also referred to as
cross-compiling.
	    </p>
	    <p>
While it is possible to configure and build a tool chain from source
it is time consuming and the myriad of configuration options makes it
quite error prone. I highly recommend using a pre-built tool chain
from a Linux vendor. The Embedded Linux Development Kit (<a href="http://www.denx.de/twiki/bin/view/DULG/ELDK">ELDK</a>), also
by Wolfgang Denk, contains the tool chains used in this article.
	    </p>
	    <p>
Using cross-development tools makes it an absolute dream to develop
embedded systems using Linux as the host development workstation. No
need to maintain machines running other operating systems in order to
run the compiler. 
	    </p>
            <h3>Configuring and Building</h3>
	    <p>
Building U-Boot for a supported platform is very straight forward,
very similar to the familiar "untar, configure, make" method used by
many software projects. To setup a default configuration for a
particular board type this at the shell prompt after untarring the
U-Boot tarball,
	    </p>
	    <pre>
localhost:$ cd u-boot
localhost:$ make mrproper
localhost:$ make &lt;board&gt;_config</pre>
	    <p>
where &lt;board&gt; matches the board you want to build. This step setups
the CPU architecture and board type.
	    </p>
	    <p>
You can fine tune the default configuration for your particular
environment and board by editing the configuration file,
"include/configs/&lt;board&gt;.h". This file contains several
C-preprocessor #define macros that you can modify for your needs.
Some common options you might want to change are:
	    </p>
	    <pre>
/* Serial port configuration */
#define CONFIG_BAUDRATE         19200
#define CFG_BAUDRATE_TABLE      { 9600, 19200 }

/* Network configuration */
#define CONFIG_IPADDR           10.0.0.11
#define CONFIG_NETMASK          255.255.255.0
#define CONFIG_SERVERIP         10.0.0.1 </pre>

	    <p>
These definitions are self explanatory, except for maybe
CONFIG_SERVERIP, which is the IP address U-Boot uses for TFTP and
NFS. Don't worry too much about these right now as you can change
them later when U-Boot is running. For the complete list of
configuration options see u-boot/README.
	    </p>
	    <p>
Now to build the binary image, u-boot.bin, type the following:
	    </p>
	    <pre>
cd u-boot
make</pre>

	    <p>
You have several options for installing the binary image on your
target board, and which option you select depends on your board and
development environment. You might use a BDM/JTAG programmer, an
existing vendor's boot loader or even an older version of
U-Boot. While this step is crucial it is beyond the scope of this
article to describe this procedure. From here on I will assume you
have successfully installed U-Boot on your target board.
	    </p>
            <h3>Getting Started</h3>
	    <p>
The next step is configuring your host workstation for serial
communications with your target platform. On my system I have a DB9
serial cable connected to /dev/ttyS0. U-Boot expects the serial line
to be set for 8 data bits, 1 stop bit, no parity and no handshake.
	    </p>
	    <p>
You can use your favorite serial communications program to connect to
U-Boot. I prefer to use Kermit and a tiny Kermit script from within
an emacs shell buffer. I put the following Kermit script into a file
called "serial-term" and make the file executable:
	    </p>
	    <pre>
#!/usr/bin/kermit
echo connecting /dev/ttyS0 .....
set line /dev/ttyS0
set FLOW AUTO
set speed 19200
set serial 8n1
SET CARRIER-WATCH OFF
connect </pre>

	    <p>
I like running serial-term from within an emacs shell because emacs
keeps track of my command history, which the U-Boot shell does not
support. Trust me, while developing you will be hitting the reset
button on your board a lot and want to "up arrow" to the previous load
command you just entered.
	    </p>
	    <p>
The user interface to U-Boot consists of a command line interrupter,
much like a Linux shell prompt. When connected via a serial line you
can interactively enter commands and see the results. After power on
the initial u-boot prompt looks like this:
	    </p>
	    <pre>
U-Boot 1.1.2 (Aug  3 2004 - 17:31:20)
RAM Configuration:
Bank #0: 00000000  8 MB
Flash:  2 MB
In:    serial
Out:   serial
Err:   serial
u-boot # </pre>

	    <p>
This tells you that you have 8 megabytes of RAM starting at address
0x00000000, two megabytes of Flash and that the C-library file streams
stdin, stdout and stderr are connected to the serial line.
	    </p>
	    <p>
You can receive more information about our board be issuing the board
info command, <code><b>bdinfo</b></code>.  In the folowing the commands typed 
by me appear in <code><b>bold</b></code>.
	    </p>

	    <code>
u-boot # <b>bdinfo</b><br>
DRAM bank   = 0x00000000<br>
-> start    = 0x00000000<br>
-> size     = 0x00800000<br>
ethaddr     = 00:40:95:36:35:33<br>
ip_addr     = 10.0.0.11<br>
baudrate    = 19200 bps<br></code>

	    <p>
Here you see the see the RAM configuration information again, the
Ethernet MAC address, the IP address and serial port baud rate.
	    </p>
            <h3>Environment Variables</h3>
	    <p>
Much like a traditional Linux shell the U-Boot shell uses environment
variables to tailor its operation. The U-Boot commands to manipulate
environment variables have the same names as the BASH shell. For
instance <code><b>printenv</b></code> and <bold><b>setenv</b></bold> behave the same as their BASH shell
counterparts.
	    </p>
	    <p>
In the following example you will dump the current environment
variables using the "printenv" command and change the IP address of
the TFTP server using the "setenv" command.
	    </p>
	    <code>
u-boot # <b>printenv</b><br>
baudrate=19200<br>
ethaddr=00:40:95:36:35:33<br>
netmask=255.255.255.0<br>
ipaddr=10.0.0.11<br>
serverip=10.0.0.1<br>
stdin=serial<br>
stdout=serial<br>
stderr=serial<br>
u-boot # <b>setenv serverip 10.0.0.2</b><br>
u-boot # <b>printenv serverip</b><br>
serverip=10.0.0.2<br>
</code>

	    <p>
You can create short shell scripts by storing a sequence of U-Boot
commands, separated by semicolons, in an environment variable. To
execute the script use the "run" command followed by the variable
name. This can be handy to automate repetitive tasks during
development.
	    </p>
            <h3>Network Commands</h3>
	    <p>
Having a network connection on your boot loader is very convenient
during development. If your project requires several networked boards
they can all download and boot the same kernel image from a
centralized server. When you update the kernel you only need to
update the single copy on the server and not each board individually.
	    </p>
	    <p>
U-Boot supports TFTP (Trivial FTP), a stripped down FTP that does not
require user authentication, for downloading images into the board's
RAM. The "tftp" command needs two pieces of information, the name of
the file to download and where in memory to store the file as shown in
the following example:
	    </p>
	    <code>
u-boot # <b>tftp 8000 u-boot.bin</b><br>
From server 10.0.0.1; our IP address is 10.0.0.11<br>
Filename 'u-boot.bin'.<br>
Load address: 0x8000<br>
Loading: ###################<br>
done<br>
Bytes transferred = 95032 (17338 hex)<br></code>

	    <p>
The size and location of the downloaded image are stored in the
<code><b>fileaddr</b></code> and <code><b>filesize</b></code> environment variables for possible latter
use by other shell commands and scripts.
	    </p>
	    <p>
U-Boot also supports NFS so you can download images from your existing
NFS server as well.
	    </p>
            <h3>Flash Commands</h3>
	    <p>
Some embedded projects only have access to a network while being
programmed "in the factory". When deployed in the field the boards
boot a kernel stored in the flash memory. The board can be updated in
the field by reprogramming the flash memory with a new kernel. U-Boot
offers several commands for programming, erasing and protecting the
flash memory.
	    </p>
	    <p>
To see what type of flash memory your board has enter the <code><b>flinfo</b></code>
command:
	    </p>
	    <code>
u-boot # <b>flinfo</b><br>
Bank # 1: AMD Am29LV160DB 16KB,2x8KB,32KB,31x64KB<br>
&nbsp;&nbsp;Size: 2048 KB in 35 Sectors<br>
&nbsp;&nbsp;Sector Start Addresses:<br>
&nbsp;&nbsp;&nbsp;&nbsp;    S00 @ 0x01000000 ! S01 @ 0x01004000 ! <br>
&nbsp;&nbsp;&nbsp;&nbsp;    S02 @ 0x01006000 ! S03 @ 0x01008000 !<br>
&nbsp;&nbsp;&nbsp;&nbsp;    S04 @ 0x01010000 ! S05 @ 0x01020000 ! <br>
&nbsp;&nbsp;&nbsp;&nbsp;    S06 @ 0x01030000   S07 @ 0x01040000  <br>
&nbsp;&nbsp;&nbsp;&nbsp;    ...<br>
&nbsp;&nbsp;&nbsp;&nbsp;    S32 @ 0x011D0000   S33 @ 0x011E0000<br>
&nbsp;&nbsp;&nbsp;&nbsp;    S34 @ 0x011F0000  <br>
</code>
	    <p>
The output carries quite a lot of information. Immediately you see
the flash manufacturer, part number and sector layout. This
particular part begins with a 16KB sector at address 0x01000000,
followed by two 8KB sectors, a 32KB sector and 31 64KB sectors for a
total of 2 megabytes in 35 sectors.
	    </p>
	    <p>
The exclamation points following sectors 0 through 5 indicate that
those sectors are "protected". In this example sectors 0 through 4
contain the code for U-Boot itself, and sector 5 is used to store the
environment variables. Any attempt to program these sectors without
first unlocking them will fail. This offers some level of protection
from "rm -rf /" type mistakes when programming the flash.
	    </p>
	    <p>
Continuing the TFTP example, let's assume the file you uploaded is a
new version of U-Boot. You need to first unlock flash sectors 0
through 4 before programming the flash. Type "protect off 1:0-4",
which instructs U-Boot to allow write access to flash bank 1, sectors
0 through 4.
	    </p>
	    <code>
u-boot # <b>protect off 1:0-4</b><br>
Un-Protect Flash Sectors 0-4 in Bank # 1<br>
	    </code>

	    <p>
Next you must prepare the flash sectors for programming by erasing
them. Enter "erase 1:0-4", which tells U-Boot to erase sectors 0
through 4 of flash bank 1.
	    </p>
	    <code>
u-boot # <b>erase off 1:0-4</b><br>
Erase Flash Sectors 0-4 in Bank # 1 <br>
&nbsp;&nbsp;  Erasing Sector 0 @ 0x01000000 ... done<br>
&nbsp;&nbsp;  Erasing Sector 1 @ 0x01004000 ... done<br>
&nbsp;&nbsp;  Erasing Sector 2 @ 0x01006000 ... done<br>
&nbsp;&nbsp;  Erasing Sector 3 @ 0x01008000 ... done<br>
&nbsp;&nbsp;  Erasing Sector 4 @ 0x01010000 ... done<br>
[end courier]
	    </code>
	    <p>
To program the flash memory you need to copy the image from RAM to the
address of flash sector 0, 0x01000000, using the <code><b>cp</b></code> command. You
will use the byte version of the command to copy the specified number
of bytes. In this case you can use the <code><b>fileaddr</b></code> and <code><b>filesize</b></code>
environment variables, which contains the RAM address and number of
bytes loaded by the last TFTP command. Type <code><b>cp.b ${fileaddr} 1000000
${filesize}</b></code> at the u-boot prompt.
	    </p>
	    <code>
u-boot # <b>cp.b ${fileaddr} 1000000 ${filesize}</b><br>
Copy to Flash... ................ done<br>
	    </code>
	    <p>
Finally restore the write protection on flash sectors 0 through 4 by
typing <code><b>protect on 1:0-4</b></code> at the U-Boot prompt.
	    </p>
	    <code>
u-boot # <b>protect on 1:0-4</b><br>
Protect Flash Sectors 0-5 in Bank # 1<br>
	    </code>
	    <p>
You have just updated the U-Boot code for you board. The next reboot
will run the newly uploaded U-Boot code. Well done!
	    </p>
	    <p>
The final flash related command is the <code><b>saveenv</b></code> command, which like
the name implies saves your current environment variables to a
reserved flash sector. This allows your environment variables to
persist across power cycles and reboots. You might want do this after
updating the server IP address or when adding a new script. Type
<code><b>saveenv</b></code> to save your environment.
	    </p>
	    <code>
u-boot # </b>saveenv</b><br>
Saving Environment to Flash...<br>
Un-Protected 1 sectors<br>
Erasing Flash...<br>
&nbsp;&nbsp;Erasing Sector 5 @ 0x01020000 ... done<br>
Erased 1 sectors<br>
Writing to Flash... ................ done<br>
Protected 1 sectors<br>
	    <code>
	    <p>
As you can see the <code><b>saveenv</b></code> command bundles together the un-protect,
erase, copy and protect steps you covered in the previous example. 
	    </p>
            <h3>Booting</h3>
	    <p>
OK, now you know how to load your image into RAM or flash. Next you
want to run your kernel and boot into Linux. Most kernel images
expect to start executing from a known location in memory, so you need
to load your image into the correct place. The U-Boot distribution
provides a nice utility for the host system called "mkimage" for just
this purpose.
	    </p>
	    <p>
After creating your kernel image use <code><b>mkimage</b></code> to add a tiny header
containing the load and execute address for the image, like this (all on one line):
	    </p>
	    <code>
localhost:$ mkimage -A arm -O linux -T kernel -C none -a 0x8000 -e 0x8000 -n "Linux 2.6.6" -d linux.bin uImage.bin
</code>
	    <p>
This command appends a small header containing the load and execute
address 0x8000 to your kernel image and creates a new file called
uImage.bin. The header also contains a CRC32 checksum, checked later
during the image load. Remember the above command is run on your
development workstation, not the embedded target.
	    </p>
	    <p>
You can now upload uImage.bin to your board and use the <code><b>bootm</b></code>
command to boot your image. In the following example let's assume you
stored uImage.bin at address 0x01030000 in the flash memory.
	    </p>
	    <code>
u-boot # <b>bootm 1030000</b><br>
## Booting image at 01030000 ...<br>
&nbsp;&nbsp;   Image Name:   Linux 2.6.6<br>
&nbsp;&nbsp;   Image Type:   ARM Linux Kernel Image<br>
&nbsp;&nbsp;   Data Size:    700256 Bytes = 683.8 kB<br>
&nbsp;&nbsp;   Load Address: 00008000<br>
&nbsp;&nbsp;   Entry Point:  00008000<br>
&nbsp;&nbsp;   Verifying Checksum ... OK<br>
Starting kernel ...<br>
	    </code>
	    <p>
And off you go!  U-Boot uses the header information to copy your image
to the correct location and then to start execution at the specified
address. Notice that U-Boot also verifies the CRC32 checksum contained
in the header before executing the kernel.
	    </p>
            <h3>Conclusion</h3>
	    <p>
This introduction to the basic features gives you feel for the power
and utility of "Das U-Boot". For the more advanced features consult
the project README file and visit the 
<a href="http://www.denx.de/twiki/bin/view/DULG/Manual">U-Boot Wiki</a>. I hope you
consider using U-Boot on your next embedded project.
	    </p>
            <h3>Acknowledgments</h3>
	    <p>
I would like to personally thank Wolfgang Denk and the other members
of the U-Boot project for their mostly thankless efforts in creating,
maintaining and extending "Das U-Boot" &ndash; open firmware today for an
open tomorrow.
	    </p>
            <h3>Resources</h3>
	    <p></p>
	    Das U-Boot project home page<br>
	    <a href="http://sourceforge.net/projects/u-boot/">http://sourceforge.net/projects/u-boot/</a>

	    <p></p>
	    DENX U-Boot and Linux Guide<br>
	    <a href="http://www.denx.de/twiki/bin/view/DULG/Manual">http://www.denx.de/twiki/bin/view/DULG/Manual</a>

	    <p></p>
	    Free Software Foundation's "Free Software Definition" Page<br>
	    <a href="http://www.fsf.org/philosophy/free-sw.html">http://www.fsf.org/philosophy/free-sw.html</a>

	    <p></p>
	    TFTP<br>
	    <a href="http://rfc.net/rfc1350.html">http://rfc.net/rfc1350.html</a>
          </td>
        </tr>
      </tbody>
    </table><a href="http://www.cucy.net/cgi-bin/mt/mt-tb.cgi?__mode=view&entry_id=22" onclick="OpenTrackback(this.href); return false">TrackBack (0)</a> | <a href="http://www.cucy.net/lacp/archives/000022.html#comments" title="Comment on: Das U-Boot: The Universal Boot Loader">Comments (6)</a></p>]]></content:encoded>
<dc:subject>General</dc:subject>
<dc:date>2004-08-27T21:46:55-08:00</dc:date>
</item>

<item>
<title>Behind The Scenes at The Embedded Systems Conference </title>
<link>http://www.cucy.net/lacp/archives/000021.html</link>
<description>Inside are the gems I discovered at this year&apos;s Embedded Systems Conference in San Francisco, including current directions in embedded Linux development ...</description>
<guid isPermaLink="false">21@http://www.cucy.net/lacp/</guid>
<content:encoded><![CDATA[    <table border="0">
      <tbody>
        <tr>
          <td>
            <font size="+2">
              <b>
                electronicaUSA 2004<br>
                Embedded Systems Conference
              </b>
            </font>
          </td>
          <td>&nbsp;&nbsp;&nbsp;<a href="http://www.esconline.com/electronicaUSA/"><img src="http://www.cucy.net/lacp/img/eusa_logo.gif"></a></td>
        </tr>
      </tbody>
    </table>
    <HR>
    <p>
      Inside are the gems I discovered at this year's <a
        href="http://www.esconline.com/electronicaUSA/">Embedded
        Systems Conference</a> in San Francisco, including <a
        href="#linux">current directions</a> in embedded Linux
      development, progressive <a href="#art">silicon art</a>, <a
        href="#robot">robots</a> for science and entertainment, public
      transportation and the relentless drive of the <a
        href="#economy">economy</a>.
    </p>
    <table>
      <tbody>
        <tr>
          <td>
            <h3>The Approach</h3>
            <p>
              The day began on an inauspicious note when I decided to use
              public transportation to commute from my apartment in the South
              Bay to the conference in San Francisco aboard the <a
                href="http://www.caltrain.com/">CalTrain</a>.  It seemed like
              a good idea &ndash; eco-friendly, no need to deal with traffic
              or parking.  A quick shuttle from the CalTrain station to the
              Moscone Convention Center and the trip would be complete, or so
              I thought.
            </p>
            <p>
              Sometimes even the simple things take focused effort.
            </p>
            <p>
              While waiting for the train I gazed around, taking in the sounds and
              sights of a bustling train stop &ndash; after about 15 minutes it dawned on
              me that at least two trains should have arrived and departed, but none
              had done either.  What was up?
            </p>
            <p>
              I pulled out one of my favorite and most useful portable devices
              &ndash; a tiny, portable radio that runs on one AAA battery.
              After two minutes with the headphones and <a
                href="http://www.kqed.org/">KQED</a>, the traffic report came
              around explaining that north bound CalTrain service was
              disrupted indefinitely due to a gas leak.  Super!
            </p>
            <table style="float:right" >
              <tbody>
                <tr>
                  <td>
                    <a href="http://www.cucy.net/lacp/img/threeguy-lg.jpg"><img vspace="4px"
                        hspace="4px" style="float:right"
                        src="http://www.cucy.net/lacp/img/threeguy-sm.jpg"></a>
                  </td>
                </tr>
                <tr>
                  <td><center>Sculpture</center></td>
                </tr>
              </tbody>
            </table>
            <p>
              I could take this news one of two ways.  I could either get upset at
              CalTrain for delaying my trip, cursing technology up and down for the
              failure or I could be grateful that some embedded gadget somewhere had
              detected a gas leak and had notified living, breathing humans of the
              problem.
            </p>
            <p>
              So with my glass both half-empty and half-full I head home and
              drive myself to the conference.  Once in San Francisco I park in
              the parking lot of SBC Park (formerly known as PacBell Park) and
              took a shuttle bus (public transportation at last) to the
              Moscone Center.  Stay tuned &ndash; the return bus trip is worth
              remembering.
            </p>
            <p>
              The day was a typical, cool gray, drizzly Spring morning in San
              Francisco.  Outside the Moscone Center a lustrous public sculpture
              dispelled the dreariness and I knew I was in San Francisco.  This
              is going to be fun.
            </p>
          </td>
        </tr>
      </tbody>
    </table>
    <hr width="80%">
    <table>
      <tbody>
        <tr>
          <td>
            <a name="keynote"></a> 
            <h3></a>Keynote Address</h3> 
            <p>
              Despite my issues with public transportation I arrived
              with plenty of time to spare before the keynote address.
              Staking out my spot in the auditorium I began to take in
              the atmosphere and measure the mood of the crowd. </p>
            <p> The demographics are pretty pedestrian &ndash; mostly
              male, wearing blue jeans and toting their conference
              backpacks.  The lights dimmed and it was time for the
              keynote address. </p>
            <table style="float:right" >
              <tbody>
                <tr>
                  <td>
                    <a href="http://www.cucy.net/lacp/img/keynote-lg.jpg"><img vspace="4px"
                        hspace="4px" style="float:right"
                        src="http://www.cucy.net/lacp/img/keynote-sm.jpg"></a>
                  </td>
                </tr>
                <tr>
                  <td><center>Keynote Auditorium</center></td>
                </tr>
              </tbody>
            </table> <p> <a
                href="http://www.nationalgeographic.com/council/eir/bio_ballard.html">Dr. 
                Robert Ballard</a>, an oceanographer, geophysicist and
              marine geologist from the University of Rhode Island,
              gave the keynote address at this year's conference.  He
              is probably most famous for leading the team that
              discovered the <i>Titanic</i> in 1985 &ndash; read his
              <a
                href="http://www.nationalgeographic.com/council/eir/bio_ballard.html">bio</a> 
              for more about this fascinating character. </p> <p> Dr.
              Ballard is not your typical speaker at an embedded
              systems conference, but he was one of the best I have
              ever heard.  His main technical thrusts concerned
              bandwidth from the un-manned deep sea vehicles to the
              support vessels on the surface from which video would be
              up-linked via satellite to colleagues and middle school
              classrooms throughout the world. </p> <p> His
              encouraging philosophy of bringing remote exploration to
              the masses is embodied in <a
                href="http://www.jason.org/">The JASON Project</a>, a
              multi-disciplinary program that sparks the imagination
              of students and enhances the classroom experience. </p>
            <p> Truly inspirational.  But he did not have a lot to say
              about GNU/Linux, embedded processors, PCI Express or
              much else to do with electronics.  Funny guy though,
              highly recommended. Hopefully his deep sea adventure
              tales can help steady the sails of the listing
              embedded systems economy. </p>
          </td>
        </tr>
      </tbody>
    </table>
    <hr width="80%">
    <table>
      <tbody>
        <tr>
          <td>
            <a name="exhibit"></a>
            <h3>The Exhibit Hall</h3>
            <p>
              I won't bore you with a run down of all the exhibits, you can
              read the website for that, nor will I bore you with the obvious
              &ndash; embedded Linux is here today, growing fast and a force
              to be reckoned with.
            </p>
            <table style="float:left" >
              <tbody>
                <tr>
                  <td>
                    <a href="http://www.cucy.net/lacp/img/conf1-lg.jpg"><img vspace="4px" hspace="4px"
                        style="float:left" src="http://www.cucy.net/lacp/img/conf1-sm.jpg"></a>
                  </td>
                </tr>
                <tr>
                  <td><center>Conference Action</center></td>
                </tr>
              </tbody>
            </table>
            <p>
              For those you who have never been to an embedded systems
              conference let fill you on a few details.  This conference deals
              with the fundamental components for making consumer and
              industrial electronic devices.  You don't see a lot of polished,
              marketable consumer products like cellphones or game consoles
              &ndash; the exciting things you see are the next generation
              silicon, processor cores, software tools, development tools and
              serial interconnect products.
            </p>
            <p>
              With that said all the big hardware players had a GNU/Linux
              offering, some partnering with the likes of <a
                href="http://www.mvista.com/">MontaVista</a>, <a
                href="http://www.redhat.com/">Red Hat</a>, <a
                href="http://www.lynuxworks.com">LynuxWorks</a> and <a
                href="http://www.timesys.com/">TimeSys</a>.  Everybody has
              development boards and board support packages (BSP) for
              GNU/Linux.
            </p>
            <p>
              At the same time, however, most of the big players also
              supported old school RTOS vendors like <a
                href="http://www.ghs.com/">Green Hill Software</a>, <a
                href="http://www.qnx.com/">QNX</a> and <a
                href="http://www.windriver.com/">VxWorks</a>.  Embedded system
              teams are a conservative lot.
            </p>
            <p>
              Looking at the various embedded GNU/Linux vendors it was
              difficult for me to see a clear winner &ndash; all of them offer
              an IDE (many using eclipse), with integrated source level
              debuggers and kernel debuggers.  Is there really that much
              difference between one vendor's IDE and another?
            </p>
            <p>
              I may be slightly biased, as I'm an <a
                href="http://www.gnu.org/software/emacs/emacs.html">emacs</a>
              user, which does everything these IDE's do and then some.  Call
              me a Luddite, I won't cringe.  Less mouse, more coding.
            </p>
            <p>
              It seems pretty clear to me that we haven't had the final shake
              out in the embedded GNU/Linux distribution arena &ndash; too
              many vendors without enough differentiators.  They all look the
              same and some will have to go.  Only time will tell which ones.
            </p>
            <p>
              I promised I wouldn't bore you with the obvious so I will
              continue on with the less obvious.
            </p>
          </td>
        </tr>
      </tbody>
    </table>
    <hr width="80%">
    <table>
      <tbody>
        <tr>
          <td>
            <a name="economy"></a>
            <h3>The Economy</h3>
            <p>
              Ever curious about the economy I asked numerous vendors
              of hardware and software if they had any first hand
              knowledge of a growing economy.  Starting with hardware
              development vendors I worked my way up the
              technology food chain through hardware products and on
              to software.  At each stage I asked two questions:
            </p>
            <ul>
              <li>Have you seen an increase in orders and sales in the
              past 6 months? </li>
              <li>Have you increased your own capital expenditures in
              terms of physical resources or employees?</li>
            </ul>
            <p>
              The low level hardware development vendors, people who
              make JTAG programmers, bus analyzers and oscilliscopes,
              all answered a qualified yes to both questions.  They
              had seen encouraging increases in the past quarters, but
              are remaining cautiously optimistic at the moment.
            </p>
            <p>
              Next I talked to PCI Express and ATCA vendors to see if
              these new technologies are making inroads.  These
              vendors responded positively to both my questions,
              saying the market is definitely showing interest in
              these areas.  Good news.
            </p>
            <p>
              Finally I talked to software tool vendors and GNU/Linux
              vendors.  These vendors also responded positively saying
              orders for products and services had increased during
              past two quarters.
            </p>
            <p>
              It looks like the economic clouds are starting to part a
              little.
            </p>
          </td>
        </tr>
      </tbody>
    </table>
    <hr width="80%">
    <a name="art"></a>
    <h3>ChipX art exhibit</h3>
    <p>
      <a href="http://www.chipexpress.com/">ChipX</a>, a structured
      ASIC company, had a fascinating gallery of silicon-inspired art
      from various artists.  These artworks incorporated bits of
      silicon wafers, packaged ICs and other hi-tech left overs to
      create visually stunning pieces.  A sampling from the gallery is
      shown here:
    </p>
    <table cellpadding="10">
      <tbody>
        <tr>
          <td>
            <a href="http://www.cucy.net/lacp/img/art1-lg.jpg"><img src="http://www.cucy.net/lacp/img/art1-sm.jpg"></a>
          </td>
          <td>
            <a href="http://www.cucy.net/lacp/img/art3-lg.jpg"><img src="http://www.cucy.net/lacp/img/art3-sm.jpg"></a>
          </td>
          <td>
            <a href="http://www.cucy.net/lacp/img/art6-lg.jpg"><img src="http://www.cucy.net/lacp/img/art6-sm.jpg"></a>
          </td>
        </tr>
        <tr>
          <td>
            <a href="http://www.cucy.net/lacp/img/art4-lg.jpg"><img src="http://www.cucy.net/lacp/img/art4-sm.jpg"></a>
          </td>
          <td align="center">
            <a href="http://www.cucy.net/lacp/img/art5-lg.jpg"><img src="http://www.cucy.net/lacp/img/art5-sm.jpg"></a>
          </td>
          <td>
            <a href="http://www.cucy.net/lacp/img/art2-lg.jpg"><img src="http://www.cucy.net/lacp/img/art2-sm.jpg"></a>
          </td>
        </tr>
      </tbody>
    </table>
    <table>
      <tbody>
        <tr>
          <td>
            <a name="linux"></a>
            <h3>Other interesting things GNU/Linux</h3>
            <table style="float:left" >
              <tbody>
                <tr>
                  <td>
                    <a href="http://www.cucy.net/lacp/img/smotion-lg.jpg" style="float:right" ><img vspace="4px" hspace="4px"
                        src="http://www.cucy.net/lacp/img/smotion-sm.jpg"></a>
                  </td>
                </tr>
                <tr>
                  <td><center>Silicon Motion</center></td>
                </tr>
              </tbody>
            </table>
            <p>
              <a href="http://www.oki.com/">OKI</a>, a company focusing on
              two-way communication products, offered several ARM7 based
              development boards using <a
              href="http://www.uclinux.org/">uClinux</a>, a flavor of
              linux for CPUs with no MMU.
              For the parents out there OKI makes the CPUs inside the popular
              <a href="http://www.leapfrog.com/">LeapFrog</a> music toys for
              children &ndash; my 15-month old son loves his <a
                href="http://www.leapfrog.com/do/findproduct?ageGroupID=ages_infant&id=learntable">LeapStart 
                Learning Table</a>.  A lot of the music toys for kids offend
              my ears, but the Learning Table uses digitized instruments with
              a high bit rate.  Parents know, anything that teaches kids music
              and keeps them entertained without annoying the hell out of you
              is a wonderful piece of technology.
            </p>
            <p>
              <a href="http://www.siliconmotion.com">Silicon Motion</a> makes
              a wide range of low-power multimedia chips that are DirectX and
              OpenGL compliant (think nVidia/ATI without a honking
              heatsink and fan on the
              GPU).  Here's a shot of their development board running
              MontaVista Linux &ndash; notice the GPU without a fan.
            </p>
            <table style="float:right" >
              <tbody>
                <tr>
                  <td>
                    <a href="http://www.cucy.net/lacp/img/rgate-lg.jpg"><img vspace="4px" hspace="4px" style="float:right" src="http://www.cucy.net/lacp/img/rgate-sm.jpg"></a>
                  </td>
                </tr>
                <tr>
                  <td><center>Toshiba 64-bit Home Gateway</center></td>
                </tr>
              </tbody>
            </table>
            <p>
              <a
                href="http://www.toshiba.com/taec/cgi-bin/display.cgi?table=Category&CategoryID=132">Toshiba</a>
              offered a wide variety of TV set-top boxes, DVRs and residential
              gateways running GNU/Linux.  All of these products are powered
              by Toshiba's MIPS based 64-bit processors &ndash; that's a lot
              of horsepower for a set-top box.  Check out their residential gateway.
            </p>
          </td>
        </tr>
      </tbody>
    </table>
    <hr width="80%">
    <table>
      <tbody>
        <tr>
          <td>
            <a name="robot"></a>
            <h3>Robots Spectrum</h3>
            <table style="float:right" >
              <tbody>
                <tr>
                  <td>
                    <a href="http://www.cucy.net/lacp/img/rover-lg.jpg"><img vspace="4px" hspace="4px" src="http://www.cucy.net/lacp/img/rover-sm.jpg"></a>
                  </td>
                </tr>
                <tr>
                  <td><center>Mars Rover</center></td>
                </tr>
                <tr>
                  <td>
                    <a href="http://www.cucy.net/lacp/img/bot-lg.jpg"><img vspace="4px" hspace="4px" src="http://www.cucy.net/lacp/img/bot-sm.jpg"></a>
                  </td>
                </tr>
                <tr>
                  <td><center>Battle-Bot</center></td>
                </tr>
              </tbody>
            </table>
            <p>
              The conference had two noteworthy robots in attendance
              at opposite ends of the spectrum.  One robot represented
              peaceful, scientific exploration and the other
              representing high testosterone, heart pumping
              entertainment.
            </p>
              The first was a replica of the Mars Rover at the WindRiver booth
              &ndash; keep track of your flash memory.  Seriously though,
              sending a robot to Mars and controlling it remotely with a
              round-trip light-speed delay of 40+ minutes is <i>very</i>
              impressive.  But why run the thing with Java on top of VxWorks?
              Why not include some lisp and python while you are at it?
            </p>
            <p>
              The other really cool robots were the <a
                href="http://www.tensilica.com/html/2004bots.html">SozBots</a>
              at the <a href="http://www.tensilica.com/">Tensilica booth</a>.
              These mini battle-bots duked it out in a small arena, complete
              with safety Plexiglas cage.  These little bots were a huge hit
              at the show.  Here's a photo of a full sized saw blade battle-bot.
            </p>
          </td>
        </tr>
      </tbody>
    </table>
    <hr width="80%">
    <table>
      <tbody>
        <tr>
          <td>
            <a name="bus"></a>
            <h3>Bus Driver</h3>
            <p>
              As I finished off the last aisle of the exhibit my aching feet
              told me it was time to head home.  Recall I needed to take a
              shuttle bus back to where my car was parked at SBC Park.  I made
              my way to the front of the Moscone Center and wearily dragged
              myself up the steps of the Greyhound bus destined for the parking
              lot. It was here that I heard the most insightful observation of
              the entire day.
            </p>
            <p>
              On board the bus driver and some of the passengers and were discussing 
              virtual reality as I plopped myself in the bus seat, my first
              sit down rest in over 5 hours.  If you've ever discussed virtual
              reality before you know the conversation can get quite "meta"
              very easily, such as 
            </p>
            <blockquote>
              <p>
                The problem with virtual reality is that the virtual reality
                universe is so engrossing that the distinction between virtual
                reality and <i>real reality</i> melts away make the
                virtual one the <i>real one</i>...  Yes, but the
                bandwidth and memory required to create a truly immersive
                environment are still years off...
              </p>
            </blockquote>
            <p>
              Or some such nonsense like that.  My bus driver was holding his
              own quite respectably in this conversation, but what he said at
              the end blew my mind and made my day:
            </p>
            <blockquote>
              <p>
                <i>All the technology in the world won't do you any good without
                  common sense.</i>
              </p>
            </blockquote>
            <p>
              Can't argue with that.
            </p>
          </td>
        </tr>
      </tbody>
    </table><a href="http://www.cucy.net/cgi-bin/mt/mt-tb.cgi?__mode=view&entry_id=21" onclick="OpenTrackback(this.href); return false">TrackBack (0)</a> | <a href="http://www.cucy.net/lacp/archives/000021.html#comments" title="Comment on: Behind The Scenes at The Embedded Systems Conference ">Comments (0)</a></p>]]></content:encoded>
<dc:subject>General</dc:subject>
<dc:date>2004-04-01T08:14:21-08:00</dc:date>
</item>

<item>
<title>Existential Programming</title>
<link>http://www.cucy.net/lacp/archives/000011.html</link>
<description><![CDATA[A man who carries a cat by the tail learns something he can learn in no other way. &ndash; Mark Twain]]></description>
<guid isPermaLink="false">11@http://www.cucy.net/lacp/</guid>
<content:encoded><![CDATA[<blockquote>
  A man who carries a cat by the tail learns something he can learn in no other way.<br>&ndash; Mark Twain
</blockquote>

<p>I strongly believe that we learn best by doing, that what you <b>know</b>
is a synthesis between what you have <b>studied</b> and what you have <b>accomplished</b>.
While there is no substitue for reading, attending classes and good
mentorship, you will never <b>know</b> a field until you undertake a
project and grapple with the details.

<p>I had a physics professor, Dr. Reid, who taught "Mathematical Methods
for Physics", which was a great class.  My favourite part was "complex
functional analysis", where we dealt with contour(path) integrals,
complex residues and the like (see <a
				     href="http://mathworld.wolfram.com/ResidueTheorem.html">details</a>).
Rather abstract stuff, but it had practical applications.

<p>Dr. Reid had a saying:

<blockquote>
  The process of learning physics is an active process.  The information does not enter the brain through the eyes and ears alone, but rather it takes a slow journey through your fingers and hands, up your arm and into your brain.
</blockquote>

<p>In other words you actually need to work the homework problems to
understand the material.

<p>Indeed.

<blockquote>
  You cannot create experience. You must undergo it.<br> &ndash; Albert Camus
</blockquote>

<p>All of this makes me think of programming as an <i>existential</i>
process.  I cannot, however, claim to have invented the term <b>existential
  programming</b> (damn!).  I don't think anyone agrees on what it
really is, but the University of Kansas offers this <a
				href="http://jade.designlab.ukans.edu/~ambler/188/chaps/introscm18.html">course</a>.  My own interpretation is somewhat broader than this.

<p>The type of programmer you are depends on the types of programs you have written and the programs you are writing now.   Choose carefully and seize your destiny.

<p>
<h3>It Takes a Project</h3>

<p>With philosophy and education as my guides it is time to embark on
a project to truly learn the ins and outs of embedded programming.  It
would have been nice if my day job coincided exactly with my
programming goals, but it did not.  Not quite.

<p>I am not down playing the useful experience I gain from my day job,
but the goals here were a little different.  The day job is all about
embedded programming for the VxWorks operating system &ndash; in my heart
of hearts I wanted to do <b>GNU/linux</b> embedded programming.  Sitting
around wishing and hoping I would do GNU/linux programming would have been
foolish. 

<p>So once again I made some investments in my future.  I decided to
teach myself embedded GNU/linux programming by reading books,
mailing-lists and by purchasing a small embedded processor board.

<p>My first goal was to boot linux on the board.  This proved to be a
wonderful journey. 

<p>At first this was a little daunting &ndash; where to begin?  What board to
buy, what GNU/linux distribution to use, what books to read...  What to buy and what to build myself?  I went to
the neighborhood technical bookstore and browsed the shelves looking
for interesting books as a starting point.  I found two that I highly
recommend for different reasons:

<ul>
  <li><i>Embedded Linux:  Hardware, Software and Interfacing</i><br>
  Craig Hollabaugh, 2002.  ISBN 0-672-32226-9

  <li><i>Linux Device Drivers, 2nd Edition</i><br>
  Alessandro Rubini & Jonathan Corbet, 2001. ISBN 0-596-00008-1
</ul>

<p>Let me tell you a little bit about these books:

<p><i>Embedded Linux</i> is a great <b>hands on</b> book.  What I really like
about it is that the author leads you through the design and
development of a complete system (not just a single computer) that
spans three different processor architectures &ndash; PowerPC, ARM
and x86.  This is great because the different architectures expose
different parts of the linux kernel.

<p>I will not bore you with a complete review of the book as a good
review is already written <a
			    href="http://www.linuxdevices.com/articles/AT8515229385.html">here</a>.  Craig Hollabaugh also has a nice <a href="http://www.embeddedlinuxinterfacing.com/">website</a> that serves as a companion to his book. 

<p>It is a really great book.  The author covers topics like
portability as he shows how to write the same device driver for the
three different target architectures.  It <b>really</b> helps to see a
problem solved in three different ways.  Highly recommended.

<p>Also Craig was very responsive to questions I emailed him as I went
through booting my board for the first time.  Very nice.

<p><i>Linux Device Drivers, 2nd Edition</i> is also a really great book.
First off it is released under the <a
				     href="http://www.gnu.org/copyleft/fdl.html">GNU Free Documentation License</a> and is freey available <a href="http://www.xml.com/ldd/chapter/book/">online from O'Reilly</a>.  I recommend buying the book as paper is so much easier to read.

<p>It covers writing device drivers for standard 2.4 kernels targeted for
the Intel x86 architecture.  It does not cover embedded GNU/linux, however it does
cover the kernel and device drivers in great detail.  A very valuable
resource.


<p><blockquote>
  Information's pretty thin stuff unless mixed with experience.<br> &ndash; Clarence Day
</blockquote>

<p>After reading most of Craig's book I was ready to purchase a board and
get busy.  To make my life a little easier I decied to stick to the
same processor architecture I used at my day job, the Motorola
PowerPC.  

<p>I purchased a RPX_Lite from <a
					href="http://www.embeddedplanet.com">EmbeddedPlanet</a>,
which has a blindingly fast (not) 80MHz 823e PowerPC processor with
16MB of RAM. It's pretty cute, a 3 inch square that includes ethernet,
USB, serial and a PCMCIA slot.  Just right for experimenting.  This board is
similar to the RPX_Classic that Craig uses in his book.

<p>Next I needed a GNU/linux distrubtion to use with my board.  This is not
as easy as it sounds and Craig's book leads the way.  The first thing
you need is a cross-compiler for your board, so that you can build <b>all</b>
the executables that your board will need.  This includes not only the
kernel, but all the supporting GNU software (cp, rm, ls, etc.) .

<p>It is a <b>lot</b> of work to build a linux distribution from source.
It is much easier to use a pre-built distribution for your board.
This is what companies like Lineo, MontaVista and LynuxWorks are
selling.  See <a
		href="http://www.linuxdevices.com/articles/AT2760742655.html">here</a> 
for a good overview of embedded linux distributions.

<p>Also I hit my first bump in the road when I realized my processor did
not have a Floating Point Unit (FPU).  Most available GNU/linux
distributions for the PowerPC assumed you were running GNU/linux on a
MacIntosh, whose processor <b>do</b> have an FPU.  Those binaries
would not work for me.

<p>It looked like I was going to build everything myself...

<p><blockquote>
  Experience is not what happens to you; it is what you do with what happens to you.<br> &ndash; Aldous Huxley
</blockquote>                                                         

<p>Until I found the <b>perfect</b> distro for my needs called the "Embedded Linux
Development Kit" (ELDK) from <a href="http://www.denx.de">DENX
  Software Engineering</a> in Germany.  

<p>The ELDK comes with pre-built binaries for a range of PowerPC
processors including my version.  This includes the cross-compiling
GCC toolchain and hundreds of pre-compiled programs and utilities that
come with GNU/linux. 

<p>Oh and the ELDK is GPL and available for free download.  The price is
right.  

<p>I must give special thanks to Wolfgang Denk (owner of DENX), who
helped me numerous times via email and patiently answered my neophyte
questions.  Companies selling a commercial product should envy the
customer support I recieved from Wolfgang &ndash; above and beyond my
expectations.  Truly awesome.

<p>Now with the ELDK in hand I was quickly able to configure and build my kernel.
I was getting tantalizingly close to my goal of "booting the board".
All I wanted to see was the first login prompt from my little board
coming to me over a serial connection.  I desperately wanted to see
the results of "uname -a" as proof that the board was up and running
GNU/linux.

<p>Since the board has a limited amount of memory I decided to mount the
root filesystem over NFS &ndash; this allowed me to have access to all the
programs of the ELDK (100s of megabytes).  I had to setup an NFS
server and configure the kernel to mount root via NFS.

<p>Once that was completed the moment of truth was at hand:

<p><pre>
Linux/PPC load: 
Uncompressing Linux...done.
Now booting the kernel
Linux version 2.4.4 (curt@hongkong) (gcc version 2.95.4 20010319
(prerelease/franzo/20011204)) #10 Sat Jan 11 14:40:07 PST 2003
Calibrating delay loop... 63.89 BogoMIPS
Memory: 14752k available (904k kernel code, 364k data, 48k init, 0k highmem)
eth0: CPM ENET Version 0.2 on SCC2, 00:10:ec:00:32:d6
VFS: Mounted root (nfs filesystem) readonly.
INIT: version 2.78 booting
Remounting root filesystem in read-write mode: 
Mounting proc filesystem:  [  OK  ]
Configuring kernel parameters:  [  OK  ]
Activating swap partitions:  [  OK  ]
Checking filesystems    [  OK  ]
Mounting local filesystems:  [  OK  ]
Enabling swap space:  [  OK  ]
INIT: Entering runlevel: 3

hoho login: root
Last login: Thu Jan  1 00:00:36 on console

hoho:~# uname -a
Linux hoho 2.4.4 #10 Sat Jan 11 14:40:07 PST 2003 ppc unknown

hoho:~# ping www.ucdavis.edu
PING www.ucdavis.edu (169.237.104.199) from 10.0.0.9 : 56(84) bytes of data.
64 bytes from 169.237.104.199: icmp_seq=0 ttl=51 time=79.617 msec
64 bytes from 169.237.104.199: icmp_seq=1 ttl=51 time=69.767 msec

hoho:~# cat /proc/cpuinfo 
processor	: 0
cpu		: 8xx
clock		: 64MHz
bus clock	: 32MHz
revision	: 0.0
bogomips	: 64.39
zero pages	: total: 0 (0Kb) current: 0 (0Kb) hits: 0/0 (0%)
</pre>

<p>Sweet!  It was working.  My first project was complete &ndash; the board booted.

<blockquote>
  Life must be understood backwards. But it must be lived forward.<br> &ndash; Soren Kierkegaard
</blockquote>

<p>Now that the board booted I need a new goal, something <i>embedded</i>.  Fun fun fun.

<p>Cheers,
Curt
                                                          
<p>
<h3>Recommended Books</h3>

<ul>
  <li><a href="http://www.embeddedlinuxinterfacing.com/">Embedded Linux:  Hardware, Software and Interfacing</a><br>
  Craig Hollabaugh, 2002.  ISBN 0-672-32226-9

  <li><a href="http://www.xml.com/ldd/chapter/book/">Linux Device Drivers, 2nd Edition</a><br>
  Alessandro Rubini & Jonathan Corbet, 2001. ISBN 0-596-00008-1
</ul>

<h3>Recommended URLs</h2>

<ul>
  <li><a href="http://www.brainyquote.com/quotes/">http://www.brainyquote.com/quotes/</a>
  <li><a href="http://www.denx.de/">http://www.denx.de/</a>
  <li><a href="http://penguinppc.org/">http://penguinppc.org/</a>
  <li><a href="http://www.linuxdevices.com/">http://www.linuxdevices.com/</a>
  <li><a href="http://alllinuxdevices.com/">http://alllinuxdevices.com/</a>
</ul><a href="http://www.cucy.net/cgi-bin/mt/mt-tb.cgi?__mode=view&entry_id=11" onclick="OpenTrackback(this.href); return false">TrackBack (0)</a> | <a href="http://www.cucy.net/lacp/archives/000011.html#comments" title="Comment on: Existential Programming">Comments (4)</a></p>]]></content:encoded>
<dc:subject>General</dc:subject>
<dc:date>2003-01-11T15:57:31-08:00</dc:date>
</item>

<item>
<title><![CDATA[Back To School &ndash; Part II]]></title>
<link>http://www.cucy.net/lacp/archives/000010.html</link>
<description>The first six months were rough -- so much new information. While most of the computing terms were familar so many electronics terms left me in the dark. I had heard of programming concepts like spin-lock, semaphore, ISR, inter-locked linked list ... but I had never used them, therefore I...</description>
<guid isPermaLink="false">10@http://www.cucy.net/lacp/</guid>
<content:encoded><![CDATA[<p>The first six months were rough -- so <b>much</b> new information.  While most of the computing terms were familar so many electronics terms left me in the dark.  I had heard of programming concepts like spin-lock, semaphore, ISR, inter-locked linked list ... but I had never used them, therefore I really did not <b>know</b> them.</p>

<p>SRAM, DRAM, SDRAM -- Do you know the difference?  I didn't and everybody else did.  Processor data cache lines, memory subsystems (what is a single beat read anyway?), LVDS drivers, pull-up resistor, bias voltage, tri-state logic, BSP, VHDL.  It was like hearing a foreign language in a bad dream -- you recognized the words, but you have <b>no</b> idea what they mean and everyone around you nods knowingly.</p>

<p>On top of all the electronics terms were all the physics, mathematics and statistics terms.  What's a Poisson distribution?  A chi-square? Probalistic histogram?  Hmmm, college calculus class was over 10 years ago ....</p>

<p>So I began re-educating myself.  I found a couple of handy technical dictionaries on the web:<br />
<ul><br />
  <li> <a href="http://thesaurus.maths.org/index.html">Math Thesaurus</a><br />
  <li> <a href="http://www.techweb.com/encyclopedia/">Technical Encyclopedia</a><br />
  <li> <a href="http://www.glossarist.com/glossaries/technology/electronics.asp">Electronics Terms</a><br />
  <li> <a href="http://dictionary.law.com/default2.asp">Law Dictionary</a><br />
</ul></p>

<p>How did that last one sneak in there?  It's a good one to have anyway.</p>

<p>These links helped hide some of my ignorance, but honestly when the conversation was 30,000 ft over my head I just asked questions.  The answers were always forthcoming -- no funny looks.</p>

<p>Another area were I thought I knew something, but realized quickly that I didn't, is C compilers.  I had programmed a lot and written dozens of C programs, but I never gave much thought to the compiler (or the linker for that matter).   One piece of advice for life in the embedded world:</p>

<p> <b>Know Thy Compiler and Toolchain</b></p>

<p>Never before had the destinctin between operating system and architecture mattered.  Now I understood that you can have differenet operating systems on the same hardware architecture (e.g. linux and Windoze running on i386 hardware) and you can have the same operating system running on different architectures (like linux running on i386 and on PowerPC).</p>

<p>In our project the data acquisition system software runs the VxWorks operating system for the PowerPC architecture (our computers are 3U CompactPCI single board computers based on the Motorola <a href="http://e-www.motorola.com/webapp/sps/library/documentationlist.jsp?rootNodeId=01&nodeId=018rH3bTdG8653&Device=MPC750&DocTypeKey=A0">PowerPC</a> microprocessor).  I in no way endorse VxWorks as a hard real time operating system (RTOS).  The company behind VxWorks, <a href="http://www.windriver.com/">WindRiver</a>, is the Microsoft of the embedded OS world.  I will not say another word about VxWorks -- it is the hand I was delt.</p>

<p>If you are just starting out look seriously into running linux on your embedded system.  If you have "hard real time" requirements consider using the <a href="http://www.linuxdevices.com/articles/AT8073314981.html">real time extentions</a> to linux.  Linux on the small devices is here to stay.</p>

<p>Motorola, on the other hand, is great.  They give away (as in free) tons of documentation about their processors.  They will even mail you printed manuals for their processors, for free.  Very useful.  Try their document <a href="http://merchant.hibbertco.com/servlet/mtrlext.MtrlExtServlet?tp=search">search</a>.</p>

<p>In our work we <b>cross compile</b> the programs for the embedded system.  Briefly cross compiling is when you run the compile/link stage on one OS (e.g. Solaris), but the resulting binary is for a different OS/Architecture (VxWorks on PowerPC).  For a more detailed treatment of cross-compiling for the PowerPC using the GNU Compiler Collection see <a href="http://penguinppc.org/embedded/cross-compiling/">here</a>.</p>

<p>Also read up on <a href="http://gcc.gnu.org/onlinedocs/gcc-2.95.3/gcc.html">GCC</a> in general, particularly the sections about GNU extentions to C and C++.  Some of these are quite useful.</p>

<p>In our testing we try to exercise our code as much as possible before downloading it to the embedded processors.  To this end we cross-compile our code for three different platforms:<br />
<ul><br />
  <li> VxWorks on PowerPC -- the real system<br />
  <li> Solaris on UltraSPARC -- development system<br />
  <li> Linux on i386 -- development system<br />
</ul></p>

<p>While we cannot debug everything on the development system (some tests <b>must</b> run on the real embedded system), we can flush out many compile time bugs by pushing our code through three seperate compile/link stages.  Sometimes different compilers for different architectures catch different bugs and warnings.</p>

<p>I could write an entire article about the compile/link process we use -- but I won't do that here, unless people are interested.  I find it interesting.</p>

<p>The first part of my re-education is well underway.  I was getting a <b>good</b> handle on my tools.  It is very important that a craftsman understand the benefits and limitations of his tools.</p>

<p>Now I needed  a project to work on ...</p><a href="http://www.cucy.net/cgi-bin/mt/mt-tb.cgi?__mode=view&entry_id=10" onclick="OpenTrackback(this.href); return false">TrackBack (0)</a> | <a href="http://www.cucy.net/lacp/archives/000010.html#comments" title="Comment on: Back To School &ndash; Part II">Comments (2)</a></p>]]></content:encoded>
<dc:subject>General</dc:subject>
<dc:date>2003-01-04T20:51:50-08:00</dc:date>
</item>

<item>
<title><![CDATA[Back To School &ndash; Part I]]></title>
<link>http://www.cucy.net/lacp/archives/000008.html</link>
<description>When last we met back in January 2002 (almost one year a go), the accidental programmer decided it was time to get serious and really learn the trade of computer programming. To that end I wanted to program embedded systems where a thorough knowledge of the underlying hardware is absolutely...</description>
<guid isPermaLink="false">8@http://www.cucy.net/lacp/</guid>
<content:encoded><![CDATA[<p>When last we met back in January 2002 (almost one year a go), the accidental programmer decided it was time to get serious and really learn the trade of computer programming.  To that end I wanted to program embedded systems where a thorough knowledge of the underlying hardware is absolutely necessary.</p>

<p>I took a 20% pay cut to work at <a href="http://www.slac.stanford.edu">SLAC</a>, a DOE National Laboratory operated by Stanford University.  What I recieved in exchange for the 20% has been absolutely invaluable -- I learned how to think, I learned all about how the computer/interfacing world operates.  I learned and understood the importance of <b>system engineering</b>.  More on that later.</p>

<p>The project I am working on is called <a href="http://www-glast.slac.stanford.edu">GLAST</a>, a large gamma-ray observatory satelite that will measure gamma-ray sources throughout our universe as the satelite orbits the Earth.  I work on the embedded system software that runs the data acquisition system for the detector.</p>

<p>I'm right where the rubber mets the road -- where an electrical engineer's piece of super custom hardware meets a Motorola PowerPC single board computer.  I write device drivers for one-of-a-kind hardware devices.  Oh yah, and the whole system will be stuffed on the tip of an explosive rocket and launched into orbit.</p>

<p>Deliciously geeky.</p>

<p>Up front though I want to give props to the physicists, researchers and engineers who toil away building the best possible machines for measuring and understanding the universe in which we live -- they dedicated their lives to scientific pursuits.  </p>

<p>SLAC is a very interesting place to work -- it is one of the few DOE labs that does <b>not</b> do defense research, i.e. it is not a bomb factory.  Also all of the projects and results are open for public scrutiny -- no so called <i>black projects</i> that occupy so many defense and aerospace companies.  The research is funded with our tax dollars and is open to you, me and everyone else.</p>

<p>That is refreshing.</p>

<p>It is also refreshing to work with people who have decided to spend their entire life at SLAC for that very reason.  These are sharp people who believe in what they are doing, but with humility, graciousness and a sense of how things could be much, much, darker.  More about the dark side in a future post.</p>

<p>So the employment was a fair trade I'd say.  They picked up a seasoned computer programmer who also had a physics background.  It's just my computer programming background was writing applications -- it was now time to dive into and beneath the operating system and write device drivers.  This is the area I wanted to explore, the embedded system.  While I knew nothing about the low level world or embedded systems it seems fascinating and valuable as computers become more pervasive as they shrink smaller and smaller.</p>

<p>For their part they signed up to teach me embedded system programming.  Or so I thought.  So far it has turned out to be much, much more.  They taught me about <b>system engineering</b>.  How to architect a complete, complex system of custom electronics and software.  How to think way, way outside of the box when designing (and debugging) an ambitious compu-electronic data acquisition system.</p>

<p>I feel the pain of the hiring managers at SLAC -- everything is a trade off.  They have ridiculously small budgets, but they need really experienced engineers to build the devices they design.  However all the really good, experienced engineers all work in industry where the pay is about 20% higher.  So they make do with the people they can afford, knowing they will have to do a bit of teaching to make it all work.</p>

<p>I'm sure they don't realize it, but I have been absorbing as much knowledge as possible at every opportunity.</p>

<p>It is not always fun, however.</p>

<p>I came from running my own company, where I was in control and I decided what needed doing when.  This was a change -- someone else was in control for the direction.  Even more than that I had no experience in the field at all.  It's quite an unsettling feeling after being in charge for so long.  I did not know enough about embedded systems to know if their ideas were right or wrong.  </p>

<p>I felt small.</p>

<p>And dumb.</p>

<p>To be continued ...</p><a href="http://www.cucy.net/cgi-bin/mt/mt-tb.cgi?__mode=view&entry_id=8" onclick="OpenTrackback(this.href); return false">TrackBack (0)</a> | <a href="http://www.cucy.net/lacp/archives/000008.html#comments" title="Comment on: Back To School &ndash; Part I">Comments (1)</a></p>]]></content:encoded>
<dc:subject>General</dc:subject>
<dc:date>2003-01-02T18:41:03-08:00</dc:date>
</item>

<item>
<title>Crossover:   WSDL to Gamma-Ray Telescopes</title>
<link>http://www.cucy.net/lacp/archives/000003.html</link>
<description>An accidental programmer takes a humbling journey as he attempts to crossover from high level web application programmer to bare iron coder � all the while looking for The Lost Art of Computer Programming. </description>
<guid isPermaLink="false">3@http://www.cucy.net/lacp/</guid>
<content:encoded><![CDATA[<p>In  this month's  article I  continue the  thread of  the transfigured programmer  who has  decided it's  time  to stop  screwing around  and actually learn  the trade.  The  last project using WSDL  left reality receding in the rear view mirror  at a frightening pace.  The Java app server,  markup  language, SOAP,  XML,  WSDL,  DOM  vs SAX,  wireless, e-commerce, pocket  palm-PC, CGI, SQL,  HTTP .  Everything  was moving too fast. </p>

<p>So I hopped off the train.</p>

<p>I quit.</p>

<p>Resigned, from  the startup  -- poof went  all my "equity".   A little less than two years after the  madness had begun it was suddenly over. All I had left were 500 now-useless business cards.</p>

<p>But I had a plan, of course.</p>

<p>"Hey, I can  do some consulting work...  Work  for myself...  yeah.  I just might do that...  Yeah..  That's what I'm going to do...  YEAH."</p>

<p>Being unemployed did not worry me at all... At least it didn't until I actually started looking for work.</p>

<p>Then  it  worried me  a  bit.  No  work  for  consultants --  economic downturn  -- the  big boys  were having  layoffs and  weren't renewing contracts  with the  people they  had.   No consulting  jobs for  you, Mr. SmartGuy.com .</p>

<p>Luckily for me  I had a very understanding  fianc�e (we're married now) at the  time.  "I can support us  while you look for  work", she said. She is  the BEST, without  whom I would  be a complete mess.   It felt weird to  be supported by someone  else, like being out  of control -- assuming you  are in control  is one of  the biggest mistakes  you can make.</p>

<p>While being unemployed is spooky it has its perks as well.</p>

<p>I spent a lot of time  reading: technical articles, well known "Art of Programming Vol.  1", newsgroups, mailing  lists and some  fiction too (read LOTR in  preparation for it's release in  12/01).  I cannot over emphasize  how important reading  for pleasure  is --  it's absolutely amazing how fun it is to  read a good book.  Turn off your televisions and read  something you  enjoy ( BTW  never, ever torture  yourself by finishing a book you don't enjoy).</p>

<p>Being  between  jobs  also   forces  you  to  ponder  the  troublesome questions,  "What do  I want  to do?"   More of  the  same?  Something different?  Both?  Neither?  Move?  Stay?"</p>

<p>At the  startup I co-founded I  was the VP of  Engineering, managing a team  of about  20 people  including development,  ops and  QA  -- and managing  not to  grieviously maime  some  of my  fellow founders  and executives.  Effectively  managing people is an  art requiring vision, organization,   patience   and    flexibility   --   I've   had   good manager/mentors and  I've had horrible schedule-centric  dolts with no personality.  I tried to "do my best".</p>

<p>Managing  people reminded  me of  teaching physics  to  bio-sci majors while  studying  particle  physics  in  graduate school  --  sure  the students  wanted to  learn,  but  the current  subject  was of  little interest.  At UCSB  ( U Can Study Buzzed )  most students would rather not be in an electronics lab  on the 4th floor of the Physics building on a Friday afternoon.</p>

<p>As a manager I tried to challenge people, to push them slightly beyond their current  comfort zone and in  the direction where  I needed work done.  I found  providing people with a method/process  as an approach to problem  solving is very valuable,  especially when I  did not know exactly what to  -- I relied on the employee's  expertise and let them reason it out.</p>

<p>employee:  But I don't see how I'm going to balance the load of<br />
	   spawning user logins across the server farm.  How do we<br />
	   figure out where to spawn the next login session?</p>

<p>me:	   Well, what are our precious resources consumed by logins?<br />
	   What can we monitor about the farm?		 </p>

<p>emp:	   Memory usage, CPU usage, open file handles, number of processes,<br />
	   uptime, current sessions.</p>

<p>me:	   Derive a load function using those variables and minimize it.</p>

<p>emp:	   uh, uh. (unsure)</p>

<p>me:	   The machine is "loaded" whenever those variables are high.  Low<br />
	   values mean the machine is not so busy, right?</p>

<p>emp:	   OK. (nodding)</p>

<p>me:	   Consider a  load function as a linear  combination of those system<br />
	   variables.  Query  all the machines  in the farm  and spawn<br />
	   the  new  login  on  the  machine  with  the  minimum  load<br />
	   function.</p>

<p>emp:	   Linear what?  I'm just going to add them together with different<br />
	   scaling factors for each term.  (Beaming as comprehension<br />
	   washes over)</p>

<p>me:	   That's an even better idea.</p>

<p>emp:	   It also seems if the load function is too high for every<br />
	   machine we should post a message saying all machines are<br />
	   busy.</p>

<p>me:	   That sounds like an excellent idea to me.</p>

<p>An so it goes...  Managing  people had its rewarding moments.  It also<br />
has it tough times too: firing a problematic employee and laying off a<br />
good employee and friend.</p>

<p>But I  digress, this  article is about  programming.  I wanted  to get<br />
back to programming, real programming.   I wished to be a linux kernel<br />
hacker, but  I knew  little about it.   There was  something appealing<br />
about getting closer to the iron,  but I could not quite put my finger<br />
on it.</p>

<p>Whenever I wanted to learn a new programming language (like python) it<br />
always took me a project to really get an understanding.  I could read<br />
the book,  but I  didn't know what  it was  like until I  actually did<br />
something -- typing  in the examples didn't not  count.  It takes some<br />
problem, some "itch" to stratch to really get into something.</p>

<p>I knew  my programming quest and  getting closer to the  iron would be<br />
like that too.</p>

<p>__Job_Hunting__</p>

<p>I applied to  various jobs and head hunters.  The  head hunters did an<br />
excellent job of  finding me jobs doing what I  had done previously --<br />
they said  I'd do well  in executive engineering positions,  which did<br />
not interest  me in the  slightest.  A recurring  theme in my  life --<br />
being good at something, but not really wanting to do it for a living.</p>

<p>I wanted to code.</p>

<p>I  wanted to code  for real.   I wanted  the end  result to  have some<br />
significance, some kind  of purpose.  I wanted to care  -- I was tired<br />
of not giving a shit.</p>

<p>I went to  one job interview for a wireless  handheld company that was<br />
making  sync-stations  in   the  car.   The  sync-stations  wirelessly<br />
communicated with  their backend  servers delivering "content"  to the<br />
handhelds  (that is  if you  consider  stock quotes  and sport  scores<br />
content -- why do wireless companies always advertise stock quotes? ).</p>

<p>Their "technology" seemed  like YAWS to me --  Yet Another Web Server.<br />
I  was getting  bored with  web  serveres, connected  to app  servers,<br />
connected to database  servers.  After a while they  all look the same<br />
with no real innovation happening.</p>

<p>The kiss of death for my  employment at said company came when I asked<br />
them my favourite  interview question "How do you  keep Micro$oft from<br />
eating your lunch?"  The answer  was "Mumble, mumble, we have partners<br />
... broad support for our platform.... mumble, mumble, partners..."</p>

<p>Yeah right and I'm the Easter Bunny.  Be afraid, be very afraid when a<br />
company  leads  with its  "partnerships"  as  a  selling point.   It's<br />
double-speak for "These companies agreed to let us tell others they're<br />
our partners if  we give them our software for free.   We have no real<br />
revenue, but hope to seed the market with our partners."  Run -- don't<br />
walk -- away.</p>

<p>The  answers  you  want  to  hear involve  the  word  "customer",  not<br />
"partner".  Having customers implies  someone, somewhere is willing to<br />
exchange ca$h for something the company has.  While that seems simple,<br />
it was an excruciating lesson I will never, ever forget.</p>

<p>__Job_Fair__</p>

<p>I  went to  a  job fair  in  San Jose  and was  suprised  to see  some<br />
companys' booths with signs  reading "No Recent Graduates", "Minimum 2<br />
years experience" -- tough times, glad I had experience.  Too bad what<br />
I had experience  in didn't interest me that much  any more.  I headed<br />
straight for the hardware companies.</p>

<p>company: Do you have any experience writing device drivers?</p>

<p>me:	 Sort of.  Does writing a linux kernel module count?</p>

<p>company: That depends.  What did the module do?</p>

<p>me:	 Printed "Hello World" in /var/log/syslog using printk(). (grin)</p>

<p>compnay: I don't think so.</p>

<p>After trolling  the isles of the  job fair for  a while I went  to the<br />
booth  of a company  that makes  energy effecient  microprocessors and<br />
also employs the creator of a well known open source UNIX-like kernel.</p>

<p>company: What kind of experience do you have?</p>

<p>me:	 I have two degrees in physics and I've been programming for<br />
	 over 10 years.	</p>

<p>company: What can you tell me about pipe lining in microprocessors?</p>

<p>me:	 Well, an instruction enters the pipeline and starts to be decoded,<br />
	 as it moves through part of the instruction is fetched from<br />
	 memory, while other units prepare for branching and and<br />
	 and.... Something like that.</p>

<p>company: good luck.</p>

<p>The crossover was going to be harder that I thought.</p>

<p>__In_Between_Jobs__</p>

<p>My unemployment was  going on three months when an  old friend of mine<br />
named Jim called asking what I  was up to.  Jim is an interesting guy,<br />
a seasoned programmer  and a quick thinking smooth  talker -- just the<br />
kind of guy to have an interesting business proposition.</p>

<p>Just what I needed.</p>

<p>As  usual Jim had  lots of  ideas and  "prospects", but  little money.<br />
Would I help him pull together YAWS(see above) for a suite of projects<br />
he had brewing?  I had nothing going  on either -- "What do  I have to<br />
lose?", I  thought.  At best  I earn a  little spending money,  at the<br />
worst  I  keep  my brain  busy  while  I  keep looking  for  something<br />
permanent.</p>

<p>Plus it  was Jim.  It  was like helping  family.  I was  not expecting<br />
compensation at  $100/hr for  my time. The  point was to  stay active,<br />
stay in the race.</p>

<p>Later I realized I cared more about  that job I did for Jim than I had<br />
about anything during  the past six months.  It's  weird, but the less<br />
money was involved the more pride I  took in the work.  I was doing it<br />
because I wanted to.</p>

<p>That  and  $950,000.00 can  buy  you  a house  in  Palo  Alto, CA.   I<br />
obviously  could  not  work  for  free,  but  my  salary  expectations<br />
definitely changed for the betterment of my state of mind.</p>

<p>__Ultimate_Frisbee__</p>

<p>Since  my  youth I  have  lived  an  active lifestyle  --  basketball,<br />
running, softball, hiking and ultimate frisbee.  For those uninitiated<br />
ultimate  frisbee is  "sort of  like  football only  with a  frisbee",<br />
played on  a grass  field slightly larger  than a soccer  field.  With<br />
seven people on a team the idea is to catch the "disc" in the end zone<br />
for  a point.   It  has some  similarities  with basketball  regarding<br />
defense and getting open  -- it's an incredible cardiovascular workout<br />
do to the size  of the playing field and amount of  ground you have to<br />
cover.</p>

<p>The fundamental rule  in ultimate is "no bodily  contact", none.  This<br />
is  very  unlike basketball  (no  boxing  out)  and soccer  (no  slide<br />
tackles).  No  contact, means no  contact.  It's an  incredibly simple<br />
rule and easy  to "call" -- at the "lunch time  pickup" level very few<br />
arguments ever occur regarding fouls.  Almost none.</p>

<p>This keeps the games very civil  for the most part (note: the national<br />
and world tournments are very  competitive and the contestants are not<br />
always so nice, I'm talking about noon-time pickup games in the park).<br />
This is  in stark constrast  to noon-time basketball and  soccer games<br />
I've been in where people think  the world championship is on the line<br />
and argue all the time.</p>

<p>People  play ultimate because  they enjoy  running and  jumping around<br />
outside  on a  grassy  field in  the  sunshine.  The  people who  play<br />
ultimate tend to be genuinely nice people, interesting people from all<br />
walks of  life: musicians, teachers,  bankers, engineers, acocuntants,<br />
students, translators,  business people, doctors,  scientists, mothers<br />
and fathers.</p>

<p>Deals of  many natures (business or  otherwise) are known  to occur on<br />
the fields of Ultimate.</p>

<p>One fortuitous sunny day in May I was tossing some warm-up throws with<br />
Ron, a guy who works for the major university in Palo Alto, California<br />
whose  mascot  is  a shade  of  red  --  at  the high  energy  physics<br />
accelerator center.</p>

<p>Lacing up my  cleats I querried, "What are you  working on these days?<br />
I studied physics for a while in grad school."</p>

<p>Whizzz went the disc.</p>

<p>"We're doing something new in  high energy physics.  We're launching a<br />
satelite  based gamma-ray  observatory.  We  know about  building atom<br />
smashers,   but  the   space  environment   is   something  altogether<br />
different." as Ron tossed a high arcing outside-in forehand throw.</p>

<p>Catching the disc I thought to myself, "Why the hell not?".  "Hey, are<br />
you guys  hiring people?", I  asked as I  threw the disc with  a quick<br />
snap of my wirst.</p>

<p>"I'm not,  but the guy two  doors down the  hall from me is.   He's in<br />
charge of  the embedded  system software that  runs on  the instrument<br />
when it's in orbit.  I don't know  too much about it, as my job in the<br />
experiment is dealing with the data  once it gets down to earth -- his<br />
job  is to  capture the  data and  get it  to the  ground.   If you're<br />
interested I can get your resume in front of him."</p>

<p>When you least expect it history comes up and bites you on the ass.  I<br />
thought I was done with Physics for good.</p>

<p>It turned  out the  position was for  a programmer  to be part  of the<br />
"flight  software" team  -- software  which  would fly  on aboard  the<br />
satelite.   It was  all  about embedded  programming: hard  real-time,<br />
multi-processor  programming  on   Motorola  PowerPCs  driving  custom<br />
particle detector flight electronics.</p>

<p>Cool,  I could  get into  this.  Instead  of programming  up  from the<br />
operating  system and to  applications, it  would be  programming down<br />
from  the OS through  device drivers  -- interrupts,  semaphores, ring<br />
buffers,  spin locks,  all manner  of  techniques I  knew very  little<br />
about.</p>

<p>I was  concerned it was  going to  be the same  old story again  -- no<br />
experience, no  job.  To my  suprise after the  interview I had  a job<br />
offer  two weeks  later.   The fact  that  I knew  computers and  some<br />
physics (as opposed to knowing physics and some computers like all the<br />
physicists) was  just what they  were looking for.   That I was  not a<br />
embedded guru, but wanted to get into it was fine with them.</p>

<p>It also did  not hurt that I was  willing to take a 20%  pay cut going<br />
from industry to a scientific research lab.  It was like when I worked<br />
for my friend Jim -- it's not completely about the money, I want to do<br />
something I care about.  I wanted to do something I was proud of.</p>

<p>Besides  it sounded totally  cool --  it's every  boy's dream  to have<br />
something to do with a gigantic rocket's firey blast off.</p>

<p>to be continued...</p>

<p>The next installment </p>

<p>   "Back to School"</p>

<p>email me and I'll send you next month's installment -- curt@acm.org</p><a href="http://www.cucy.net/cgi-bin/mt/mt-tb.cgi?__mode=view&entry_id=3" onclick="OpenTrackback(this.href); return false">TrackBack (0)</a> | <a href="http://www.cucy.net/lacp/archives/000003.html#comments" title="Comment on: Crossover:   WSDL to Gamma-Ray Telescopes">Comments (2)</a></p>]]></content:encoded>
<dc:subject>General</dc:subject>
<dc:date>2002-01-18T23:54:58-08:00</dc:date>
</item>

<item>
<title>Accidental Programming</title>
<link>http://www.cucy.net/lacp/archives/000001.html</link>
<description>Did you wake up one day to find that you had become a computer programmer almost entirely by accident? See the intriguing article, The Lost Art of Computer Programming, written by an accidental programmer.</description>
<guid isPermaLink="false">1@http://www.cucy.net/lacp/</guid>
<content:encoded><![CDATA[<p>In this month's article I'll examine "The Lost Art of Computer Programming" giving credit to the original author of "The Art of Computer Programming".  Along the way you'll find a status report on my continuing journey towards heightened awareness and a reminder of the dirty tricks of history.</p>

<p>In these heady daze(sic) of .NET, mono, SOAP, java, xml, object oriented software design and "network as computer" metaphors we (professional programmers) seem to have lost sight of the "computer as machine" truism.  Despite all the power of abstractions a fundamental understanding of how the machine really works remains invaluable.</p>

<p>Like many modern engineers today I began life with a computer in the house -- OK technically not since birth, but since the time I was 8 years old and Pops brought home that Apple ][+ things just haven't been the same (with a little math YOU can date me).  By no means do I consider myself a great programmer, or even a good programmer -- in polite company I stifle a cough when saying I'm a "Software Engineer", quietly knowing I'm a little more than a quick hack.  I know people who can code circles around me in various problem domains, whose understanding of the underpinnings of the problem far exceed my own.  </p>

<p>I am an accidental programmer.</p>

<p>That first Apple that my father bought did little to teach me the "Art of Computer Programming".  What it did teach me is that playing games like Ultima, The Bard's Tale and Wizardy was wickedly fun -- not a very  practical thing to know.  </p>

<p>As a teenager I spelunked into 6502 programming enough to implement  a bubble sort algorithm simply because I could, not out of necessity. I also played with "Apple Pascal" -- it's compile and link stages fascinated the BASIC programmer I was.  I thought it cute I had to shuffle four 5.25" floppy disks in and out of the drive to compile and link a simple "Hello World" application.  The LOGO-like "TurleGraphics" was also very cool, with simple statements like <br />
		move(30);<br />
		turn(120);<br />
		move(30);<br />
		turn(120);<br />
		move(30);</p>

<p>used to make isoscelese triangles.</p>

<p>All things being equal computers rated about a 6.5 on a scale of one to ten, somewhat behind playing basketball during the day and drinking cold beer during cool summer nights in the Mojave Desert where I grew up.  After all you couldn't get a computer drunk under a stary desert sky as you unhooked her bra all the while explaining that the twinkling starlight was billions of years old.  (BTW the desert is an excellent place to be a teenager, where one can get into all manner of red neck rural mischief -- guns, dirt bikes, beer, explosives ... all the stories you've ever heard are true.)</p>

<p>Computers did rank above going to church on Sunday's and watching TV strangely enough.  Computers were fun, but my sport-o, jock-o, red neck friends could care less -- the sun is shining (the sun is always shining)  outside in the desert.</p>

<p>Being mathematically inclined and curious about the universe I enrolled as a Physics major at a University of California.  Physics seemed like the ideal major for one whom mathematics came easily, but for whom actually **doing** math was tedious.  The beauty of partial differential equations, wave mechanics and complex numbers intrigued me -- using these concepts to model and understand the sights, sounds and experiences of the physical world around me was extremely compelling.</p>

<p>The further I went in physics the more intriguing it became, going from simple torque equations that explained why I could ride my bicycle with no hands to the more esoteric quantum mechanics, general relativity, high energy particle physics, astrophysics and cosmology. Very heady concepts for a young man set about understanding the universe and securing his place in it. </p>

<p>But I digress, this article is about programming.</p>

<p>As a physics major I received my first mainframe computer account unlocking a Pandora's Box that has not closed since.  Gopher, FTP, email, who-is -- all these people connected to machines, which in turn are connected to more machines with people connected to them.   </p>

<p>Fascinating.  </p>

<p>People to machines.  Machines to people.</p>

<p>Fascinating, but not physics.</p>

<p>Physics was all about FORTRAN, long doubles, complex variables, crunch, crunch, crunch. While in graduate school in the early 1990s two realizations would lead me to discover that Physics was not for me, sort of.</p>

<p>First, while questioning the universe I thought physics held some answers to the unexplainable.  So I attended a seminar on "Early Universe Cosmology" given by visiting theoretical "bad-asses" from around the globe.  What a disappointment to find these "experts"  arguing over the fundamentals of their science.  In truth they knew just as little as I did, perhaps less.</p>

<p>Second, while writing pattern recognition software for a high energy physics detector I decided that FORTRAN was crap and would instead write my filter routines in C and figure out how to link to the monolithic FORTRAN libraries (we were running Ultrix at the time).  A fellow grad student questioned this approach to which I dryly replied "If physics does not pan out I hope to get a real job some day."  (BTW Graduate school is a great place to see what you do not want to become -- either a grumpy 7th year student, or worse an even grumpier post-doc making slightly less than the campus grounds keeper on four hours of sleep per night.)</p>

<p>It was also clear I was no Einstein, that I was not destined to be a theoretical physicist ( my hat's off to those that are!) .  At 23 years old I was hopelessly washed up as a theoretical physicist and the thought of spending all my time indoors in a basement laboratory sounded, well ... horrible.</p>

<p>That the summer the kiss of death came:  I discovered this little program called mosaic.  The rest, as they say, is history.  I dropped out of grad school, packed my bags and landed a job in the heart of silicon valley -- Menlo Park, CA.</p>

<p>__Close_but_no_cigar__</p>

<p>I landed in Silicon Valley, but I did not land on the Internet.  When the dust cleared I found myself at a digital map company, writing software that integrated text tour guide information with digital map data.  All of this was for GPS car navigation systems and had little to do with the Internet (though a couple of people left said digital map company to go and found MapQuest about the time I joined).</p>

<p>Here I really cut my teeth with UNIX on SunOS 4.1 .  Here I had to keep up with people who were "real" computer scientists, people with Ph.D's in mathematics and topology (calculating routes on a topologically correct road network map is non-trivial).  These people were good to me and taught me many programming principles, most of which were gleaned by trying to grok their source code.</p>

<p>I also learned to leverage the power of an OS with virtual memory -- I really could allocate a gigabytes worth of unsigned ints, even if my Sparc5 workstation only had 128MB of RAM.  Really, how cool is that? What a beautiful abstraction!  That discovery also marked the beginning of my decline -- I started to become a really lazy programmer.</p>

<p>From there I moved to C/C++ Win32 programming and sloppy GUI design. I copied and pasted, cursed, used the debugger, swore and generated the most horrible looking makefiles.  At one point I even generated afx DLLs that worked only during certain phases of the moon.  Nasty bad habits.</p>

<p>Then things took a turn for the worse....</p>

<p>I was assigned to a Visual Basic project -- now I really could sit back and forget all about how the underlying OS machinery worked (except when it came time to write the InstallShield, which unfailing fucked any system we installed to -- uninstall, my butt).  VB made life so simple, so easy, so ... dangerous. </p>

<p>About this time the Internet madness was really picking up steam, when it seemed like any hack (me) with confidence could get funding for even the most hair brained idea.  It was time to found a start-up Internet company.  What could be more en vogue? </p>

<p>Luckily for me and my partners funding a bad idea is a two-way street -- first it takes a hare brained idea and then it takes someone zany enough to invest in it.  Coupled together you really understand the phrase "burn rate".  The story about the formation, function and dis-function of that start-up I will leave for a future article. Remember I promised this story, I mean article, would be about programming.</p>

<p>Our start-up was based on a well known GNU operating system including Apache, PERL and postgresql.  Perl is great for implementing whatever you want in the shortest amount of time possible ... a hacker's language.</p>

<p>Among other things our company was into the nuevo chic business of wireless e-commerce.  We were right in the middle of everything that was happening:  web meets phone meets bank account.  Who has the most efficient method of moving money from one wallet into one's own?</p>

<p>We quickly adopted SOAP before most application server vendor's supported it -- it seemed like the perfect way to get disparate machines talking the same language quickly and easily.  Our colleagues on the other end of the pipe balked at first, but ultimately gave into our design more out of fear of being left behind in the information arms race than anything else.</p>

<p>__Kaboom__</p>

<p>Then the bubble burst... wireless wasn't hot, e-commerce wasn't hot, nothing was hot.  Our fun little start-up whirlwind settled down to little more than a gentle breeze on a Sunday afternoon. </p>

<p>It was about this time I started going to a little Lutheran church around the corner from my apartment -- I was raised Lutheran and I could draw some comfort from ceremonies repeated throughout my childhood. Something stable.</p>

<p>The first Sunday my fianc� and I attended Church we stood around after the service talking with various people.  One tall older gentleman came up, shook our hands and asked if we were new to the area.  Did we work at Stanford?</p>

<p>"No," I replied.  "I work at a small Internet startup," I said sheepishly while stifling a cough.</p>

<p>"Oh, well don't tell me anything I need to sign an NDA for," he said. </p>

<p>"Don't worry about that," I laughed. "All of our stuff is open source and public domain anyway."</p>

<p>The old man cocked an eyebrow at me and said, "I've written a few open source programs in my day.  Perhaps I didn't introduce myself.  My name is Don ... Don Knuth."</p>

<p>Holy shit.  Exposed.  In church no less.  In front of a true computer scientist, if not THE defining computer scientist. </p>

<p>"I have your books on my bookshelf," I gushed like a school girl. </p>

<p>"A lot of people have my books on their bookshelves.  That's the problem, they need to read them," he said.</p>

<p>I don't remember much of what happened next.  Later my fianc� told me I looked sort of pitiful with my mouth hanging open.  She had never seen my fast talking self stopped dead in my tracks.  It was terribly humbling.  Terribly.</p>

<p>It was then I decided that my next gig would be to uncover the lost art of programming.  Time to quit screwing around and actually learn the trade.</p>

<p>to be continued...</p>

<p>The next installment </p>

<p>   "Crossover -- WSDL to Gamma Ray Telescopes"</p>

<p>email me and I'll send you next month's installment -- curt@acm.org<br />
</p><a href="http://www.cucy.net/cgi-bin/mt/mt-tb.cgi?__mode=view&entry_id=1" onclick="OpenTrackback(this.href); return false">TrackBack (0)</a> | <a href="http://www.cucy.net/lacp/archives/000001.html#comments" title="Comment on: Accidental Programming">Comments (6)</a></p>]]></content:encoded>
<dc:subject>General</dc:subject>
<dc:date>2001-12-19T13:17:26-08:00</dc:date>
</item>


</channel>
</rss>