From b48635fa1d26da9532fbfe5e746b69aa82f632ef Mon Sep 17 00:00:00 2001 From: Adam Joseph Date: Sun, 9 Apr 2023 21:08:45 -0700 Subject: [PATCH] src/main: init This commit adds several useful scripts (alongside the coreboot image) in a `main` expression, which should be the primary build expression going forward. The following scripts should exists on all platforms: - flashrom wrappers: - `flashrom.sh` - `flash-write-all.sh` - `flash-write-fallback.sh` - `flash-write-normal.sh` - scripts to select which image (normal or fallback) is used for the next boot: - `nextboot-show.sh` - `nextboot-use-fallback.sh` - `nextboot-use-normal.sh` - a script to write an image to the em100 flash-chip-emulator device: - `em100-write.sh` --- src/default.nix | 27 ++++++++++++++++ src/main/default.nix | 34 ++++++++++++++++++++ src/platform/common/amd64.nix | 58 ++++++++++++++++++++++++++++++++++ src/platform/common/arm64.nix | 13 ++++++++ src/platform/kevin/default.nix | 11 +++++++ 5 files changed, 143 insertions(+) create mode 100644 src/main/default.nix diff --git a/src/default.nix b/src/default.nix index e78bc9f..a1ab025 100644 --- a/src/default.nix +++ b/src/default.nix @@ -32,6 +32,33 @@ let userspace = final.callPackage ./userspace { }; initramfs = final.callPackage ./initramfs { }; flashrom = final.nixpkgsOnBuildForHost.callPackage ./util/flashrom { }; + main = final.callPackage ./main { }; + scripts = prev.scripts or { + # these are default values to be overridden + flashrom = throw "platforms must override this attribute"; + flash-write-fallback = throw "platforms must override this attribute"; + flash-write-normal = throw "platforms must override this attribute"; + flash-write-all = throw "platforms must override this attribute"; + nextboot-show = throw "platforms must override this attribute"; + nextboot-use-fallback = throw "platforms must override this attribute"; + nextboot-use-normal = throw "platforms must override this attribute"; + em100-write = + # currently weakly bound via $PATH because it is often + # useful to connect them em100 to a machine belonging to a + # totally different platform than the Device Under Test. + # TODO(amjoseph): don't hardwire the chip type here + '' + em100 -v --stop --holdpin float -c GD25Q128C --download ${final.coreboot}/coreboot.rom --start --trace + ''; + # + # TODO(amjoseph): add a sanity check that (a) the image being + # written to FALLBACK matches the image currently existing in + # NORMAL and (b) the most recent boot was from NORMAL. This + # ensures that the user cannot write an untested image to + # FALLBACK. I suppose in theory we also need to verify that + # NORMAL has not been written to since the most recent boot, but + # there's not simple way to check that. + }; }; in (lib.makeScope diff --git a/src/main/default.nix b/src/main/default.nix new file mode 100644 index 0000000..aec8d88 --- /dev/null +++ b/src/main/default.nix @@ -0,0 +1,34 @@ +# This is the "top level" derivation for an ownerboot build +{ nixpkgsOnBuildForHost +, nixpkgsOnBuildForBuild +, lib +, coreboot +, scripts +}: + +let + writeShellScript = name: text: + (nixpkgsOnBuildForHost.writeShellScript name text) + .overrideAttrs(previousAttrs: { + preferLocalBuild = true; + }); + +in nixpkgsOnBuildForHost.stdenv.mkDerivation (finalAttrs: { + name = "ownerboot"; + dontUnpack = true; + dontBuild = true; + installPhase = '' + runHook preInstall + + mkdir -p $out/{etc,bin} + ln -s ${coreboot}/coreboot.rom $out/ + ln -s ${coreboot}/config $out/etc/coreboot.config + ln -s ${coreboot.passthru.fmap} $out/etc/coreboot.fmap + + '' + (lib.concatStringsSep "\n" (lib.mapAttrsToList (scriptName: scriptText: '' + ln -s ${writeShellScript scriptName scriptText} $out/bin/${scriptName}.sh + + '') scripts)) + '' + runHook postInstall + ''; +}) diff --git a/src/platform/common/amd64.nix b/src/platform/common/amd64.nix index 859685f..ed264bf 100644 --- a/src/platform/common/amd64.nix +++ b/src/platform/common/amd64.nix @@ -7,5 +7,63 @@ if prev.hostPlatform != null then prev.hostPlatform else lib.systems.examples.gnu64; + + flashrom = prev.flashrom.override { + # AMD hardware expects to see an FMAP region called "BIOS" + # which covers the entire ROM image; flashrom doesn't like + # this overlapping so we have to patch it + overlappingFmapRegionSupport = true; + }; + + scripts = let + layoutFlags = + # Using `flashrom --fmap-file` is undesirable because + # there is no validation that the layout of the chip + # we are flashing matches the `flashrom.layout` file. + # If they don't match, bricking is likely. So please + # use the overlappingFmapRegionSupport patch, and ask + # the upstream maintainers to merge it. + if final.flashrom.passthru.overlappingFmapRegionSupport + then "--fmap" + else "--fmap-file ${final.fmap}"; + flashromScript = moreFlags: '' + set -euo pipefail + ${final.flashrom}/bin/flashrom -p internal ${layoutFlags} ${moreFlags} + ''; + flashromWriteScript = moreFlags: + flashromScript "-w ${final.coreboot}/coreboot.rom ${moreFlags}"; + nvramToolScript = moreFlags: '' + set -euo pipefail + ${final.nixpkgsOnBuildForHost.nvramtool}/bin/nvramtool -y ${final.coreboot}/cmos.layout ${moreFlags} + ''; + in prev.scripts // { + flashrom = flashromScript "$@"; + flash-write-fallback = flashromWriteScript "-i FALLBACK"; + flash-write-normal = flashromWriteScript "-i NORMAL"; + flash-write-all = flashromWriteScript ""; + nextboot-use-fallback = nvramToolScript "-w boot_option=Fallback"; + nextboot-use-normal = nvramToolScript "-w boot_option=Normal"; + nextboot-show = nvramToolScript "-n -r boot_option"; + + # FIXME(amjoseph): store the cmos.layout and cmos.default in + # the flash chip so we don't have to worry about + # desynchronization (parallel to --fmap-file concern above). + nvram-tool = nvramToolScript "$@"; + nvram-all-read = nvramToolScript "-a"; + nvram-all-write = nvramToolScript "-p $1"; + nvram-all-defaults = nvramToolScript "-p ${final.coreboot}/cmos.default"; + nvram-bootcount-show = nvramToolScript "-n -r reboot_counter"; + nvram-parameter-read = nvramToolScript "-n -r $1"; + nvram-parameter-choices = nvramToolScript "-e $1"; + nvram-checksum-read = nvramToolScript "-c"; + nvram-checksum-write = nvramToolScript "-c $1"; + }; + + main = prev.main.overrideAttrs(previousAttrs: { + # cmos nvram is an x86-ism + postInstall = (previousAttrs.postInstall or "") + '' + ln -s ${final.coreboot}/{cmos.layout,cmos.default} $out/etc/ + ''; + }); })]; } diff --git a/src/platform/common/arm64.nix b/src/platform/common/arm64.nix index 1653ea0..48aada2 100644 --- a/src/platform/common/arm64.nix +++ b/src/platform/common/arm64.nix @@ -7,5 +7,18 @@ if prev.hostPlatform != null then prev.hostPlatform else lib.systems.examples.aarch64-multiplatform; + scripts = let + flashromScript = moreFlags: '' + set -euo pipefail + ${final.flashrom}/bin/flashrom -p linux_mtd --fmap ${moreFlags} + ''; + flashromWriteScript = moreFlags: + flashromScript "-w ${final.coreboot}/coreboot.rom ${moreFlags}"; + in prev.scripts // { + flashrom = flashromScript "$@"; + flash-write-fallback = flashromWriteScript "-i FALLBACK"; + flash-write-normal = flashromWriteScript "-i NORMAL"; + flash-write-all = flashromWriteScript ""; + }; })]; } diff --git a/src/platform/kevin/default.nix b/src/platform/kevin/default.nix index 3176199..1a13b5f 100644 --- a/src/platform/kevin/default.nix +++ b/src/platform/kevin/default.nix @@ -112,5 +112,16 @@ in { flashrom = prev.flashrom.override { forChromebook = true; }; ectool = final.nixpkgsOnBuildForHost.callPackage (import ../../util/ectool { boardName = "kevin"; }) { }; + + scripts = let + notImplemented = '' + echo FIXME not implemented yet + exit -1 + ''; + in prev.scripts // { + nextboot-use-fallback = notImplemented; + nextboot-use-normal = notImplemented; + nextboot-show = notImplemented; + }; })]; }