First compiling version
This commit is contained in:
commit
3f38f87aad
668
build.sh
Normal file
668
build.sh
Normal file
@ -0,0 +1,668 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# use TERM to exit on error
|
||||||
|
trap "exit 1" TERM
|
||||||
|
export TOP_PID=$$
|
||||||
|
|
||||||
|
# coreboot repo
|
||||||
|
COREBOOT_REPO_PURISM="https://source.puri.sm/coreboot/coreboot.git"
|
||||||
|
COREBOOT_REPO_TAG="4.14-Purism-1"
|
||||||
|
|
||||||
|
# dependencies
|
||||||
|
DEPS_BASE=(dmidecode wget sha256sum gzip)
|
||||||
|
DEPS_FLASH=(git build-essential libpci-dev libudev-dev zlib1g-dev)
|
||||||
|
DEPS_FLASH_FEDORA=(git gcc g++ make xz bzip2 pciutils-devel)
|
||||||
|
DEPS_COREBOOT=(gnat m4 bison flex libncurses5-dev python python2)
|
||||||
|
DEPS_COREBOOT_FEDORA=(gcc-gnat bison flex ncurses-devel zlib-devel python python2 patch)
|
||||||
|
DEPS_GRUB2=(autoconf automake autopoint libfreetype-dev fonts-unifont)
|
||||||
|
DEPS_GRUB2_FEDORA=(autoconf automake gettext-devel freetype-devel unifont-fonts)
|
||||||
|
|
||||||
|
#local dirs
|
||||||
|
LOCAL_TOOLS_PATH="./tools"
|
||||||
|
LOCAL_FIRMWARE_PATH="./firmware"
|
||||||
|
LOCAL_TEMP_DIR="$(mktemp -d)"
|
||||||
|
|
||||||
|
# locally compiled coreboot utils
|
||||||
|
CBFSTOOL_CB="./coreboot/util/cbfstool/cbfstool"
|
||||||
|
IFDTOOL_CB="./coreboot/util/ifdtool/ifdtool"
|
||||||
|
|
||||||
|
# functions, functions, functions
|
||||||
|
|
||||||
|
check_root() {
|
||||||
|
if [[ "$EUID" != 0 ]]; then
|
||||||
|
die "This script must be run as root; re-run prefixed with sudo"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
print_info () {
|
||||||
|
|
||||||
|
clear
|
||||||
|
echo "################################################"
|
||||||
|
echo "## Purism Librem coreboot Utility "
|
||||||
|
echo "################################################"
|
||||||
|
if [[ "${LIBREM_MODEL^^}" != "UNKNOWN" ]]; then
|
||||||
|
model=${LIBREM_MODEL^}
|
||||||
|
echo "# Device: Librem ${model//_/ }"
|
||||||
|
echo "# Serial: ${DMIDECODE_SERIAL_NUMBER}"
|
||||||
|
echo "# Firmware: ${FW_TYPE_STRING}"
|
||||||
|
echo "# Version: ${CURRENT_FW_VER} ${CURRENT_FW_DATE}"
|
||||||
|
echo "################################################"
|
||||||
|
fi
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
initial_setup () {
|
||||||
|
|
||||||
|
# get model, firmware version, serial # via dmidecode
|
||||||
|
vendor=$(dmidecode -s bios-vendor)
|
||||||
|
model=$(dmidecode -s system-product-name | grep -i Librem)
|
||||||
|
CURRENT_FW_VER=$(dmidecode -s bios-version)
|
||||||
|
CURRENT_FW_DATE=$(dmidecode -s bios-release-date)
|
||||||
|
DMIDECODE_SERIAL_NUMBER=$(dmidecode -t 1 | grep "Serial Number" | cut -d' ' -f 3-)
|
||||||
|
# set CURRENT_FW_TYPE type
|
||||||
|
if [ "$vendor" = "coreboot" ]; then
|
||||||
|
case ${CURRENT_FW_VER^^} in
|
||||||
|
*"PUREBOOT"* )
|
||||||
|
CURRENT_FW_TYPE="HEADS";;
|
||||||
|
*"HEADS"* )
|
||||||
|
CURRENT_FW_TYPE="HEADS";;
|
||||||
|
*"GRUB2"* )
|
||||||
|
CURRENT_FW_TYPE="GRUB2";;
|
||||||
|
* )
|
||||||
|
CURRENT_FW_TYPE="STANDARD";;
|
||||||
|
esac
|
||||||
|
else
|
||||||
|
CURRENT_FW_TYPE="UNKNOWN"
|
||||||
|
fi
|
||||||
|
FW_UPDATE=""
|
||||||
|
case $CURRENT_FW_TYPE in
|
||||||
|
"HEADS" )
|
||||||
|
FW_TYPE_STRING="PureBoot (coreboot+Heads)"
|
||||||
|
CURR_FW_NUM=`echo ${CURRENT_FW_VER} | sed -e "s/^PureBoot-beta-//" -e "s/^PureBoot-Release-//"`
|
||||||
|
UPD_FW_NUM=`echo ${COREBOOT_HEADS_VERSION} | sed -e "s/^PureBoot-beta-//" -e "s/^PureBoot-Release-//"`
|
||||||
|
[[ "$UPD_FW_NUM" > "$CURR_FW_NUM" ]] \
|
||||||
|
&& FW_UPDATE=`echo ${COREBOOT_HEADS_VERSION} | tr '-' ' '`
|
||||||
|
CURRENT_FW_VER=`echo ${CURRENT_FW_VER#PureBoot-} | tr '-' ' '`
|
||||||
|
CURRENT_FW_DATE=""
|
||||||
|
;;
|
||||||
|
"STANDARD" )
|
||||||
|
FW_TYPE_STRING="Standard (coreboot+SeaBIOS)"
|
||||||
|
[[ "$COREBOOT_SEABIOS_VERSION" > "$CURRENT_FW_VER" ]] \
|
||||||
|
&& FW_UPDATE="$COREBOOT_SEABIOS_VERSION";
|
||||||
|
CURRENT_FW_DATE="(${CURRENT_FW_DATE})"
|
||||||
|
;;
|
||||||
|
"GRUB2" )
|
||||||
|
FW_TYPE_STRING="Grub2 (coreboot+Grub2)"
|
||||||
|
[[ "$COREBOOT_GRUB2_VERSION" > "$CURRENT_FW_VER" ]] \
|
||||||
|
&& FW_UPDATE="$COREBOOT_GRUB2_VERSION";
|
||||||
|
CURRENT_FW_DATE="(${CURRENT_FW_DATE})"
|
||||||
|
;;
|
||||||
|
|
||||||
|
|
||||||
|
* )
|
||||||
|
FW_TYPE_STRING="Unknown" ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# set LIBREM_MODEL, MODEL_INDEX
|
||||||
|
# strip leading 'librem' + space/underscore
|
||||||
|
model=`echo ${model,,} | sed -e "s/^librem//" -e "s/^ //" -e "s/^_//"`
|
||||||
|
case ${model} in
|
||||||
|
"14")
|
||||||
|
LIBREM_MODEL="14";
|
||||||
|
PLATFORM="CML";
|
||||||
|
MODEL_INDEX="9";;
|
||||||
|
*)
|
||||||
|
LIBREM_MODEL="unknown";
|
||||||
|
PLATFORM="UNK";
|
||||||
|
MODEL_INDEX="0";;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
cleanup() {
|
||||||
|
# ensure all files owned by calling/non-root user
|
||||||
|
chown -R -f $(logname). .
|
||||||
|
}
|
||||||
|
|
||||||
|
die () {
|
||||||
|
local msg=$1
|
||||||
|
|
||||||
|
if [ ! -z "$msg" ]; then
|
||||||
|
echo ""
|
||||||
|
echo -e "$msg"
|
||||||
|
echo ""
|
||||||
|
fi
|
||||||
|
kill -s TERM $TOP_PID
|
||||||
|
cleanup
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
get_flashrom () {
|
||||||
|
# check if flashrom exists on system
|
||||||
|
echo ""
|
||||||
|
echo "Checking for usable version of flashrom"
|
||||||
|
FLASHROM_CMD=$(which flashrom)
|
||||||
|
if [[ ! -z "$FLASHROM_CMD" && "$PLATFORM" != "CML" ]]; then
|
||||||
|
#check version
|
||||||
|
version=$($FLASHROM_CMD -R | awk -F" " '{print $2;exit}' | grep "1.")
|
||||||
|
if [[ "$version" > "v1.1" ]]; then
|
||||||
|
# verify build supports logging (some PureOS/Debian versions broken)
|
||||||
|
if $FLASHROM_CMD -L -o /tmp/flashrom.log >/dev/null 2>&1 ; then
|
||||||
|
#use system flashrom
|
||||||
|
echo "Found built-in flashrom version $version"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# no system flashrom, not version 1.2+, or PLATFORM == CML:
|
||||||
|
# build from upstream flashrom source
|
||||||
|
|
||||||
|
# check deps first
|
||||||
|
check_dependencies "flashrom"
|
||||||
|
if [ ! -d ${LOCAL_TOOLS_PATH}/flashrom ]; then
|
||||||
|
(
|
||||||
|
mkdir -p ${LOCAL_TOOLS_PATH}
|
||||||
|
cd ${LOCAL_TOOLS_PATH}
|
||||||
|
echo -n "Cloning flashrom git repo..."
|
||||||
|
git clone --single-branch --branch master https://review.coreboot.org/flashrom.git >/dev/null
|
||||||
|
[ $? -ne 0 ] && die "Error cloning flashrom repo from git"
|
||||||
|
echo "done"
|
||||||
|
)
|
||||||
|
fi
|
||||||
|
(
|
||||||
|
echo -n "Building flashrom from source..."
|
||||||
|
cd ${LOCAL_TOOLS_PATH}/flashrom
|
||||||
|
git fetch origin >/dev/null 2>&1
|
||||||
|
if ! git show c64486b >/dev/null 2>&1; then
|
||||||
|
cd ..
|
||||||
|
rm -rf ./flashrom
|
||||||
|
git clone --single-branch --branch master https://review.coreboot.org/flashrom.git >/dev/null
|
||||||
|
[ $? -ne 0 ] && die "Error cloning flashrom repo from git"
|
||||||
|
cd flashrom
|
||||||
|
fi
|
||||||
|
git reset --hard c64486b >/dev/null 2>&1
|
||||||
|
[ $? -ne 0 ] && die "Error checking out flashrom via git"
|
||||||
|
make CONFIG_NOTHING=yes CONFIG_DUMMY=yes CONFIG_INTERNAL=yes WARNERROR=no
|
||||||
|
[ $? -ne 0 ] && die "Error building flashrom (missing build dependency libpci-dev?)"
|
||||||
|
echo "done"
|
||||||
|
)
|
||||||
|
FLASHROM_CMD="${LOCAL_TOOLS_PATH}/flashrom/flashrom"
|
||||||
|
}
|
||||||
|
|
||||||
|
get_serial () {
|
||||||
|
if [ "$PLATFORM" = "BDW" ]; then
|
||||||
|
#no serial to set, clear file if exists
|
||||||
|
rm -f ${LOCAL_TEMP_DIR}/serial_number.txt >/dev/null
|
||||||
|
return;
|
||||||
|
fi
|
||||||
|
#prompt user for serial # selection/entry
|
||||||
|
echo ""
|
||||||
|
echo "Set the device serial number:"
|
||||||
|
echo ""
|
||||||
|
if [ "$DMIDECODE_SERIAL_NUMBER" != "" ]; then
|
||||||
|
DMIDECODE_SERIAL_OPT=1
|
||||||
|
MANUAL_SERIAL_OPT=2
|
||||||
|
NO_SERIAL_OPT=3
|
||||||
|
echo "${DMIDECODE_SERIAL_OPT} - Extracted from your local system (${DMIDECODE_SERIAL_NUMBER})"
|
||||||
|
else
|
||||||
|
DMIDECODE_SERIAL_OPT=0
|
||||||
|
MANUAL_SERIAL_OPT=1
|
||||||
|
NO_SERIAL_OPT=2
|
||||||
|
fi
|
||||||
|
echo "${MANUAL_SERIAL_OPT} - Enter serial number manually"
|
||||||
|
echo "${NO_SERIAL_OPT} - Do not set a serial number"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
serial=0
|
||||||
|
[ ${MODEL_INDEX} = 0 ] && default=2 || default=1
|
||||||
|
while [ "$serial" == "0" ]; do
|
||||||
|
read -r -p "Enter your choice (default: $default): " serial
|
||||||
|
[ "$serial" = "" ] && serial=$default
|
||||||
|
case $serial in
|
||||||
|
${DMIDECODE_SERIAL_OPT} )
|
||||||
|
if [ "$DMIDECODE_SERIAL_OPT" = 1 ]; then
|
||||||
|
echo -n "$DMIDECODE_SERIAL_NUMBER" > ${LOCAL_TEMP_DIR}/serial_number.txt
|
||||||
|
else
|
||||||
|
echo "Invalid option"
|
||||||
|
serial=0
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
${MANUAL_SERIAL_OPT} )
|
||||||
|
read -r -p "Enter the machine's serial number : " serial_number
|
||||||
|
echo -n "$serial_number" > ${LOCAL_TEMP_DIR}/serial_number.txt
|
||||||
|
;;
|
||||||
|
${NO_SERIAL_OPT} )
|
||||||
|
echo -n "" > ${LOCAL_TEMP_DIR}/serial_number.txt
|
||||||
|
;;
|
||||||
|
* )
|
||||||
|
echo "Invalid option"
|
||||||
|
serial=0
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
echo ""
|
||||||
|
}
|
||||||
|
|
||||||
|
flashrom_progress() {
|
||||||
|
local current=0
|
||||||
|
local total_bytes=0
|
||||||
|
local percent=0
|
||||||
|
local IN=''
|
||||||
|
local spin='-\|/'
|
||||||
|
local spin_idx=0
|
||||||
|
local progressbar=''
|
||||||
|
local progressbar2=''
|
||||||
|
local status='init'
|
||||||
|
local prev_word=''
|
||||||
|
local prev_prev_word=''
|
||||||
|
|
||||||
|
progressbar2=$(for ((i=0; i < 49; i++)) do echo -ne ' ' ; done)
|
||||||
|
echo "Initializing internal Flash Programmer"
|
||||||
|
while true ; do
|
||||||
|
prev_prev_word=$prev_word
|
||||||
|
prev_word=$IN
|
||||||
|
read -r -d' ' IN || break
|
||||||
|
if [ "$total_bytes" != "0" ]; then
|
||||||
|
current=$(echo "$IN" | grep -E -o '0x[0-9a-f]+-0x[0-9a-f]+:.*' | grep -E -o "0x[0-9a-f]+" | tail -n 1)
|
||||||
|
if [ "${current}" != "" ]; then
|
||||||
|
percent=$((100 * (current + 1) / total_bytes))
|
||||||
|
progressbar=$(for ((i=0; i < $((percent / 2)); i++)) do echo -ne '#' ; done)
|
||||||
|
progressbar2=$(for ((i=0; i < $((49 - percent / 2)); i++)) do echo -ne ' ' ; done)
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
if [ "$prev_prev_word" == "Reading" ] && [ "$IN" == "bytes" ]; then
|
||||||
|
total_bytes=$prev_word
|
||||||
|
echo "Total flash size : $total_bytes bytes"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
if [ "$percent" -eq 100 ]; then
|
||||||
|
spin_idx=4
|
||||||
|
else
|
||||||
|
spin_idx=$(( (spin_idx+1) %4 ))
|
||||||
|
fi
|
||||||
|
if [ "$status" == "init" ]; then
|
||||||
|
if [ "$IN" == "contents..." ]; then
|
||||||
|
status="reading"
|
||||||
|
echo "Reading old flash contents. Please wait..."
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
if [ "$status" == "reading" ]; then
|
||||||
|
if echo "${IN}" | grep "done." > /dev/null ; then
|
||||||
|
status="writing"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
if [ "$status" == "writing" ]; then
|
||||||
|
echo -ne "Flashing: [${progressbar}${spin:$spin_idx:1}${progressbar2}] (${percent}%)\\r"
|
||||||
|
if echo "$IN" | grep "Verifying" > /dev/null ; then
|
||||||
|
status="verifying"
|
||||||
|
echo ""
|
||||||
|
echo "Verifying flash contents. Please wait..."
|
||||||
|
fi
|
||||||
|
if echo "$IN" | grep "identical" > /dev/null ; then
|
||||||
|
status="done"
|
||||||
|
echo ""
|
||||||
|
echo "The flash contents are identical to the image being flashed."
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
if [ "$status" == "verifying" ]; then
|
||||||
|
if echo "${IN}" | grep "VERIFIED." > /dev/null ; then
|
||||||
|
status="done"
|
||||||
|
echo "The flash contents were verified and the image was flashed correctly."
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
echo ""
|
||||||
|
if [ "$status" == "done" ]; then
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
echo 'Error flashing coreboot -- see timestampped flashrom log in current directory for more info'
|
||||||
|
echo ""
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
set_serial_number () {
|
||||||
|
# pass in full path of file in which to inject serial
|
||||||
|
[[ -z "$1" || ! -f "$1" ]] && die "Error: a valid firmware filename is required"
|
||||||
|
|
||||||
|
# check if we have a serial # to add to cbfs
|
||||||
|
if [ -f ${LOCAL_TEMP_DIR}/serial_number.txt ]; then
|
||||||
|
# get cbfstool if needed
|
||||||
|
get_cbfstool
|
||||||
|
# inject serial into coreboot image
|
||||||
|
echo "Injecting serial number into firmware image"
|
||||||
|
$CBFSTOOL_BIN "$1" remove -n serial_number -r COREBOOT >/dev/null 2>&1
|
||||||
|
$CBFSTOOL_BIN "$1" add -n serial_number -t raw -f ${LOCAL_TEMP_DIR}/serial_number.txt -r COREBOOT >/dev/null 2>&1
|
||||||
|
[ $? -ne 0 ] && die "Error adding serial number to file ${1}"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
backup_firmware () {
|
||||||
|
|
||||||
|
# assume FLASHROM_CMD exists/is set already, LOCAL_TEMP_DIR set up
|
||||||
|
mkdir -p ${BACKUP_DIR}
|
||||||
|
DATE_FIX=$(date '+%Y%m%d-%H%M%S')
|
||||||
|
$FLASHROM_CMD -p internal:ich_spi_mode=hwseq -r ${BACKUP_DIR}/backup-${DATE_FIX}.bin -o ${BACKUP_DIR}/backup-$(date '+%Y%m%d-%H%M%S').log >/dev/null 2>&1
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
die "Error reading current firmware; see flashrom log for more info."
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
flash_firmware_internal () {
|
||||||
|
# assume FLASHROM_CMD exists/is set already
|
||||||
|
# pass in full path of file to be flashed
|
||||||
|
[[ -z "$1" || ! -f "$1" ]] && die "Error: a valid filename to be flashed is required"
|
||||||
|
$FLASHROM_CMD -p internal:ich_spi_mode=hwseq -w "$1" -V -o "./flashrom-$(date '+%Y%m%d-%H%M%S').log" 2>&1 | flashrom_progress
|
||||||
|
return $?
|
||||||
|
}
|
||||||
|
|
||||||
|
update_serial_number () {
|
||||||
|
|
||||||
|
# ensure using SeaBIOS
|
||||||
|
if [[ "${CURRENT_FW_TYPE}" != "STANDARD" ]]; then
|
||||||
|
echo "This feature is only valid for use with the standard/SeaBIOS firmware"
|
||||||
|
echo ""
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
# show serial menu / create serial.txt
|
||||||
|
get_serial
|
||||||
|
|
||||||
|
# check for / get flashrom
|
||||||
|
get_flashrom
|
||||||
|
|
||||||
|
# read current firmware
|
||||||
|
echo ""
|
||||||
|
if [ ! -f ${LOCAL_TEMP_DIR}/${CURRENT_FW_BIN} ]; then
|
||||||
|
echo "Reading current firmware..."
|
||||||
|
read_current_firmware
|
||||||
|
else
|
||||||
|
echo "Current firmware already read from flash"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# inject into current firmware
|
||||||
|
set_serial_number "${LOCAL_TEMP_DIR}/${CURRENT_FW_BIN}"
|
||||||
|
|
||||||
|
# prompt to update
|
||||||
|
echo ""
|
||||||
|
flash=0
|
||||||
|
while [ "$flash" != "y" ] && [ "$flash" != "n" ]; do
|
||||||
|
read -r -p "Do you want to update the serial number now (Y/n) ? " flash
|
||||||
|
[[ "$flash" == "N" ]] && flash="n"
|
||||||
|
[[ "$flash" = "" || "$flash" == "Y" ]] && flash="y"
|
||||||
|
done
|
||||||
|
if [ "$flash" == "y" ]; then
|
||||||
|
echo ""
|
||||||
|
echo "coreboot flashing in progress. Do NOT interrupt this process."
|
||||||
|
echo ""
|
||||||
|
flash_firmware_internal "${LOCAL_TEMP_DIR}/${CURRENT_FW_BIN}"
|
||||||
|
if [ $? -eq 0 ]; then
|
||||||
|
echo "Serial number successfully updated; change will take effect on next boot"
|
||||||
|
echo ""
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
update_crossgcc_toolchain() {
|
||||||
|
# assume called from coreboot root dir
|
||||||
|
|
||||||
|
local CURRENT_TOOLCHAIN_VERSION=0
|
||||||
|
local GCC_FILE='util/crossgcc/xgcc/bin/i386-elf-gcc'
|
||||||
|
local TARGET_TOOLCHAIN_VERSION="$(git log -n 1 --pretty=%h util/crossgcc)"
|
||||||
|
|
||||||
|
if [ -f "${GCC_FILE}" ]; then
|
||||||
|
CURRENT_TOOLCHAIN_VERSION=$(${GCC_FILE} --version | grep -m 1 'coreboot toolchain' \
|
||||||
|
| cut -f2 -d'v' | cut -f2 -d'_' | cut -f1 -d')')
|
||||||
|
fi
|
||||||
|
if [ "${CURRENT_TOOLCHAIN_VERSION}" != "${TARGET_TOOLCHAIN_VERSION}" ]; then
|
||||||
|
echo "coreboot toolchain version changed from ${CURRENT_TOOLCHAIN_VERSION} to ${TARGET_TOOLCHAIN_VERSION}"
|
||||||
|
echo "Cleaning crossgcc compiler before rebuilding it"
|
||||||
|
make crossgcc-clean
|
||||||
|
retries=0
|
||||||
|
until [ "$retries" -ge 5 ]
|
||||||
|
do
|
||||||
|
make crossgcc-i386 CPUS=$(nproc) && break
|
||||||
|
retries=$((retries+1))
|
||||||
|
done
|
||||||
|
[ $? -ne 0 ] && die "Error building coreboot toolchain" || true
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
build_coreboot() {
|
||||||
|
|
||||||
|
# extract / set device serial # to be injected later
|
||||||
|
get_serial
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "Checking out/updating coreboot repo..."
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# check dir, clone if needed
|
||||||
|
if [ ! -d coreboot ]; then
|
||||||
|
echo ""
|
||||||
|
git clone --branch ${COREBOOT_REPO_TAG} ${COREBOOT_REPO_PURISM} coreboot
|
||||||
|
[ $? -ne 0 ] && die "Error cloning coreboot git repo"
|
||||||
|
(
|
||||||
|
cd coreboot
|
||||||
|
# It can fail if you don't have a git global user.name/user.email setup
|
||||||
|
make gitconfig 2>/dev/null || true
|
||||||
|
# init/update submodules
|
||||||
|
git submodule update --init --force --checkout >/dev/null 2>&1
|
||||||
|
[ $? -ne 0 ] && die "Error checking out/updating coreboot submodules"
|
||||||
|
)
|
||||||
|
fi
|
||||||
|
|
||||||
|
# check out correct branch
|
||||||
|
(
|
||||||
|
cd coreboot
|
||||||
|
git fetch 2>/dev/null
|
||||||
|
[ $? -ne 0 ] && die "Error fetching coreboot git repo"
|
||||||
|
git fetch --tags 2>/dev/null
|
||||||
|
[ $? -ne 0 ] && die "Error fetching coreboot git repo"
|
||||||
|
git checkout --detach ${COREBOOT_REPO_TAG} 2>/dev/null
|
||||||
|
[ $? -ne 0 ] && die "Error checking out coreboot git repo"
|
||||||
|
|
||||||
|
# ensure submodules sane
|
||||||
|
if [[ "`git diff 3rdparty`" != "" ]]; then
|
||||||
|
git submodule update --force --checkout >/dev/null 2>&1
|
||||||
|
[[ "`git diff 3rdparty`" != "" ]] && \
|
||||||
|
die "submodules have been modified; build would not be reproducible"
|
||||||
|
fi
|
||||||
|
|
||||||
|
#build cbfstool and ifdtool
|
||||||
|
(
|
||||||
|
cd util/cbfstool
|
||||||
|
make
|
||||||
|
[ $? -ne 0 ] && die "Error building cbfstool"
|
||||||
|
)
|
||||||
|
(
|
||||||
|
cd util/ifdtool
|
||||||
|
make
|
||||||
|
[ $? -ne 0 ] && die "Error building ifdtool"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
# build coreboot
|
||||||
|
(
|
||||||
|
# set pwd
|
||||||
|
cd coreboot
|
||||||
|
|
||||||
|
# let user know this will take a few
|
||||||
|
echo -e "\n\n"
|
||||||
|
echo "Ready to build coreboot - this will take some time depending on your connection"
|
||||||
|
echo "speed and CPU/RAM, esp if the toolchain needs to be built."
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# check/build toolchain
|
||||||
|
update_crossgcc_toolchain || die
|
||||||
|
|
||||||
|
# get git version
|
||||||
|
GIT_VERSION=$(git describe --tags --dirty)
|
||||||
|
|
||||||
|
# do a clean build
|
||||||
|
make distclean
|
||||||
|
# copy config
|
||||||
|
cp ../resources/config .config
|
||||||
|
# copt grub config
|
||||||
|
cp ../resources/grub.cfg grub.cfg
|
||||||
|
echo "CONFIG_LOCALVERSION=\"${GIT_VERSION}\"" >> .config
|
||||||
|
make olddefconfig >/dev/null
|
||||||
|
# build coreboot and payload(s)
|
||||||
|
make
|
||||||
|
[ $? -ne 0 ] && die "Error building coreboot"
|
||||||
|
# copy to root dir
|
||||||
|
#cp build/coreboot.rom ../${COREBOOT_IMAGE}
|
||||||
|
)
|
||||||
|
|
||||||
|
# calculate hash of BIOS region before injecting bootorder/serial
|
||||||
|
${IFDTOOL_CB} -x ${COREBOOT_IMAGE}
|
||||||
|
bios_sha=$(sha256sum flashregion_1_bios.bin | awk '{print $1}')
|
||||||
|
rm -f flashregion*.bin
|
||||||
|
|
||||||
|
# set serial
|
||||||
|
set_serial_number ${COREBOOT_IMAGE}
|
||||||
|
|
||||||
|
#set boot delay
|
||||||
|
# add an 8s boot delay for the Librem Mini so splash screen
|
||||||
|
# actually shown on displays with sluggish init
|
||||||
|
if [[ ${LIBREM_MODEL^^} == "MINI"* ]]; then
|
||||||
|
${CBFSTOOL_CB} ${COREBOOT_IMAGE} add-int -i 8000 -n etc/boot-menu-wait >/dev/null
|
||||||
|
fi
|
||||||
|
# print CBFS contents
|
||||||
|
${CBFSTOOL_CB} ${COREBOOT_IMAGE} print
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo ""
|
||||||
|
echo "Finished building coreboot for Librem ${LIBREM_MODEL^}"
|
||||||
|
echo ""
|
||||||
|
COREBOOT_BIOS_SHA="COREBOOT_BIOS_SHA_${LIBREM_MODEL^^}"
|
||||||
|
COREBOOT_BIOS_SHA=${!COREBOOT_BIOS_SHA}
|
||||||
|
if [ "${bios_sha}" != "${COREBOOT_BIOS_SHA}" ]; then
|
||||||
|
echo "WARNING: Built coreboot image hash does not match expected reproducible build hash"
|
||||||
|
echo "Built: ${bios_sha}"
|
||||||
|
echo "Expected: ${COREBOOT_BIOS_SHA}"
|
||||||
|
else
|
||||||
|
echo "Built coreboot image hash matches expected reproducible build hash"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# prompt to flash
|
||||||
|
echo ""
|
||||||
|
if [ ${CURRENT_FW_TYPE} != "HEADS" ]; then
|
||||||
|
flash=0
|
||||||
|
while [ "$flash" != "y" ] && [ "$flash" != "n" ]; do
|
||||||
|
read -r -p "Do you want to flash the coreboot update now (y/N) ? " flash
|
||||||
|
if [ "$flash" = "" ] || [ "$flash" == "N" ]; then
|
||||||
|
flash="n"
|
||||||
|
fi
|
||||||
|
if [ "$flash" == "Y" ]; then
|
||||||
|
flash="y"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
if [ "$flash" == "y" ]; then
|
||||||
|
# check for / get flashrom
|
||||||
|
get_flashrom
|
||||||
|
echo ""
|
||||||
|
echo "coreboot flashing in progress. Do NOT interrupt this process."
|
||||||
|
echo ""
|
||||||
|
flash_firmware_internal ${COREBOOT_IMAGE}
|
||||||
|
if [ $? -eq 0 ]; then
|
||||||
|
echo ""
|
||||||
|
echo "You must reboot for the coreboot update to take effect."
|
||||||
|
echo ""
|
||||||
|
read -r -p "Reboot now? (y/N) ? " rb
|
||||||
|
if [ "$rb" = "Y" ] || [ "$rb" == "y" ]; then
|
||||||
|
cleanup
|
||||||
|
reboot
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo ""
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "You may now copy the coreboot update file ($COREBOOT_IMAGE) to USB for updating via Heads."
|
||||||
|
echo ""
|
||||||
|
read -ep "Press [Enter] to exit."
|
||||||
|
cleanup
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
check_dependencies() {
|
||||||
|
|
||||||
|
local dep_type=$1
|
||||||
|
local DEPS
|
||||||
|
local use_dnf=false
|
||||||
|
[[ `which dnf 2>/dev/null` ]] && use_dnf=true
|
||||||
|
|
||||||
|
case $dep_type in
|
||||||
|
"base")
|
||||||
|
DEPS=${DEPS_BASE[@]} ;;
|
||||||
|
"flashrom")
|
||||||
|
if [ $use_dnf = true ]; then
|
||||||
|
DEPS=(${DEPS_BASE[@]} ${DEPS_FLASH_FEDORA[@]}) ;
|
||||||
|
else
|
||||||
|
DEPS=(${DEPS_BASE[@]} ${DEPS_FLASH[@]}) ;
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
"coreboot")
|
||||||
|
if [ $use_dnf = true ]; then
|
||||||
|
DEPS=(${DEPS_BASE[@]} ${DEPS_FLASH_FEDORA[@]} ${DEPS_GRUB2_FEDORA[@]}) ;
|
||||||
|
else
|
||||||
|
DEPS=(${DEPS_BASE[@]} ${DEPS_FLASH[@]} ${DEPS_COREBOOT[@]} ${DEPS_GRUB2[@]}) ;
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
local pkg needed=()
|
||||||
|
for pkg in "${DEPS[@]}"; do
|
||||||
|
if [[ ! `which ${pkg} 2>/dev/null` \
|
||||||
|
&& ! `dnf list installed 2>/dev/null | grep "^${pkg}"` \
|
||||||
|
&& ! `apt list --installed 2>/dev/null | grep "^${pkg}"` \
|
||||||
|
&& ! -f "/usr/share/doc/${pkg}/copyright" ]]; then
|
||||||
|
needed+=("${pkg}")
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
if [[ "${#needed[@]}" -gt 0 ]]; then
|
||||||
|
echo ""
|
||||||
|
echo "One or more required dependencies are missing: ${needed[@]}"
|
||||||
|
echo "The script will now attempt to install them for you"
|
||||||
|
echo ""
|
||||||
|
read -rp "Press [Enter] to continue " discard
|
||||||
|
echo ""
|
||||||
|
if [ $use_dnf = true ]; then
|
||||||
|
if ! sudo dnf -y install "${needed[@]}" ; then
|
||||||
|
die "Some required dependencies could not be installed automatically"
|
||||||
|
fi
|
||||||
|
elif which apt >/dev/null ; then
|
||||||
|
sudo apt-get update >/dev/null 2>&1
|
||||||
|
if ! sudo apt-get -y install "${needed[@]}" ; then
|
||||||
|
die "Some required dependencies could not be installed automatically"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "The script was unable to install the required dependencies automatically"
|
||||||
|
echo ""
|
||||||
|
die "Please ensure all required dependencies are installed and re-run this script"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Start of main script
|
||||||
|
# let's do stuff
|
||||||
|
|
||||||
|
check_root
|
||||||
|
|
||||||
|
check_dependencies "base"
|
||||||
|
|
||||||
|
check_dependencies "flashrom"
|
||||||
|
|
||||||
|
check_dependencies "coreboot"
|
||||||
|
|
||||||
|
initial_setup
|
||||||
|
|
||||||
|
print_info
|
||||||
|
|
||||||
|
get_flashrom
|
||||||
|
|
||||||
|
build_coreboot
|
BIN
resources/background.jpg
Normal file
BIN
resources/background.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 254 KiB |
20
resources/config
Normal file
20
resources/config
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
CONFIG_VENDOR_PURISM=y
|
||||||
|
CONFIG_IFD_BIN_PATH="3rdparty/purism-blobs/mainboard/purism/librem_cnl/librem_14/flashdescriptor.bin"
|
||||||
|
CONFIG_ME_BIN_PATH="3rdparty/purism-blobs/mainboard/purism/librem_cnl/librem_14/me.bin"
|
||||||
|
CONFIG_HAVE_IFD_BIN=y
|
||||||
|
CONFIG_BOARD_PURISM_LIBREM_14=y
|
||||||
|
CONFIG_CPU_MICROCODE_CBFS_EXTERNAL_BINS=y
|
||||||
|
CONFIG_CPU_UCODE_BINARIES="3rdparty/purism-blobs/mainboard/purism/librem_cnl/cpu_microcode_blob.bin"
|
||||||
|
CONFIG_HAVE_ME_BIN=y
|
||||||
|
CONFIG_GENERIC_LINEAR_FRAMEBUFFER=y
|
||||||
|
CONFIG_LINEAR_FRAMEBUFFER_MAX_WIDTH=1920
|
||||||
|
CONFIG_LINEAR_FRAMEBUFFER_MAX_HEIGHT=1080
|
||||||
|
CONFIG_MAINBOARD_SERIAL_NUMBER="System Serial Number"
|
||||||
|
|
||||||
|
CONFIG_PAYLOAD_GRUB2=y
|
||||||
|
CONFIG_PAYLOAD_FILE="payloads/external/GRUB2/grub2/build/default_payload.elf"
|
||||||
|
CONFIG_GRUB2_STABLE=y
|
||||||
|
CONFIG_GRUB2_EXTRA_MODULES="gcry_seed gcry_rijndael gcry_sha256 lvm luks cryptodisk jpeg gfxmenu gfxterm_menu gfxterm_background password password_pbkdf2 pbkdf2"
|
||||||
|
CONFIG_GRUB2_INCLUDE_RUNTIME_CONFIG_FILE=y
|
||||||
|
CONFIG_GRUB2_RUNTIME_CONFIG_FILE="grub.cfg"
|
||||||
|
CONFIG_COMPRESS_SECONDARY_PAYLOAD=y
|
0
resources/grub.cfg
Normal file
0
resources/grub.cfg
Normal file
BIN
resources/ukqwerty.gkb
Normal file
BIN
resources/ukqwerty.gkb
Normal file
Binary file not shown.
Loading…
Reference in New Issue
Block a user