Skip to content

Commit 1e583e0

Browse files
authored
Merge pull request #1661 from tlaurion/wip-nix-for-build
Move to nix buildstack (and nix develop produced docker image used under CircleCI)
2 parents 77f1e34 + ecbfdbc commit 1e583e0

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

78 files changed

+990
-281
lines changed

.circleci/config.yml

Lines changed: 113 additions & 118 deletions
Large diffs are not rendered by default.

.envrc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
has nix && use flake

.gitignore

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,25 @@
1-
.*.sw*
2-
*.xz
1+
*.bad
32
*.bz2
3+
*.cpio
4+
*.dep
5+
*.ffs
6+
*.fv
47
*.gz
5-
*.sign
6-
*.rom
7-
*.o
8-
*.gz
9-
*.tgz
108
*.img
11-
*.rom
12-
*.cpio
13-
typescript*
14-
config/*.old
159
*.log
16-
*~
17-
crossgcc
18-
clean
10+
*.lz
11+
*.o
12+
*.rom
1913
*.sec
20-
*.dep
21-
*.ffs
14+
*.sign
15+
*.tgz
2216
*.vol
23-
*.lz
24-
*.fv
25-
*.bad
17+
*.xz
18+
*~
19+
.*.sw*
20+
/.direnv
21+
clean
22+
config/*.old
23+
crossgcc
24+
typescript*
25+
result

Makefile

Lines changed: 70 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,48 @@ INSTALL = $(pwd)/install/$(CONFIG_TARGET_ARCH)
2525
log_dir = $(build)/log
2626
board_build = $(build)/$(BOARD)
2727

28+
29+
# Estimated memory required per job in GB (e.g., 1GB for gcc)
30+
MEM_PER_JOB_GB ?= 1
31+
2832
# Controls how many parallel jobs are invoked in subshells
29-
CPUS ?= $(shell nproc)
30-
MAKE_JOBS ?= -j$(CPUS) --max-load 16
33+
CPUS ?= $(shell nproc)
34+
AVAILABLE_MEM_GB ?= $(shell cat /proc/meminfo | grep MemAvailable | awk '{print int($$2 / 1024)}')
35+
36+
# Calculate the maximum number of jobs based on available memory
37+
MAX_JOBS_MEM := $(shell echo $$(( $(AVAILABLE_MEM_GB) / $(MEM_PER_JOB_GB) )))
38+
39+
# Use the minimum of the system's CPUs and the calculated max jobs based on memory
40+
CPUS := $(shell echo $$(($(CPUS) < $(MAX_JOBS_MEM) ? $(CPUS) : $(MAX_JOBS_MEM))))
41+
42+
# Load average can be adjusted to be higher than CPUS to allow for some CPU overcommit
43+
# Multiply by 3 and then divide by 2 to achieve the effect of multiplying by 1.5 using integer arithmetic
44+
LOADAVG ?= $(shell echo $$(( ($(CPUS) * 3) / 2 )))
45+
46+
# Construct MAKE_JOBS with dynamic CPU count and load average
47+
MAKE_JOBS := -j$(CPUS) --load-average=$(LOADAVG) # Add other flags as needed to be more adaptive to CIs
48+
49+
# Print out the settings and compare system values with actual ones used
50+
$(info ----------------------------------------------------------------------)
51+
$(info !!!!!! BUILD SYSTEM INFO !!!!!!)
52+
$(info System CPUS: $(shell nproc))
53+
$(info System Available Memory: $(AVAILABLE_MEM_GB) GB)
54+
$(info System Load Average: $(shell uptime | awk '{print $$10}'))
55+
$(info ----------------------------------------------------------------------)
56+
$(info Used **CPUS**: $(CPUS))
57+
$(info Used **LOADAVG**: $(LOADAVG))
58+
$(info Used **AVAILABLE_MEM_GB**: $(AVAILABLE_MEM_GB) GB)
59+
$(info ----------------------------------------------------------------------)
60+
$(info **MAKE_JOBS**: $(MAKE_JOBS))
61+
$(info )
62+
$(info Variables available for override (use 'make VAR_NAME=value'):)
63+
$(info **CPUS** (default: number of processors, e.g., 'make CPUS=4'))
64+
$(info **LOADAVG** (default: 1.5 times CPUS, e.g., 'make LOADAVG=54'))
65+
$(info **AVAILABLE_MEM_GB** (default: memory available on the system in GB, e.g., 'make AVAILABLE_MEM_GB=4'))
66+
$(info **MEM_PER_JOB_GB** (default: 1GB per job, e.g., 'make MEM_PER_JOB_GB=2'))
67+
$(info ----------------------------------------------------------------------)
68+
$(info !!!!!! Build starts !!!!!!)
3169

32-
WGET ?= wget
3370

3471
# Timestamps should be in ISO format
3572
DATE=`date --rfc-3339=seconds`
@@ -162,6 +199,7 @@ heads_cc := $(CROSS)gcc \
162199
-fdebug-prefix-map=$(pwd)=heads \
163200
-gno-record-gcc-switches \
164201
-D__MUSL__ \
202+
--sysroot $(INSTALL) \
165203
-isystem $(INSTALL)/include \
166204
-L$(INSTALL)/lib \
167205

@@ -230,12 +268,10 @@ all payload:
230268
FORCE:
231269

232270
# Copies config while replacing predefined placeholders with actual values
271+
# This is used in a command like 'this && $(call install_config ...) && that'
272+
# so it needs to evaluate to a shell command.
233273
define install_config =
234-
sed -e 's!@BOARD_BUILD_DIR@!$(board_build)!g' \
235-
-e 's!@BLOB_DIR@!$(pwd)/blobs!g' \
236-
-e 's!@BRAND_DIR@!$(pwd)/branding/$(BRAND_NAME)!g' \
237-
-e 's!@BRAND_NAME@!$(BRAND_NAME)!g' \
238-
"$1" > "$2"
274+
$(pwd)/bin/prepare_module_config.sh "$1" "$2" "$(board_build)" "$(BRAND_NAME)"
239275
endef
240276

241277
# Make helpers to operate on lists of things
@@ -783,6 +819,8 @@ $(board_build)/$(CB_OUTPUT_BASENAME)-gpg-injected.rom: $(board_build)/$(CB_OUTPU
783819
./bin/inject_gpg_key.sh --cbfstool "$(build)/$(coreboot_dir)/cbfstool" \
784820
"$(board_build)/$(CB_OUTPUT_FILE_GPG_INJ)" "$(PUBKEY_ASC)"
785821

822+
823+
#Dev cycles helpers:
786824
real.clean:
787825
for dir in \
788826
$(module_dirs) \
@@ -794,4 +832,28 @@ real.clean:
794832
done
795833
cd install && rm -rf -- *
796834
real.gitclean:
835+
@echo "Cleaning the repository using Git ignore file as a base..."
836+
@echo "This will wipe everything not in the Git tree, but keep downloaded coreboot forks (detected as Git repos)."
797837
git clean -fxd
838+
839+
real.gitclean_keep_packages:
840+
@echo "Cleaning the repository using Git ignore file as a base..."
841+
@echo "This will wipe everything not in the Git tree, but keep the 'packages' directory."
842+
git clean -fxd -e "packages"
843+
844+
real.remove_canary_files-extract_patch_rebuild_what_changed:
845+
@echo "Removing 'canary' files to force Heads to restart building board configurations..."
846+
@echo "This will check package integrity, extract them, redo patching on files, and rebuild what needs to be rebuilt."
847+
@echo "It will also reinstall the necessary files under './install'."
848+
@echo "Limitations: If a patch creates a file in an extracted package directory, this approach may fail without further manual actions."
849+
@echo "In such cases, Git will inform you about the file that couldn't be created as expected. Simply delete those files and relaunch the build."
850+
@echo "This approach economizes time since most build artifacts do not need to be rebuilt, as the file dates should be the same as when you originally built them."
851+
@echo "Only a minimal time is needed for rebuilding, which is also good for your SSD."
852+
@echo "*** USE THIS APPROACH FIRST ***"
853+
find ./build/ -type f -name ".canary" -print -delete
854+
find ./install/*/* -print -exec rm -rf {} +
855+
856+
real.gitclean_keep_packages_and_build:
857+
@echo "Cleaning the repository using Git ignore file as a base..."
858+
@echo "This will wipe everything not in the Git tree, but keep the 'packages' and 'build' directories."
859+
git clean -fxd -e "packages" -e "build"

