Installing Android on the Samsung XE303C12 Chromebook

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.

Putting the Chromebook in developer mode

Booting into Recovery Mode is the first thing to do. This requires holding down the Esc and Refresh keys, while pressing the Power key.

It should now display a nice scary message that the installation is broken. This is of course a lie, so ignore it.

Pressing Ctrl-D now will start the switch into Developer Mode.

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.

The ChromeBook will reboot and tell you that verification is disabled.

Wait a short while, or press Ctrl-D, and it'll display another message that it is transitioning to Developer Mode.

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.

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):

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:

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.

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:

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:

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:

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.

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:

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:

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.

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

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:

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:

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:

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:

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.

Please, do consider that the installation of Android you get from this blog is just a starting point. I believe that some work is necessary to improve its usability. If you make any progress towards this, please feel free to share it here!

I have tried everything you said, as well as attempted to boot a pre built image (dd-ed onto the card) of kali, just to see if it would boot, and it still would not... any way you can upload the two kernels here and i can just put them on the card? or is that asking too much?

This document demonstrates how to call the JNI, through a procedure :written with the GNU ARM Assembly syntax,assembled and stored in a ELF shared library,executed by an Android system through an Android…