===================== Debian on the TF101 ===================== :Date: Sep 2011 :Author: Trent W. Buck :Contact: trentbuck@gmail.com :Audience: Experienced Debian end users :Status: draft :Abstract: This document is the first step towards a `Debian Pure Blend`__ for the `ASUS Eee Pad Transformer`__ (TF101), with full hardware support. The up-coming armhf Debian architecture is used. .. __: http://wikipedia.org/wiki/Debian_Pure_Blend .. __: http://wikipedia.org/wiki/ASUS_Eee_Pad_Transformer .. WARNING:: the install process is rife with gotchas. Reading the article in full *before* purchase is strongly recommended. .. WARNING:: this process executes binary blobs outside Debian's trust infrastructure. Before you proceed, consider the risk that any given blob has been compromised, and how unhappy you would be if an attacker had a back door into your TF101, all the secrets you will put on it, and all the networks to which you will connect it. http://wikipedia.org/wiki/Reflections_on_Trusting_Trust Acknowledgements: this document was possible thanks to the constant assistance of lilstevie (Steven Barker), who had a working Ubuntu 11.04 armel install on the TF101 before I even owned one. The TF101 is built around the `NVidia Tegra 2`__ platform, a dual-core `ARM Cortex-A9`__ SOC. The TF101 mainboard is very similar to the Toshiba AC100 mainboard. A 16GB or 32GB eMMC__ package provides non-volatile storage; it is soldered onto the mainboard and *can not* be replaced or upgraded. The eMMC is believed to be a "modern" NAND+FTL package with more than enough write-erase cycles to last a typical lifetime. Having said that, someone (I forgot who) in #ubuntu-arm suggested that the FTL on SD/MMC readers is pretty crap (compared to e.g. Sandforce), and it would still be beneficial to run a log-oriented filesystem (e.g. NILFS) instead of a conventional block-oriented filesystem (e.g. ext4). .. __: http://wikipedia.org/wiki/NVIDIA_Tegra_2#Tegra_2_series .. __: http://wikipedia.org/wiki/ARM_Cortex-A9_MPCore .. __: http://wikipedia.org/wiki/eMMC#eMMC A conventional d-i install was never attempted. Instead, a Debian environment was prepared elsewhere and loaded onto the eMMC using the proprietary nvflash program. NVFlash & Prerequisites ======================= As at Sep 2011, only a static x86 binary is available. It is included in the latest linux4tegra release (12~a1.0). - http://tegradeveloper.nvidia.com/content/linux-tegra-release-12-alpha-1-released - http://developer.download.nvidia.com/assets/mobile/files/tegra-linux-12.alpha.1.0.tar.gz 8b39ad25ee73c94fe83c8ca15a9f387d ldk/bootloader/nvflash For some reason, a bootloader must be uploaded into RAM before the eMMC can be read from or written to. It does *not* need to match the version already in the eMMC's EBT partition, nor will it overwrite that partition unless/until you ask nvflash to do so. A binary copy of the ASUS bootloader is embedded in the ASUS firmware zip file. As at Sep 2011 the latest US firmware is 8.6.5.9. Within the zip is a single file called "blob", containing several partitions. To extract the EBT partition from "blob", git clone BlobTools, make blobunpack, and run blobunpack on blob. The EBT file is the ASUS bootloader. The US 8.6.5.9 EBT's md5sum was 7934929ae976dbbea24a7e97308ceb04. .. WARNING:: the ASUS zipfile is a couple of hundred megabytes. - http://support.asus.com/Download.aspx?SLanguage=en&m=Eee+Pad+Transformer+TF101&p=20&s=16&os=32 - http://dlcdnet.asus.com/pub/ASUS/EeePAD/TF101/UpdateLauncher_US_epaduser8659.zip - git clone git://github.com/AndroidRoot/BlobTools NVFlash requires a local copy of the partition table, in an ini-style plain text format. NVFlash can repartition the eMMC based on flash.cfg, but it cannot query the eMMC for its current partition table. Except when repartitioning, flash.cfg *must* correspond to the partition table already on the eMMC. For example, to back up the Android user data (UDA) partition from the eMMC requires the default partition table. A reverse-engineered copy of this is available in lilstevie's linux-flash-kit. - http://lilstevie.geek.nz/ports/linux-flash-kit.tar.gz b01994ff4e085f02353e6ab2aaf1e81f flash/default.cfg Similar to the partition table and EBT partition (bootloader), nvflash must have a local copy of the BCT partition before it can do anything useful. This contains model-specific magic that I (twb) do not comprehend. Unfortunately neither NVidia nor ASUS provide a copy of the TF101 BCT, and it is non-trivial to extract from an existing TF101. Therefore a reverse-engineered third-party copy must be used. I (twb) used the copy from lilstevie's linux-flash-kit. - http://lilstevie.geek.nz/ports/linux-flash-kit.tar.gz 2a2aa50b9f01ab98b1c0fac9d4101d2a images/transformer.bct NVidia Tegra 2 systems have an optional signing process called "SBK". ASUS have elected to enable this feature on the TF101. The SBK is a shared secret baked into the device. The corresponding SBK must be passed to nvflash. If this is not done, or the SBK passed is incorrect, nvflash will exit with status 0x4. Every TF101 has the same SBK baked into it:: 0x1682CCD8 0x8A1A43EA 0xA532EEB6 0xECFE1D98 .. WARNING:: some/all TF101G (the 3G model) are expected to have a different SBK. Until you know the SBK that corresponds to your device, you *can not install Debian*. To acquire an SBK, perform rubber-hose or black-bag cryptanalysis on the associated ASUS staff. Once successful, please publish the SBK widely, as (AFAIK) ASUS cannot revoke it from units that have already rolled out. Finally, there is an "ODM Data" magic number, believed to model-specific or perhaps SOC-specific. For the TF101, it is:: 0x300d8011 This number if the xor of a bunch of flags, described here: - http://tosh-ac100.wetpaint.com/thread/4252500/odmdata which has a broken link to - http://nv-tegra.nvidia.com/gitweb/?p=linux-2.6.git;a=blob;f=arch/arm/mach-tegra/odm_kit/query/harmony/tegra_devkit_custopt.h Not sure you want to use 0x3b2d8011 for odm data, it would mean that you have 1GB of SDRAM on your system. Here are some values I know:: ..2..... HDMI ..3..... VGA ..0..... LVDS ...D8... debug over UART .0...... ? .4...... 16MB video .8...... 32MB video 3....... 1GB SDRAM ......11 noDHCP (.1 or 1. ?) Using NVFlash ============= To use nvflash, the target TF101 is connected to the nvflash host via the USB-to-40pin cable, and the TF101 is put into "APX mode". To enter APX mode, hold the VolUp and Power buttons for several seconds during the boot process. In APX mode, *the TF101's screen is off*, and lsusb on the nvflash host will report an NVidia device. If lsusb lists an ASUS device, you're in Android, not APX. :: $ lsusb -d 0955: Bus 001 Device 036: ID 0955:7820 NVidia Corp. If the device is running or suspended, hold the power button for several seconds to turn it off. In the above example, observe the USB bus address is 001/036. nvflash can be run as an unprivileged user by granting that user write access to /dev/bus/usb/NNN/MMM, e.g. :: $ sudo chgrp nogroup /dev/bus/usb/001/036 $ sudo -u nobody nvflash ... Note that every time you reboot the TF101 or disconnect and reconnect the USB cable, the USB bus address will change and you will need to chgrp again. This might be circumvented via a udev rule; this is left as an exercise for the reader. Having everything lined up, we can now initiate a backup of the UDA partition to a local file (where 15 is UDA's id in flash.cfg) :: $ sudo -u nobody ./nvflash \ --bct transformer.bct --setbct \ --configfile flash.cfg \ --bl bootloader.bin \ --odmdata 0x300d8011 \ --sbk 0x1682CCD8 0x8A1A43EA 0xA532EEB6 0xECFE1D98 \ --sync [output...] $ sudo -u nobody ./nvflash -r --read 15 UDA.img $ file UDA.img Linux rev 1.0 ext4 filesystem data, UUID=[...] (extents) (large files) .. NOTE:: from power on, you have a few seconds to hit Power+VolUP to enter APX. Unlike entering a PC BIOS, it doesn't matter if Android or Linux area already running -- all that matters is how long since boot. Bootloader (u-boot) =================== Apparently the default (ASUS) bootloader can't boot the CrOS 2.6.38 kernel, so we will build and install u-boot. This is a better bootloader anyway -- smaller, more configurable, and it's also the bootloader used on other (Samsung) ARM A9 devices. Root Filesystem (Debian Sid armhf) ================================== We will use qemu CPU emulation to do a normal cdebootstrap process. (I would've used deboostrap, but it failed). On the host you're going to be chrooting *from*, you will want to install both binfmt-misc and qemu-user-static -- the latter's binaries aren't used, but it is an easy way to register ``/usr/bin/qemu-arm-static`` as the handler for ARM ELF binaries. There is a bug in qemu 0.15, so we will build qemu from git and apply a patch to fix the bug. :: # http://patchwork.ozlabs.org/patch/111725/ # http://patchwork.ozlabs.org/patch/111725/raw/ diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 6bdf4e6..ae08c9e 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -797,6 +797,15 @@ abi_long do_brk(abi_ulong new_brk) MAP_ANON|MAP_PRIVATE, 0, 0)); if (mapped_addr == brk_page) { + /* Heap contents are initialized to zero, as for anonymous + * mapped pages. Technically the new pages are already + * initialized to zero since they *are* anonymous mapped + * pages, however we have to take care with the contents that + * come from the remaining part of the previous page: it may + * contains garbage data due to a previous heap usage (grown + * then shrunken). */ + memset(g2h(target_brk), 0, brk_page - target_brk); + target_brk = new_brk; brk_page = HOST_PAGE_ALIGN(target_brk); DEBUGF_BRK("%#010x (mapped_addr == brk_page)\n", target_brk); I compiled it thusly: ``./configure --static --target-list=arm-linux-user && make``. I had to use binutils ld; binutils gold didn't work. Now, copy arm-linux-user/qemu-arm to rootfs/usr/bin/qemu-arm-static, and run:: cdebootstrap --allow-unauthenticated -f minimal -a armhf unstable rootfs http://ftp.debian-ports.org/debian/ FIXME/TODO ========== - Kernel (ChromeOS fork of linux) - Root Filesystem (Debian Sid armhf + btrfs) - Bootloader (u-boot) - Notes on the Partition Table (flash.cfg) - debian live + aufs dkms + squashfs ? Hardware Grumbling ================== The dock has four rubber feet on its base, but when the unit is open, only the front pair are used. The hinge has a separate pair of crappier rubber feet, and these push the entire unit up off the base's rear rubber feet. Unlike Eee netbooks (e.g. the 701 and the 1005), when the unit is closed its "rest" position is to be open by some half a centimetre. This means that if you bounce the unit in your hand, the case bangs shut then springs back out a little. This worries me about how well it will handle being transported loose in e.g. a backpack or suitcase. Because the panel is sidelit instead of backlit, there is a noticable white smudge in the middle of the bottom of the screen. This is especially noticable in a dark room, with a completely black background -- for example, when at the framebuffer console. The USB ports on the keyboard dock sit behind little slide-out covers. These covers are a pain to open, and must be bent out of the way to insert a USB device. If a device is constantly inserted during normal use (e.g. a USB mouse), these plastic covers will quickly get stuck in a bent position and be impossible to reinsert. Possibly the covers can simply be cut off and thrown away; I have yet to attempt this. Where holding the power button on a PC does a hard-halt, holding the TF101's power button does a hard reset. This means that unless you have a working OS installed that can do a soft shutdown, the device can *never* be turned off, and it will reboot back into APX until it runs out of power. The TF101 powers itself on when you connect it to the keyboard dock, and when you connect A/C power to either. If you want to plug it in to charge it back up to 100% and then unplug it, you have to remember to shut it down, otherwise the batteries will just drain away again. References ========== - http://forum.xda-developers.com/showthread.php?t=1191141 - http://dev.gentoo.org/~armin76/arm/tegra2/install.2011.xml - #ubuntu-arm (and #tegralinux, #tegratab) on Freenode - http://launchpad.net/tegralinux .. This comment provides hints for editors about what kind of file this is, and conventions to adhere to when editing it. The page break (^L) above helps Emacs find quickly locate this metadata. The Emacs major mode is set twice so that if rst.el (a non-standard library) isn't installed, Emacs will fall back on text mode instead of fundamental mode. Local Variables: mode: text mode: rst coding: utf-8 indent-tabs-mode: nil fill-column: 70 End: vim: filetype=rst fileencoding=utf-8 tw=70 expandtab :