Installing Android on the Samsung XE303C12 Chromebook

Chinese Version中文版: Samsung XE303C12 Chromebook 上安装 Android

Introduction

I think the Samsung Chromebook (model XE303C12) is definitely an interesting product. It is very portable, rather inexpensive and comes with the ARM-based Samsung Exynos 5 Dual CPU. There are several posts on the web explaining how to install different linux distributions on it, but I could not find any successful attempt to port Android to it. In this blog post I give details of how I ported Android to the Samsung Chromebook model XE303C12. I try to be quite pedantic in giving details of the procedure I followed. I do this in the hope of generating documentation which can be useful in other similar ports.

Prerequisites

Hardware:

  • The Samsung Chromebook model XE303C12, with the Samsung Exynos 5 Dual CPU,
  • An SD card, 8 GB in this guide,
  • A desktop PC, used to compile the kernel and the Android filesystem, with a card reader,
  • A good internet connection: the source download for Android is approximately 8.5 GB in size,
  • An USB-to-ethernet dongle (optional),

Software:

  • 64-bit Ubuntu 12.04 installed on the desktop PC. Other operating systems may work as well, but have not been tested.

Getting ready

Below I describe how to setup the Chromebook and the machine to be used for building the software. This knowledge will be useful in the following sections.

     

Install additional software

Install some required packages on the desktop PC with:

        desktop-pc$ sudo apt-get install \
                      u-boot-tools device-tree-compiler \
                      gcc-4.6-arm-linux-gnueabi g++-arm-linux-gnueabi

This will allow you to generate u-Boot images and use dtc to add the required Flattened Device Tree to your kernel image.

Putting the Chromebook in developer mode

There are various blogs explaining how to do this. I recommend following Daniel P. Berrangé's instructions, which are copied below for your convenience:

  1. Booting into Recovery Mode is the first thing to do. This requires holding down the Esc and Refresh keys, while pressing the Power key.
  2. It should now display a nice scary message that the installation is broken. This is of course a lie, so ignore it.
  3. Pressing Ctrl-D now will start the switch into Developer Mode.
  4. It should now display a less scary message asking if you want to turn off verification. We do indeed want to do this, so press ENTER.
  5. The ChromeBook will reboot and tell you that verification is disabled.
  6. Wait a short while, or press Ctrl-D, and it'll display another message that it is transitioning to Developer Mode.
  7. Erasing local data can take a while, so be patient here. Strangely, there’s a crude ascii art progress bar along the top of the screen here, while everything else remains pretty & graphical.

When the Chromebook is in developer mode it behaves like this: immediately after the device is turned on, it shows a white screen, with the text "OS verification is OFF/Press SPACE to re-enable". At this point you can do various things:

  • You can just ignore the message and wait: after about 30 seconds the Chromebook boots normally,
  • You can press CTRL+D and induce the Chromebook to boot normally,
  • You can press CTRL+U and induce the bootloader to boot from the SD card. The SD card, however, needs to be prepared appropriately and the system does also need to be instructed not to ignore it (I explain below how to do it),
  • You can press SPACE to leave the developer mode and return to normal (verified) mode.

     

Opening a root shell

Turn on the Chromebook and allow it to boot Chrome-OS. If you have just bought the device, you do not need to accept the Chrome-OS license. Wait until you get the first screen where you are asked to choose and setup the network.  Setting up the network is not required in this guide, but you can easily do it, if required: just follow the instructions on the screen and proceed until you are shown the license agreement.  You can now press CTRL+ALT+→ where is the third key starting from the left at the top of your keyboard, where the keys F1, F2, ... would normally be. The Chromebook displays a console. Login as root; there is no password. The cursor may not be visible. A not-so-nice way of showing the cursor is starting vi. Launch vi, by typing vi + ENTER and immediately quit it typing :q! + ENTER.

