OpenBSD on the Chromebook Pixel 2015
joshua stein
jcs@(jcs.org|openbsd.org)
https://jcs.org/

Who's this guy?

I like OpenBSD and laptops

What is the Chromebook Pixel (2015)?

(Nothing special so far)

How is it different?

What works?

What doesn't work?

How did I get here?

Detour: x86 Chromebook boot (ChromeOS)

  1. Coreboot
  2. libpayload - Depthcharge
  3. vboot - verified Linux kernel boot
  4. ChromeOS

Detour: x86 Chromebook boot (OpenBSD)

  1. Coreboot
  2. libpayload - SeaBIOS
  3. MBR active partition / OpenBSD MBR
  4. OpenBSD boot(8)

Detour: SPI flash layout

$ fmap_decode bios.bin
fmap_signature="0x5f5f464d41505f5f" fmap_ver_major="1" fmap_ver_minor="0" fmap_base="0x0000000000000000" fmap_size="0x800000" fmap_name="FMAP" fmap_nareas="33" 
area_offset="0x00000000" area_size="0x00200000" area_name="SI_ALL" area_flags_raw="0x01" area_flags="static" 
area_offset="0x00000000" area_size="0x00001000" area_name="SI_DESC" area_flags_raw="0x01" area_flags="static" 
area_offset="0x00001000" area_size="0x001ff000" area_name="SI_ME" area_flags_raw="0x01" area_flags="static" 
area_offset="0x00200000" area_size="0x00600000" area_name="SI_BIOS" area_flags_raw="0x01" area_flags="static" 
area_offset="0x00200000" area_size="0x000f0000" area_name="RW_SECTION_A" area_flags_raw="0x01" area_flags="static" 
area_offset="0x00200000" area_size="0x00010000" area_name="VBLOCK_A" area_flags_raw="0x01" area_flags="static" 
area_offset="0x00210000" area_size="0x000b0000" area_name="FW_MAIN_A" area_flags_raw="0x01" area_flags="static" 
area_offset="0x002c0000" area_size="0x00010000" area_name="PD_MAIN_A" area_flags_raw="0x01" area_flags="static" 
area_offset="0x002d0000" area_size="0x0001ffc0" area_name="EC_MAIN_A" area_flags_raw="0x01" area_flags="static" 
area_offset="0x002effc0" area_size="0x00000040" area_name="RW_FWID_A" area_flags_raw="0x01" area_flags="static" 
area_offset="0x002f0000" area_size="0x000f0000" area_name="RW_SECTION_B" area_flags_raw="0x01" area_flags="static" 
area_offset="0x002f0000" area_size="0x00010000" area_name="VBLOCK_B" area_flags_raw="0x01" area_flags="static" 
area_offset="0x00300000" area_size="0x000b0000" area_name="FW_MAIN_B" area_flags_raw="0x01" area_flags="static" 
area_offset="0x003b0000" area_size="0x00010000" area_name="PD_MAIN_B" area_flags_raw="0x01" area_flags="static" 
area_offset="0x003c0000" area_size="0x0001ffc0" area_name="EC_MAIN_B" area_flags_raw="0x01" area_flags="static" 
area_offset="0x003dffc0" area_size="0x00000040" area_name="RW_FWID_B" area_flags_raw="0x01" area_flags="static" 
area_offset="0x003e0000" area_size="0x00010000" area_name="RW_MRC_CACHE" area_flags_raw="0x01" area_flags="static" 
area_offset="0x003f0000" area_size="0x00004000" area_name="RW_ELOG" area_flags_raw="0x01" area_flags="static" 
area_offset="0x003f4000" area_size="0x00004000" area_name="RW_SHARED" area_flags_raw="0x01" area_flags="static" 
area_offset="0x003f4000" area_size="0x00002000" area_name="SHARED_DATA" area_flags_raw="0x01" area_flags="static" 
area_offset="0x003f6000" area_size="0x00002000" area_name="VBLOCK_DEV" area_flags_raw="0x01" area_flags="static" 
area_offset="0x003f8000" area_size="0x00002000" area_name="RW_VPD" area_flags_raw="0x01" area_flags="static" 
area_offset="0x003fa000" area_size="0x00006000" area_name="RW_UNUSED" area_flags_raw="0x01" area_flags="static" 
area_offset="0x00400000" area_size="0x00200000" area_name="RW_LEGACY" area_flags_raw="0x01" area_flags="static" 
area_offset="0x00600000" area_size="0x00200000" area_name="WP_RO" area_flags_raw="0x01" area_flags="static" 
area_offset="0x00600000" area_size="0x00004000" area_name="RO_VPD" area_flags_raw="0x01" area_flags="static" 
area_offset="0x00604000" area_size="0x0000c000" area_name="RO_UNUSED" area_flags_raw="0x01" area_flags="static" 
area_offset="0x00610000" area_size="0x001f0000" area_name="RO_SECTION" area_flags_raw="0x01" area_flags="static" 
area_offset="0x00610000" area_size="0x00000800" area_name="FMAP" area_flags_raw="0x01" area_flags="static" 
area_offset="0x00610800" area_size="0x00000040" area_name="RO_FRID" area_flags_raw="0x01" area_flags="static" 
area_offset="0x00610840" area_size="0x000007c0" area_name="RO_FRID_PAD" area_flags_raw="0x01" area_flags="static" 
area_offset="0x00611000" area_size="0x000ef000" area_name="GBB" area_flags_raw="0x01" area_flags="static" 
area_offset="0x00700000" area_size="0x00100000" area_name="BOOT_STUB" area_flags_raw="0x01" area_flags="static" 

