linux3_0

Compiling custom kernel on Chromebook

WARNING: this article is unfinished, under revision and is not tested 100% yet. I do not issue any guarantee that this will work and maybe you can crash your system. I will update this article when all this process works fine. Keep in touch! Requeriments This guide assumes you’ve installed Ubuntu, Debian or another GNU/Linux distribution [...]





WARNING: this article is unfinished, under revision and is not tested 100% yet. I do not issue any guarantee that this will work and maybe you can crash your system. I will update this article when all this process works fine. Keep in touch!



Requeriments

This guide assumes you’ve installed Ubuntu, Debian or another GNU/Linux distribution on your Chromebook, and you’ve succesful installed a Chrome OS chroot environment on your local machine.
Please look at previous posts of this blog for install Ubuntu on your Chromebook, and follow this guide to install a Chrome OS chroot environment in your local machine: http://www.chromium.org/chromium-os/developer-guide

1. Install required packages for kernel compilation
If you are an experienced Linux user, you can skip this and go thru step 4.


First we update our package database:

CODE
sudo apt-get update

Then we install some needed packages like this:

CODE
sudo apt-get install ncurses-dev wget bzip2



2. Getting the source
We are going to work with last stable (when writing this article) kernel version (Linux 3.1.1). But you should check the last stable kernel here: http://www.kernel.org

CODE
sudo wget -P /usr/src http://www.kernel.org/pub/linux/kernel/v3.0/linux-3.1.1.tar.bz2

Then we unpack the kernel sources and create a symlink linux to the kernel sources directory:

CODE
cd /usr/src
sudo tar -xjvf linux-3.1.1.tar.bz2
sudo ln -s linux-3.1.1 linux
cd linux

3. Configuring and compiling the kernel
It’s a good idea to use the configuration of your current working kernel as a basis for your new kernel. After copying the .config file we run:

CODE
sudo make menuconfig

which brings up the kernel configuration menu. Go to Load an Alternate Configuration File and choose .config (which contains the configuration of your current working kernel) as the configuration file.

Configure the kernel at your choice, save and exit.

 Processor type and features  --->
     [*] Symmetric multi-processing support
         Processor family (Intel Atom)  --->
     [*] Enable DMI scanning
     [*] EFI runtime service support
 Power management and ACPI options  --->
     [*] Suspend to RAM and standby
     [*] Run-time PM core functionality
     CPU Frequency scaling  --->
         x86 CPU frequency scaling drivers  --->
             < *> ACPI Processor P-States driver
     -*- CPU idle PM support
 Bus options (PCI, PCMCIA, EISA, MCA, ISA) --->
     [*] PCI support
     [*] PCI Express support
 Networking --->
     <m>   Bluetooth subsystem support  --->
         Bluetooth device drivers  --->
             </m><m> HCI USB driver
     -*-   Wireless  --->
         </m><m>   cfg80211 - wireless configuration API
         [*]     enable powersave by default
         [*]     cfg80211 DebugFS entries
         [*]     cfg80211 wireless extensions compatibility
         {M}   Common routines for IEEE802.11 drivers
         </m><m>   Generic IEEE 802.11 Networking Stack (mac80211)
         [*]   Minstrel
         [*]     Minstrel 802.11n support
         [*]   Export mac80211 internals in DebugFS
 File systems  ---> 
     Partition Types  --->
         [*] Advanced partition selection
         [*]   EFI GUID Partition support
 Device Drivers --->
     SCSI device support  --->
         < *> SCSI disk support
     < *> Serial ATA and Parallel ATA drivers  --->
         [*]   ATA ACPI Support
         < *>   AHCI SATA support
         [*]   ATA SFF support
         [*]     ATA BMDMA support
         < *>       Intel ESB, ICH, PIIX3, PIIX4 PATA/SATA support
         < *>     Generic ATA support
     [*] Network device support  --->
         [*]   Wireless LAN  --->
             </m><m>   Atheros Wireless Cards  --->
                 [*]   Atheros wireless debugging
                 </m><m>   Atheros 802.11n wireless cards support
                 [*]     Atheros ath9k PCI/PCIe bus support
                 [*]     Atheros ath9k debugging
                 [*]     Atheros ath9k rate control
         Input device support  --->
             [*]   Mice  --->
                 < *>   PS/2 mouse
                 [*]     Synaptics PS/2 mouse protocol extension
             Hardware I/O ports  --->
                 -*- Serial I/O support
                 -*-   i8042 PC Keyboard controller
                 -*-   PS/2 driver library
                 < *>   Raw access to serio ports
         -*- I2C support  --->
             I2C Hardware Bus support  --->
                 </m><m> Intel 82801 (ICH/PCH)
     < *> Hardware Monitoring support  --->
         < *>   Intel Core/Core2/Atom temperature sensor
     -*- Generic Thermal sysfs driver  --->
         [*]   Hardware monitoring support
     </m><m> Multimedia support  --->
         [*]   Video capture adapters  --->
             </m><m>   Video For Linux
             [*]   V4L USB devices  --->
                 </m><m>   USB Video Class (UVC)
     Graphics support  --->
         < *> /dev/agpgart (AGP Support)  --->
             < *>   Intel 440LX/BX/GX, I8xx and E7x05 chipset support
         < *> Direct Rendering Manager (XFree86 4.1.0 and higher DRI support)  --->
             < *>   Intel 8xx/9xx/G3x/G4x/HD Graphics
             [*]     Enable modesetting on intel by default
         -*- Lowlevel video output switch controls
         [*] Backlight & LCD device support  --->
             -*-   Lowlevel Backlight controls
             < *>     Generic (aka Sharp Corgi) Backlight Driver
     < *> Sound card support  --->
         < *>   Advanced Linux Sound Architecture  --->
             [*]   PCI sound devices  --->
                 </m><m>   Intel HD Audio  --->
                     [*]   Build HDMI/DisplayPort HD-audio codec support
                     [*]   Aggressive power-saving on HD-audio
             [*]   USB sound devices  --->
                 </m><m>   USB Audio/MIDI driver
     [*] USB support  --->
         {*}   Support for Host-side USB
         [*]     USB runtime power management (autosuspend) and wakeup
         < *>   EHCI HCD (USB 2.0) support
         < *>   OHCI HCD support
         < *>   UHCI HCD (most Intel and VIA) support
         < *>   USB Mass Storage support
         < *>     Realtek Card Reader support
         [*]   The shared table of common (or usual) storage devices
