Saturday, January 2, 2016

Space Quest

The quest for space continues.  No, not the game -- although that might be a good excuse to compile ScummVM, since I never completed the mission in Space Quest 3.  But no, we're talking about my personal quest for free disk space here.  The goodie bag hasn't been updated in over a year, and my temporary datafilehost.com links were all fading away from lack of exercise.  A remedy for the situation was clearly long overdue.

I tried dropbox, and it works.  I fixed up the expired datafilehost links by moving them to dropbox, but the dropbox interface doesn't suit my style. Meanwhile mozzwald generously donated a directory on his server.  So I recreated the goodie bag there and started making updates for the more recent blog posts.

While this was happening, I also went off on a quest of sorts for free disk space in the openwrt jffs.  When you install the openwrt jffs from flashstock, the first thing you probably notice is the jffs performing poorly due to the lack of free erase blocks.  It's packed to the gills with good stuff, but there's no room to breathe.  Most of us end up deleting some big files (like streamripper) and moving them to an SD card instead, just to make it behave.  However there's actually plenty of wasted space on the flash, and I so finally decided to try and take some of it for the jffs.

Mozzwald's version of the openwrt rc23 jffs (with streamripper already gone)

My first target was the UBOOT Splash Image partition.  I don't know anyone who'd rather stare at a static image than the informative boot messages.  I want to see what's going on (or more often than I'd like, what's going wrong) when the thing is starting up.  Given a choice, I'm never gonna hide the boot messages behind a pretty picture of a penguin or somesuch nonsense.  So, for me the stupid empty splash partition was a total waste of 128K bytes of precious flash that by all rights should've belonged to the jffs.  That right there is just enough erase blocks to uncramp the jffs and allow a decent amount of customization.

Because the image partition is empty and contiguous with the end of the jffs, this turned out to be some low hanging fruit.  The kernel will automatically format the extra space as jffs when it boots.  Here are the steps to merge the uboot image partition with jffs.  Power up the zipit and quickly press a key to pause inside uboot at the uboot command prompt.  Then update the uboot environment to include a modified mtdparts setting in the bootargs environment variable.

printenv

setenv bootargs "console=ttyS2,115200 fbcon=rotate:3 root=/dev/mtdblock3 rw rootfstype=jffs2 mtdparts=physmap-flash:256k(uboot),128k(ubootenv),1152k(kernel),-(filesystem)"

saveenv
boot
Once openwrt is up and running, open up bash and confirm the new partition scheme, and the extra space in the jffs.

cat /proc/mtd
df -h

Enjoy the additional headroom.


Mozzwald's version of the openwrt rc23 jffs (with 128K recovered from bootsplash)

Now, at this point I got greedy.  Riding the high of easy victory I decided to go for the gold.  For the last three years I've been waffling over an existing uboot hack https://github.com/stratumnine/u-boot-pxa-zipit-env8k that carves out another 192K of flash from the uboot and uboot environment partitions. So I booted up the zipit with openwrt from the SD card and started making preparations.  First I fetched some tools for uboot.

opkg update
opkg install uboot-envutils

This only installs the fw_printenv binary so you have do do some legwork.

cd /etc
echo "/dev/mtd1 0x0000 0x20000 0x10000 2" >fw_env.config
cd /usr/sbin
ln -s fw_printenv fw_setenv

I decided to test the tools by stashing the MAC address of the zipit in the uboot environment.

fw_printenv
fw_setenv ethaddr xx:xx:xx:xx:xx:xx
strings /dev/mtdblock1 |grep ethaddr

I'm planning to use that bit with strings to (someday) make the MAC address match the zipit when I boot from an SD card.  It should work with both openwrt and arch SD cards.

Next I got the tools to tinker with the /boot/uboot.script uboot environment files we use when booting from the SD card.

wget http://mozzwald.com/zipit/uboot/z2uflasher_03222011.tar.bz2

