build.sh 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668
  1. #!/bin/bash
  2. # use TERM to exit on error
  3. trap "exit 1" TERM
  4. export TOP_PID=$$
  5. # coreboot repo
  6. COREBOOT_REPO_PURISM="https://source.puri.sm/coreboot/coreboot.git"
  7. COREBOOT_REPO_TAG="4.14-Purism-1"
  8. # dependencies
  9. DEPS_BASE=(dmidecode wget sha256sum gzip)
  10. DEPS_FLASH=(git build-essential libpci-dev libudev-dev zlib1g-dev)
  11. DEPS_FLASH_FEDORA=(git gcc g++ make xz bzip2 pciutils-devel)
  12. DEPS_COREBOOT=(gnat m4 bison flex libncurses5-dev python python2)
  13. DEPS_COREBOOT_FEDORA=(gcc-gnat bison flex ncurses-devel zlib-devel python python2 patch)
  14. DEPS_GRUB2=(autoconf automake autopoint libfreetype-dev fonts-unifont)
  15. DEPS_GRUB2_FEDORA=(autoconf automake gettext-devel freetype-devel unifont-fonts)
  16. #local dirs
  17. LOCAL_TOOLS_PATH="./tools"
  18. LOCAL_FIRMWARE_PATH="./firmware"
  19. LOCAL_TEMP_DIR="$(mktemp -d)"
  20. # locally compiled coreboot utils
  21. CBFSTOOL_CB="./coreboot/util/cbfstool/cbfstool"
  22. IFDTOOL_CB="./coreboot/util/ifdtool/ifdtool"
  23. # functions, functions, functions
  24. check_root() {
  25. if [[ "$EUID" != 0 ]]; then
  26. die "This script must be run as root; re-run prefixed with sudo"
  27. fi
  28. }
  29. print_info () {
  30. clear
  31. echo "################################################"
  32. echo "## Purism Librem coreboot Utility "
  33. echo "################################################"
  34. if [[ "${LIBREM_MODEL^^}" != "UNKNOWN" ]]; then
  35. model=${LIBREM_MODEL^}
  36. echo "# Device: Librem ${model//_/ }"
  37. echo "# Serial: ${DMIDECODE_SERIAL_NUMBER}"
  38. echo "# Firmware: ${FW_TYPE_STRING}"
  39. echo "# Version: ${CURRENT_FW_VER} ${CURRENT_FW_DATE}"
  40. echo "################################################"
  41. fi
  42. }
  43. initial_setup () {
  44. # get model, firmware version, serial # via dmidecode
  45. vendor=$(dmidecode -s bios-vendor)
  46. model=$(dmidecode -s system-product-name | grep -i Librem)
  47. CURRENT_FW_VER=$(dmidecode -s bios-version)
  48. CURRENT_FW_DATE=$(dmidecode -s bios-release-date)
  49. DMIDECODE_SERIAL_NUMBER=$(dmidecode -t 1 | grep "Serial Number" | cut -d' ' -f 3-)
  50. # set CURRENT_FW_TYPE type
  51. if [ "$vendor" = "coreboot" ]; then
  52. case ${CURRENT_FW_VER^^} in
  53. *"PUREBOOT"* )
  54. CURRENT_FW_TYPE="HEADS";;
  55. *"HEADS"* )
  56. CURRENT_FW_TYPE="HEADS";;
  57. *"GRUB2"* )
  58. CURRENT_FW_TYPE="GRUB2";;
  59. * )
  60. CURRENT_FW_TYPE="STANDARD";;
  61. esac
  62. else
  63. CURRENT_FW_TYPE="UNKNOWN"
  64. fi
  65. FW_UPDATE=""
  66. case $CURRENT_FW_TYPE in
  67. "HEADS" )
  68. FW_TYPE_STRING="PureBoot (coreboot+Heads)"
  69. CURR_FW_NUM=`echo ${CURRENT_FW_VER} | sed -e "s/^PureBoot-beta-//" -e "s/^PureBoot-Release-//"`
  70. UPD_FW_NUM=`echo ${COREBOOT_HEADS_VERSION} | sed -e "s/^PureBoot-beta-//" -e "s/^PureBoot-Release-//"`
  71. [[ "$UPD_FW_NUM" > "$CURR_FW_NUM" ]] \
  72. && FW_UPDATE=`echo ${COREBOOT_HEADS_VERSION} | tr '-' ' '`
  73. CURRENT_FW_VER=`echo ${CURRENT_FW_VER#PureBoot-} | tr '-' ' '`
  74. CURRENT_FW_DATE=""
  75. ;;
  76. "STANDARD" )
  77. FW_TYPE_STRING="Standard (coreboot+SeaBIOS)"
  78. [[ "$COREBOOT_SEABIOS_VERSION" > "$CURRENT_FW_VER" ]] \
  79. && FW_UPDATE="$COREBOOT_SEABIOS_VERSION";
  80. CURRENT_FW_DATE="(${CURRENT_FW_DATE})"
  81. ;;
  82. "GRUB2" )
  83. FW_TYPE_STRING="Grub2 (coreboot+Grub2)"
  84. [[ "$COREBOOT_GRUB2_VERSION" > "$CURRENT_FW_VER" ]] \
  85. && FW_UPDATE="$COREBOOT_GRUB2_VERSION";
  86. CURRENT_FW_DATE="(${CURRENT_FW_DATE})"
  87. ;;
  88. * )
  89. FW_TYPE_STRING="Unknown" ;;
  90. esac
  91. # set LIBREM_MODEL, MODEL_INDEX
  92. # strip leading 'librem' + space/underscore
  93. model=`echo ${model,,} | sed -e "s/^librem//" -e "s/^ //" -e "s/^_//"`
  94. case ${model} in
  95. "14")
  96. LIBREM_MODEL="14";
  97. PLATFORM="CML";
  98. MODEL_INDEX="9";;
  99. *)
  100. LIBREM_MODEL="unknown";
  101. PLATFORM="UNK";
  102. MODEL_INDEX="0";;
  103. esac
  104. }
  105. cleanup() {
  106. # ensure all files owned by calling/non-root user
  107. chown -R -f $(logname). .
  108. }
  109. die () {
  110. local msg=$1
  111. if [ ! -z "$msg" ]; then
  112. echo ""
  113. echo -e "$msg"
  114. echo ""
  115. fi
  116. kill -s TERM $TOP_PID
  117. cleanup
  118. exit 1
  119. }
  120. get_flashrom () {
  121. # check if flashrom exists on system
  122. echo ""
  123. echo "Checking for usable version of flashrom"
  124. FLASHROM_CMD=$(which flashrom)
  125. if [[ ! -z "$FLASHROM_CMD" && "$PLATFORM" != "CML" ]]; then
  126. #check version
  127. version=$($FLASHROM_CMD -R | awk -F" " '{print $2;exit}' | grep "1.")
  128. if [[ "$version" > "v1.1" ]]; then
  129. # verify build supports logging (some PureOS/Debian versions broken)
  130. if $FLASHROM_CMD -L -o /tmp/flashrom.log >/dev/null 2>&1 ; then
  131. #use system flashrom
  132. echo "Found built-in flashrom version $version"
  133. return
  134. fi
  135. fi
  136. fi
  137. # no system flashrom, not version 1.2+, or PLATFORM == CML:
  138. # build from upstream flashrom source
  139. # check deps first
  140. check_dependencies "flashrom"
  141. if [ ! -d ${LOCAL_TOOLS_PATH}/flashrom ]; then
  142. (
  143. mkdir -p ${LOCAL_TOOLS_PATH}
  144. cd ${LOCAL_TOOLS_PATH}
  145. echo -n "Cloning flashrom git repo..."
  146. git clone --single-branch --branch master https://review.coreboot.org/flashrom.git >/dev/null
  147. [ $? -ne 0 ] && die "Error cloning flashrom repo from git"
  148. echo "done"
  149. )
  150. fi
  151. (
  152. echo -n "Building flashrom from source..."
  153. cd ${LOCAL_TOOLS_PATH}/flashrom
  154. git fetch origin >/dev/null 2>&1
  155. if ! git show c64486b >/dev/null 2>&1; then
  156. cd ..
  157. rm -rf ./flashrom
  158. git clone --single-branch --branch master https://review.coreboot.org/flashrom.git >/dev/null
  159. [ $? -ne 0 ] && die "Error cloning flashrom repo from git"
  160. cd flashrom
  161. fi
  162. git reset --hard c64486b >/dev/null 2>&1
  163. [ $? -ne 0 ] && die "Error checking out flashrom via git"
  164. make CONFIG_NOTHING=yes CONFIG_DUMMY=yes CONFIG_INTERNAL=yes WARNERROR=no
  165. [ $? -ne 0 ] && die "Error building flashrom (missing build dependency libpci-dev?)"
  166. echo "done"
  167. )
  168. FLASHROM_CMD="${LOCAL_TOOLS_PATH}/flashrom/flashrom"
  169. }
  170. get_serial () {
  171. if [ "$PLATFORM" = "BDW" ]; then
  172. #no serial to set, clear file if exists
  173. rm -f ${LOCAL_TEMP_DIR}/serial_number.txt >/dev/null
  174. return;
  175. fi
  176. #prompt user for serial # selection/entry
  177. echo ""
  178. echo "Set the device serial number:"
  179. echo ""
  180. if [ "$DMIDECODE_SERIAL_NUMBER" != "" ]; then
  181. DMIDECODE_SERIAL_OPT=1
  182. MANUAL_SERIAL_OPT=2
  183. NO_SERIAL_OPT=3
  184. echo "${DMIDECODE_SERIAL_OPT} - Extracted from your local system (${DMIDECODE_SERIAL_NUMBER})"
  185. else
  186. DMIDECODE_SERIAL_OPT=0
  187. MANUAL_SERIAL_OPT=1
  188. NO_SERIAL_OPT=2
  189. fi
  190. echo "${MANUAL_SERIAL_OPT} - Enter serial number manually"
  191. echo "${NO_SERIAL_OPT} - Do not set a serial number"
  192. echo ""
  193. serial=0
  194. [ ${MODEL_INDEX} = 0 ] && default=2 || default=1
  195. while [ "$serial" == "0" ]; do
  196. read -r -p "Enter your choice (default: $default): " serial
  197. [ "$serial" = "" ] && serial=$default
  198. case $serial in
  199. ${DMIDECODE_SERIAL_OPT} )
  200. if [ "$DMIDECODE_SERIAL_OPT" = 1 ]; then
  201. echo -n "$DMIDECODE_SERIAL_NUMBER" > ${LOCAL_TEMP_DIR}/serial_number.txt
  202. else
  203. echo "Invalid option"
  204. serial=0
  205. fi
  206. ;;
  207. ${MANUAL_SERIAL_OPT} )
  208. read -r -p "Enter the machine's serial number : " serial_number
  209. echo -n "$serial_number" > ${LOCAL_TEMP_DIR}/serial_number.txt
  210. ;;
  211. ${NO_SERIAL_OPT} )
  212. echo -n "" > ${LOCAL_TEMP_DIR}/serial_number.txt
  213. ;;
  214. * )
  215. echo "Invalid option"
  216. serial=0
  217. ;;
  218. esac
  219. done
  220. echo ""
  221. }
  222. flashrom_progress() {
  223. local current=0
  224. local total_bytes=0
  225. local percent=0
  226. local IN=''
  227. local spin='-\|/'
  228. local spin_idx=0
  229. local progressbar=''
  230. local progressbar2=''
  231. local status='init'
  232. local prev_word=''
  233. local prev_prev_word=''
  234. progressbar2=$(for ((i=0; i < 49; i++)) do echo -ne ' ' ; done)
  235. echo "Initializing internal Flash Programmer"
  236. while true ; do
  237. prev_prev_word=$prev_word
  238. prev_word=$IN
  239. read -r -d' ' IN || break
  240. if [ "$total_bytes" != "0" ]; then
  241. current=$(echo "$IN" | grep -E -o '0x[0-9a-f]+-0x[0-9a-f]+:.*' | grep -E -o "0x[0-9a-f]+" | tail -n 1)
  242. if [ "${current}" != "" ]; then
  243. percent=$((100 * (current + 1) / total_bytes))
  244. progressbar=$(for ((i=0; i < $((percent / 2)); i++)) do echo -ne '#' ; done)
  245. progressbar2=$(for ((i=0; i < $((49 - percent / 2)); i++)) do echo -ne ' ' ; done)
  246. fi
  247. else
  248. if [ "$prev_prev_word" == "Reading" ] && [ "$IN" == "bytes" ]; then
  249. total_bytes=$prev_word
  250. echo "Total flash size : $total_bytes bytes"
  251. fi
  252. fi
  253. if [ "$percent" -eq 100 ]; then
  254. spin_idx=4
  255. else
  256. spin_idx=$(( (spin_idx+1) %4 ))
  257. fi
  258. if [ "$status" == "init" ]; then
  259. if [ "$IN" == "contents..." ]; then
  260. status="reading"
  261. echo "Reading old flash contents. Please wait..."
  262. fi
  263. fi
  264. if [ "$status" == "reading" ]; then
  265. if echo "${IN}" | grep "done." > /dev/null ; then
  266. status="writing"
  267. fi
  268. fi
  269. if [ "$status" == "writing" ]; then
  270. echo -ne "Flashing: [${progressbar}${spin:$spin_idx:1}${progressbar2}] (${percent}%)\\r"
  271. if echo "$IN" | grep "Verifying" > /dev/null ; then
  272. status="verifying"
  273. echo ""
  274. echo "Verifying flash contents. Please wait..."
  275. fi
  276. if echo "$IN" | grep "identical" > /dev/null ; then
  277. status="done"
  278. echo ""
  279. echo "The flash contents are identical to the image being flashed."
  280. fi
  281. fi
  282. if [ "$status" == "verifying" ]; then
  283. if echo "${IN}" | grep "VERIFIED." > /dev/null ; then
  284. status="done"
  285. echo "The flash contents were verified and the image was flashed correctly."
  286. fi
  287. fi
  288. done
  289. echo ""
  290. if [ "$status" == "done" ]; then
  291. return 0
  292. else
  293. echo 'Error flashing coreboot -- see timestampped flashrom log in current directory for more info'
  294. echo ""
  295. return 1
  296. fi
  297. }
  298. set_serial_number () {
  299. # pass in full path of file in which to inject serial
  300. [[ -z "$1" || ! -f "$1" ]] && die "Error: a valid firmware filename is required"
  301. # check if we have a serial # to add to cbfs
  302. if [ -f ${LOCAL_TEMP_DIR}/serial_number.txt ]; then
  303. # get cbfstool if needed
  304. get_cbfstool
  305. # inject serial into coreboot image
  306. echo "Injecting serial number into firmware image"
  307. $CBFSTOOL_BIN "$1" remove -n serial_number -r COREBOOT >/dev/null 2>&1
  308. $CBFSTOOL_BIN "$1" add -n serial_number -t raw -f ${LOCAL_TEMP_DIR}/serial_number.txt -r COREBOOT >/dev/null 2>&1
  309. [ $? -ne 0 ] && die "Error adding serial number to file ${1}"
  310. fi
  311. }
  312. backup_firmware () {
  313. # assume FLASHROM_CMD exists/is set already, LOCAL_TEMP_DIR set up
  314. mkdir -p ${BACKUP_DIR}
  315. DATE_FIX=$(date '+%Y%m%d-%H%M%S')
  316. $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
  317. if [ $? -ne 0 ]; then
  318. die "Error reading current firmware; see flashrom log for more info."
  319. fi
  320. }
  321. flash_firmware_internal () {
  322. # assume FLASHROM_CMD exists/is set already
  323. # pass in full path of file to be flashed
  324. [[ -z "$1" || ! -f "$1" ]] && die "Error: a valid filename to be flashed is required"
  325. $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
  326. return $?
  327. }
  328. update_serial_number () {
  329. # ensure using SeaBIOS
  330. if [[ "${CURRENT_FW_TYPE}" != "STANDARD" ]]; then
  331. echo "This feature is only valid for use with the standard/SeaBIOS firmware"
  332. echo ""
  333. return
  334. fi
  335. # show serial menu / create serial.txt
  336. get_serial
  337. # check for / get flashrom
  338. get_flashrom
  339. # read current firmware
  340. echo ""
  341. if [ ! -f ${LOCAL_TEMP_DIR}/${CURRENT_FW_BIN} ]; then
  342. echo "Reading current firmware..."
  343. read_current_firmware
  344. else
  345. echo "Current firmware already read from flash"
  346. fi
  347. # inject into current firmware
  348. set_serial_number "${LOCAL_TEMP_DIR}/${CURRENT_FW_BIN}"
  349. # prompt to update
  350. echo ""
  351. flash=0
  352. while [ "$flash" != "y" ] && [ "$flash" != "n" ]; do
  353. read -r -p "Do you want to update the serial number now (Y/n) ? " flash
  354. [[ "$flash" == "N" ]] && flash="n"
  355. [[ "$flash" = "" || "$flash" == "Y" ]] && flash="y"
  356. done
  357. if [ "$flash" == "y" ]; then
  358. echo ""
  359. echo "coreboot flashing in progress. Do NOT interrupt this process."
  360. echo ""
  361. flash_firmware_internal "${LOCAL_TEMP_DIR}/${CURRENT_FW_BIN}"
  362. if [ $? -eq 0 ]; then
  363. echo "Serial number successfully updated; change will take effect on next boot"
  364. echo ""
  365. fi
  366. fi
  367. }
  368. update_crossgcc_toolchain() {
  369. # assume called from coreboot root dir
  370. local CURRENT_TOOLCHAIN_VERSION=0
  371. local GCC_FILE='util/crossgcc/xgcc/bin/i386-elf-gcc'
  372. local TARGET_TOOLCHAIN_VERSION="$(git log -n 1 --pretty=%h util/crossgcc)"
  373. if [ -f "${GCC_FILE}" ]; then
  374. CURRENT_TOOLCHAIN_VERSION=$(${GCC_FILE} --version | grep -m 1 'coreboot toolchain' \
  375. | cut -f2 -d'v' | cut -f2 -d'_' | cut -f1 -d')')
  376. fi
  377. if [ "${CURRENT_TOOLCHAIN_VERSION}" != "${TARGET_TOOLCHAIN_VERSION}" ]; then
  378. echo "coreboot toolchain version changed from ${CURRENT_TOOLCHAIN_VERSION} to ${TARGET_TOOLCHAIN_VERSION}"
  379. echo "Cleaning crossgcc compiler before rebuilding it"
  380. make crossgcc-clean
  381. retries=0
  382. until [ "$retries" -ge 5 ]
  383. do
  384. make crossgcc-i386 CPUS=$(nproc) && break
  385. retries=$((retries+1))
  386. done
  387. [ $? -ne 0 ] && die "Error building coreboot toolchain" || true
  388. fi
  389. }
  390. build_coreboot() {
  391. # extract / set device serial # to be injected later
  392. get_serial
  393. echo ""
  394. echo "Checking out/updating coreboot repo..."
  395. echo ""
  396. # check dir, clone if needed
  397. if [ ! -d coreboot ]; then
  398. echo ""
  399. git clone --branch ${COREBOOT_REPO_TAG} ${COREBOOT_REPO_PURISM} coreboot
  400. [ $? -ne 0 ] && die "Error cloning coreboot git repo"
  401. (
  402. cd coreboot
  403. # It can fail if you don't have a git global user.name/user.email setup
  404. make gitconfig 2>/dev/null || true
  405. # init/update submodules
  406. git submodule update --init --force --checkout >/dev/null 2>&1
  407. [ $? -ne 0 ] && die "Error checking out/updating coreboot submodules"
  408. )
  409. fi
  410. # check out correct branch
  411. (
  412. cd coreboot
  413. git fetch 2>/dev/null
  414. [ $? -ne 0 ] && die "Error fetching coreboot git repo"
  415. git fetch --tags 2>/dev/null
  416. [ $? -ne 0 ] && die "Error fetching coreboot git repo"
  417. git checkout --detach ${COREBOOT_REPO_TAG} 2>/dev/null
  418. [ $? -ne 0 ] && die "Error checking out coreboot git repo"
  419. # ensure submodules sane
  420. if [[ "`git diff 3rdparty`" != "" ]]; then
  421. git submodule update --force --checkout >/dev/null 2>&1
  422. [[ "`git diff 3rdparty`" != "" ]] && \
  423. die "submodules have been modified; build would not be reproducible"
  424. fi
  425. #build cbfstool and ifdtool
  426. (
  427. cd util/cbfstool
  428. make
  429. [ $? -ne 0 ] && die "Error building cbfstool"
  430. )
  431. (
  432. cd util/ifdtool
  433. make
  434. [ $? -ne 0 ] && die "Error building ifdtool"
  435. )
  436. )
  437. # build coreboot
  438. (
  439. # set pwd
  440. cd coreboot
  441. # let user know this will take a few
  442. echo -e "\n\n"
  443. echo "Ready to build coreboot - this will take some time depending on your connection"
  444. echo "speed and CPU/RAM, esp if the toolchain needs to be built."
  445. echo ""
  446. # check/build toolchain
  447. update_crossgcc_toolchain || die
  448. # get git version
  449. GIT_VERSION=$(git describe --tags --dirty)
  450. # do a clean build
  451. make distclean
  452. # copy config
  453. cp ../resources/config .config
  454. # copt grub config
  455. cp ../resources/grub.cfg grub.cfg
  456. echo "CONFIG_LOCALVERSION=\"${GIT_VERSION}\"" >> .config
  457. make olddefconfig >/dev/null
  458. # build coreboot and payload(s)
  459. make
  460. [ $? -ne 0 ] && die "Error building coreboot"
  461. # copy to root dir
  462. #cp build/coreboot.rom ../${COREBOOT_IMAGE}
  463. )
  464. # calculate hash of BIOS region before injecting bootorder/serial
  465. ${IFDTOOL_CB} -x ${COREBOOT_IMAGE}
  466. bios_sha=$(sha256sum flashregion_1_bios.bin | awk '{print $1}')
  467. rm -f flashregion*.bin
  468. # set serial
  469. set_serial_number ${COREBOOT_IMAGE}
  470. #set boot delay
  471. # add an 8s boot delay for the Librem Mini so splash screen
  472. # actually shown on displays with sluggish init
  473. if [[ ${LIBREM_MODEL^^} == "MINI"* ]]; then
  474. ${CBFSTOOL_CB} ${COREBOOT_IMAGE} add-int -i 8000 -n etc/boot-menu-wait >/dev/null
  475. fi
  476. # print CBFS contents
  477. ${CBFSTOOL_CB} ${COREBOOT_IMAGE} print
  478. echo ""
  479. echo ""
  480. echo "Finished building coreboot for Librem ${LIBREM_MODEL^}"
  481. echo ""
  482. COREBOOT_BIOS_SHA="COREBOOT_BIOS_SHA_${LIBREM_MODEL^^}"
  483. COREBOOT_BIOS_SHA=${!COREBOOT_BIOS_SHA}
  484. if [ "${bios_sha}" != "${COREBOOT_BIOS_SHA}" ]; then
  485. echo "WARNING: Built coreboot image hash does not match expected reproducible build hash"
  486. echo "Built: ${bios_sha}"
  487. echo "Expected: ${COREBOOT_BIOS_SHA}"
  488. else
  489. echo "Built coreboot image hash matches expected reproducible build hash"
  490. fi
  491. # prompt to flash
  492. echo ""
  493. if [ ${CURRENT_FW_TYPE} != "HEADS" ]; then
  494. flash=0
  495. while [ "$flash" != "y" ] && [ "$flash" != "n" ]; do
  496. read -r -p "Do you want to flash the coreboot update now (y/N) ? " flash
  497. if [ "$flash" = "" ] || [ "$flash" == "N" ]; then
  498. flash="n"
  499. fi
  500. if [ "$flash" == "Y" ]; then
  501. flash="y"
  502. fi
  503. done
  504. if [ "$flash" == "y" ]; then
  505. # check for / get flashrom
  506. get_flashrom
  507. echo ""
  508. echo "coreboot flashing in progress. Do NOT interrupt this process."
  509. echo ""
  510. flash_firmware_internal ${COREBOOT_IMAGE}
  511. if [ $? -eq 0 ]; then
  512. echo ""
  513. echo "You must reboot for the coreboot update to take effect."
  514. echo ""
  515. read -r -p "Reboot now? (y/N) ? " rb
  516. if [ "$rb" = "Y" ] || [ "$rb" == "y" ]; then
  517. cleanup
  518. reboot
  519. fi
  520. fi
  521. else
  522. echo ""
  523. fi
  524. else
  525. echo "You may now copy the coreboot update file ($COREBOOT_IMAGE) to USB for updating via Heads."
  526. echo ""
  527. read -ep "Press [Enter] to exit."
  528. cleanup
  529. exit 0
  530. fi
  531. }
  532. check_dependencies() {
  533. local dep_type=$1
  534. local DEPS
  535. local use_dnf=false
  536. [[ `which dnf 2>/dev/null` ]] && use_dnf=true
  537. case $dep_type in
  538. "base")
  539. DEPS=${DEPS_BASE[@]} ;;
  540. "flashrom")
  541. if [ $use_dnf = true ]; then
  542. DEPS=(${DEPS_BASE[@]} ${DEPS_FLASH_FEDORA[@]}) ;
  543. else
  544. DEPS=(${DEPS_BASE[@]} ${DEPS_FLASH[@]}) ;
  545. fi
  546. ;;
  547. "coreboot")
  548. if [ $use_dnf = true ]; then
  549. DEPS=(${DEPS_BASE[@]} ${DEPS_FLASH_FEDORA[@]} ${DEPS_GRUB2_FEDORA[@]}) ;
  550. else
  551. DEPS=(${DEPS_BASE[@]} ${DEPS_FLASH[@]} ${DEPS_COREBOOT[@]} ${DEPS_GRUB2[@]}) ;
  552. fi
  553. ;;
  554. *)
  555. ;;
  556. esac
  557. local pkg needed=()
  558. for pkg in "${DEPS[@]}"; do
  559. if [[ ! `which ${pkg} 2>/dev/null` \
  560. && ! `dnf list installed 2>/dev/null | grep "^${pkg}"` \
  561. && ! `apt list --installed 2>/dev/null | grep "^${pkg}"` \
  562. && ! -f "/usr/share/doc/${pkg}/copyright" ]]; then
  563. needed+=("${pkg}")
  564. fi
  565. done
  566. if [[ "${#needed[@]}" -gt 0 ]]; then
  567. echo ""
  568. echo "One or more required dependencies are missing: ${needed[@]}"
  569. echo "The script will now attempt to install them for you"
  570. echo ""
  571. read -rp "Press [Enter] to continue " discard
  572. echo ""
  573. if [ $use_dnf = true ]; then
  574. if ! sudo dnf -y install "${needed[@]}" ; then
  575. die "Some required dependencies could not be installed automatically"
  576. fi
  577. elif which apt >/dev/null ; then
  578. sudo apt-get update >/dev/null 2>&1
  579. if ! sudo apt-get -y install "${needed[@]}" ; then
  580. die "Some required dependencies could not be installed automatically"
  581. fi
  582. else
  583. echo "The script was unable to install the required dependencies automatically"
  584. echo ""
  585. die "Please ensure all required dependencies are installed and re-run this script"
  586. fi
  587. fi
  588. }
  589. # Start of main script
  590. # let's do stuff
  591. check_root
  592. check_dependencies "base"
  593. check_dependencies "flashrom"
  594. check_dependencies "coreboot"
  595. initial_setup
  596. print_info
  597. get_flashrom
  598. build_coreboot