Shared publicly  - 
 
Building your own kernel and installing it in the Chromebook isn't
that hard, but there are a couple of extra steps needed.

The kernel resides in the boot partition, and it has to be signed for
the verified boot firmware to load and boot it. In developer mode,
it can be signed with any key though, including the default developer
keys provided on the Chrome OS filesystem.

To make life easier on Ubuntu, I copied over some of the tools from
Chrome OS. One of them needs libssl 0.9.8, so you need to install that:

# apt-get install libssl0.9.8

Then, the vbutil_kernel tool is used to pack and sign the kernel image
that is written to disk. You'll also want to install the keys, etc:

# mount -o ro /dev/mmcblk0p3 /mnt
# cp /mnt/usr/bin/vbutil_kernel /usr/bin
# rsync -a /mnt/usr/share/vboot /usr/share

There's also another tool that is convenient to have, dump_kernel_config.
It actually dumps the command line, not the kernel config, from a packed
kernel image. You can also use vbutil_kernel to do it, but this tool is
more practical for scripting. So, also:

# cp /mnt/usr/bin/dump_kernel_config /usr/bin

Also, if you haven't already copied over cgpt, do so now.

# cp /mnt/usr/bin/cgpt /usr/bin

And then, of course:

# umount /mnt

Now you have the tools you need on the filesystem. Just to make sure they
work, try verifying the current kernel on the disk. So:

# vbutil_kernel --verify /dev/mmcblk1p1

Now, configuring and building a kernel is something that I will mostly
skip over here. People like Marcin Juszkiewicz and others who clean up
my rough instructions and package things up for the distro will sort
most of that out. Just a couple of quick pointers:

The sources for the Chrome OS kernel are at
https://git.chromium.org/git/chromiumos/third_party/kernel.git. The
current active branch there is chromeos-3.4. To find the branch that
corresponds to the release that your Chromebook runs, see the release-R*
branches.

To generate the kernel config that we build with, besides getting it
from /boot on the Chrome OS filesystem, you can (in the source tree) run:

$ chromeos/scripts/prepareconfig chromeos-exynos5

It will create the .config file for you.

Then just use the regular distro build tools (make-kpkg), or just make
+ make_install. If you want/need to rebuild the kernel, you probably
know how to do these things already. If not, just use the kernel
copied over from Chrome OS.