Via the root console you can do things like inspect the configuration (e.g. find the modules currently loaded in the kernel with lsmod or see how the network is configured with ifconfig), which may be useful to solve issues later with Android. The machine can be rebooted with the command reboot or powered off with the command poweroff.

Installing a Linux distribution to use as a support system

In this guide I explain how to install a GNU/Linux distribution to allow testing your own compiled kernel before using it with Android.  While installing a GNU/Linux distribution is not strictly necessary to get Android running on your Chromebook, having such a system may prove useful for debugging purposes. Unlike Android, a GNU/Linux distribution comes with many useful tools for inspecting the system and interacting with it directly.

In this guide we will prepare the SD card to allow a dual boot setup with both Android and another regular GNU+Linux distribution. There are different distributions which can be used for the purpose: Fedora, Bodhi Linux, Debian, Ubuntu.

In this guide I choose Fedora, as the instructions are written down with particular clarity.

Follow the instructions given for Fedora, but do partition the SD card differently. Create four partitions: two 16 MB partitions for the kernel, followed by two ext4 partitions: one for Fedora — give it ~4 GB — and one for Android, give it the remaining ~4 GB:

  • Partition 1: 16 MB, unformatted, Fedora kernel,
  • Partition 2: 16 MB, unformatted, Android kernel,
  • Partition 3: 4 GB, ext4, Fedora file system,
  • Partition 4: 4 GB, ext4, Android file system,

At this point you should be able to boot Fedora. You should have taken the kernel and modules from Chrome-OS and Fedora should be able to use graphics, the wireless and the USB-to-ethernet dongle, if you have one. Next step is compiling the kernel ourselves and making sure Fedora can use our own kernel with our own modules.

Getting the sources and compiling the kernel

In order to run Android, you need a kernel which supports some Android specific features (e.g. the binder kernel driver). You then need to compile a kernel which has these features enabled (unlike the kernel which comes with the Chromebook). In this section we explain how to do this.

Download the Chromium Linux Kernel:

         desktop-pc$ mkdir chromebook
         desktop-pc$ cd chromebook
         desktop-pc$ git clone http://git.chromium.org/chromiumos/third_party/kernel.git \
                       -b chromeos-3.4

Where chromebook is a name for the directory where you want to download the sources. Here I use the branch chromeos-3.4.

A directory with name kernel should have been created by git. In what follows, I assume:

        CHROMEOS=chromebook/kernel

If you want to use exactly the same kernel which is used in this guide do as follows (I suggest to do this, unless you know what you are doing):

        desktop-pc$ cd $CHROMEOS
        desktop-pc$ git checkout 70301d5c21ee9d422e2621b76239f51f0e008362

Now, configure the Kernel:

        desktop-pc$ ./chromeos/scripts/prepareconfig chromeos-exynos5

This script creates the .config file in the kernel top directory for you. Note that there is a file /boot/config-3.4.0 in the chromebook native filesystem which contains the configuration used to build the native chromebook kernel.

Now tweak the configuration and add some features needed for Android. Make sure .config contains the following lines (uncommented):

        CONFIG_ANDROID=y
        CONFIG_ANDROID_BINDER_IPC=y
        CONFIG_ANDROID_LOGGER=y
        CONFIG_ANDROID_LOW_MEMORY_KILLER=y
        CONFIG_ASHMEM=y
        CONFIG_FB_TILEBLITTING=y

Start compiling the configured kernel:

        desktop-pc$ make -j8 ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- uImage

Notice that you need to have the "arm-linux-gnueabi" version of gcc installed, as explained in the section Install additional software. If you do, then

        desktop-pc$ arm-linux-gnueabi-gcc --version