</m>

Now we can to compile the kernel with ‘make‘, but we’re going to speed up the building process:
CODE
sudo make -j `cat /proc/cpuinfo | grep processor | wc -l`

This command `cat /proc/cpuinfo | grep processor | wc -l` will return the number of cores availables on your machine. So, make will run at most N jobs at time, taking full advantage of your multi-core CPU and RAM. Also we can use ccache to speed up the subsequent compilations by caching the object files, but we don’t cover this part on this article.
When the process finishes will generate a bzImage which we need to sign later.
4. Kernel parameters

I assume you’ve a GNU/Linux distribution running on your Chromebook, so we’re going to get the same kernel parameters that we’re using on our Chromebook device:

CODE
cat /proc/cmdline

Which returns something like this:
CODE
console=tty1 init=/sbin/init add_efi_memmap boot=local rootwait ro noresume noswap i915.modeset=1 loglevel=7 kern_guid=%U tpm_tis.force=1 tpm_tis.interrupts=0 root=/dev/sda7 noinitrd
Let’s save this parameters into a file that we need for signing the kernel image:
CODE
echo "console=tty1 init=/sbin/init add_efi_memmap boot=local rootwait ro noresume noswap i915.modeset=1 loglevel=7 kern_guid=%U tpm_tis.force=1 tpm_tis.interrupts=0 root=/dev/sda7 noinitrd” > config.txt


More easy: cat /proc/cmdline > config.txt, but you should check what parameters are you passing to kernel. 


Basically, you should change the kern_guid to %U, check if the rootfs path is correct, change the loglevel to 7 and check if console is tty1.

5. Build and sign the kernel image
Into our chroot environment we need to build and sign the kernel image like this:

CODE
vbutil_kernel –pack kern.bin \
    --keyblock /usr/share/vboot/devkeys/kernel.keyblock \
    --signprivate /usr/share/vboot/devkeys/kernel_data_key.vbprivk \
    --version 1 \
    --config config.txt \
    --vmlinuz bzImage \
    --bootloader /lib64/bootstub/bootstub.efi

6. Copying the kernel blob and prioritizing partitions
Now we’ve to copy the kernel blob on a valid kernel partition of our device. We are going to use KERN-C partition as /dev/sda6:

CODE
sudo dd if=kern.bin of=/dev/sda6

Now we want our kernel boots first, so we reprioritze this kernel partition:
CODE
sudo cgpt add -i 6 -P 15 -S 1 /dev/sda

This article isn’t finished yet and will be updated !!


Special thanks to Bill Richardson for help me understanding a lot of more the Chrome OS bootloader.