Detour: Coreboot layout (BOOT_STUB)

$ cbfstool bios.bin print
bios.bin: 8192 kB, bootblocksize 2864, romsize 8388608, offset 0x700000
alignment: 64 bytes, architecture: x86

Name                           Offset     Type         Size
cmos_layout.bin                0x700000   cmos_layout  1164
pci8086,0406.rom               0x7004c0   optionrom    65536
spd.bin                        0x710500   (unknown)    4096
cpu_microcode_blob.bin         0x711540   microcode    70720
fallback/romstage              0x722a00   stage        54226
fallback/ramstage              0x72fe40   stage        96717
config                         0x747880   raw          6075
fallback/vboot                 0x749080   stage        15980
fallback/refcode               0x74cf40   stage        75591
fallback/payload               0x75f6c0   payload      221615
u-boot.dtb                     0x7958c0   (unknown)    5318
(empty)                        0x796dc0   null         37336
mrc.bin                        0x79ffc0   (unknown)    223640
(empty)                        0x7d69c0   null         166552

Detour: SeaBIOS layout (RW_LEGACY)

$ cbfstool rw_legacy.bin print
rw_legacy.rom: 2048 kB, bootblocksize 64, romsize 2097152, offset 0x0
alignment: 64 bytes, architecture: x86

Name                           Offset     Type         Size
payload                        0x0        payload      53207
pci8086,0406.rom               0xd000     optionrom    28160
links                          0x13e40    raw          796
bootorder                      0x141c0    raw          465
etc/boot-menu-key              0x143c0    raw          8
etc/boot-menu-message          0x14400    raw          28
etc/boot-menu-wait             0x14480    raw          8
(empty)                        0x144c0    null         2013848

Detour: ChromeOS partition layout (GPT)

Number  Start (sector)    End (sector)  Size       Code  Name
   1         8671232        10768383   1024.0 MiB  0700  STATE
   2           20480           53247   16.0 MiB    7F00  KERN-A
   3         4476928         8671231   2.0 GiB     7F01  ROOT-A
   4           53248           86015   16.0 MiB    7F00  KERN-B
   5          282624         4476927   2.0 GiB     7F01  ROOT-B
   6           16448           16448   512 bytes   7F00  KERN-C
   7           16449           16449   512 bytes   7F01  ROOT-C
   8           86016          118783   16.0 MiB    0700  OEM
   9           16450           16450   512 bytes   7F02  reserved
  10           16451           16451   512 bytes   7F02  reserved
  11              64           16447   8.0 MiB     FFFF  RWFW
  12          249856          282623   16.0 MiB    EF00  EFI-SYSTEM
  13        10768384       125045390   54.5 GiB    A600  OpenBSD

Two kernel partitions (KERN-A and KERN-B) so one can be updated and set active (via GPT attributes), but if it fails to boot, vboot will flip back to the previous kernel

OpenBSD on the HP Chromebook 13

That's all... now what?

Debugging OpenBSD boot (blind)

Why does our console stop working?

So let's also draw on Coreboot's framebuffer

Coreboot puts a table in memory at 0x0 that identifies each device (log buffer, framebuffer, etc.)

jcs@pixie:~/code/coreboot/util/cbmem> sudo ./cbmem -lV
Looking for coreboot table at 0 1048576 bytes.
Mapping 1MB of physical memory at 0x0.
Found!
  coreboot table entry 0x11
    Found forwarding entry.
Unmapping 1MB of virtual memory at 0x1fc28fe7f000.
Looking for coreboot table at 7ce3a000 1048576 bytes.
Mapping 1MB of physical memory at 0x7ce3a000.
Found!
  coreboot table entry 0x01
    Found memory map.
      LB_MEM_TABLE found.
      LB_MEM_TABLE found.
  coreboot table entry 0x03
  coreboot table entry 0x04
  coreboot table entry 0x05
  coreboot table entry 0x06
  coreboot table entry 0x07
  coreboot table entry 0x08
  coreboot table entry 0x09
  coreboot table entry 0x0a
  coreboot table entry 0x12
    Found framebuffer @ d0000000 1280x850 with 16 bpp (stride 16)
  coreboot table entry 0x21
  coreboot table entry 0x13
  coreboot table entry 0x15
[...]

So let's also draw on Coreboot's framebuffer

Back to installing OpenBSD on the Pixel

Finally booting OpenBSD from sd0

Detour: Chrome Embedded Controller

Detour: Chrome Embedded Controller

Finally booting OpenBSD from sd0

Touchpad and Touchscreen

Suspend and Resume

Suspend and Resume - TPM

Back to Touchpad and Touchscreen

Touchpad and Touchscreen Working

Ambient Light Sensor

Back to the Chrome EC

So what still doesn't work?

The End


More technical info available at
https://jcs.org/pixel