User:0xdc/Drafts/Samsung ARM Chromebook

From Gentoo Wiki
Jump to:navigation Jump to:search

The Samsung ARM Chromebook is the first generation of 11.6 inch Chromebook laptops built by Samsung.

The laptop features:

  • a dual-core Samsung Exynos5250 ARMv7-A (Cortex-A15) CPU with virtualisation extensions, clocked at 1.7GHz
  • 2GB RAM
  • 16GB eMMC flash
  • 11.6", 1366x768 (16:9 ratio), TN panel
  • One USB3 (Type-A) port
  • One USB2 (Type-A) port
  • One HDMI port
  • One SD card slot

At the time of writing, the ChromeOS Auto Update Expiry date was July 2018.

Installation options

You need to have the Chromebook in developer mode to run a custom Linux distribution.

Developer mode includes a shell that can be used to install a Gentoo system to a USB drive (or SD card for the Samsung ARM Chromebook).

By default, most of the ChromeOS filesystem is mounted read-only. While it is possible to make more of the system writable and persistant, locations such as /home and /mnt/stateful_partition are already writable.

If you have a prepared stage4, or are willing to build upon the upstream stage3, a bootable disk can be prepared from another machine. Once unpacked, you can chroot into the environment to customise it.

Hardware support

These instructions target ARM Chromebooks running the Samsung Exynos 5250 SoC in 11.6" laptop bodies, specifically the following:

Name a.k.a. codename/dtb board name base board
Samsung ARM Chromebook XE303C12, Series 3 snow daisy daisy
HP Chromebook 11 HP Chromebook 11 G1 spring daisy_spring snow

Bootable ports

Snow can boot from the USB2 port (the port closest to the HDMI port) and the SD card.

Snow cannot boot from the USB3 port.

Snow revisions

The XE303C12 has up to 5 revisions:

Revision ChromeOS dtb Mainline dtb
1, 2, 3, 4 exynos5250-snow-rev4.dtb exynos5250-snow.dtb
5 exynos5250-snow-rev5.dtb exynos5250-snow-rev5.dtb

First time setup

Entering developer mode

Warning

This action causes the laptop to wipe its disk and disable security protections

Instructions can be found on the chromium website.

Once rebooted, enable dev_usb_boot=1 with:

# enable_dev_usb_boot

Once set, operating systems can be booted from an SD card or USB storage device by pressing Ctrl-U on the startup warning screen.

Tip

If you want the Chromebook in Developer Mode but not run a custom kernel (e.g. crouton, which isn’t covered here), set dev_boot_signed_only=1 with crossystem.

Getting a shell

You can access a console window by pressing Ctrl+Alt+F2. The top row of function keys is equivalent to the Functionkeys, so it may be labelled as a Forward arrow (→). You can use Ctrl+Alt+F1 (Back, ←) to return to Aura. You can do this at any time once ChromeOS has booted.

If you log in as a guest (Browse as Guest) or with a Google Account, you can open a shell with Ctrl+Alt+T. From the crosh shell (prompt crosh>), use the shell command to get a shell as the user chronos.

chronos has sudo access to gain root privileges.

Neutering the warning screen (optional)

Warning

This requires the removal of the firmware write-protect screw

By default, the "scary" developer screen has a 30 second timeout and a loud beep. These can be neutered to a 3 second delay and no beep.

These changes persist even if the laptop is taken out of developer mode (i.e. back to secure ChromeOS mode).

Model Firmware write-protect screw location
Samsung ARM Chromebook Inside the case, near the HDMI port; remove the 5 visible screws on the bottom of the case and the 4 screws under the feet
HP Chromebook 11 Inside the case; remove screws from under the soft padding on the bottom of the laptop and pry open

The easy way

Use gbb_flags.sh:

# /usr/share/vboot/bin/set_gbb_flags.sh 0x11

Run gbb_flags.sh without arguments for a description of available flags.

The hard way

For full instructions, including backing up the firmware flash data, see these instructions (johnlewis.ie).

Cross-compiling

# crossdev -S -t armv7a-hardfloat-linux-gnueabi

When building the kernel, set the following environment variables:

ARCH=arm
CROSS_COMPILE=armv7a-hardfloat-linux-gnueabi-

To change the version of gcc to install, pass the flag --gcc <version>. See crossdev --help.

qemu user-mode emulation

# emerge --buildpkg -a qemu[static-user,qemu_user_targets_arm]
# mkdir stage3-armv7a
# tar xf stage3-armv7a_hardfp-latest.tar.bz2 -C stage3-armv7a
# ROOT=stage3-armv7a emerge --nodeps --oneshot --usepkgonly qemu

Because arm has a variety of possible CPU emulations, you will need to use a wrapper script to customise the CPU.

I recommend unpacking qemu into its own directory and copying that prepared directory into any arm chroots that you need (if you need a lot).

# ROOT=qemu emerge --nodeps --oneshot --usepkgonly qemu
# cd qemu
/*
 * pass arguments to qemu binary
 */

#include <string.h>
#include <unistd.h>

int main(int argc, char **argv, char **envp) {
        char *newargv[argc + 3];

        newargv[0] = argv[0];
        newargv[1] = "-cpu";
        newargv[2] = "cortex-a15";

        memcpy(&newargv[3], &argv[1], sizeof(*argv) * (argc -1));
        newargv[argc + 2] = NULL;
        return execve("/usr/bin/qemu-arm", newargv, envp);
}
# gcc -static qemu-wrapper.c -O3 -s -o qemu-wrapper
# cd ..
# echo ':arm:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x28\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/qemu-wrapper:' > /proc/sys/fs/binfmt_misc/register
# rsync -a qemu/ stage3-armv7a