Shows something like:

        arm-linux-gnueabi-gcc (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3
        Copyright (C) 2011 Free Software Foundation, Inc.
        This is free software; see the source for copying conditions.  There is NO
        warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

Let's return to the compilation of the kernel. After giving the make command, you may get messages like,

        Android RAM buffer console (ANDROID_RAM_CONSOLE) [N/y] (NEW)

Just type ENTER to all of them to use the default values.  Compilation will then take a while.

The compilation creates the files Image, zImage and uImage in the directory $CHROMEOS/arch/arm/boot. Run the command below to create the dtb files for your device in the directory $CHROMEOS/arch/arm/boot:

        desktop-pc$ make -j8 ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- dtbs

Next, create a file in $CHROMEOS/arch/kernel.its with the following content:

        /dts-v1/;

        / {
            description = "Chrome OS kernel image with one or more FDT blobs";
            #address-cells = <1>;
            images {
           kernel@1{
           description = "kernel";
               data = /incbin/("arm/boot/zImage");
               type = "kernel_noload";
               arch = "arm";
               os = "linux";
               compression = "none";
               load = <0>;
               entry = <0>;
           };
           fdt@1{
               description = "exynos5250-snow.dtb";
               data = /incbin/("arm/boot/exynos5250-snow.dtb");
               type = "flat_dt";
               arch = "arm";
               compression = "none";
               hash@1{
              algo = "sha1";
               };
           };
            };
            configurations {
           default = "conf@1";
           conf@1{
               kernel = "kernel@1";
               fdt = "fdt@1";
           };
            };
        };

See also Olof Johansson's post and Siarhei Siamashka's mkimage script.

Note that the paths arm/boot/zImage and arm/boot/exynos5250-snow.dtb are pointing to files which — by now — should exist in your filesystem.  Then, do as follows:

        desktop-pc$ cd $CHROMEOS/arch
        desktop-pc$ mkimage -f kernel.its kernel.itb

A file kernel.itb is produced which contains the kernel in the right form: a FIT kernel image. It should be possible to use kernel.itb as a replacement for what — in the original device — is stored as /boot/vmlinuz-3.4.0.

Compiling the kernel modules

Do as follows:

        desktop-pc$ cd $CHROMEOS
        desktop-pc$ mkdir $CHROMEOS/../modules
        desktop-pc$ make -j8 ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- modules
        desktop-pc$ make -j8 ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- modules_install \
                      INSTALL_MOD_PATH=$CHROMEOS/../modules

The directory $CHROMEOS/../modules should be populated with the kernel modules.

     

Using the compiled kernel and modules with Fedora

Insert the SD card on your PC. Here I assume that the partition containing the Fedora filesystem is mounted in /mnt/Fedora. I also assume that you created a user named guest in Fedora. While installing Fedora, if you have followed the instruction correctly, you will have copied the modules from Chrome-OS inside /mnt/Fedora/lib/modules/ and the firmware files inside /mnt/Fedora/lib/firmware/. Do as follows:

        desktop-pc$ mv /mnt/Fedora/lib/modules/3.4.0 /mnt/Fedora/lib/modules/original-3.4.0
        desktop-pc$ cp -a $CHROMEOS/../modules/lib/modules/3.4.0 /mnt/Fedora/lib/modules/

It is also a good idea to check the permissions for the module files: the kernel may refuse to load a module if it has loose permissions!

        desktop-pc$ cd /mnt/Fedora/lib/modules/
        desktop-pc$ find . -type f -print0 | xargs -0 chmod 0644

Copy the kernel onto the SD card:

        desktop-pc$ cp $CHROMEOS/arch/kernel.itb /mnt/Fedora/home/guest/kernel.itb

Create a file in /mnt/Fedora/home/guest/fedora-install-kernel.sh with the following content:

        echo "console=tty1 debug verbose root=/dev/mmcblk1p3 lsm.module_locking=0 rootwait rw" > /tmp/config

        vbutil_kernel \
          --pack=/tmp/outkernel \
          --keyblock=/usr/share/vboot/devkeys/kernel.keyblock \
          --version=1 \
          --signprivate=/usr/share/vboot/devkeys/kernel_data_key.vbprivk \
          --config=/tmp/config \
          --vmlinuz=/tmp/inkernel \
          --arch=arm
        dd if=/tmp/outkernel of=/dev/mmcblk1p1
        cgpt add -i 1 -S 1 -T 5 -P 10 -l kern-fedora /dev/mmcblk1
        rm /tmp/outkernel /tmp/inkernel /tmp/config

A few things to notice:

  • /dev/mmcblk1p3 is the partition in the SD card containing the Fedora filesystem. This will be the case if you followed the instructions above,
  • The kernel option lsm.module_locking=0 tells the kernel to disable the module-locking restrictions when loading the modules,
  • The kernel is installed in the first (dedicated) partition, /dev/mmcblk1p1,

Now boot the Chromebook and open a root shell, as explained in the subsection Opening a root shell.  Once you enter the root shell, insert the SD card inside the Chromebook and do as follows:

        chromebook$ cd /tmp
        chromebook$ mount /dev/mmcblk1p3 /mnt
        chromebook$ cp /mnt/home/guest/kernel.itb inkernel
        chromebook$ cp /mnt/home/guest/fedora-install-kernel.sh .
        chromebook$ bash fedora-install-kernel.sh

The script installs the kernel inside the first partition of the SD card. If you have not done it already while installing Fedora, you will have to run the command below:

        chromebook$ crossystem dev_boot_usb=1

Now reboot:

        chromebook$ reboot

When the system comes up, open a shell and try the following:

        chromebook$ dmesg | head

You should get something like:

        dmesg | head
        [    0.000000] Booting Linux on physical CPU 0
        [    0.000000] Initializing cgroup subsys cpu
        [    0.000000] Linux version 3.4.0 (username@hostname) (gcc version 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5) ) #3 SMP Fri Mar 22 14:26:00 GMT 2013
        [    0.000000] CPU: ARMv7 Processor [410fc0f4] revision 4 (ARMv7), cr=10c5387d
        [    0.000000] CPU: PIPT / VIPT nonaliasing data cache, PIPT instruction cache
        [    0.000000] Machine: SAMSUNG EXYNOS5 (Flattened Device Tree), model: Google Snow
        [    0.000000] Ramoops: 41f00000 - 41ffffff
        [    0.000000] Memory policy: ECC disabled, Data cache writealloc
        [    0.000000] CPU EXYNOS5250 (id 0x43520010)
        [    0.000000] exynos5_init_clocks: initializing clocks

