---
title: Froyo for nookcolor
date: 2010-12-05 12:00:15.000000000 -08:00
type: post
parent_id: '0'
published: true
password: ''
status: publish
categories: []
tags: []
meta:
  _publicize_pending: '1'
  _import_original_date: 12/06/2010 04:53:55 PM
author:
permalink: "/2010/12/05/froyo-for-nookcolor/"
---
<p><a href="http://tempexport1.files.wordpress.com/2010/12/c14f3-6a00d83456074b69e20148c66efe13970c-pi.jpg" style="display:inline;"><img alt="Froyo" class="asset  asset-image at-xid-6a00d83456074b69e20148c66efe13970c" src="{{ site.baseurl }}/assets/2010/12/c14f3-6a00d83456074b69e20148c66efe13970c-pi.jpg?w=224" title="Froyo" /></a></p>
<p>&#160;</p>
<p>&#160;</p>
<p>If you&#039;ve read my blog for a while, you&#039;ve probably seen my unfortunate interactions with Barnes and Noble trying to buy a nook last Christmas.  You&#039;ve also probably seen some of my Kindle hacking and Android development work.</p>
<p>The big takeaway from last Christmas was &quot;don&#039;t by a nook&quot;</p>
<p>The nookcolor is B&amp;N&#039;s latest - a 7 inch eReader.</p>
<p>Calling it an eReader is somewhat disingenuous.  It&#039;s somewhat different from the original nook:</p>
<ul>
<li>No 3G </li>
<li>No E Ink screen </li>
<li>50% heavier than the original nook </li>
</ul>
<p>Like the original nook, it&#039;s running Android. It has a microSD slot. And it&#039;s been rooted. (Not by me.)</p>
<p>I&#039;ve been on the road for work a lot lately. That usually means I have rather a lot of time to kill in the evenings. Last Wednesday night, I found myself in a Barnes &amp; Noble store in Northern Virginia.  I wanted to check out the new nookcolor, but, well, I wasn&#039;t about to give Barnes &amp; Noble any more of my money.</p>
<p>I walked in the front door to find one of the booksellers standing in front of the nook kisok messing around with the nookcolor.  I asked if  I could play with it for a moment.</p>
<p>As I popped into the Setttings menu, she started to tell me about the device. I&#039;m...not quite sure how it happened, but some of the first words out of her mouth were &quot;It&#039;s been rooted, you know.&quot;</p>
<p>I guess I look the part.</p>
<p>I played with the device for a while. It felt reasonably solid and was impressively speedy.  The bookseller (I&#039;ve forgotten her name :/) started talking about how much she was looking forward to a community port of Froyo.</p>
<p>My resolve began to weaken, but I knew that I knew <span style="text-decoration:underline;">nothing</span>&#160;about the internals of the device and I wasn&#039;t about to buy another Android tablet with an anemic CPU. (I bought a ZT-180 from China and dropped my PixelQi display into it, just to see if it would work. I bought a Viewsonic G Tablet a couple weeks ago with the same intent, but haven&#039;t fully disassembled it to get to the display yet.)</p>
<p>I played my get out of jail free card: &quot;So, uh, I suspect that this isn&#039;t the typical sort of question you get about the nookcolor, but how fast is the CPU?&quot;</p>
<p>&quot;It&#039;s 800MHz.&quot;</p>
<p>I bought one. And sat down in the B&amp;N cafe.  I used their free wifi to download nooter from nookdevs.</p>
<p>15 minutes later, I had ADW.Launcher, Angry Birds and K-9 Mail installed. Angry Birds was remarkably smooth.</p>
<p>Like everyone else, I spent some time messing around on the device, which identified itself as a &quot;LogicPD zoom2&quot; internally.</p>
<p>&quot;Wow. This is a pretty standard Android device. I wonder how hard a vanilla Android build would be.&quot;</p>
<p>Flash forward to Friday.</p>
<p>B&amp;N finally shipped bootloader and kernel source.  The source distribution was  a zip file containing &quot;Documents and Settings/awu/Desktop/distro.tar&quot;</p>
<p>The content inside the tarball left a bit to be desired. I haven&#039;t yet found enough markers to figure out what kernel tree and tag was used as the branchpoint, so I don&#039;t know precisely what the local changes are.</p>
<p>I have made reasonable headway on figuring that out, though.</p>
<p>I started reading up on the relevant bits.</p>
<p>Meanwhile, this YouTube video was NOT posted by me:  <a href="http://www.youtube.com/watch?v=uviopU8Ve-Y">http://www.youtube.com/watch?v=uviopU8Ve-Y</a></p>
<p>Over the past couple days, with help from [mbm] on #nookcolor (who did all this before I did ;),  I&#039;ve cobbled together a basic working Froyo userland.</p>
<p>Below is a first pass braindump of what I&#039;ve done. I&#039;m 100% sure I&#039;m missing steps - and what I have running so far is hardly something I&#039;d want to run full time on my device.</p>
<p>Per usual, what you&#039;re doing could turn your device into an expensive paperweight. (It&#039;s too flat to make a decent doorstop.)</p>
<p>As nooter (the nookcolor rooting tool) showed us, the nookcolor can boot from SD. In fact, it&#039;s set to prefer to boot from SD. This makes development rather  less painful than it might otherwise be.</p>
<p>I initially started building a full cleanroom filesystem, but [mbm] convinced me that it&#039;s a bit easier to start off with the working nookcolor filesystem image and customize from there. Long term, this is obviously not the right plan.</p>
<p>Root your nookcolor (nc) with nooter.</p>
<p>Download a full filesystem image from the nc.  There are a few ways to do this. The fastest is to dd to a local filesystem on the flash card. and mount that on your workstation. The most trivial is:</p>
<pre>adb pull /dev/block/mmcblk0 ./nook-8-gig-raw-filesystem</pre>
<p>You&#039;ll need a MicroSD card of at least 8 gigs to drop this filesystem onto.  This will (sort of obviously) obliterate every single bit on that MicroSD.</p>
<pre>dd &lt; nook-8-gig-raw-filesystem &gt; /dev/sdX</pre>
<p>When you pop the MicroSD out and re-insert it, you&#039;ll likely see a whole bunch of partitions automount.</p>
<p>Be careful not to distribute this SD image, as the factory partition contains a zip file including a full (proprietary) OS image and the rom partition includes personal device details.</p>
<p>If you stick this into your nc, it should boot to the regular nook image using the boot partition on the MicroSD card.</p>
<p>Right now, the one you REALLY care about is &quot;boot&quot; (On ubuntu, it&#039;ll mount as /media/boot).  It&#039;s a VFAT filesystem on partition 1.</p>
<p>For now, what we care about on that filesystem is uRamdisk, the boot ramdisk.  As of this moment, it&#039;s set up to mount the nook&#039;s internal flash and continue boot from there.</p>
<p>Make a backup of uRamdisk.</p>
<p>uRamdisk is a u-boot filesystem.</p>
<p>You need to unpack it, twiddle some bits and repack it. I have some tools for this, which I&#039;ll publish to github as soon as I untangle them from the rest of the nook image in my local repo (Which contains B&amp;N code I can&#039;t distribute because it&#039;s not obviously under an opensource license).</p>
<p>There&#039;s likely a <span style="text-decoration:underline;">correct</span> way to do this, but the quick-and-dirty way was a bit easier for me to sort out. u-boot ramdisks are gzipped cpio archives with a 64 byte header.</p>
<p>My &quot;unpack&quot; script looks like this:</p>
<pre>	#!/bin/sh
IMAGE=$1
mkdir work-$$
dd if=$IMAGE of=/tmp/image.cpio.gz bs=64 skip=1
zcat /tmp/image.cpio.gz &gt; work-$$.cpio
cd work-$$
cpio -i -F ../work-$$.cpio
echo &quot;Unpacked ramdisk is in work-$$&quot;
</pre>
<p>The two files you really care about right now are env.txt and init.rc</p>
<p>Right now, all we care about is twiddling pointers to partitions.</p>
<p><span style="text-decoration:line-through;"></p>
<p>env.txt should look like this:</p>
<pre>
bootdelay=1
bootargs=console=ttyS0,115200n8 androidboot.console=ttyS0 root=/dev/mmcblk1p2 rw rootdelay=1 mem=512M init=/init videoout=omap24xxvout omap_vout.video1_numbuffers=6 omap_vout.vid1_static_vrfb_alloc=y omapfb.vram=0:8M
bootcmd=mmc 0 read 0x800 0x81c00000 ${kernel_size}; bootm 81c00000
recovery=echo recovery mode
</pre>
<p>I&#039;ve altered the bootcmd&#039;s pointer from &quot;mmc 1&quot; to &quot;mmc 0&quot; - this is very much cargo-culting based on the TI docs and not something I&#039;ve looked at.</p>
<p>Similarly, I&#039;ve flipped the &quot;root&quot; argument of &quot;bootargs&quot; from mmcblk0p2 to mmcblk1p2. It shouldn&#039;t really matter.</p>
<p></span></p>
<p><strong>EDIT: Turns out this isn&#039;t strictly necessary</strong></p>
<p>In init.rc, anywhere the mmcblk0 is mentioned, make it mmcblk1</p>
<p>I also forced adb to always start, just for ease of development.</p>
<p>Now you&#039;ll want to repack the ramdisk. My &quot;repack&quot; script looks like this:</p>
<pre>
#!/bin/sh
DIR=&quot;$( basename `pwd`)&quot;
cpio -i -t -F ../${DIR}.cpio | cpio -o -H newc -O ../ramdisk-repacked-${DIR}.cpio
cd ..
gzip ramdisk-repacked-${DIR}.cpio
./mkimage  -A ARM -O Linux -T RAMDisk -C gzip -n Image -d ramdisk-repacked-${DIR}.cpio.gz uRamdisk-${DIR}
</pre>
<p>mkimage is a standard tool from the u-boot tools directory shipped as part of the B&amp;N nookcolor sourcedrop. I&#039;d assume that the mkimage from any copy of u-boot would be fine.</p>
<p>Once you repack the ramdisk, put it back on the boot partition as uRamdisk.</p>
<p>Umount all the filesystems on the MicroSD, eject the MicroSD and drop it in your nc.</p>
<p>Boot your nc. It should boot normally.</p>
<p>Once it&#039;s booted, use adb shell to check that filesystems are mounted from mmcblk1 and not mmcblk0</p>
<p>You can now shutdown your nook.</p>
<p>You have a full OS image on SD.</p>
<p>It&#039;s now time for the interesting bit, building Android.</p>
<p>I built from TI&#039;s omapzoom branch of Android - They&#039;re the folks who make the innermost parts of the nc.  <a href="http://www.omappedia.org/wiki/Android_Getting_Started">http://www.omappedia.org/wiki/Android_Getting_Started</a>&#160;should tell you everything you need to know about using repo to clone the repositories, check out froyo and build.</p>
<p>You&#039;ll need a crosscompiler. TI recommend:</p>
<p><a href="http://www.codesourcery.com/sgpp/lite/arm/portal/release858">http://www.codesourcery.com/sgpp/lite/arm/portal/release858</a></p>
<p>Follow the instructions for zoom2</p>
<p>Once the build is done, put your MicroSD card back in the nc. This time, you&#039;re looking for the system partition (sdX5).</p>
<p>You have two options. You can either wipe out B&amp;N&#039;s Android build entirely and install the pristine zoom2 build or you can overlay the zoom2 build on top of B&amp;N&#039;s build of Eclair.</p>
<p>I went for the former, though [mbm] had better luck with the latter, as it means you won&#039;t have to pick out proprietary libraries and tools and install them one by one.</p>
<p>Obviously, if you use any of the B&amp;N bits, you MUST not distribute your filesystem image.  It appears that TI publishes just about every proprietary bit we could possibly want on their GForge instance, though I haven&#039;t actually dug in too deep just yet.</p>
<p>You&#039;ll want to neuter etc/vold.* on the system partition once you&#039;ve installed the new image, as it tries to mount an sd card that&#039;s now... otherwise occupied.</p>
<p>Once you&#039;re done with this, it&#039;s time to go back to work on your uRamdisk image, since froyo wants somewhat different startup bits than eclair.</p>
<p>I ended up with something a bit wonky causing mount failures as I was migrating init.rc to froyo.  Again, this is courtesy of [mbm]:</p>
<pre>	--- ../work-20413/init.rc   2010-12-05 11:22:40.514818375 -0500
+++ init.rc 2010-12-04 21:34:36.209385337 -0500
@@ -1,4 +1,3 @@
-# init.rc used on Encore hardware
on early-init
# Give the kernel time to enumerate the internal and external MMC/SD cards
@@ -16,7 +15,8 @@
export ANDROID_ROOT /system
export ANDROID_ASSETS /system/app
export ANDROID_DATA /data
-    export EXTERNAL_STORAGE /sdcard
+    export EXTERNAL_STORAGE /mnt/sdcard
+    export ASEC_MOUNTPOINT /mnt/asec
export INTERNAL_STORAGE /media
export BOOTCLASSPATH /system/framework/core.jar:/system/framework/ext.jar:/system/framework/framework.jar:/system/framework/android.policy.jar:/system/framework/services.jar
export DSP_PATH /system/lib/dsp
@@ -37,16 +37,39 @@
# Backward compatibility
symlink /system/etc /etc
-# create mountpoints and mount tmpfs on sqlite_stmt_journals
+# create mountpoints
+    mkdir /mnt 0775 root system
+    mkdir /mnt/sdcard 0000 system system
+
+# Create cgroup mount point for cpu accounting
+    mkdir /acct
+    mount cgroup none /acct cpuacct
+    mkdir /acct/uid
+
+# Backwards Compat - XXX: Going away in G*
+    symlink /mnt/sdcard /sdcard
+
mkdir /system
-    mkdir /tmp 0777
mkdir /data 0771 system system
mkdir /cache 0770 system cache
mkdir /media 0777 system system
-    mkdir /sdcard 0777 system system
-    mkdir /sqlite_stmt_journals 01777 root root
mkdir /rom 0777 root root
-    mount tmpfs tmpfs /sqlite_stmt_journals size=4m
+
+    mkdir /config 0500 root root
+
+    # Directory for putting things only root should see.
+    mkdir /mnt/secure 0700 root root
+
+    # Directory for staging bindmounts
+    mkdir /mnt/secure/staging 0700 root root
+
+    # Directory-target for where the secure container
+    # imagefile directory will be bind-mounted
+    mkdir /mnt/secure/asec  0700 root root
+
+    # Secure container public mount points.
+    mkdir /mnt/asec  0700 root system
+    mount tmpfs tmpfs /mnt/asec mode=0755,gid=1000
mount rootfs rootfs / ro remount
@@ -55,6 +78,46 @@
write /proc/cpu/alignment 4
write /proc/sys/kernel/sched_latency_ns 10000000
write /proc/sys/kernel/sched_wakeup_granularity_ns 2000000
+    write /proc/sys/kernel/sched_compat_yield 1
+    write /proc/sys/kernel/sched_child_runs_first 0
+
+# Create cgroup mount points for process groups
+    mkdir /dev/cpuctl
+    mount cgroup none /dev/cpuctl cpu
+    chown system system /dev/cpuctl
+    chown system system /dev/cpuctl/tasks
+    chmod 0777 /dev/cpuctl/tasks
+    write /dev/cpuctl/cpu.shares 1024
+
+    mkdir /dev/cpuctl/fg_boost
+    chown system system /dev/cpuctl/fg_boost/tasks
+    chmod 0777 /dev/cpuctl/fg_boost/tasks
+    write /dev/cpuctl/fg_boost/cpu.shares 1024
+
+    mkdir /dev/cpuctl/bg_non_interactive
+    chown system system /dev/cpuctl/bg_non_interactive/tasks
+    chmod 0777 /dev/cpuctl/bg_non_interactive/tasks
+    # 5.0 %
+    write /dev/cpuctl/bg_non_interactive/cpu.shares 52
+
+    # Create dump dir and collect dumps.
+    # Do this before we mount cache so eventually we can use cache for
+    # storing dumps on platforms which do not have a dedicated dump partition.
+
+    mkdir /data/dontpanic
+    chown root log /data/dontpanic
+    chmod 0750 /data/dontpanic
+
+    # Collect apanic data, free resources and re-arm trigger
+    copy /proc/apanic_console /data/dontpanic/apanic_console
+    chown root log /data/dontpanic/apanic_console
+    chmod 0640 /data/dontpanic/apanic_console
+
+    copy /proc/apanic_threads /data/dontpanic/apanic_threads
+    chown root log /data/dontpanic/apanic_threads
+    chmod 0640 /data/dontpanic/apanic_threads
+
+    write /proc/apanic_console 1
# mount MMC partitions
mount vfat /dev/block/mmcblk1p2 /rom sync noatime nodiratime uid=1000,gid=1000,fmask=117,dmask=007
@@ -382,8 +445,8 @@
service vold /system/bin/vold
socket vold stream 0660 root mount
-#service mountd /system/bin/mountd
-#    socket mountd stream 0660 root mount
+service netd /system/bin/netd
+    socket netd stream 0660 root system
service debuggerd /system/bin/debuggerd
@@ -396,10 +459,13 @@
service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
socket zygote stream 666
onrestart write /sys/android_power/request_state wake
+    onrestart write /sys/power/state on
+    onrestart restart media
service media /system/bin/mediaserver
user media
-    group system audio camera graphics inet net_bt net_bt_admin
+    group system audio camera graphics inet net_bt net_bt_admin net_raw
+    ioprio rt 4
service fw3a /system/bin/fw3a_core
user root
@@ -421,6 +487,37 @@
user bluetooth
group bluetooth net_bt_admin
+service bluetoothd /system/bin/bluetoothd -n
+    socket bluetooth stream 660 bluetooth bluetooth
+    socket dbus_bluetooth stream 660 bluetooth bluetooth
+    # init.rc does not yet support applying capabilities, so run as root and
+    # let bluetoothd drop uid to bluetooth with the right linux capabilities
+    group bluetooth net_bt_admin misc
+    disabled
+
+service hfag /system/bin/sdptool add --channel=10 HFAG
+    user bluetooth
+    group bluetooth net_bt_admin
+    disabled
+    oneshot
+
+service hsag /system/bin/sdptool add --channel=11 HSAG
+    user bluetooth
+    group bluetooth net_bt_admin
+    disabled
+    oneshot
+
+service opush /system/bin/sdptool add --channel=12 OPUSH
+    user bluetooth
+    group bluetooth net_bt_admin
+    disabled
+    oneshot
+
+service pbap /system/bin/sdptool add --channel=19 PBAP
+    user bluetooth
+    group bluetooth net_bt_admin
+    disabled
+    oneshot
service installd /system/bin/installd
socket installd stream 600 system system
@@ -432,8 +529,6 @@
disabled
oneshot
-
-
service ifcfg_ti /system/bin/ifconfig tiwlan0 up
disabled
oneshot
@@ -447,6 +542,19 @@
disabled
oneshot
+service racoon /system/bin/racoon
+    socket racoon stream 600 system system
+    # racoon will setuid to vpn after getting necessary resources.
+    group net_admin
+    disabled
+    oneshot
+
+service mtpd /system/bin/mtpd
+    socket mtpd stream 600 system system
+    user vpn
+    group vpn net_admin net_raw
+    disabled
+    oneshot
service keystore /system/bin/keystore /data/misc/keystore
user keystore
@@ -463,5 +571,7 @@
service debuglog /system/bin/debuglog.sh
user root
-
-
+service dumpstate /system/bin/dumpstate -s
+    socket dumpstate stream 0660 shell log
+    disabled
+    oneshot
</pre>
<p>At this point, (assuming I haven&#039;t forgotten anything), you should have a MicroSD that will boot froyo on a nookcolor.</p>
<p>...and then immediately shut down, ostensibly due to power issues. My sneaking suspicion is that this is because the kernel the nc is booting from is B&amp;N&#039;s original 2.6.29 image and there&#039;s been a bit of skew in how it reads some bit of information out of /proc.</p>
<p>The correct next step is to go and build a proper kernel for the device.</p>
<p>The easy next step is to perform a brutal hackjob on android&#039;s batteryservice.</p>
<h2>IF YOU DO THIS, YOUR NOOKCOLOR WON&#039;T SHUT DOWN WHEN THE BATTERY GETS HOT ENOUGH TO DAMAGE YOUR NOOK OR EXPLODE. &#160;IF YOU DISTRIBUTE AN ANDROID IMAGE WITH THIS HACK TO _ANYONE_, YOUR INTERNET LICENSE WILL BE REVOKED AND MEN WITH PITCHFORKS AND TORCHES WILL COME FOR YOU:</h2>
<h2>Edit: I have no reason to believe that this is actually likely. But it&#039;d be double-plus irresponsible of me to suggest that turning off a hardware safety feature was a good idea.</h2>
<p>&#160;</p>
<pre>	jesse@puppy ~/android-omapzoom/frameworks/base/services ((6c81cb0...) *) $ git diff
diff --git a/services/java/com/android/server/BatteryService.java b/services/java/com/android/server/BatteryService.java
index 5cf61bd..bf96479 100644
--- a/services/java/com/android/server/BatteryService.java
+++ b/services/java/com/android/server/BatteryService.java
@@ -176,8 +176,8 @@ class BatteryService extends Binder {
void systemReady() {
// check our power situation now that it is safe to display the shutdown dialog.
-        shutdownIfNoPower();
-        shutdownIfOverTemp();
+        //shutdownIfNoPower();
+       // shutdownIfOverTemp();
}
private final void shutdownIfNoPower() {
@@ -210,8 +210,8 @@ class BatteryService extends Binder {
boolean logOutlier = false;
long dischargeDuration = 0;
-        shutdownIfNoPower();
-        shutdownIfOverTemp();
+      //  shutdownIfNoPower();
+        //shutdownIfOverTemp();
mBatteryLevelCritical = mBatteryLevel &lt;= CRITICAL_BATTERY_LEVEL;
if (mAcOnline) {
</pre>
<p>Once you&#039;ve rebuilt the android core and reinstalled it on your system partition, you should now have something that boots froyo on your nook.</p>
<p>This froyo is VERY MUCH not ready for primetime. Don&#039;t expect WIFI, Bluetooth, Google Apps, reasonable performance, sensor access, etc.</p>
<p>TI distributes wifi drivers and all the hardware acceleration you could possibly want:      <a href="http://omappedia.org/wiki/WiLink_Connectivity_Project">http://omappedia.org/wiki/WiLink_Connectivity_Project</a> <a href="http://www.omappedia.org/wiki/Android_DSP_Codecs">http://www.omappedia.org/wiki/Android_DSP_Codecs</a></p>
<p>This all would have taken me a great deal longer without [mbm]&#039;s assistance and advice.</p>
<p>My next steps will (probably) be to try to build a modern kernel from source and see what that does for driver support.</p>
<p>Please note that I don&#039;t plan to build a distributable ROM or to port Cyanogenmod, though I&#039;d be thrilled to see someone pick up the torch and do so.</p>
<p>I can&#039;t distribute the OS image I have, as it contains a mix of free stuff and proprietary stuff pulled off of my nookcolor&#039;s system partitions.</p>
<p>If you&#039;re looking to chatter with folks about development for the nookcolor, I&#039;d recommend #nookcolor on chat.freenode.net</p>