You can then chroot, pychroot or systemd-nspawn as normal.

Building a kernel

Build requirements: @system bc u-boot-tools vboot-utils dtc

Kernel version Snow (Samsung) Spring (HP) config command
linux-4.14.y Yes No make exynos_defconfig
chromeos-3.8 Yes Yes (gcc-5.4.0-r4) ./chromeos/scripts/prepareconfig chromeos-exynos5

Note

ChromeOS 3.8 requires additional patches for gcc 4.9.4, 5.4.0-r4, 6.4.0 and 7.3.0.

Warning

However, a ChromeOS 3.8 kernel must be built with 5.4.0-r4.

# make zImage
# make dtbs
# make modules
/dts-v1/;
/ {
        description = "Chrome OS kernel image with one or more FDT blobs";
        #address-cells = ;
        images {
                kernel@1{
                        description = "kernel";
                        data = /incbin/("arch/arm/boot/zImage");
                        type = "kernel_noload";
                        arch = "arm";
                        os = "linux";
                        compression = "none";
                        load = ;
                        entry = ;
                };
                fdt@1{
                        description = "exynos5250-snow.dtb";
                        data = /incbin/("arch/arm/boot/dts/exynos5250-snow.dtb");
                        type = "flat_dt";
                        arch = "arm";
                        compression = "none";
                        hash@1{
                                algo = "sha1";
                        };
                };
                fdt@2{
                        description = "exynos5250-spring.dtb";
                        data = /incbin/("arch/arm/boot/dts/exynos5250-spring.dtb");
                        type = "flat_dt";
                        arch = "arm";
                        compression = "none";
                        hash@1{
                                algo = "sha1";
                        };
                };
        };
        configurations {
                default = "conf@1";
                conf@1{
                        description = "snow";
                        kernel = "kernel@1";
                        fdt = "fdt@1";
                };
                conf@2{
                        description = "spring";
                        kernel = "kernel@1";
                        fdt = "fdt@2";
                };
        };
};
# mkimage -f kernel.its kernel.itb
# tee cmdline <<<"console=tty1 debug verbose root=/dev/${DEVICE}2 rootwait ro"
# vbutil_kernel --pack exynos5.kpart \
  --keyblock /usr/share/vboot/devkeys/kernel.keyblock \
  --version 1 \
  --signprivate /usr/share/vboot/devkeys/kernel_data_key.vbprivk \
  --config cmdline \
  --bootloader cmdline \
  --vmlinuz kernel.itb \
  --arch arm
# dd if=exynos5.kpart of=/dev/${DEVICE}1

Prepare installation media

  • GPT partition table
  • SD card
    • Samsung ARM Chromebook only
    • Device is /dev/mmcblk1
    • Partitions are separated with p, e.g. /dev/mmcblk1p2
  • USB storage
    • Device is /dev/sda
  • Internal Storage
    • Device is /dev/mmcblk0
    • Factory shipped with ChromeOS

The minimum required partition layout is as follows:

Partition number Type Size
1 ChromeOS kernel ~8M
2 ext4 >3G

8MB is the size of a bootable kernel image. Additional space may need to be allocated to support an initramfs.

Depending on your partitioning tool, the type of the ChromeOS kernel partition may differ:

Tool ChromeOS kernel type is
fdisk 66
gdisk 7f00
* FE3A2A5D-4F32-41A7-B725-ACCC3285A309

Booting with nv-u-boot / upstream u-boot

While the stock firmware is capable of booting custom Operating Systems, it can have a number of strange quirks:

  • updating a kernel requires overwriting a ChromeOS kernel partition, which (depending on your partition layout) may be limited in number, or cause your system to fail to boot
  • in addition to the configured kernel command line, the firmware prepends the string "console= cros_secure"
  • embedded (e.g. ARM) developers may be more familiar with a u-boot environment to boot payloads

Google provide a version called nv-u-boot that can be booted like any other ChromeOS kernel, that boots to a u-boot prompt. Upstream u-boot also contains support for these boards.

The default nv-u-boot environment assumes a layout like this:

Partition number Type Size
1 ChromeOS kernel ~1M
2 ChromeOS kernel ~8M
3 ext2 ~256M
4 ext4 >3G

More info:

Customisations

make.conf

CFLAGS="-mfloat-abi=hard -mfpu=vfpv3-d16 -mtls-dialect=gnu -march=armv7ve -mtune=cortex-a15 -fstack-protector-strong"
CPU_FLAGS_ARM="edsp neon thumb vfp vfpv3 vfpv4 vfp-d32 v4 v5 v6 v7 thumb2"

Wireless networking

  • Driver: MWIFIEX_SDIO
  • Firmware: mrvl/sd8797_uapsta.bin
  • Software
    • iw
    • wpa_supplicant

/etc/wpa_supplicant/wpa_supplicant.conf:

ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=wheel
update_config=1

You can customise wpa_supplicant further or use wpa_cli as root or, if configured like above, as a user in the wheel group.

X11

/etc/X11/xorg.conf.d/10-keyboard.conf:

Section "InputClass"
        Identifier "Keyboard"
        MatchProduct "cros-ec-i2c" #XXX: Confirm product name
        MatchIsKeyboard "on"
        Option "XkbLayout" "gb"
        Option "XkbModel" "chromebook"
EndSection

Multi Format Codec (Hardware Video Encode/Decode Acceleration)

Caution

This has not been tested by the author and is here for reference

The Samsung SoC contains a hardware accelerated video encoder and decoder which requires a firmware blob and compatible software.

Firmware: s5p-mfc-v6.fw