Where username@hostname is replaced with your username and hostname. This proves that you are using your own kernel. Now do check that some modules are being used:

        chromebook$ lsmod
        Module                  Size  Used by
        rfcomm                 24189  4 
        uvcvideo               62616  0 
        videobuf2_vmalloc       2941  1 uvcvideo
        mcs7830                 5683  0 
        usbnet                 14225  1 mcs7830
        isl29018                7782  0 
        joydev                  8791  0 
        industrialio           15248  1 isl29018
        btmrvl_sdio             8602  0 
        mwifiex_sdio           14642  0 
        sbs_battery             7117  0 
        mwifiex               109577  1 mwifiex_sdio
        cfg80211              167815  1 mwifiex
        btmrvl                 12715  1 btmrvl_sdio
        bluetooth             178735  22 btmrvl,rfcomm,btmrvl_sdio
        lib80211                3707  1 mwifiex
        uinput                  6922  0

Note that the modules usbnet and mcs7830 are the modules loaded to handle the USB-to-ethernet dongle. It is likely that you will not see these modules if your dongle is of a different type (different vendor or model). You should then try to identify which modules are needed for your specific hardware, as this will be useful later.

Notice also that in the dmesg log you should get a number of lines like:

        [   14.840425] Chromium OS LSM: init_module old-api-locking-ignored module= pid=1 cmdline="/init"

These indicate that the kernel module loading restriction is disabled.

Downloading and patching the Android filesystem

