[Nook Color Android Development] steven676:
Towards an improved install experience

(I'm posting this in a Nook Color thread, but all of this discussion applies to Nook Tablet and Nook HD/HD+ as well.)

As many of you know, there are companies who take advantage of the fact that it's possible to boot the Nook tablet family (Color, Tablet, HD/HD+) off a microSD card without modifying the device to sell pre-made bootable SD cards and images which can simply be dropped into the device for a working Android install.

Now, there's nothing illegal, or even necesarily wrong, with that business model (if it weren't for the ridiculous prices which some of them charge, anyway) -- but we (NookieDevs) believe that many users would be better served by downloading CyanogenMod without paying their markup. (Obviously, no one is going to be offering pre-installed physical microSD cards for free, and there is a certain convenience that comes with that product.) To that end, we'd like to provide an install- and update-time experience as least as easy as purchasing a card image: "download this image, flash it to a card, place into your device, boot, voila!"

For SD card installs, that means providing a single SD card image (with ROM and recovery preinstalled) and clear, easy-to-follow instructions (both text and video?) on how to write the image to a microSD card. When booted, this SD card image would adjust the size of its /data and /sdcard partitions to fit the card and then reboot into CyanogenMod.

For eMMC installs, this means providing a single, easy-to-use bootable SD card image which installs the ROM and recovery onto the eMMC and then reboots into CyanogenMod.

In either case, updates and addons should be flashable via standard mechanisms (the CM updater, ROM Manager, the standard recovery) without having to worry about special procedures or differences between eMMC and SD card installs.

The good news is that most of the infrastructure to make this happen is already in place; the bad news is that we're not quite there yet:

Nook Color: one ROM download (OTA package ZIP) for both eMMC and SD installs, but no standard way of getting a recovery onto eMMC to start the process, and a fragile SD installer which modifies the ROMs it installs for creating and updating SD card installs.

Nook Tablet: separate ROMs for eMMC and SD card installs.

Nook HD/HD+: separate ROMs for eMMC and SD card installs.

So what's missing?

We need to be able to run the same, completely unmodified ROMs and recoveries on both eMMC and SD installs

We need to provide "batteries-included" eMMC installers and SD card initial images: no more "download X, Y, Z, then flash X to SD card, place Y and Z here, then boot it and select options P, Q and R" to install

We need to produce better instructions and make them easier to find -- it should not take an hour (or hours!) of browsing forums to piece together all the bits to install successfully

We'd like to do something about the Google apps installation experience

We probably want to tackle these in the order given above -- it's hard to build batteries-included installers without batteries to put in the installers, for instance :)

Creating a single system image

How do we get one system/recovery image to run unmodified on both eMMC and SD? The only thing that absolutely must change between eMMC and SD is the location of the /system and /data partitions on disk. If we know where we've booted from, we can point the system at these accordingly, but the kernel and early userspace have no way of learning this information on their own. On the other hand, the bootloader (Cyanoboot/u-boot) does know this, so we could do the following:

Replace all references to raw block devices in the system (fstab.boardname, init.rc files, the like) with symbolic links which will be set up during the boot process. (For instance, on encore, /dev/block/mmcblk0p5 might become /dev/block/by-name/system.)

Modify the bootloaders to pass the boot location on the kernel command line (something like sdcard_boot or emmc_boot depending on the boot source)