The one thing I've done differently than the default build tools
is that I tend to also do a "make dtbs" and copy the contents from
arch/arm/boot/dts/*.dtb into /boot. The script below uses those paths
so revise accordingly if you don't do the same.

So, the kernel format used on ARM Chrom{e,ium} OS is a combined format
called FIT Image. It's produced by the mkimage u-boot tool, which is
provided by the u-boot-tools package on Ubuntu:

# apt-get install u-boot-tools

Then you need a source file (kernel.its). Mine contains:

/dts-v1/;

/ {
    description = "Chrome OS kernel image with one or more FDT blobs";
    #address-cells = <1>;
    images {
        kernel@1{
   description = "kernel";
            data = /incbin/("/boot/zImage");
            type = "kernel_noload";
            arch = "arm";
            os = "linux";
            compression = "none";
            load = <0>;
            entry = <0>;
        };
        fdt@1{
            description = "exynos5250-snow.dtb";
            data = /incbin/("/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, to create the binary kernel image, you do:

mkimage -f kernel.its kernel.itb

That creates kernel.itb as the binary image. Finally, you need to sign
this with the verified boot tools. You also need to specify the kernel
command line as part of this. The command to do so is:

$ echo "console=tty1 debug root=/dev/mmcblk1p3 rw rootwait" > config.txt

$ vbutil_kernel --pack /tmp/newkernel \
      --keyblock /usr/share/vboot/devkeys/kernel.keyblock \
      --version 1 \
      --signprivate /usr/share/vboot/devkeys/kernel_data_key.vbprivk \
      --config config.txt --vmlinuz kernel.itb --arch arm

Then you write out the newly generated kernel to disk. I use the second
kernel partition for my test kernels:

# dd if=/tmp/newkernel of=/dev/mmcblk1p2

Then you need to mark the second kernel partition bootable, and you need
to mark it as higher priority than the first kernel partition. Here is
where verified boot has a feature that is very convenient when you are
testing new kernels:

If you mark the kernel partition as higher priority, but don't set the
"successful" bit in the partition table, it will try to boot it as
many times as the "tries" field specifies, decrementing it each time.

This means that if I want to try booting a kernel just once, and if
that doesn't work, boot back to the known good kernel, I will set it to
something like:

# cgpt add -i 2 -P 15 -S 0 -T 1 /dev/mmcblk1

In other words: For partition index 2 (mmcblk1p2), set priority to 15,
successful to 0 and tries to 1. Since the first partition has priority
10, it means this will be tried first, as long as the tries counter is >0.

To see what your settings are, use:

# cgpt show -i 2 /dev/mmcblk1

(and compare with -i 1).

That mostly wraps up most of what I was planning on writing up so far.

Based on my descriptions here, it seems like some of the distro guys
have gotten enough going that they are mostly self sufficient. I'm of
course happy to help answer questions, and I want to make sure that the
platform is convenient to work on once we have upstreamed most of our
kernel changes over the upcoming months, but beyond that I'll leave most
of the polish and packaging up to others.
42
8
Marcin Juszkiewicz's profile photoPeter Robinson's profile photoIsrael Torres's profile photoMario Marietto's profile photo
47 comments
 
+Olof Johansson - hehe - sorry trolling you with the normal comments from random IRC users asking for help - "please give exact steps!"
 
Thanks for the steps +Olof Johansson. Do you know where the source for cgpt is? We've got vboot packaged up just need to package cgpt.
 
I would like to install my own root key to be able to skip the "scream and press key" on every boot.  I'm fine if it shows a different splash screen or whatever, but developer mode isn't very useful.
 
Doh!, thanks I missed it in the file listing
 
+H. Peter Anvin: you'll need to replace firmware to get away from that. It's one of the basic concepts of the security model to warn the user if the verification and chain of trust is not enforced, so it's not something we can just remove, unfortunately.
 
Has anyone managed to get a useful patch set that would enable one to rebase against 3.7? 
 
+Andrew Wafaa I've not yet, although my question would be what are the plans for pushing it upstream :)
 
+Andrew Wafaa: Doug Anderson is working on bringing up a mainline kernel on the platform now, and upstreaming the pieces needed.

There's quite a bit of work left to do, so I suggest practicing patience. 3.8 isn't a likely target for a fully working system at this time, but 3.9 is looking more promising. Basics such as serial and MMC is up, but there's a lot left.
 
+Olof Johansson oh I fully understand that it wont be upstream any time soon, I'm just grateful that work is under way to push it upstream. 

I suppose I was hoping that there would be an easy way to get say a 3.7 kernel running on the Chromebook seeing as the Arndale board works fine(ish) with upstream, and they're pretty close relatives.
 
Do you know if there's any way to instead of a kernel boot u-boot that can bootstrap itself on with sane zImages from an ext2 partition? :)
 
Nothing should stop you from loading a u-boot binary and launching that instead. It'll have to be wrapped up in a uImage, but that should be fine.

I think someone was looking at doing that, but I don't remember who.
 
Hrm. Interesting idea :). Let me give that a try. And if you happen to remember who wanted to look into that, please let me know!
 
Oh and if you have any debugging hints, I'd be more than happy to get those too ;)
 
#1 hint: Don't write bugs, debugging is a pain and avoid it if you can.
 
Lack of easily accessible serial ports definitely makes things harder. There's a debug header on the board that has an UART on it, but there's no connector soldered down on the mass-produced devices. The pads are right by the speaker plug by the SD slot.

We've talked about adding some ad-hoc way of at least wiggling some lines and get data out there through some other bus (or GPIO), but the options are somewhat limited.

tty serial console can get you a bit of the way, but it's obviously not going to fly for lowlevel debugging and early boot issues.
 
Yeah, I do manage to jump into u-boot, but it never gets to the point where it should be initializing the LCD. The Xen guys are using nvram for information transfer for their bringup - maybe I should do the same ;)
 
There's a region in memory we use for pstore across reboots, as long as you match the format you can reboot into a regular image and get to it after. That might be the easiest way to debug these things. I'll leave the format (and address) as an exercise for the reader, it's not hard to find out from a running system -- I don't have one next to me right now.
 
Hrm - odd. Apparently I don't get around to execute any code after all. Can I just take a random uImage, shove it through vbutil_kernel, dump it on the (cgpt properly set up) partition on the sd card and expect things to work?
 
Or put differently: If I use the above scheme but instead of using a zImage, I put in my u-boot.bin. It should be executed just as well, right? Either something's odd or my ARM asm foo isn't quite as well as it should be ;). I don't even manage to flip a bit of memory very early in the init code, so I most likely never get executed.
 
Nevermind, I can execute code now and debug it using the pstore region. Awesome :)
 
There we go. All green :). Thanks a lot for the hints! That pstore region hint was really awesome!
 
Olof, I was trying to find out if Linux was booted in non-secure mode. Reading the SCR.NS bit is possible and yields "0". However, Linux could be transparently handling the exception.

Can you confirm that Linux runs in secure mode on the Chromebook?

Thanks!
 
There is no secure monitor running on the chromebook, so you are indeed in non-secure mode.
 
+Olof Johansson I'm trying to build a Chromium OS image in the Chromium OS dev environment, and use the kernel from this image for Ubuntu. I've successfully built the image, and have located the vmlinuz kernel to be in chroot/build/daisy/boot.
Then I execute the step above with the vbutil_kernel command, on the vmlinuz image, and write it to the usual partition, but it won't boot :(. It boots into Chrome OS instead, presumably because it fails to boot and then defaults to Chrome OS after decrementing the "tries" counter for that partition.
Is there any reason this shouldn't work?
I've successfully booted the vmlinuz-3.4.0 kernel (the one that is in /boot on a running Chrome OS system) with an Ubuntu root fs using your instructions above.
 
Wow! I have been looking for this information for 2 days - wondering how to create a bootable kernel. Thanks!

+Arthy Sundaram From what I've read, there are out-of-tree patches to get upstream kernels working but the mainline is lacking major things such as display, sound, keyboard, and such. See: http://www.chromium.org/chromium-os/how-tos-and-troubleshooting/using-an-upstream-kernel-on-snow ... "What is known NOT to work" is dated Nov 2012. Maybe more stuff works now?
 
I’m trying to install the kernel 3.7 because I want to see how it works. According to your instructions I need to create the kernel binary file (itb file) starting from the kernel.its file. To do this I need to create the kernel.its like this :

root@localhost:/boot# nano kernel.its

/dts-v1/;

/ { description = “Chrome OS kernel image with one or more FDT blobs”;

address-cells = ;

images { kernel@1{ description = “kernel”; data = /incbin/(“/boot/zImage”); type = “kernel_noload”; arch = “arm”; os = “linux”; compression = “none”; load = ; entry = ; }; fdt@1{ description = “exynos5250-snow.dtb”; data = /incbin/(“/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″;}; }; };

root@localhost:/boot# mkimage -f kernel.its

kernel.itb sh: 1: dtc: not found mkimage: Can’t read kernel.itb.tmp: Invalid argument

this is the error I get,how can I fix it ? I have no idea…
 
you have to install the device tree compiler dtc. get the source and install it 
 
Can you write the exact steps please ? I miss something. thanks.
 
Hello.

I'm trying to boot Ubuntu using PXE from U-Boot on the Samsung XE303C12-A01US Chromebook. I would like to understand better the point 5 of the tutorial here :

https://wiki.linaro.org/Boards/Arndale/Setup/PXEBoot

it says : "At the u-boot prompt, set the environmental variables "serverip" and "ipaddr" as per the board and host PC configuration. Now set the following environmental variables as mentioned..."

the problem is that the Samsung XE303C12-A01US does not have a serial port and I can't stop the u-boot booting and set the enviromental variables manually. I would like to know how can I embed them inside u-boot. Also because there is not a configuration file like boot.cmd/boot.scr like there is on the pandaboard that can be used to pass the parameters. Thanks.
 
Do you know what support went into 3.9 please? Will the keyboard/display work for a console, or do I still need to crack the case open for serial?
 
Any chance this method can work for Android? I am looking to get android installed on at least the SDcard of a chromebook. I have been attempting using the arndale notes but even with the prebuilds insignal has posted it seems like incomplete information to get it working. I have had no luck getting it running. I am sure I am missing a critical piece. Thanks
 
trying to boot xubuntu saucy with kernel-next [3.8]. looking promising getting a black screen with movable mouse pointer ... ill hack it a bit futher.

+Tony Serrata should work the same with the newer kernels that have support for android in staging these options will need to be enabled in the kernel and the cmd line option point to the droid rootfs. i may try this out myself.
 
+Olof Johansson one thing in the default configs -Werror is enabled not sure in what universe the kernel will build without warnings at least with gcc 4.8.X there a lot more warnings generated.

also change -stack-protector-strong to -stack-protector-all in arch/arm/Makefile to use with gcc 4.8
 
http://malideveloper.arm.com/develop-for-mali/features/graphics-and-compute-development-on-samsung-chromebook/

+Marcin Juszkiewicz +Olof Johansson suspect you may have a hand in this thx for the fish .. will be awesome to get full graphics up.

quick tip for those worried about console the kernel-next works fine by the looks of it [the link with this message hopefully will get X11/3D working]. Using init=/bin/bash will drop you into a shell replacing init [pid 0] with a shell no way of hooking it up to the trusty epson rs232 line printer but works. you may need to remount rw and mount proc/sys manually "exec /sbin/init" will start up the system replacing the shell [pid 0] with init once again.
Add a comment...