Unzip it and copy mkscript.sh and mkimage.arm.static to openwrt sd card.  I used these to add mtdparts to the bootargs in /boot/uboot.script on the SD card and then rebooted the zipit from the SD card.  The kernel gave me an error because of spaces in the partition names, so I tried again without the spaces and it worked.  Now the mtd partitions when booting from SD matched the ones I got when booting from flash.  This meant I could relocate partitions when booting from SD.  So I thought I was ready.

I fetched the env8k-uboot.bin from stratumnine and examined it.  I verified the first instruction ea000ffe really does branch to 0x4000 in ARM asm.  The small 8k uboot environment is completely empty, which should be ok.  The rest of the file looks like code so I decided to go for broke.  Unfortunately I got impatient and rushed it.  I wrote to the character mtd device instead of the block mtd device and bricked the zipit.  Darn it!   Probably should've used the mtd program instead of dd, or maybe some of the other standalone mtd-utils (which are apparently packaged individually by openwrt), or simply modified the flashstock script which is already known to work.

 
Perhaps it's time for daddy to learn how to solder...

Update Jan 9, 2016:

Turns out the env8k-uboot.bin has a bug that renders it useless anyhow.  It's able to save changes to the uboot environment in the 8k sector, but it does't read the saved environment on boot.  So we can't add an mtdparts setting to the bootargs.  Also, the code on github doesn't have all of the changes required to make the 8kenv-uboot.bin file.  Additionally the uboot partition in this setup starts with six 8k blocks and ends with two 64k blocks, which appears to render the /dev/mtdblock2 device unwritable because there's no one size fits all erase block.  That's a nuisance, but not a deal breaker.  However, unless we find the code and fix it, the 8kenv-uboot is a dead end.

Not one to give up so easily, I retrieved from my archives a slightly older tiny uboot setup from stratumnine with a more conventional layout that's only 64k bigger than the 8kenv-uboot.  I modified my flashstock SD card by creating a new flashdump directory combining the tiny uboot with the kernel and filesystem from mozzwalds zipity-beeps flashdump directory.  Here's what's in the modified flash.def file.

u-boot-z2-tiny.bin 0 bae3dc47a78032e8c98990767743aaba
mtdblock2.bak 262144 374666a92397653c2dd5119b3270b2e2
mtdblock3.bak 1441792 26f82b88f912d44f6db1388141ad4fb4


I then booted the zipit from the updated flashstock SD card, selected my new option from the list, crossed my fingers and let it flash.  This time uboot started up just fine.  Yay!  So I quickly hit the enter key to interrupt it and fix up the environment.


printenv

setenv bootargs "console=tty0 console=ttyS2,115200 fbcon=rotate:3 root=/dev/mtdblock3 rw rootfstype=jffs2 mtdparts=physmap-flash:192k(uboot),64k(ubootenv),1152k(kernel),-(filesystem)"

saveenv
boot



Check it out!  500K free in the jffs.  Let's examine the partitions.

cat /proc/mtd
dev:    size   erasesize  name
mtd0: 00030000 00010000 "uboot"
mtd1: 00010000 00010000 "ubootenv"
mtd2: 00120000 00010000 "kernel"
mtd3: 006a0000 00010000 "filesystem"


Next I saved the uboot environment and added it to the tinyuboot flashdump to make this all simple and automated.  But first I removed console=/dev/tty0 from bootargs.  That gets a bit annoying when it prints kernel messages all over your bash session.  Here's the final result.

tinyuboot-flashdump.zip

Unzip it onto your flashstock SD card if you want to try it.  It'll give you an additional menu choice of tinyuboot to write to flash.

In the flashstock menu.  More options to choose from.

I'm still undecided which way to go on the kernel messages so I included two backups of the uboot environment partition in the tinyuboot directory -- one with kernel logging to tty0, and one that only logs to ttyS2.  It's currently setup to use the the one that's quiet on tty0 because the openwrt busybox on the jffs backup lacks the setlogcons applet to change that at runtime.  But I don't really like the lack of screen updates during boot.  Makes me nervous.  So I might try just turning the log messages off in the openwrt init system file /etc/config/system.

config 'system'
    option 'hostname'    'engine12'

    option 'conloglevel'    1

So hard to decide...


No comments:

Post a Comment