README.md

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,87 @@ Please refer to [Heads-wiki](https://osresearch.net) for your Heads' documentati
2828

2929
Building heads
3030
===
31+
32+
Under QubesOS?
33+
====
34+
* Setup nix persistent layer under QubesOS (Thanks @rapenne-s !)
35+
* https://dataswamp.org/~solene/2023-05-15-qubes-os-install-nix.html
36+
* Install docker under QubesOS (imperfect old article of mine. Better somewhere?)
37+
* https://gist.github.com/tlaurion/9113983bbdead492735c8438cd14d6cd
38+
39+
Build docker from nix develop layer locally
40+
====
41+
42+
#### Set up Nix and flakes
43+
44+
* If you don't already have Nix, install it:
45+
* `[ -d /nix ] || sh <(curl -L https://nixos.org/nix/install) --no-daemon`
46+
* `. /home/user/.nix-profile/etc/profile.d/nix.sh`
47+
* Enable flake support in nix
48+
* `mkdir -p ~/.config/nix`
49+
* `echo 'experimental-features = nix-command flakes' >>~/.config/nix/nix.conf`
50+
51+
#### Build image
52+
53+
* Build nix developer local environment with flakes locked to specified versions
54+
* `nix --print-build-logs --verbose develop --ignore-environment --command true`
55+
* Build docker image with current develop created environment (this will take a while and create "linuxboot/heads:dev-env" local docker image:
56+
* `nix build .#dockerImage && docker load < result`
57+
58+
Done!
59+
60+
Your local docker image "linuxboot/heads:dev-env" is ready to use, reproducible for the specific Heads commit used and will produce ROMs reproducible for that Heads commit ID.
61+
62+
Jump into nix develop created docker image for interactive workflow
63+
=====
64+
`docker run -e DISPLAY=$DISPLAY --network host --rm -ti -v $(pwd):$(pwd) -w $(pwd) linuxboot/heads:dev-env`
65+
66+
67+
From there you can use the docker image interactively.
68+
3169
`make BOARD=board_name` where board_name is the name of the board directory under `./boards` directory.
3270

71+
72+
One such useful example is to build and test qemu board roms and test them through qemu/kvm/swtpm provided in the docker image.
73+
Please refer to [qemu documentation](targets/qemu.md) for more information.
74+
75+
Eg:
76+
```
77+
make BOARD=qemu-coreboot-fbwhiptail-tpm2 # Build rom, export public key to emulated usb storage from qemu runtime
78+
make BOARD=qemu-coreboot-fbwhiptail-tpm2 PUBKEY_ASC=~/pubkey.asc inject_gpg # Inject pubkey into rom image
79+
make BOARD=qemu-coreboot-fbwhiptail-tpm2 USB_TOKEN=Nitrokey3NFC PUBKEY_ASC=~/pubkey.asc ROOT_DISK_IMG=~/qemu-disks/debian-9.cow2 INSTALL_IMG=~/Downloads/debian-9.13.0-amd64-xfce-CD-1.iso run # Install
80+
```
81+
82+
Alternatively, you can use locally built docker image to build a board ROM image in a single call.
83+
84+
Eg:
85+
`docker run -e DISPLAY=$DISPLAY --network host --rm -ti -v $(pwd):$(pwd) -w $(pwd) linuxboot/heads:dev-env -- make BOARD=nitropad-nv41`
86+
87+
88+
Pull docker hub image to prepare reproducible ROMs as CircleCI in one call
89+
====
90+
```
91+
docker run -e DISPLAY=$DISPLAY --network host --rm -ti -v $(pwd):$(pwd) -w $(pwd) tlaurion/heads-dev-env:latest -- make BOARD=x230-hotp-maximized
92+
docker run -e DISPLAY=$DISPLAY --network host --rm -ti -v $(pwd):$(pwd) -w $(pwd) tlaurion/heads-dev-env:latest -- make BOARD=nitropad-nv41
93+
```
94+
95+
Maintenance notes on docker image
96+
===
97+
Redo the steps above in case the flake.nix or nix.lock changes. Then publish on docker hub:
98+
99+
```
100+
docker tag tlaurion/heads-dev-env:vx.y.z tlaurion/heads-dev-env:latest
101+
docker push tlaurion/heads-dev-env:latest
102+
```
103+
104+
Notes:
105+
- Local builds can use ":latest" tag, which will use latest tested successful CircleCI run
106+
- To reproduce CirlceCI results, make sure to use the same versioned tag declared under .circleci/config.yml's "image:"
107+
108+
109+
110+
General notes on reproducible builds
111+
===
33112
In order to build reproducible firmware images, Heads builds a specific
34113
version of gcc and uses it to compile the Linux kernel and various tools
35114
that go into the initrd. Unfortunately this means the first step is a

bin/cpio-clean

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#!/usr/bin/perl
1+
#!/usr/bin/env perl
22
# Clean all non-deterministric fields in a newc cpio file
33
#
44
# Items fixed:

bin/prepare_module_config.sh

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
#! /usr/bin/env bash
2+
3+
TEMPLATE="$1"
4+
RESULT="$2"
5+
BOARD_BUILD="$3"
6+
BRAND_NAME="$4"
7+
8+
repo="$(realpath "$(dirname "${BASH_SOURCE[0]}")/..")"
9+
# For both coreboot and Linux, the config file is in a board-
10+
# specific build directory, but the build occurs from the
11+
# parent of that directory.
12+
module_dir="$(realpath "$(dirname "$2")/..")"
13+
14+
# Use relative paths since the config may be part of the ROM
15+
# artifacts, and relative paths won't depend on the workspace
16+
# absolute path.
17+
board_build_rel="$(realpath --relative-to "$module_dir" "$BOARD_BUILD")"
18+
repo_rel="$(realpath --relative-to "$module_dir" "$repo")"
19+
20+
echo "board_build_rel=$board_build_rel"
21+
echo "repo_rel=$repo_rel"
22+
23+
sed -e "s!@BOARD_BUILD_DIR@!${board_build_rel}!g" \
24+
-e "s!@BLOB_DIR@!${repo_rel}/blobs!g" \
25+
-e "s!@BRAND_DIR@!${repo_rel}/branding/$BRAND_NAME!g" \
26+
-e "s!@BRAND_NAME@!$BRAND_NAME!g" \
27+
"$TEMPLATE" > "$RESULT"

bin/verity-sign

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#!/usr/bin/perl
1+
#!/usr/bin/env perl
22
# Generate dm-verity hashes and sign the root hash
33
#
44
# Output looks like

blobs/haswell/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
mrc.bin

blobs/haswell/obtain-mrc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#!/bin/bash
1+
#!/usr/bin/env bash
22

33
set -e
44

blobs/p8z77-m_pro/download_BIOS_clean.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#!/bin/bash
1+
#!/usr/bin/env bash
22
# P7 ASUS
33

44
function printusage {

blobs/t420/extract.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#!/bin/bash
1+
#!/usr/bin/env bash
22

33
function printusage {
44
echo "Usage: $0 -f <romdump> -m <me_cleaner>(optional) -i <ifdtool>(optional)"

blobs/t440p/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
me.bin

blobs/t440p/download-clean-me

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#!/bin/bash
1+
#!/usr/bin/env bash
22

33
set -e
44

blobs/t440p/extract

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#!/bin/bash
1+
#!/usr/bin/env bash
22

33
set -e
44

blobs/w541/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
me.bin

blobs/w541/download-clean-me

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#!/bin/bash
1+
#!/usr/bin/env bash
22

33
set -e
44

blobs/w541/extract

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#!/bin/bash
1+
#!/usr/bin/env bash
22

33
set -e
44

blobs/x220/extract.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#!/bin/bash
1+
#!/usr/bin/env bash
22

33
function printusage {
44
echo "Usage: $0 -f <romdump> -m <me_cleaner>(optional) -i <ifdtool>(optional)"

blobs/xx20/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
me.bin

blobs/xx20/download_parse_me.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#!/bin/bash
1+
#!/usr/bin/env bash
22

33
BLOBDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
44

blobs/xx20/me7_update_parser.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#!/usr/bin/python
1+
#!/usr/bin/env python
22

33
"""ME7 Update binary parser."""
44

blobs/xx30/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
me.bin

blobs/xx30/download_clean_me.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#!/bin/bash
1+
#!/usr/bin/env bash
22

33
function printusage {
44
echo "Usage: $0 -m <me_cleaner>(optional)"

blobs/xx30/download_clean_me_manually.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#!/bin/bash
1+
#!/usr/bin/env bash
22

33
function printusage {
44
echo "Usage: $0 -m <me_cleaner>(optional)"

blobs/xx30/extract.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#!/bin/bash
1+
#!/usr/bin/env bash
22

33
function printusage {
44
echo "Usage: $0 -f <romdump> -m <me_cleaner>(optional) -i <ifdtool>(optional)"

blobs/xx30/me_cleaner.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#!/usr/bin/python
1+
#!/usr/bin/env python
22

33
# me_cleaner - Tool for partial deblobbing of Intel ME/TXE firmware images
44
# Copyright (C) 2016-2018 Nicola Corna <[email protected]>

blobs/xx30/vbios_t530.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#!/bin/bash
1+
#!/usr/bin/env bash
22

33
BLOBDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
44
ROMPARSER="94a615302f89b94e70446270197e0f5138d678f3"

blobs/xx30/vbios_w530.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#!/bin/bash
1+
#!/usr/bin/env bash
22

33
BLOBDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
44
ROMPARSER="94a615302f89b94e70446270197e0f5138d678f3"

blobs/z220/.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
ifd.bin
2+
me.bin

0 commit comments

Comments
 (0)