A blog Write an awesome description for your new site here. You can edit this line in _config.yml. It will appear in your document head meta (for Google search results) and in your feed.xml site description. http://yourdomain.com/ Sun, 22 Oct 2017 04:29:49 +0000 Sun, 22 Oct 2017 04:29:49 +0000 Jekyll v2.5.3 The FlySky iBus protocol <p>This is the FlySky iBus protocol that I’ve gleaned from <a href="https://basejunction.wordpress.com/2015/08/23/en-flysky-i6-14-channels-part1/">a blog post</a> and a <a href="https://github.com/aanon4/FlySkyIBus">single library</a>.</p> <p>Data is transmitted as serial UART data, 115200bps, 8N1. A message is sent every 7 milliseconds. <a href="https://www.banggood.com/818CH-Mini-Receiver-With-PPM-iBus-SBUS-Output-for-Flysky-i6-i6x-AFHDS-2A-Transmitter-p-1183313.html">My receiver</a> sends this over its white wire, and stops sending a few tenths of a second after the transmitter is switched off (unlike the PPM signal on the yellow wire, which keeps sending its last value).</p> <p>The first byte is 0x20, the second is 0x40.</p> <p>Next are 14 pairs of bytes, which is the channel value in little endian byte order. The FS-i6 is a 6 channel receiver, so it fills in the first 6 values. The remainder are set to 0x05DC. My transmitter sends values between 0x3E8 and 0x7D0.</p> <p>Finally a 2 byte checksum is sent. It’s in little endian byte order, it starts at 0xFFFF, from which every byte’s value is subtracted except for the checksum.</p> <p>I’ve written <a href="https://github.com/33d/ibus-library">a library</a> to decode this data. An Arduino could measure the time of the message start to improve detection of the message start. One problem using an Arduino is that the board will interfere with programming - a resistor (maybe 10k) on the data line should help.</p> Sun, 22 Oct 2017 00:00:00 +0000 http://yourdomain.com/posts/2017/10/22/flysky-ibus-protocol/ http://yourdomain.com/posts/2017/10/22/flysky-ibus-protocol/ Build a Jekyll blog with Travis CI without granting write access <p>With the demise of Openshift Online and its free tier, I was looking for somewhere else to host my blog. Even though it’s a <a href="https://jekyllrb.com/">Jekyll</a> blog, it does some image resizing, so I can’t use Github’s native builder. I should be able to use <a href="https://travis-ci.org/">Travis CI</a> though, then push them to another Github repository for <a href="https://help.github.com/categories/github-pages-basics/">Pages</a> hosting.</p> <p>The <a href="https://docs.travis-ci.com/user/deployment/pages/">Travis instructions for Github Pages</a> instructions suggest you use Github personal access tokens for authentication, but that seems to give write access to all of my Github repositories - which I don’t want to do.</p> <p>You will need the <a href="https://github.com/travis-ci/travis.rb">command line client</a> installed and logged in.</p> <ol> <li> <p>Generate a key pair for Travis to use when pushing</p> <pre><code> ssh-keygen -t rsa -b 4096 -f travis-key </code></pre> <p>Don’t commit the generated files!</p> </li> <li> <p>Create a repository on Github for the generated site to be pushed to. In that repository, go to Settings, Deploy keys, then Add deploy key. Copy in <code>travis-key.pub</code> which you generated in the previous step, check “Enable write access”, then add the key.</p> </li> <li> <p>The private key should be <a href="https://docs.travis-ci.com/user/encrypting-files/">encrypted</a>. From the blog repository:</p> <pre><code> travis encrypt-file -r 33d/blog travis-key </code></pre> <p>where <code>travis-key</code> is one of the files created earlier by <code>ssh-keygen</code>.</p> <p>This command will suggest you add a line to your <code>before_install</code> section - do that.</p> </li> <li> <p>Put at the end of <code>.travis.yml</code>’s <code>before_install</code>, to stop <code>ssh-add</code> complaining about the key’s permissions:</p> <pre><code> - chmod 400 ../travis-key </code></pre> </li> <li> <p>Add this to <code>.travis.yml</code>, to perform the Git push:</p> <p><code> after_success: - eval "$(ssh-agent -s)" - ssh-add ../travis-key - git clone git@github.com:33d/blog-pages.git target - cp -pr _site/* target - git -C target checkout -b gh-pages - git -C target add . - git -C target commit -m "$( date --utc --iso-8601=seconds )" - git -C target push --force origin gh-pages </code></p> <p>I use a different repository for this, because I don’t want the build artifacts clogging the blog repository.</p> </li> </ol> <p>You can see <a href="https://github.com/33d/blog/blob/blog/.travis.yml">my completed <code>.travis.yml</code> file</a>.</p> Sun, 08 Oct 2017 00:00:00 +0000 http://yourdomain.com/posts/2017/10/08/jekyll-blog-travis-ci/ http://yourdomain.com/posts/2017/10/08/jekyll-blog-travis-ci/ Check that your flash memory isn't fake <p>Here’s how I’ve checked that my flash memory (USB stick, SD card etc) isn’t fake. The idea is to use a cipher to produce a psuedorandom stream, write its output to the flash memory, then genenrate the stream again comparing it to the card.</p> <p>First, find out how big the flash is:</p> <pre><code>$ cat /proc/paritions major minor #blocks name ... 8 16 30736384 sdb </code></pre> <p>Some quick maths tells me the block size is 1024 bytes. Next, use <code>openssl</code> to encrypt some zeroes, writing the output to the card:</p> <pre><code>$ dd if=/dev/zero bs=1024 count=30736384 | openssl enc -aes128 -k some-passworrd -nosalt | sudo tee /dev/sdb &gt; /dev/null 30736384+0 records in 30736384+0 records out 31474057216 bytes (31 GB) copied, 989.076 s, 31.8 MB/s tee: /dev/sdb: No space left on device </code></pre> <p>I don’t know why it complains about no space, but the number of bytes written looks correct.</p> <p>(Change some-password to some other word.) <code>-nosalt</code> prevents openssl writing a header, which contains the password salt. Because our encryption key (the <code>some-password</code> above) doesn’t need to be secure, we don’t care about it, and will stop the same stream being output next time.</p> <p>Now check the result:</p> <pre><code>$ dd if=/dev/zero bs=1024 count=30736384 | openssl enc -aes128 -k some-password -nosalt | sudo cmp - /dev/sdb 30736384+0 records in 30736384+0 records out 31474057216 bytes (31 GB) copied, 367.183 s, 85.7 MB/s cmp: EOF on /dev/sdb </code></pre> <p>If it hits the end without complaining about differences, what’s on the card is what was produced again by the cipher stream, so the card contains the advertised flash chip.</p> Sat, 11 Jul 2015 00:00:00 +0000 http://yourdomain.com/posts/2015/07/11/check-for-fake-flash/ http://yourdomain.com/posts/2015/07/11/check-for-fake-flash/ Save space used by an Ubuntu VM by using the live CD, the slightly easier way <p>Yesterday I worked out how to use the Ubuntu live CD to save space on Ubuntu VMs. It turns out you don’t need to change <code>initrd.lz</code>.</p> <p>Instead, all of the options in <code>casper.conf</code> except <code>root_persistence</code> can be specified on the kernel command line - simply add them (without the quotes) to <code>extlinux.conf</code>.</p> <ol> <li>Create a virtual machine with a hard disk of your choosing. Boot the Ubuntu live CD in it.</li> <li>Create a partition on the virtual hard disk for persistence, and make it bootable.</li> <li> <p>Format it, give it a label:</p> <pre><code>$ sudo bash # mkfs.ext2 /dev/sda1 -L overlay </code></pre> </li> <li> <pre><code># mount /dev/sda1 /mnt </code></pre> </li> <li> <pre><code># mkdir /mnt/boot </code></pre> </li> <li> <pre><code># cp -p /cdrom/casper/vmlinuz.efi /mnt/boot </code></pre> </li> <li> <p>We need to <a href="https://wiki.ubuntu.com/CustomizeLiveInitrd">edit <code>/etc/casper.conf</code> inside the initrd</a>:</p> <pre><code># cd /tmp # mkdir i # cd i # lzcat /cdrom/casper/initrd.lz | cpio -i </code></pre> <p>now put in /tmp/i/etc/casper.conf (I found out the variables by looking through <a href="http://bazaar.launchpad.net/~ubuntu-branches/ubuntu/trusty/casper/trusty/view/head:/scripts/casper"><code>/usr/share/initramfs-tools/scripts/casper</code></a>, which is run by the kernel command line’s <code>boot</code> parameter.):</p> <pre><code># This file should go in /etc/casper.conf # Supported variables are: # USERNAME, USERFULLNAME, HOST, BUILD_SYSTEM, FLAVOUR export USERNAME="user" export USERFULLNAME="Live session user" export HOST="vm" export BUILD_SYSTEM="Ubuntu" # USERNAME and HOSTNAME as specified above won't be honoured and will be set to # flavour string acquired at boot time, unless you set FLAVOUR to any # non-empty string. export FLAVOUR="Ubuntu" export PERSISTENT="Yes" export root_persistence="overlay" </code></pre> <p>You can customize your username and host name in this file too. Note <code>root_persistence</code> is the label we specified in step 3. Now compress the initramfs:</p> <pre><code># cd /tmp/i # find . | cpio --quiet --dereference -o -H newc | lzma -7 &gt; /mnt/boot/initrd.lz </code></pre> </li> <li> <p>Now for a bootloader which uses the above stuff. Install the extlinux package. I grabbed the .deb <a href="http://packages.ubuntu.com/trusty/extlinux">from the package search</a>.</p> </li> <li> <p>Install extlinux:</p> <pre><code># mkdir /mnt/boot/extlinux # extlinux -i /mnt/boot/extlinux </code></pre> <p>Put this in <code>/mnt/boot/extlinux/extlinux.conf</code>:</p> <pre><code>DEFAULT linux LABEL linux KERNEL /boot/vmlinuz.efi APPEND boot=casper initrd=/boot/initrd.lz noprompt </code></pre> </li> <li> <p>The hard disk is probably missing a master boot record.</p> <pre><code># dd if=/usr/lib/syslinux/mbr.bin of=/dev/sda </code></pre> </li> <li>Unmount <code>/mnt</code> and reboot.</li> </ol> Wed, 22 Apr 2015 00:00:00 +0000 http://yourdomain.com/posts/2015/04/22/save-space-used-by-an-ubuntu-vm-mk-ii/ http://yourdomain.com/posts/2015/04/22/save-space-used-by-an-ubuntu-vm-mk-ii/ Save space used by an Ubuntu VM by using the live CD <p>I like to use VMs when doing things which might put stuff all over the filesystem or needs root access to install. But at a few gigabytes each they quickly take up space. I managed to use the live CD image as a base, which is compressed and can be shared among virtual machines.</p> <ol> <li>Create a virtual machine with a hard disk of your choosing. Boot the Ubuntu live CD in it.</li> <li>Create a partition on the virtual hard disk for persistence, and make it bootable.</li> <li> <p>Format it, give it a label:</p> <pre><code>$ sudo bash # mkfs.ext2 /dev/sda1 -L overlay </code></pre> </li> <li> <pre><code># mount /dev/sda1 /mnt </code></pre> </li> <li> <pre><code># mkdir /mnt/boot </code></pre> </li> <li> <pre><code># cp -p /cdrom/casper/vmlinuz.efi /mnt/boot </code></pre> </li> <li> <p>We need to <a href="https://wiki.ubuntu.com/CustomizeLiveInitrd">edit <code>/etc/casper.conf</code> inside the initrd</a> (<em>Edit</em>: You don’t need to do this; see the end of the post):</p> <pre><code># cd /tmp # mkdir i # cd i # lzcat /cdrom/casper/initrd.lz | cpio -i </code></pre> <p>now put in /tmp/i/etc/casper.conf (I found out the variables by looking through <a href="http://bazaar.launchpad.net/~ubuntu-branches/ubuntu/trusty/casper/trusty/view/head:/scripts/casper"><code>/usr/share/initramfs-tools/scripts/casper</code></a>, which is run by the kernel command line’s <code>boot</code> parameter.):</p> <pre><code># This file should go in /etc/casper.conf # Supported variables are: # USERNAME, USERFULLNAME, HOST, BUILD_SYSTEM, FLAVOUR export USERNAME="user" export USERFULLNAME="Live session user" export HOST="vm" export BUILD_SYSTEM="Ubuntu" # USERNAME and HOSTNAME as specified above won't be honoured and will be set to # flavour string acquired at boot time, unless you set FLAVOUR to any # non-empty string. export FLAVOUR="Ubuntu" export PERSISTENT="Yes" export root_persistence="overlay" </code></pre> <p>You can customize your username and host name in this file too. Note <code>root_persistence</code> is the label we specified in step 3. Now compress the initramfs:</p> <pre><code># cd /tmp/i # find . | cpio --quiet --dereference -o -H newc | lzma -7 &gt; /mnt/boot/initrd.lz </code></pre> </li> <li> <p>Now for a bootloader which uses the above stuff. Install the extlinux package. I grabbed the .deb <a href="http://packages.ubuntu.com/trusty/extlinux">from the package search</a>.</p> </li> <li> <p>Install extlinux:</p> <pre><code># mkdir /mnt/boot/extlinux # extlinux -i /mnt/boot/extlinux </code></pre> <p>Put this in <code>/mnt/boot/extlinux/extlinux.conf</code>:</p> <pre><code>DEFAULT linux LABEL linux KERNEL /boot/vmlinuz.efi APPEND boot=casper initrd=/boot/initrd.lz noprompt </code></pre> </li> <li> <p>The hard disk is probably missing the master boot record code, so write that.</p> <pre><code># dd if=/usr/lib/syslinux/mbr.bin of=/dev/sda </code></pre> </li> <li>Unmount <code>/mnt</code> and reboot.</li> </ol> <p><em>Edit:</em> It turns out you don’t need to change <code>initrd.lz</code>.</p> <p>Instead, all of the options in <code>casper.conf</code> except <code>root_persistence</code> can be sp ecified on the kernel command line - simply add them (without the quotes) to <code>ex tlinux.conf</code>, like this:</p> <pre><code>APPEND boot=casper initrd=/boot/initrd.lz noprompt username=user hostname=host </code></pre> <p>You also need to label your hard disk partition <code>casper-rw</code>.</p> Tue, 21 Apr 2015 00:00:00 +0000 http://yourdomain.com/posts/2015/04/21/save-space-used-by-an-ubuntu-vm/ http://yourdomain.com/posts/2015/04/21/save-space-used-by-an-ubuntu-vm/ Back up the flash of a Huawei Mediapad 7 Lite <p>I recently purchased a Huawei Mediapad 7 Lite 4GB very cheaply on clearance. It’s based on a Rockchip RK2918, which there are tools for to read and write the flash directly. Before I start trying to hack it, I should get a backup of what’s already on it.</p> <p>I found <a href="http://valentijn.sessink.nl/?p=382">a post</a> which describes how the flash of a different Rockchip tablet can be backed up. Maybe I can catch the USB device being recognized as I restart the tablet.</p> <p>So, in one terminal:</p> <pre><code>tail -f /var/log/kern.log </code></pre> <p>and then turn off the tablet. The battery charge screen appears, and there’s nothing useful yet.</p> <p>So I held down Volume + and the power button, the screen goes blank. So I switched it off. But wait: in the kernel log:</p> <pre><code>Aug 24 22:29:24 xpee kernel: [ 2187.324056] usb 1-5: new high-speed USB device number 7 using ehci-pci Aug 24 22:29:25 xpee kernel: [ 2187.869050] usb 1-5: unable to get BOS descriptor Aug 24 22:29:25 xpee kernel: [ 2187.869674] usb 1-5: New USB device found, idVendor=2207, idProduct=290a Aug 24 22:29:25 xpee kernel: [ 2187.869681] usb 1-5: New USB device strings: Mfr=0, Product=0, SerialNumber=0 </code></pre> <p>and a quick search for vendor 2207… Rockchip! Interesting…</p> <p>Following <a href="http://valentijn.sessink.nl/?p=382">the post mentioned earlier</a>:</p> <pre><code>$ sudo ./rkflashtool r 0x0000 0x2000 &gt; dump^C $ strings dump PARM FIRMWARE_VER:0.2.3 MACHINE_MODEL:MediaPad 7 Lite MACHINE_ID:007 MANUFACTURER:HUAWEI MAGIC: 0x5041524B ATAG: 0x60000800 MACHINE: 2929 CHECK_MASK: 0x80 KERNEL_IMG: 0x60408000 COMBINATION_KEY: 0,6,A,1,0 CMDLINE: console=ttyS1,115200n8n androidboot.console=ttyS1 init=/init initrd=0x62000000,0x800000 mtdparts=rk29xxnand:0x00002000@0x00002000(misc),0x00004000@0x00004000(kernel),0x00008000@0x00008000(boot),0x00008000@0x00010000(recovery),0x00002000@0x00018000(backup),0x00006000@0x0001a000(oeminfo),0x00004000@0x00020000(vrcb),0x00008000@0x00024000(reserved),0x00100000@0x0002c000(cust),0x000e6000@0x0012c000(system),0x00080000@0x00212000(cache),0x00008000@0x00292000(userdata),0x00002000@0x0029a000(kpanic),-@0x0029c000(user) </code></pre> <p>I notice that this text appears several times, so I’d better keep this in mind.</p> <p>The <a href="https://www.kernel.org/doc/menuconfig/drivers-mtd-Kconfig.html#MTD_CMDLINE_PARTS">Linux MTD documentation describes what <code>mtdparts</code> is for</a>. So after copying the <code>mtdparts</code> bit to a file, with a bit of Perl magic I can dump each “part” to a file:</p> <pre><code>$ perl -pe 's/([0-9a-fx-]*)@([a-f0-9x]*)\(([a-z]*)\).?/\2 \1 \3\n/g' &lt; mtdparts | while read off len name ; do sudo ./rkflashtool r $off $len 2&gt;/dev/null | xz &gt; $name.xz ; done </code></pre> <p>But what about the last one, which lists the size as <code>-</code>? I’ll try reading a block which shouldn’t exist:</p> <pre><code>$ sudo ./rkflashtool r 0xfffffffd 1 | hexdump -C </code></pre> <p>It doesn’t seem to matter what I change the offset to, it seems to output part of the first block at some seemingly arbitrary offset. Also, the offset seems to be the start offset in 512 byte blocks, but trying to read one block returns 0x4000 bytes of data. Looking at <a href="http://sourceforge.net/p/rkflashtool/Git/ci/2bd62daeb5e63f4f1f92d1876b053a2be8cf428c/tree/rkflashtool.c#l248">the source</a> suggests that it reads blocks of 0x4000 bytes, so that’s the minimum it’s going to return. I tried hacking the code to fail <a href="http://sourceforge.net/p/rkflashtool/Git/ci/2bd62daeb5e63f4f1f92d1876b053a2be8cf428c/tree/doc/protocol.txt#l46">if the error flag in the response</a> is set, but that didn’t help.</p> <p>But <a href="http://sourceforge.net/p/rkflashtool/Git/ci/2bd62daeb5e63f4f1f92d1876b053a2be8cf428c/tree/doc/protocol.txt#l94">the bottom of the protocol description lists a FlashInfo structure</a>, which contains the number of blocks of flash, but I notice that command hasn’t been implemented. I hope they didn’t leave it out because it bricks devices… (<a href="https://github.com/33d/rkflashtool/commit/3955541b14adbb8ad55198e870165752a52e4271">hack hack hack</a>) I tried implementing it, but got this:</p> <pre><code>$ sudo ./rkflashtool l | hexdump -C 00000000 00 00 80 00 00 08 08 18 21 04 01 00 00 00 00 00 |........!.......| 00000010 44 4e 41 4e 20 01 65 00 02 00 00 00 01 01 01 00 |DNAN .e.........| 00000020 01 01 18 21 04 10 08 70 00 10 00 00 00 08 00 00 |...!...p........| 00000030 00 01 00 00 00 00 10 00 00 00 80 00 00 00 80 00 |................| 00000040 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| * 00000060 00 00 00 00 00 00 00 00 30 00 10 80 d0 60 70 00 |........0....`p.| 00000070 30 60 10 80 d0 60 70 00 80 80 78 00 78 00 15 80 |0`...`p...x.x...| 00000080 85 00 e0 05 e0 06 10 85 35 00 00 00 00 00 00 00 |........5.......| 00000090 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| * 00000200 </code></pre> <p>No permutations of those first 6 bytes and their endianness seem to produce anything useful, so I’ll try something else.</p> <p>Maybe <code>/proc/mtd</code> will yield some secrets:</p> <pre><code>1|shell@android:/ $ cat /proc/mtd dev: size erasesize name mtd0: 00400000 00004000 "misc" mtd1: 00800000 00004000 "kernel" mtd2: 01000000 00004000 "boot" mtd3: 01000000 00004000 "recovery" mtd4: 00400000 00004000 "backup" mtd5: 00c00000 00004000 "oeminfo" mtd6: 00800000 00004000 "vrcb" mtd7: 01000000 00004000 "reserved" mtd8: 20000000 00004000 "cust" mtd9: 1cc00000 00004000 "system" mtd10: 10000000 00004000 "cache" mtd11: 01000000 00004000 "userdata" mtd12: 00400000 00004000 "kpanic" mtd13: 9a800000 00004000 "user" </code></pre> <p>Everything in the “size” column seems to be 512*what was listed in <code>mtdparts</code>. This makes the <code>user</code> part 0x4D4000 long. I can finally back up that part:</p> <pre><code>$ sudo ./rkflashtool r 0x0029c000 0x4d4000 2&gt;user.log | xz &gt; user.xz </code></pre> <p>I ran <code>fsck.ext4 -c</code> on the result, and it was happy, so I guess I have the right length.</p> <p>But I think it might be better to just grab the whole lot:</p> <pre><code>$ sudo ./rkflashtool r 0 0x800000 2&gt;all.log | xz &gt; all.xz </code></pre> <p>where 0x800000 is 4GB/512, and is a bit bigger than the 0x0029c000+0x4d4000 that I calculated earlier. I can verify various parts:</p> <pre><code>$ diff &lt;(xzcat user.xz | dd bs=512 ) &lt;( xzcat all.xz | dd bs=512 count=$((0x4d4000)) skip=$((0x29c000)) ) 5062656+0 records in 5062656+0 records out 2592079872 bytes (2.6 GB) copied, 56.8184 s, 45.6 MB/s 5062656+0 records in 5062656+0 records out 2592079872 bytes (2.6 GB) copied, 56.8161 s, 45.6 MB/s </code></pre> <p><code>diff</code> produced no output, so the data are the same. I’ll keep a copy of <code>all.xz</code> and the output from <code>./rkflashtool p</code> and <code>cat /proc/mtd</code>, which will let me recover whatever I need to.</p> Mon, 25 Aug 2014 00:00:00 +0000 http://yourdomain.com/posts/2014/08/25/huawei-mediapad-7-lite-backup/ http://yourdomain.com/posts/2014/08/25/huawei-mediapad-7-lite-backup/ Running a Z-machine on an AVR <p>Can you make a <a href="http://en.wikipedia.org/wiki/Z-machine">Z-machine</a> console - a virtual machine for text adventure games -  complete with screen and keyboard on an AVR?</p> <p>No. Well, probably not on a ATmega328P.</p> <p>I <a href="ftp://sunsite.unc.edu/pub/Linux/games/textrpg/zipinfocm-2.0.linux.tar.gz">got the code for ZIP</a>, and stripped out all of the code for reading files and displaying stuff on the screen.  This let me compile it with avr-gcc.</p> <p>I looked at the result of objdump:</p> <pre><code>$ avr-objdump -h zip_linux zip_linux:     file format elf32-avr Sections: Idx Name          Size      VMA       LMA       File off  Algn   0 .data         000001e4  00800100  0000579c  00005830  2**0                   CONTENTS, ALLOC, LOAD, DATA   1 .text         0000579c  00000000  00000000  00000094  2**1                   CONTENTS, ALLOC, LOAD, READONLY, CODE   2 .bss          00000ac8  008002e4  008002e4  00005a14  2**0                   ALLOC   3 .stab         0000dcec  00000000  00000000  00005a14  2**2                   CONTENTS, READONLY, DEBUGGING   4 .stabstr      00003aad  00000000  00000000  00013700  2**0                   CONTENTS, READONLY, DEBUGGING   5 .comment      00000022  00000000  00000000  000171ad  2**0                   CONTENTS, READONLY </code></pre> <p>The good news is that the code (the .text section) fits into 22k.  That leaves 10k for the screen rendering code (probably from <a href="http://www.batsocks.co.uk/products/Other/TellyMate.htm">TellyMate</a>), the keyboard and the SD card code.</p> <p>The .data section is quite small too, which means there aren’t many strings in the interpreter itself.</p> <p>The problem is the .bss section, which gets copied to RAM on startup.  It’s 2760 bytes, much more than the 2048 which this chip has.</p> <p>Let’s look at this further:</p> <pre><code>$ avr-objdump -t zip_linux | grep bss | sort -t $'\t' -k 2 ... 0080030c g     O .bss    00000004 pc 00800da6 g     O .bss    00000006 __iob 00000114 g       .text    00000010 __do_clear_bss 00800552 g     O .bss    0000004e lookup_table 00800436 l     O .bss    00000100 record_name 00800332 l     O .bss    00000100 save_name 008005a0 g     O .bss    00000800 stack </code></pre> <p>There’s a 2048 byte stack, which fills the entire memory!  The Infocom games <a href="http://www.gnelson.demon.co.uk/zspec/sect06.html">might only need a 1k stack</a>, which will help.</p> <p>Tellymate has a 38x25 screen, which needs 950 bytes.  This could be brought down to 10 lines, but games might be tricky to play.  The ZX80 didn’t store a full line if it didn’t fill the width of the screen, but adventure games tend to be wordy so this won’t help much.</p> <p>An SD card library needs about 600 bytes of RAM, which blows the budget.  We’d have to go without a filesystem on the SD card, because it takes up too much flash space.  It sounds like the 512 byte buffer might be optional.</p> <p>4k of RAM should be plenty.  But with ARM chips being much cheaper than the larger AVRs, that might be the way to go - if I can sort out the <a href="http://sourcegate.wordpress.com/2012/11/04/code-to-produce-video-signals-on-the-stm32l-discovery/">jittering image problems</a>.</p> <p>You might be able to squeeze the interpreter only onto the chip, and communicate with it via its serial port, or another AVR running TellyMate.</p> <p><strong>Update:</strong> It turns out I wasn’t the only one to look at this - Rossum <a href="http://rossumblog.com/2011/04/19/zork-for-the-microtouch/">implemented it on the 2560-byte ATmega32U4</a>, but needed to store a 1MB swap file on the SD card!  I don’t know why you need that much - maybe you don’t - but I forgot to include dynamic memory and room for the stack.</p> Sun, 06 Apr 2014 06:44:08 +0000 http://yourdomain.com/posts/2014/04/06/running-a-z-machine-on-an-avr/ http://yourdomain.com/posts/2014/04/06/running-a-z-machine-on-an-avr/ advenure arduino avr infocom text tv video z-machine OpenWRT on a Nokia N800 <p><strong>This is work in progress, so expect it to be added to/abandoned (probably the latter) at any time.</strong></p> <p>I’ve got a Nokia N800 whose screen is on its way out that I’d like to find some other use for. Since Nokia seems <a href="http://talk.maemo.org/showthread.php?t=89268">to</a> <a href="http://discussions.nokia.com/t5/Maemo-and-MeeGo-Devices/How-to-obtain-firmware-when-tablets-dev-nokia-com-site-is-down/td-p/1779564">have</a> <a href="http://tablets-dev.nokia.com/">abandoned this device</a>, it looks like I’m on my own.  (To think I used to like their products!)  Good thing I still have a copy of the firmware, and found <a href="http://213.128.137.28/showthread.php?t=90144">a copy</a> of the flasher software.  Let’s hope Nokia really doesn’t care, and lets this link stay here.</p> <p>Anyway it looks like OpenWRT supported it once upon a time - <a href="https://dev.openwrt.org/browser/trunk/target/linux/omap24xx?rev=39554">it’s still listed in the source tree</a>, albeit broken.  The omap24xx doesn’t seem to be in any of the branches or tags, so I don’t know how things get there.  Revision 30798 seems to be before they added the “broken” tag, so maybe that’s a good place to start.</p> <pre><code>$ git clone https://github.com/mirrors/openwrt.git $ cd openwrt.git $ git checkout 2f3210027ca1393766b0293b1bdd9fc6a13e88d7 $ git branch n800 $ git checkout n800 </code></pre> <p>So now you apparently:</p> <pre><code>$ make defconfig $ make menuconfig </code></pre> <p>select the N800/810 as the target</p> <pre><code>$ make </code></pre> <p>I had a problem with mklibs not working with GCC 4.7, which <a href="https://lists.debian.org/debian-boot/2012/04/msg00057.html">was easily fixed</a> (I made it <a href="http://wiki.openwrt.org/doc/devel/patches">as a patch</a>).</p> <p>And that worked for me!  In <code>bin</code>, I have a kernel, root filesystem and so on.</p> <h1 id="testing-it-out">Testing it out</h1> <p>I happened to notice <a href="https://web.archive.org/web/20130401071739/http://wiki.meego.com/ARM/N900/Using_Rescue_Initrd">that you can boot a kernel that’s been loaded into RAM</a>:</p> <pre><code>$ sudo flasher-3.5 -k openwrt-omap24xx-zImage \ -r openwrt-omap24xx-root.squashfs -l -b"root=/dev/ram0" </code></pre> <p>That seemed to work, and the kernel output appears on my dodgy screen.  That stuff with the root filesystem didn’t seem to work, but I noticed that the kernel was trying to look for the root filesystem on an MMC card.  I grabbed a convenient SD card and put the root filesystem on it, and the boot process seemed to go a bit further.</p> <p>One problem: I get “Press enter to activate this console”.  Without a keyboard, how will I do that?</p> <h1 id="adding-a-keyboard">Adding a keyboard</h1> <p>Now that it boots, how am I going to communicate with it?  It’s alright for a N810, which has a keyboard, but the N800 doesn’t.  Apparently <a href="http://wiki.maemo.org/Compiling_the_kernel#Serial_Console">there’s a serial port in the back near the battery</a>, but I don’t know how I’d attach cables to those pads.  Maybe I can plug a USB keyboard into the USB OTG port.</p> <p>Maybe someone has sorted it out - <a href="https://www.google.com.au/search?q=openwrt+usb+keyboard">Google to the rescue</a> again!  <a href="http://h-wrt.com/en/doc/kb">Apparently you have to</a>:</p> <pre><code>$ make menuconfig Base system: &lt;*&gt; busybox: Linux System Utilities: &lt;*&gt; lsusb Kernel modules: USB Support: &lt;M&gt; kmod-usb-hid </code></pre> <p>The kernel module was already selected for me.  Exit, save, then <code>make</code>.</p> <p>Looking in the new root filesystem, lsusb is there.</p> <p>I just found out about <a href="http://nopcode.org/0xFFFF/">0xFFFF</a>, another flasher for this device.  Let’s give it a whirl:</p> <pre><code>$ sudo 0xFFFF -i ... Device's USB mode is 'client </code></pre> <p>Maybe the USB port needs to be switched into OTG mode.</p> <pre><code>$ sudo src/0xFFFF -U 1 ... Set USB mode to: 'host'. </code></pre> <p>I’ll try loading the kernel again, and… no luck</p> <p>Maybe OpenWRT doesn’t have any hotplugging function.  I’ll try logging as much as possible on the console by <a href="http://wiki.openwrt.org/doc/uci/system?s#system">setting <code>klogconloglevel</code> to 8 in <code>/etc/config/system</code></a>.  But there are two problems with this: I want to see syslog, not the kernel log; and that property <a href="https://dev.openwrt.org/browser/trunk/package/base-files/files/etc/init.d/system?rev=39615">doesn’t seem to be used</a> anyway.</p> <p>During random googling, I found a link to Qemu. It turns out Qemu can emulate the N800! There seemed to be no keyboard input - since the n800 doesn’t have a keyboard - but apparently the connector near the battery is <a href="http://lists.gnu.org/archive/html/qemu-devel/2008-04/msg00368.html">the 3rd serial port</a>. So you can solicit a terminal like this:</p> <pre><code>$ qemu-system-arm -machine n800 -drive file=root,if=sd -kernel \ openwrt-omap24xx-zImage -serial vc -serial vc -serial stdio </code></pre> <p>where <code>root</code> is an SD card image containing the root filesystem.</p> <p>Now I’ve got something I can interact with, which should make things easier! (It sounds like <a href="http://qemu.weilnetz.de/qemu-doc.html#ARM-System-emulator">the Bluetooth module is connected to one of the UARTs</a>, which the above command might upset.)</p> Sun, 23 Feb 2014 11:39:06 +0000 http://yourdomain.com/posts/2014/02/23/openwrt-on-a-nokia-n800/ http://yourdomain.com/posts/2014/02/23/openwrt-on-a-nokia-n800/ n800 nokia openwrt Science Alive noise maker <p>For <a href="https://www.facebook.com/Science4Everyone">Science Alive</a>, I made a simple circuit that made noises in response to light changes.  Being something which makes noise it was popular with the kids.  It’s based on circuits described in Nicolas Collins’ “<a href="http://www.nicolascollins.com/handmade.htm">Handmade Electronic Music</a>”.  A few people asked me a circuit so I’ll describe it here.</p> <p>The circuit contains four oscillators provided by a <a href="http://www.ti.com/lit/ds/symlink/cd4093bc.pdf‎">4093 Schmitt Trigger quad 2-input NAND gate</a>.  <a href="http://www.fairchildsemi.com/an/AN/AN-118.pdf">Individual inverting Schmitt trigger gates can oscillate</a>, and by having more than one I could get one to turn another on and off, and mix the output of different oscillators together.</p> <p>You’ll need to play with different valued capacitors, I’ve listed the values I’ve used but try some different ones, particularly since your LDRs might be different to mine.</p> <p>You’ll need:</p> <ul> <li> <p>1 4093 CMOS Schmitt trigger quad 2-input NAND gate</p> </li> <li> <p>2 small value electrolytic capacitors (I used 1µF)</p> </li> <li> <p>2 ceramic or greencap capacitors (I used 47pf)</p> </li> <li> <p>2 diodes (I used 1n914)</p> </li> <li> <p>4 light dependent resistors (LDRs) aka Cadmium Sulphide (CdS) cells</p> </li> <li> <p>Batteries which provide 3-12V (I used 4×AAs) and a way to connect them to the breadboard</p> </li> <li> <p>An amplifier and speaker, computer speakers or those battery powered speakers you get for music players should work</p> </li> <li> <p>A breadboard (mine is a 390 hole “half size” one), and suitable wire</p> </li> </ul> <p>Here’s the schematic.  I chose to pair my oscillators so that one turns the other on and off, and connected their outputs with diodes.  You can connect all four together in a line, or connect all of the outputs using diodes.  I’ve shown  a resistor to pull the output down when the oscillators are all low, but the amplifier probably has enough resistance at its input for that.</p> <div class="content-image"><a href="/images/wp/2013-08-12-science-alive-noise-maker//science-alive-noisemaker-schematic.png"><img src="/generated/science-alive-noisemaker-schematic-388x300-d51ce1.png" width="388" height="300" /></a></div> <p>It looks like this wired up on a breadboard:</p> <div class="content-image"><a href="/images/wp/2013-08-12-science-alive-noise-maker//science-alive-noisemaker-breadboard.png"><img src="/generated/science-alive-noisemaker-breadboard-332x300-e6b73b.png" width="332" height="300" /></a></div> <p>Mine looks like this:</p> <div class="content-image"><a href="/images/wp/2013-08-12-science-alive-noise-maker//science-alive-noisemaker-photo.jpg"><img src="/generated/science-alive-noisemaker-photo-300x225-7242a1.jpg" width="300" height="225" /></a></div> <p>You can also see <a href="http://tinypic.com/r/144a5vd/5">this video of it in action</a>.</p> Mon, 12 Aug 2013 12:25:49 +0000 http://yourdomain.com/posts/2013/08/12/science-alive-noise-maker/ http://yourdomain.com/posts/2013/08/12/science-alive-noise-maker/ Synchronize a Linux box to a digital TV signal <p>I remembered seeing some command which could synchronize the system clock to the digital TV (DVB) signal. This is ideal for a MythTV box which isn’t connected to the internet.  It’s <code>dvbdate</code>. One problem: <a href="http://www.mythtv.org/wiki/Dvbdate">it ignores the system time zone</a>. It can use the <code>TZ</code> environment variable, whose current value can be obtained using the date <code>command</code>:</p> <pre><code>date +'%z' </code></pre> <p>so this will set the date:</p> <pre><code>sudo TZ=$(date +'%:z') dvbdate --set </code></pre> <p>so you can put this script in <code>/etc/cron.hourly</code>, and make it executable:</p> <pre><code>#!/bin/sh -e TZ=$(date +'%:z') dvbdate --set </code></pre> Fri, 14 Jun 2013 09:54:55 +0000 http://yourdomain.com/posts/2013/06/14/sync-to-a-digital-tv-signal/ http://yourdomain.com/posts/2013/06/14/sync-to-a-digital-tv-signal/