Get familiar with the Android build mechanisms by reading instructions, which explains how to setup your desktop machine correctly.  Also, have a look at these instructions explaining how to retrieve the sources (e.g. how to install the repo utility and how to use it). Once you are familiar with these instructions, checkout the Android filesystem with the following:

        desktop-pc$ mkdir -p $ANDROID && cd $ANDROID
        desktop-pc$ repo init -u https://android.googlesource.com/platform/manifest -b jb-mr1.1-dev
        desktop-pc$ repo sync

Here and in what follows I assume that $ANDROID is the directory where you want to download the Android sources.

The sync will take a while. Now apply the patches listed on Linux for the "Jelly Bean MR1" release. Only apply the patches. Do not decompress the tarball given in that page, but instead use the tarball given.. After decompressing this tarball inside the device directory, the new target samsung_xe303c12 is added to the Android build system.

Next, you should patch some of the files in the Android filesystem.  Details about how to do this are given in the next sections: Adjusting the screen set up, Getting wpa_supplicant to compile and Adjusting init.rc to load extra modules and use the network.

     

Adjusting the screen set up

You may have to modify the Android sources in order to have Android render graphics properly. The problem is that the hardware in the Samsung Chromebook expects pixels to be in the format BGR, while Android expects to use the RGB pixel format. If this is the case, logcat will report the following in the output (log.txt) of adb logcat -d -f log.txt:

        [...]
        W/SurfaceFlinger(  101): no suitable EGLConfig found, trying without EGL_FRAMEBUFFER_TARGET_ANDROID
        W/SurfaceFlinger(  101): no suitable EGLConfig found, trying without EGL_RECORDABLE_ANDROID
        W/SurfaceFlinger(  101): no suitable EGLConfig found, trying with 16-bit color allowed
        E/SurfaceFlinger(  101): no suitable EGLConfig found, giving up
        [...]
      

Android can be hacked to use a BGR format. In the file frameworks/native/opengl/libagl/egl.cpp, locate the following code:

        static configs_t const gConfigs[] = {
           { config_0_attribute_list, NELEM(config_0_attribute_list) },
           { config_1_attribute_list, NELEM(config_1_attribute_list) },
           { config_2_attribute_list, NELEM(config_2_attribute_list) },
           { config_3_attribute_list, NELEM(config_3_attribute_list) },
           { config_4_attribute_list, NELEM(config_4_attribute_list) },
           { config_5_attribute_list, NELEM(config_5_attribute_list) },
           { config_6_attribute_list, NELEM(config_6_attribute_list) },
           { config_7_attribute_list, NELEM(config_7_attribute_list) },
        };

Add a new entry at the end of the table:

          { config_8_attribute_list, NELEM(config_8_attribute_list) },

Place the code below just before the definition of the gConfigs[] table to define the new pixel format:

          /* 32-bit BGRA */
          static config_pair_t const config_8_attribute_list[] = {
             { EGL_BUFFER_SIZE,     32 },
             { EGL_ALPHA_SIZE,       8 },
             { EGL_BLUE_SIZE,        8 },
             { EGL_GREEN_SIZE,       8 },
             { EGL_RED_SIZE,         8 },
             { EGL_DEPTH_SIZE,       0 },
             { EGL_CONFIG_ID,        2 },
             { EGL_NATIVE_VISUAL_ID, GGL_PIXEL_FORMAT_BGRA_8888 },
             { EGL_SURFACE_TYPE,     EGL_WINDOW_BIT|EGL_PBUFFER_BIT|EGL_PIXMAP_BIT },
          };

This entry was basically copied from config_4_attribute_list, with the difference that GGL_PIXEL_FORMAT_RGBA_8888 is replaced with GGL_PIXEL_FORMAT_BGRA_8888 (EGL_NATIVE_VISUAL_ID attribute). With this changes, logcat should give:

        [...]
        W/SurfaceFlinger(   99): no suitable EGLConfig found, trying without EGL_FRAMEBUFFER_TARGET_ANDROID
        W/SurfaceFlinger(   99): no suitable EGLConfig found, trying without EGL_RECORDABLE_ANDROID
        W/SurfaceFlinger(   99): EGL_SLOW_CONFIG selected!
        [...]

