You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
147 lines
5.4 KiB
Markdown
147 lines
5.4 KiB
Markdown
# Building Ownerboot
|
|
|
|
Ownerboot should work with any recent version of nixpkgs. By
|
|
default a tarball of a known-good nixpkgs commit will be downloaded;
|
|
you can override this with the `nixpkgs` or `pkgsFun` top-level
|
|
parameters.
|
|
|
|
To build ownerboot, execute one of the following three lines,
|
|
depending on which platform you want to build for:
|
|
|
|
```
|
|
nix-build --option trusted-public-keys "" src -A kgpe.image # kgpe-d16 AMD opteron
|
|
nix-build --option trusted-public-keys "" src -A am1i.image # am1-i AMD kabini
|
|
nix-build --option trusted-public-keys "" src -A kevin.image # Samsung chromebook rk3399 arm64
|
|
```
|
|
|
|
The `--option trusted-public-keys ""` tells nix not to trust binaries
|
|
signed by the people who run `nixos.org`. This is the simplest and
|
|
most effective way to force nix to build everything from source
|
|
(except nix itself and the compiler-which-compiles-your-compiler).
|
|
|
|
After a *lot* of compiling you should find a symbolic link `result` to
|
|
a directory containing the following files:
|
|
|
|
```
|
|
coreboot.rom # this is the flash image
|
|
flashrom.layout # this is a copy of the flash image's "partition table"
|
|
config # the Linux kernel .config
|
|
cmos.layout # layout of RTC NVRAM values (amd64 only)
|
|
cmos.default # default RTC NVRAM values (amd64 only)
|
|
```
|
|
|
|
## First Flash
|
|
|
|
The first time you write ownerboot to your flash chip you don't have a
|
|
"known good" image to fall back to. So you need to save a copy of
|
|
your flash chip's contents, and make sure you know how to write it
|
|
back to the chip without booting your machine first (generally this
|
|
involves using an SPI clip or removing the flash chip from its socket).
|
|
|
|
Once you've done that, you can write the complete flash image
|
|
(bootblock, normal image, and fallback image) with one of the
|
|
following two commands.
|
|
|
|
```
|
|
# amd64
|
|
flashrom -p internal -w result/coreboot.rom
|
|
```
|
|
|
|
```
|
|
# rk3399-gru-kevin
|
|
flashrom -p linux_mtd -w result/coreboot.rom
|
|
```
|
|
|
|
Note that in both cases you will need to already have booted using a
|
|
bootloader which allows you to write to the flash chip. None of the
|
|
manufacturer bootloaders allow this, so if you aren't already using
|
|
coreboot your first flashing will need to be done with an SPI clip or
|
|
by removing the chip from its socket (if it is socketed).
|
|
|
|
If you're using an em100 to emulate a real flash chip, use the
|
|
following command instead. This should execute in 2-3 seconds instead
|
|
of the 20-30 seconds it takes to write to a flash chip:
|
|
|
|
```
|
|
nix-shell -p em100 --run \
|
|
'em100 -v --stop -c GD25Q128C --download result/coreboot.rom --start'
|
|
```
|
|
|
|
Once you've done this, cross your fingers, hold your breath, and
|
|
reboot.
|
|
|
|
## Testing Upgrades
|
|
|
|
### arm64
|
|
|
|
To overwrite *only the normal-boot image* on the `kevin` arm64
|
|
platform, use the following commands:
|
|
|
|
```
|
|
flashrom -p linux_mtd --fmap -i NORMAL -w coreboot.rom
|
|
```
|
|
|
|
The command above tells flashrom to read the "fmap descriptor" from
|
|
the chip before writing. An "fmap descriptor" is basically the flash
|
|
chip equivalent of a partition table. The `-i NORMAL` tells it to
|
|
read the `NORMAL` partition out of the `coreboot.rom` image and write
|
|
it to the `NORMAL` partition on your flash chip.
|
|
|
|
### amd64
|
|
|
|
AMD platforms require a rather unusual fmap descriptor format, with
|
|
nested partitions. This is needed for the AMD-supplied AEGSA code
|
|
(which is open source, but fragile enough that issues like this tend
|
|
to be worked around rather than fixed), which uses the outer partition
|
|
for SMRAM protection (a critical security requirement). Unfortunately
|
|
flashrom gets confused by these nested partition tables, so on that
|
|
platform you need to pass the partition table to flashrom explicitly,
|
|
in a format it understands, and with the outer partitions omitted. To
|
|
do this, execute the following command:
|
|
|
|
```
|
|
flashrom -p internal --layout result/flashrom.layout -i NORMAL -w result/coreboot.rom
|
|
```
|
|
|
|
## Accepting Upgrades
|
|
|
|
If all went well, you can write the now-known-good image to your
|
|
`FALLBACK` partition by using the same commands above, but replacing
|
|
`NORMAL` with `FALLBACK`.
|
|
|
|
## Recovery
|
|
|
|
If you flash a bad `NORMAL` image, you can switch to the `FALLBACK`
|
|
image several ways:
|
|
|
|
# arm64
|
|
|
|
Eject the stylus pen from the laptop and pull it all the way out before powering on the device. There is an internal sensor that detects if the stylus is inserted or not; ownerboot checks this sensor very early in the boot process.
|
|
|
|
You can also use the watchdog reboot to select the `FALLBACK` image; ownerboot examines the "reboot reason" register early in the boot process and takes it into account when selecting an image:
|
|
|
|
```
|
|
cat > /dev/watchdog # will block for a while, then hard reboot
|
|
```
|
|
|
|
# amd64
|
|
|
|
Connect the two motherboard pins designated as the "recovery jumper" before powering the machine on. I have these pins wired to the power switch on the front of my servers' chassis so I can use the power button as a recovery button.
|
|
|
|
You can also use the RTC NVRAM to force a `FALLBACK` image boot. The first command below selects the `Fallback` image; the second command reads back the value written so you can confirm that it was stored correctly.
|
|
|
|
```
|
|
nvramtool -y result/cmos.layout -w boot_option=Fallback
|
|
nvramtool -y result/cmos.layout -r boot_option
|
|
```
|
|
|
|
## Extracting the NORMAL/FALLBACK copy
|
|
|
|
If you want to extract one of the two copies of the bootloader, use
|
|
`cbfstool`:
|
|
|
|
```
|
|
cbfstool result/coreboot.rom read -r NORMAL -f primary.region.out
|
|
cbfstool result/coreboot.rom read -r FALLBACK -f fallback.region.out
|
|
```
|