Run a program (can't be a shell script unless we ship a statically-linked shell in the initramfs) early in the init which parses the kernel command line (/proc/cmdline) to discover the boot location and then creates the appropriate symlinks accordingly.

Have the boot wait on the existence of these links to ensure that the program completes before continuing the boot.

(Alternately, if we give the kernel command line option a name starting with "androidboot.", for example "androidboot.boot_source=emmc", init would automatically copy the value to a system property with a name starting with "ro.boot." ("ro.boot.boot_source=emmc" in this example). We might then be able to set up the symlinks in the init.board.rc script directly using a property trigger ("on ro.boot.boot_source=emmc"), though we'd still need a separate shell script for the recovery since init.board.rc doesn't run there.)

There is at least one complication here: on an SD card install, the SD card is obviously non-removable, and we should tell the framework this. (This isn't currently being done on Nook Color, but is done on Nook HD/HD+ SD card installs.) There are two places where this is set -- the fs_mgr flags in /fstab.boardname, and in the storage_list.xml that's built into the framework resources. It's relatively easy for us to modify the fstab at runtime, but close to impossible to modify the framework resources -- more research is required on how we might get around this problem.

Creating images for SD card installs

In principle, someone could just create a bootable SD card, put one of the new eMMC/SD compatible recoveries on it, grab an OTA download, install it, and then image the resulting card for distribution -- I suspect this is pretty close to what the companies have already been doing. That's less than ideal, though, as it means we have to offer one download for each SD card size that people might want to use. A better approach would be to do as the Nook Color SD installer does and repartition the card during initial setup.

How are we going to do this, though? There are a few options:

Build a special SD card installer image, similar to the Nook Color SD installer, which runs on first boot to partition the card, then removes itself and reboots into CM.

Create a specially-modified recovery that runs on first boot to partition the card, then removes itself and reboots into CM.

Teach the ROM how to do this itself on first boot.

My personal inclination is to use the modified recovery, because we're already going to need to develop the needed infrastructure for the Nook Color repartitioner (see this post). That's open for discussion, though.

There's also a question of how to generate the images:

Build the images by hand. This requires the least infrastructure, but the most person-hours -- as a result, we'd likely only generate SD card images for selected CM builds (first nightlies for a particular CM branch, milestone builds, and RC/stable releases, most likely), and users who wanted to jump straight onto the bleeding edge would need to upgrade right after installing.

Autobuild the images somehow. This requires a lot of infrastructure, but would potentially allow us to automatically generate SD card images for every CM nightly.

Don't create pre-installed images at all -- instead, ship an image which consists of an installer and an OTA package. This is really easy to generate (the "installer" would basically be the standard recovery with an instruction to install the included OTA package when it boots), but it results in a long first-run process relative to the other two options.

Personally, I'd say we build the images by hand, at least to start -- SD card images only being available for certain hand-selected builds could be construed as an advantage, because it means that users can always be sure that the image they download will boot and run correctly -- but we can revisit this in the future.

Creating eMMC installer images

Given the above, this comes almost for free -- an install process is going to be required in any event, so all we need to do is ship a slightly modified recovery (one which acts on eMMC even though it's booted from SD) which is instructed to install the included OTA package on boot. The question of whether we want to generate these images automatically or by hand remains; I'd suggest that we should treat these images the same way we treat the SD card install images and only provide them for selected builds known to be stable, but we could revisit this at any point. (In any event, someone who wants to use a different build could just swap the OTA package on the image for the build of their choice after flashing the image to the SD card.)

Hosting the resulting images

More discussion required ... ideally, these get hosted by the CyanogenMod project itself, but that would require some discussions with them (and possibly some changes to their infrastructure). Alternately, eyeballer's offered to host the images at his site (thanks!).

Producing better instructions

Once we have all this stuff, someone's gotta write them :) (A slickly-produced video would be nice, but it mustn't be the only form of documentation.)

As for making sure people can find this information ... forum threads probably aren't the best place to do it. Presumably we could put this stuff on the CyanogenMod wiki, but we may want to work on increasing its visibility even further (perhaps by registering a domain name and putting together some splashy, eye-catching web pages?)

We also need a better story for how to create bootable SD cards from downloaded images -- "dd if=image of=/dev/mmcblk0 bs=64M" makes perfect sense to you and me, but not necessarily to our target audience :) fattire's offered the use of his rather impressive "derp" guided installation system, which (as I understand it) could walk the user through (or perhaps even completely automate) the process of flashing an SD card from Mac OS X and Linux, but Windows represents a bigger challenge. (Someone want to chime in about relatively easy and/or scriptable ways of getting images onto SD cards in Windows?)

Google Apps

There are two things we know to be true about the Google apps:

We cannot legally include them with any image we create(*);

Just about everyone is going to want them.

(*)

Even if we could get permission from Google to ship their proprietary apps with our builds directly, if CyanogenMod's experience with bugfix releases on the Oppo N1 CM Edition is any indication, it's likely that any such build would have to pass the Android compatibility tests before being released. I don't know of any technical limitations which would prevent any of our devices from eventually passing those tests, but it's an involved process that requires human intervention, so it's unlikely that we would want to go through it except for stable releases. In other words, we still need to look at this for the purposes of nightlies and M builds.

The best idea we can come up with is a first-run setup app which offers to download a Google apps package if one isn't present -- but someone would have to write it, and we'd probably want to get permission from whoever's hosting the Google apps download we'd point the app at first (unless we make the app use BitTorrent?). It's also not clear whether that would actually leave us in the clear legally (at least under US copyright law), thanks to the inducement rule.