This fix was inspired by the following threads: http://comments.gmane.org/gmane.comp.handhelds.android.porting/521 and https://groups.google.com/forum/?fromgroups=#!topic/android-porting/rSttzZE9SBo.

     

Getting wpa_supplicant to compile

You should patch the file $ANDROID/external/wpa_supplicant_8/wpa_supplicant/src/drivers/driver_nl80211.c, or otherwise you may get a link error while building the Android filesystem. You should comment the line which sets the field driver_cmd, as shown below:

        //.driver_cmd = wpa_driver_nl80211_driver_cmd,

This change will disable some features of wpa_supplicant, but should not prevent the wireless from working.

     

Adjusting init.rc to load extra modules and use the network

The Samsung Chromebook does not have an ethernet port. If you need to connect to the internet you can use the built-in wireless. If wireless is not available, however, you may want to use an USB-to-ethernet dongle. In this section, I explain how to set this up.

Android boot can be customised through the init.rc file placed at the top of the Android filesystem.

The init.rc produced for PRODUCT-samsung_xe303c12-eng has been partially tailored for the Samsung Chromebook. In particular, there are a number of modules which are loaded in the kernel using the insmod command. You should add some additional lines for your USB-to-ethernet dongle. The required modules can be determined by inspecting the output of lsmod in Fedora or ChromeOS: boot without the dongle, type lsmod, connect the dongle, wait 5 seconds, retype lsmod and take note of which additional modules were loaded after the dongle was inserted.

In my case I had to add two insmod commands:

          [...]
              insmod /system/lib/modules/kernel/net/ipv6/netfilter/nf_conntrack_ipv6.ko
              insmod /system/lib/modules/kernel/net/netfilter/xt_mark.ko

          # The two lines below are the ones I had to add for my dongle:
              insmod /system/lib/modules/kernel/drivers/net/usb/usbnet.ko
              insmod /system/lib/modules/kernel/drivers/net/usb/mcs7830.ko
              #wait /nonexistentfile 60

The last line is commented, but you may want to uncomment it in order to pause Android for 60 seconds while it loads the modules. This may give you a possibility of seeing if the modules are loaded correctly. Note that getting the network setup right is rather important, as it allows using adb (the Android Debugging Bridge) which — in turn — allows debugging other issues the system may have.

To enable the wired ethernet, define a service by adding the following lines to the end of init.rc:

        service wired-ethernet /system/bin/netcfg eth0 dhcp
            oneshot

Next, tell Android to start the service on boot by adding the following to the end of the "on boot" section:

        start wired-ethernet

This line should follow the lines:

        class_start core
        class_start main

     

Building the Android filesystem

Build the sources as follows:

        desktop-pc$ cd $ANDROID
        desktop-pc$ source build/envsetup.sh
        desktop-pc$ make -j8 PRODUCT-samsung_xe303c12-eng

The output of the compilation is placed inside the directory $ANDROID/out/target/product/samsung_xe303c12/.  In particular, this directory contains two directories: root and system. These contain the files which — in the Android device — will be seen at the locations / and /system respectively.

Transferring the Android filesystem to the SD card

