Xen ARM with Virtualization Extensions/Chromebook

Getting Xen on the Chromebook is not an easy task. There is no serial port, for this reason you need to boot Xen blindly and wait for Linux in dom0 to start the display for seeing valuable information. If you plan to add a serial port you could try this: please note that you will likely brick your Chromebook if you don't know exactly what you are doing. I'm not even sure this console port will actually display Xen boot information, so do it at your own risk, you have been advised! 
For some unknown reason, the chromebook keyboard does not work when running Linux under Xen. You will need an external USB keyboard once dom0 has booted.
You should probably take a look at the Xen ARM with Virtualization Extensions wiki page to get most of the information needed to develop on ARM.
== Running a simple Linux distribution ==
You should start with running a simple Linux on a SD card (not ChromeOS). There is plenty of doc on the internet, show your <your-favorite-search-engine>-skill. To simplify the Xen development, make sure to have 2 kernel partitions on your sd-card, so you will be able to switch between the Xen kernel and the Linux kernel with more ease.
There is some information about the ChromeOS Developer Mode and the boot sequence on their wiki page Samsung ARM Chromebook.
== Compilation ==
To compile both Linux and Xen, you will need a cross compile environment.
=== Linux ===
http://xenbits.xen.org/gitweb/?p=people/aperard/linux-chromebook.git
Tree based on the kernel tree from the ChromiumOS project.
Use this updated config file to compile the Linux kernel: the original one provided by Anthony (here) was missing some definitions that prevented Linux to boot on my Chromebook: given also other reports I think Samsung revised the hardware (e.g., my Chromebook erases the RAMOOPS memory after a keyboard-issued reset, while this does not seem to happen on older Chromebooks).
You MUST check the bootargument given to dom0. It's in arch/arm/boot/dts/cros5250-common.dtsi, and search for xen,dom0-bootargs, check in particular for the rootfs path.
You MUST apply this really short patch to the kernel source otherwise Linux will panic. The patch is just a quick-and-dirty fix to prevent Linux to panic: work needed!
 git clone git://xenbits.xen.org/people/aperard/linux-chromebook.git
 # cd to the tree and replace the .config with the one referred above, apply the patch!
 export CROSS_COMPILE=arm-unknown-linux-gnueabi-
 export ARCH=arm
 make zImage
 make dtbs
If your gcc complains about wrong arm instruction format, download this patch and apply it to the source.
=== Xen ===
http://xenbits.xen.org/gitweb/?p=people/aperard/xen-arm.git
Branch: chromebook-2013-03-22
And follow the guide to build Xen on ARM with the dtb found at linux.git/arch/arm/boot/exynos5250-snow.dtb (add CONFIG_DTB_FILE=/path/to/exynos5250-snow.dtb to make command line).
 git clone git://xenbits.xen.org/people/aperard/xen-arm.git
 # cd into xen-arm
 git fetch origin
 git checkout origin/chromebook-2013-03-22
 make dist-xen XEN_TARGET_ARCH=arm32 CONFIG_DTB_FILE="/path/to/exynos5250-snow.dtb"
(Anthony suggests to give a try to branch "master": it is a bit more recent and might contain useful commits, but don't expect it to work any better.)
=== mkimage ===
To start a kernel, the Chromebook need the kernel image to build in a specific manner.
So put the following "script" in a file, and replace the few paths to Xen and Linux images:
 /dts-v1/;
 / {
 description = "Chrome OS kernel image with one or more FDT blobs";
 #address-cells = <1>;
 images {
 kernel@1 {
 data = /incbin/("$path_to_xen_tree/xen/xen.bin");
 type = "kernel";
 arch = "arm";
 os = "linux";
 compression = "none";
 load = <0x80200000>;
 entry = <0x80200000>;
 };
 kernel@2 {
 data = /incbin/("$path_to_linux_tree/arch/arm/boot/zImage");
 type = "kernel_noload";
 arch = "arm";
 os = "linux";
 compression = "none";
 load = <0>;
 entry = <0>;
 };
 fdt@1 {
 description = "exynos5250-arndale.dtb";
 data = /incbin/("$path_to_linux_tree/arch/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";
 };
 };
 };
Then:
 mkimage -f "$path_to_the_previous_script" output_dir/xen-chromebook-image
In order to be validated, the image needs to be signed, which we will do using the developper keys. The most simple way is to do that under ChromeOS:
 vbutil_kernel --keyblock /usr/share/vboot/devkeys/kernel.keyblock --version 1 --signprivate /usr/share/vboot/devkeys/kernel_data_key.vbprivk --vmlinuz output_dir/xen-chomebook-image --arch arm --pack output_dir/signed-xen-chromebook-image
This long line have two arguments to be changed:
* output_dir/xen-chomebook-image is the image previously made by mkimage.
* output_dir/signed-xen-chromebook-image is where you want your signed image to be copied.
Once done, dd the image to the kernel partition you've dedicated to Xen (dd if=output_dir/signed-xen-chromebook-image of=/dev/mmcblk1pX).
Next step, ask the Chromebook to start Xen. You probably know about cgpt after you've installed your own linux:
 cgpt add -i X -P 15 -S 0 -T 1 /dev/mmcblk1
Here, we ask to start the Xen kernel partition, we set the highest priority (15), and it will be only started once (-S success=0, -T tries=1). On a reboot, your linux should be back.
== Debug ==
In my ArchLinux based environment Linux starts correctly under Xen: /proc/xen is populated and I think Xen tools should work even though I have not thoroughly tested them.
If you plan to work on a more recent tree, remember that Xen does not know how to drive the display, so you need Linux to boot and live for at least a couple of seconds to make the display code to properly start up the video interface. Even if the display is set up but Linux panics too early, then you will not see anything.
Even in the worst case however there is a workaround: both Xen and Linux trees referred above have been patched to dump console information into a specific RAM area (called RAMOOPS) which is not overwritten by ChromeOS when rebooting after a panic: you can read the console by getting a shell in ChromeOS and doing
 more /dev/pstore/dmesg-ramoops-0
You can also read that if you reboot into Linux (no Xen of course) by doing
 mount -t pstore xenlog /mnt
 less /mnt/dmesg-ramoops-0
Remember that at least on my Chromebook issuing "reload"+"power" has the same effect as power off and restart, the RAMOOPS gets corrupted. To avoid this you should manually place somewhere a softreset line BEFORE panic (e.g., use "emergency_restart();" on Linux). This could be a problem if panic happens before "emergency_restart();" can be called, or if it's Xen to panic. What I did was to write 0x01010101 to address 0x10040400 BEFORE paging (both in Xen and Linux): after paging is enabled you have to reserve a page to cover the same address and use the virtual address to do a softreset. If panic happens really early, then the boot code does not know how to redirect console into RAMOOPS, you have to write info by yourself there.
== Another way, using chained u-boot ==
TO WRITE
== Ressource ==
The ChromiumOS project.
http://www.chromium.org/chromium-os/how-tos-and-troubleshooting/using-an-upstream-kernel-on-snow
http://chromeos-cr48.blogspot.co.uk/, but not sure which posts are relevant.
Category:XenARM
Category:Developers
Category:Xen 4.3
Category:Xen 4.4