Debian hardfloat with upstream U-Boot

Here I'm documenting my progress on using my ac100-116 “the right way”. Feel free to reach me on irc, my nick is PaulFertser.

UPDATE 24 Oct 2016: migrated the system to current upstream U-boot and Linux. Everything seems to be nice and reliable. The limitations section still applies. Some notes on update:

  • Needs the latest (from firmware git) rt2870.bin for stable wifi
  • Missing nvec_event so lid open/close events are not generated
  • To be able to use synaptics X.org driver the elantech protocol needs to be forced for psmouse kernel driver
  • mpv works nicely for unaccelerated video playback, including streaming from Youtube and other popular hostings (ytdl-format=18 is usually needed)

Status

What works

  • Booting (currently fetching kernel+rootfs is a bit slow due to u-boot bug, ~15s)
  • Display (both text console and X.org fbdev), keyboard, touchpad
  • Wifi
  • Bluetooth
  • GSM/UMTS data transfer
  • Stereo sound both on internal speakers and the headphones
  • Webcam
  • Integrated digital microphone
  • External stereo headset with microphone

What doesn't

Installation and initial configuration story

U-boot doesn't support the display yet. Kernel initialises and uses the integrated panel and the backlight properly. It's possible that you'll manage this with a specially prepared bootloader that will boot from external SD automatically without a serial console.

I use a toolchain compiled by Gentoo crossdev, putusb, uboot, Marvin's 3.0.8 kernel.

Configure u-boot with make paz00_config and build it with your toolchain.

I then used my laptop and an SD card, created a single ext2 partition there and unpacked the preinstalled ubuntu rootfs. Copied the uImage to root and the created modules to /lib/modules. Erased unneeded boot scripts (including network-manager) from /etc/init/. Created there a file to start getty on ttyS0, 115200 baud. Placed a suitable wpa_supplicant.conf somewhere on the card. Removed password from /etc/shadow to give me root login.

I boot the u-boot.bin via putusb, then

mmc dev 1; ext2load mmc 1 0x408000 uImage; setenv bootargs "mem=509M@0M console=tty1 console=ttyS0,115200n8 root=/dev/mmcblk1p1"; bootm

Logged in, set password to 1, start wpa_supplicant -Dnl80211 -iwlan0 -c /etc/wpa_supplicant/wpa_supplicant.conf &, then dhclient eth0. Installed openssh-server and switched to that (because the serial console sometimes stops to function).

Installed gdisk and repartitioned from scratch /dev/mmcblk0, creating two partitions there (one for /boot, 32M should be enough), another for LVM pv. Created LVM there, with two (for now) volumes: 1G for swap, and everything else for the rootfs. mkfs.nilfs /dev/emmc-lvm/rootfs. Mounted it, and started to Debootstrap debian armhf according to the official manual (you'll need to read both installing debian and armhf chroot, though debian-ports.org repositories are not needed).

Copied /lib/firmware/rt2870.bin to the newly established system, configured /etc/network/interfaces to bring up wlan0 for my home wlan automatically. Created a symlink from /bin/true to /usr/sbin/mkfs.nilfs2 to make the boot happy.

Initramfs is a bit tricky: a workaround from http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=649288 is needed (it has a typo where .. is used instead of . and also the script should be made +x), and also you need to pay attention to using /dev/mapper/emmc--lvm-rootfs and not /dev/emmc-lvm/rootfs for the root= kernel command line argument (see http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=612402) or else initramfs won't call vgchange -ay automatically. Add nilfs2 to /etc/initramfs-tools/modules (if you're using MODULES=most). Make a symlink from initrd-3.0.8 to initramfs in /boot. You'll also need a custom initramfs-tools addon script to add nilfs_cleanerd to the initramfs or you'll need to start it later from e.g. /etc/rc.local.

The resulting system should be bootable with

mmc dev 0; ext2load mmc 0 0x408000 uImage; ext2load mmc 0 0x1408000 initramfs; setenv bootargs "mem=509M@0M console=tty1 console=ttyS0,115200n8 root=/dev/mapper/emmc--lvm-rootfs zcache initrd=0x1408000,0x${filesize}"; bootm 0x408000

You can hardcode this command line by adding

#define CONFIG_BOOTCOMMAND     \
       "mmc dev 0; ext2load mmc 0 0x408000 uImage; ext2load mmc 0 0x1408000 initramfs; setenv bootargs \"mem=509M@0M console=tty1 console=ttyS0,115200n8 root=/dev/mapper/emmc--lvm-rootfs zcache initrd=0x1408000,0x${filesize}\"; bootm 0x408000"

to include/configs/paz00.h and recompiling u-boot.

If you want to flash uboot as your main bootloader, get the dump of your part2 (DCT) with putusb, use bct_dump to dump the current config to file, add

BootLoader    = u-boot.bin,0x00108000,0x00108000,Complete;

in there and create a new image with cbootimage. Then either flash it with putusb or from a running system by echo 0 > /sys/block/mmcblk0boot0/force_ro; dd if=newdct.bin of=/dev/mmcblk0boot0.

I managed to successfully recompile u-boot on the device itself using the Debian hardfloat native toolchain, but i needed this patch to bct_dump:

diff --git a/parse.c b/parse.c
index 1005ebc..c9153a1 100644
--- a/parse.c
+++ b/parse.c
@@ -913,7 +913,7 @@ void process_config_file(build_image_context *context)
 {
        char buffer[MAX_BUFFER];
        int  space = 0;
-       char current;
+       int current;
        u_int8_t c_eol_comment_start = 0; // True after first slash
        u_int8_t comment = 0;
        u_int8_t string = 0;

And then be sure to read suckless tips_and_tricks.

Log In