I just picked up a discounted HP TouchPad from my man Greg Chan (via a real stand-up guy who would probably prefer to remain anonymous). Haven’t even played around with WebOS; it doesn’t interest me in the slightest. We need to get Android on this contraption! Here are my modest contributions to the effort. First: an attempt to get an SSH client and server running.
Preparing for the Worst
First, establish a backup plan! Once you register the device, you’ll have access to the HP WebOS site. From there you can download WebOS Doctor, a Java app that will let you restore your TouchPad should something untoward happen to it.
I haven’t used WebOS Doctor yet and I hope I never have to. But as a backup-backup plan, let’s make a copy of the filesystem. Follow the instructions here to get terminal (root) access to the TouchPad. After logging in, I ran this command:
tar cvfz /media/internal/downloads/backup.tar.gz / --exclude '/media/internal/downloads/*
to backup the filesystem. It’s far from a perfect backup, and it may never be useful, but I like having it around just in case. Let me know if you need a copy, it’s about 300MB.
Setting up a Cross-Compiler
Wow, setting up a cross compiler has gotten a lot easier since the last time I checked. All I had to do was download the ARM cross-compiler from here and install it.
The cross-compiler build tools are set up with weird names like “arm-none-linux-gnueabi-ar”. There’s got to be an easier way to configure this but I just ran this command to set up shortened symlinks:
rweeks@faithless:/bitsafe/CodeSourcery/Sourcery_G++_Lite/bin$ for CMD in *; do CMD_TRIM=`echo $CMD | sed -e 's/arm-none-linux-gnueabi-//'`; ln -s $CMD $CMD_TRIM; done
Then you can control whether you’re using your native buildtools or the cross-compiler buildtools just by setting your $PATH.
I figure a good first-day milestone is to get OpenSSH running on the TouchPad. I’ll try to work my way up to a full-on Android distro :). I pretty much followed the instructions here with some minor changes for the cross-compiler.
First I defined a directory where I want to put all the build output:
The commands I used to build zLib:
make && make install
The commands I used to build openSSL (this will take a while):
./Configure --prefix=/bitsafe/arm-openssh-server/output linux-armv4
make && make install
The commands I used to build openSSH:
./configure --host=arm-none-linux-gnueabi --prefix=/bitsafe/arm-openssh-server/output --with-zlib=$PWD/../zlib-1.2.5 --with-ssl-dir=../openssl-1.0.0d
make && make install
The OpenSSH build will fail to install due to the cross-compiler (it can’t strip the output files). But that should be OK.
Deploying OpenSSH to the TouchPad
OK, everything should be built at this point. You can double-check that you’re using the cross-compiler by, eg.
find . -type f -print0 | xargs -0 file
Where you see executable files, it should indicate that they have been built for the ARM architecture. I wrapped up everything in a tarball:
tar cvfz openssh-server.tar.gz arm-openssh-server/
This grabbed my “output” directory, as well as the source directories for zLib, openSSL and openSSH (in case any files failed to install correctly into output/)
I had a vastly complicated procedure in mind to copy the tarball to my TouchPad, but it turns out that the TouchPad just mounts as a vfat file system which was mounted automatically by my build machine. The whole thing was just a drag-and-drop, which was nice.
Extract the tar file like so:
tar xvfz openssh-server.tar.gz --no-same-owner
You’ll get a bunch of errors on the extraction because it can’t create symbolic links: I think this is because you’re extracting to a filesystem that doesn’t support symlinks. No big deal.
Test that the cross-compiler worked!
cd /media/internal/downloads/arm-openssh-server/zlib-1.2.5 ./example zlib version 1.2.5 = 0x1250, compile flags = 0x55 uncompress(): hello, hello! gzread(): hello, hello! gzgets() after gzseek: hello! inflate(): hello, hello! large_inflate(): OK after inflateSync(): hello, hello! inflate with dictionary: hello, hello!
Starting OpenSSH Server
Harder than it sounds! The root filesystem is mounted read-only by default, but you can hack your way around that with:
mount -w -o remount /
Then, add the sshd user and group to /etc/passwd and /etc/group
Setup an ssh key using ssh-keygen and set the “HostKey” property in sshd_config to point to the private key.
If you didn’t remount the root FS as read-write, you need to set UsePrivilegeSeparation to true.
Start sshd like so:
root@RussHPTouchPad:/media/internal/downloads/arm-openssh-server/openssh-5.8p2# $PWD/sshd -f sshd_config -ddd
(This is required because by setting up the “prefix” properties during the SSH build, all the commands will now be looking for their config in /bitsafe/…)
Last thing is to undo all the custom iptables config:
iptables -P INPUT ACCEPT
iptables -X ALLOWED_PACKETS
iptables -X ICMPFLOOD
iptables -X INVALID_PACKETS
OpenSSH 5.8 Running on TouchPad:
backfire:bin rweeks$ ssh -p 2222 firstname.lastname@example.org The authenticity of host '[192.168.10.128]:2222 ([192.168.10.128]:2222)' can't be established. RSA key fingerprint is de:c2:1f:6a:30:e9:33:cc:85:f6:28:07:62:f9:8b:9b. Are you sure you want to continue connecting (yes/no)? yes Warning: Permanently added '[192.168.10.128]:2222' (RSA) to the list of known hosts. email@example.com's password: lastlog_openseek: Couldn't stat /var/log/lastlog: No such file or directory lastlog_openseek: Couldn't stat /var/log/lastlog: No such file or directory debug1: permanently_set_uid: 0/0 Environment: USER=root LOGNAME=root HOME=/home/root PATH=/usr/bin:/bin:/usr/sbin:/sbin:/bitsafe/arm-openssh-server/output/bin MAIL=/var/mail/root SHELL=/bin/sh TZ=:/var/luna/preferences/localtime SSH_CLIENT=192.168.10.107 52206 2222 SSH_CONNECTION=192.168.10.107 52206 192.168.10.128 2222 SSH_TTY=/dev/pts/1 TERM=xterm-color root@RussHPTouchPad:/var/home/root#