Sunday, May 1, 2016

On the Edge

While I was off tinkering with my lego toys, the ever industrious folks on the zipit irc channel got together and started assembling a new set of software building blocks for the zipit.  We got a new modern kernel, a new build of uboot, and an updated openwrt distribution with musl instead of the decrepit old uclibc.  Mozzwald gathered it up, cobbled it all together and christened it "bleeding edge".

Now I'm not much of an early adopter.  In fact, I'm really much more of a time biding trailing lurker.  When I finally jump in and get busy, it's more than likely the project is on life support with one foot in the grave.  But mozzwald made a point of suggesting, more than once, that I could probably pinch in and help test some of the new bleeding edge stuff.  Eventually I got the message.

One feature of the new kernel is improved handling of the sd cards.  We've had some trouble in the past on the zipit with corrupted sd cards.  Many cards would give errors reading, writing, or both.  The problem didn't seem too bad way back in the olden days with the stock zipit software, and that's one of the reasons I've stuck with the iz2s distribution.  It's one giant kludge on top of another, but it does most of what I want from the zipit and doesn't munge the sd card. 

Now over the years I've built up a collection of assorted size sd cards loaded up with various flavors of the different zipit distributions.  I have some trouble keeping track of what's on all the sd cards because you can't attach a large label sticker to the teensy bits of plastic like you could with the sizable floppy disks of days gone by.  So I try to keep them in their little plastic enclosures along with a small scrap of paper suggesting what might actually be on them.  It's not a good system, things occasionally get into the wrong enclosure with the wrong scrap of paper, but it's all me. 

Anyhow, a few of the sd enclosures have paper scraps that say things like "reads on zipit, but writes fail".  So I cracked open one of those, loaded it up with mozzwalds bleeding edge openwrt distribution, and stuck it in an unsuspecting zipit.  It booted up nice and pretty in a somewhat minimalist gmenu2x setup.  So I wrote a few test files in the nano text editor, saved them and rebooted.  As expected, the test files were gone and the sd was corrupted.  Fortunately mozzwald fitted the bleeding edge openwrt with an alternate "sdfix" uboot script that starts the new kernel up with the new slower, but safer, sd card setting.  I made the switch, rebooted the zipit and tried again.

   mv /boot/uboot.script /boot/uboot.script.bak
   cp /boot/uboot.script.sdfix /boot/uboot.script

This time it was good.  My test files survived several reboots.  It also remembered my wifi settings and kept a few updated packages I installed.  Nice!

It's minimal and rough around the edges, but it sure is shiny.

Naturally I wanted more.  Nano is ok as minimal text editors go, but I prefer something that understands the emacs keystokes that my fingers know by heart.  I've got a fork of the qemacs source code on github that does the trick but I don't have the disk space right now to install another full openwrt build setup in order to compile it.  So I went where I usually go for a self contained native arm compiler to do it on the zipit, the aboriginal linux goodies over at landley.net.  The latest arm compilers there have switched over to targeting the musl libc instead of uclibc.   That's perfect for bleeding-edge since openwrt also made that switch.  So it's just what I needed. 

I unzipped the aboriginal armv5l compiler into /usr/share on the bleeding edge sd card, renamed the long-winded directory it created to /usr/share/gcc, and added the /usr/share/gcc/usr/bin directory to my PATH.  Then I tried to compile a simple hello world program with the gcc -o hello hello.c command.  All went well until I tried to run it.  I got some weird "can't find the file to run" error.  It turns out the aboriginal compiler targets a slightly differently name for the musl dynamic linker so the hello program couldn't find it.  It wanted /lib/ld-musl.so.0 instead of /lib/ld-musl-arm.so.1.  That's not so bad.  You can fix that up with a soft link in /lib, but I wanted to compile programs that'd run right out out of the box so I went with a gcc command line option instead.  Like this:

  gcc -Wl,-dynamic-linker,/lib/ld-musl-arm.so.1 -o hello hello.c

It worked.  And that's ok for small things, but qemacs uses a configure script, so it's more difficult to add that switch to all the various Makefiles it creates.  So I started researching how to do it with a specs file so gcc would default to the right dynamic linker target, invisibly.  Also, I got mozzwald to zip up a tarball with all the includes and libs from his bleeding edge openwrt cross compiler setup so I could use them to build more interesting things with the native compiler on the zipit.  That required me to put the libs and includes in an odd location so they wouldn't interfere with the files installed by the package manager.  I unzipped the openwrt-libs-includes_bleeding-edge.tar.bz2 into /usr/share/gcc/ and renamed the longish bleeding edge directory name to /usr/share/gcc/wrt so it'd be easier to type.  Then I attempted to make it seamless.

First I fished a static linked arm4l strace executable from the extras folder in the old binaries download area at landley.net and ran:

  strace gcc

Then I sifted through the text it printed out to see where gcc was looking for the specs file.  I discovered one place it was looking was in /usr/share/gcc/usr/armv5l-unknown-linux-gnueabi/lib/gcc/ so I went there (I actually had to make the directory since it didn't exist yet) and told gcc to dump its built in specs:

  gcc -dumpspecs >specs

I edited that specs file (still using nano) and fixed the dynamic linker target.  This was a little tricky because all the hints on the internet said to do it in a different place than where I eventually  made a change that did work.  I suspected the link_libgcc setting, which appeared after the recommended change in the link_command, was overriding it with another -dynamic_linker setting.  Running gcc -v helped me move my preferred musl dynamic linker setting around and see when I got it to be the last one used, with the final say.  Once this was working, I also added some -I and -L paths to make it search in the /usr/share/gcc/wrt directories for includes and libs.

When I finished, it all seemed to behave just like you'd expect.  Seamless.  Well, at least I was able to build a nice qemacs executable that runs on the bleeding edge openwrt.  I also tested a tiny ncurses example.  Then I built fbgrab, a small framebuffer screen grabber program so I can produce some pretty pictures like the one above.  I didn't see it in the bleeding edge package repository so I figured maybe the bleeding edge Makefile possibly needed a tweak.  Later on I realized it was actually there, but in the separate zipit section of the package repo.  Oh well.

I also built some small real world programs -- nsudoku to test ncurses and fgui for SDL. The ncurses program was easy, but it revealed the default bleeding edge TERM=vt102 setting was inadequate for colored text.  TERM=linux worked better...  The SDL program required me to tweak the sdl-config script in the wrt/usr/bin directory to switch the cross compiler paths to the appropriate paths on the zipit itself.  No surprise there.

Here's the specs file.

And here's the qemacs executable.

qemacs-wrt-bleeding-edge.tgz 


Update 6/2/2016

Lately I've been fiddling with tinyfiledialogs for my lego project, but I took a quick break to compile tinyirc for the bleeding edge openwrt.  So here it is, source and executable.

tinyirc-wrt-bleedingedge.tgz

Ok, back to tinyfiledialogs.  I swear I'm gonna get it working on OSX 10.3 panther if it's the last thing I do.  Gotta get my money's worth outta my ancient Mac IceBook before it dies...

No comments:

Post a Comment