I here assume the partition of the SD card which is going to contain the Android filesystem has been mounted in /mnt/Android. Copy the Android filesystem you obtained in the section Building the Android filesystem onto the SD card:

        desktop-pc$ cp -a $ANDROID/out/target/product/samsung_xe303c12/root/* /mnt/Android
        desktop-pc$ cp -a $ANDROID/out/target/product/samsung_xe303c12/system/* /mnt/Android/system

Copy the firmware and modules directory from the Fedora partition:

        desktop-pc$ mkdir -p /mnt/Android/system/lib/modules
        desktop-pc$ cp -a /mnt/Fedora/lib/modules/3.4.0/* /mnt/Android/system/lib/modules/
        desktop-pc$ mkdir -p /mnt/Android/system/etc/firmware/
        desktop-pc$ cp -a /mnt/Fedora/lib/firmware/* /mnt/Android/system/etc/firmware/

Remember that the firmware directory was taken directly from the Chromebook.

You may also have to change the permission of the prop and rc files so that they can be written only by the owner:

        desktop-pc$ find /mnt/Android \( -name "*.prop" -o -name "*.rc" \) -print0 | xargs -0 chmod 0644

Check that the permissions of the module files are right; they should be, if you followed the instructions. If not:

        desktop-pc$ cd /mnt/Android/system/lib/modules
        desktop-pc$ find . -type f -print0 | xargs -0 chmod 0644

Now we need to setup the SD card so that Android is booted. Similarly to what was done in section Using the compiled kernel and modules with Fedora, create a file in /mnt/Fedora/home/guest/android-install-kernel.sh with the following content:

        echo "console=tty1 debug verbose root=/dev/mmcblk1p4 lsm.module_locking=0 init=/init rootwait rw" > /tmp/config

        vbutil_kernel \
          --pack=/tmp/outkernel \
          --keyblock=/usr/share/vboot/devkeys/kernel.keyblock \
          --version=1 \
          --signprivate=/usr/share/vboot/devkeys/kernel_data_key.vbprivk \
          --config=/tmp/config \
          --vmlinuz=/tmp/inkernel \
          --arch=arm
        dd if=/tmp/outkernel of=/dev/mmcblk1p2
        cgpt add -i 2 -S 1 -T 5 -P 15 -l kern-android /dev/mmcblk1
        rm /tmp/outkernel /tmp/inkernel /tmp/config

Make sure that the file kernel.itb is present in the directory /mnt/Fedora/home/guest/; it should be the case if you followed the instructions in section Using the compiled kernel and modules with Fedora.

Notice the init=/init option which tells the kernel to pass control to the init executable at the top directory in the Android filesystem. Similarly to what done for Fedora, boot the Chromebook and open a root shell. Once you enter the root shell, insert the SD card inside the Chromebook and do as follows:

        chromebook$ cd /tmp
        chromebook$ mount /dev/mmcblk1p3 /mnt
        chromebook$ cp /mnt/home/guest/kernel.itb inkernel
        chromebook$ cp /mnt/home/guest/android-install-kernel.sh .
        chromebook$ bash android-install-kernel.sh

The script installs the kernel inside the second partition of the SD card. It gives to this kernel priority 15, which is higher than the priority currently assigned to the Fedora kernel in partition /dev/mmcblk1p3 and is hence selected by the bootloader at boot. This means that, from now on, Android is booted rather than Fedora. In section Switching back to Fedora I explain how to change the priorities so that Fedora is booted again.

Next, type reboot to reboot the system and press CTRL+U at the white boot screen to trigger boot from SD card.

        chromebook$ reboot

Android should come up. It may take several minutes.  Graphics, keyboard, touchpad and wireless should all work.

Tips and tricks

I recommend to go to "Settings" and on the left menu scroll down (you can use the down arrow) and select "{} Developer options". On the right there is a checkbox "Stay awake" that you can tick in order to stop the device to go to standby.

Keep in mind that to turn off Android you can just press the power button and keep it pressed for a couple of seconds.

The wireless can be activated by clicking on the wireless symbol on the toolbox, which also contains other buttons for bluetooth, etc.  Wait a minute and Android should automatically detect the wireless and give you the chance of setting it up. Settings should be remembered in future boots.

Logging

Debugging Android can be a nightmare when adb is not available; you cannot easily open a shell or configure the system easily. The first thing to do is then to get the network to work, so that adb can be used. If the network is not working, then you may want to add the following two lines to your init.rc file:

        service logstuff /system/bin/logcat -f /mylogstuff
            oneshot

You can then start the service with

        start logstuff

This line starts the Android logging service and redirects its output to the file mylogstuff at the top of the Android filesystem. You can then boot your system, turn it off, take the SD card from the Chromebook and insert it in your PC to inspect the content of the file mylogstuff.

Using lines like:

        wait /filethatdoesnotexist {number of seconds}

Can also be handy to slow down the system while loading the modules so that you can see the output of these commands. Certainly not orthodox nor beautiful, but handy...

Checking that ADB works

In order to start the Android Debug Bridge, you can use the command below:

        desktop-pc$ adb kill-server
        desktop-pc$ ADBHOST=AAA.BBB.CCC.DDD adb devices

Where AAA.BBB.CCC.DDD is the IP address of the Android device. One way of getting the IP of your device (which works well if the device is connected to the same switch/router as your desktop PC) is to do as follows:

        desktop-pc$ sudo tcpdump -n -i eth0 'tcp port 54321'

This shows on the screen of your PC all the packets arriving-to/departing-from port 54321 on your desktop PC. You can then open the browser in the Android device and use as URL the IP address of your computer. For example, if your desktop PC has IP address (try ifconfig) XXX.YYY.ZZZ.WWW then enter as URL in the Android browser "XXX.YYY.ZZZ.WWW:54321" and press ENTER. tcpdump should show a line like:

        15:42:04.188811 IP AAA.BBB.CCC.DDD.51734 > XXX.YYY.ZZZ.WWW.54321: Flags
         [S], seq 3681918437, win 14600, options [mss 1460,sackOK,TS val 290000
         ecr 0,nop,wscale 7], length 0

Where AAA.BBB.CCC.DDD is the IP address of your device. You can now use this address as a value for ADBHOSTadb devices should then find your Android device:

        desktop-pc$ ADBHOST=... adb devices
        * daemon not running. starting it now on port 5037 *
        * daemon started successfully *
        List of devices attached
        emulator-5554   device

You can now use adb. For example,

  • adb shell allows to login inside the device,
  • adb shell logcat -d allows to see the log messages,
  • adb help explains how to use adb.

Opening a root terminal in Android

Download a terminal emulator app. For example, Jack Palevich's terminal emulator app. Install it remotely from your host using adb:

        desktop-pc$ adb install Term.apk
        desktop-pc$ adb shell # this opens a remote root shell
        adb-shell# cd /system/bin
        adb-shell# cp mksh mysh
        adb-shell# chown root:root mysh
        adb-shell# chmod 4775 mysh
        adb-shell# exit

Now open the terminal emulator app from the Chromebook and type /system/bin/mysh. You should now have root priviledges.

mysh is a copy of the default shell mksh which belongs to root, can be executed by everybody and has the setuid flag set.  The latter permission setting, in particular, means that whoever executes this executable will be treated as the root user. Remember to delete this file once you do not need it anymore, as it clearly represents a serious security hole (unauthenticated root access).

     

Switching back to Fedora

To switch back to Fedora you can use the cgpt utility.  From the ChromeOS shell, try cgpt show /dev/mmcblk1. This command should show a list of partitions with details about which kernel is installed in which partition, including the boot priorities.  To induce the bootloader to select the Fedora kernel, just type cgpt add -i 2 -P 5 /dev/mmcblk1. This command should reduce the priority of the Android kernel to 5, which is lower than the priority of the Fedora kernel (previously set to 10). On the next reboot, Fedora should come up.

Conclusions

This guide should allow you to boot Android on your Chromebook. You should be able to use it for browsing the web and run some apps. There are a number improvements that could be done to the system to provide a better user experience: audio, codecs for playing videos (e.g. YouTube), bluetooth support, tailored menus and configuration, security, etc.  All these improvements, including the release and maintainance of binary images, are outside the scope of this guide and are left to the good will of generous volunteers in the open source community.

Further reading

Anonymous