From 5a7902c5ab6913a509ffff4db0a21f43d245305b Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Wed, 26 Oct 2022 15:14:29 -0400 Subject: [PATCH 1/4] flash.sh: single firmware read backup and logic fixes - Have Talos II supported by detecting correctly size of mtd chip (not internal: different flashrom output needs to be parsed for chip size) - Read SPI content only once: 66% speedup (TOCTOU? Don't think so, nothing should happen in parallel when flashing insingle user mode) - Have the main flash_progress loop not break, but break in flash_rom state subcases (otherwise, verifying step was breaking) - Change "Initializing internal Flash Programmer" -> "Initializing Flash Programmer" - Apply changes suggested by @SergiiDmytruk under https://github.com/osresearch/heads/pull/1230#issuecomment-1295332539 to reduce userland wasted time processing flashrom -V output --- initrd/bin/flash.sh | 40 +++++++++++++++++++++------------------- 1 file changed, 21 insertions(+), 19 deletions(-) diff --git a/initrd/bin/flash.sh b/initrd/bin/flash.sh index d414fdc61..d58cfcef1 100755 --- a/initrd/bin/flash.sh +++ b/initrd/bin/flash.sh @@ -27,21 +27,23 @@ flashrom_progress() { local status='init' local prev_word='' local prev_prev_word='' + local spaces=' ' + local hashes='##################################################' progressbar2=$(for i in `seq 48` ; do echo -ne ' ' ; done) - echo -e "\nInitializing internal Flash Programmer" + echo -e "\nInitializing Flash Programmer" while true ; do prev_prev_word=$prev_word prev_word=$IN - read -r -d' ' IN || break + read -r -d' ' IN 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) + current=$(echo "$IN" | sed -nE 's/.*(0x[0-9a-f]+).*/\1/p') if [ "${current}" != "" ]; then percent=$((100 * (current + 1) / total_bytes)) pct1=$((percent / 2)) - pct2=$((49 - percent / 2)) - progressbar=$(for i in `seq $pct1 2>/dev/null` ; do echo -ne '#' ; done) - progressbar2=$(for i in `seq $pct2 2>/dev/null` ; do echo -ne ' ' ; done) + pct2=$((50 - percent / 2)) + progressbar=${hashes:0:$pct1} + progressbar2=${spaces:0:$pct2} fi else if [ "$prev_prev_word" == "Reading" ] && [ "$IN" == "bytes" ]; then @@ -51,6 +53,11 @@ flashrom_progress() { echo "Total flash size : $total_bytes bytes" fi fi + if [ "$prev_word" == "total_size:" ]; then + # Next is total size in bytes + total_bytes=$(echo "$IN" | grep -E -o '[0-9]+') + echo "Total flash size : $total_bytes bytes" + fi fi if [ "$percent" -gt 99 ]; then spin_idx=4 @@ -77,14 +84,19 @@ flashrom_progress() { fi if echo "$IN" | grep "identical" > /dev/null ; then status="done" - echo "" + echo "" echo "The flash contents are identical to the image being flashed." + break 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." + break + elif echo "${IN}" | grep "FAILED" > /dev/null ; then + echo 'Error while verifying flash content' + break fi fi done @@ -101,18 +113,8 @@ flashrom_progress() { flash_rom() { ROM=$1 if [ "$READ" -eq 1 ]; then - flashrom $CONFIG_FLASHROM_OPTIONS -r "${ROM}.1" \ - || die "$ROM: Read failed" - flashrom $CONFIG_FLASHROM_OPTIONS -r "${ROM}.2" \ - || die "$ROM: Read failed" - flashrom $CONFIG_FLASHROM_OPTIONS -r "${ROM}.3" \ - || die "$ROM: Read failed" - if [ `sha256sum ${ROM}.[123] | cut -f1 -d ' ' | uniq | wc -l` -eq 1 ]; then - mv ${ROM}.1 $ROM - rm ${ROM}.[23] - else - die "$ROM: Read inconsistent" - fi + flashrom $CONFIG_FLASHROM_OPTIONS -r "${ROM}" \ + || die "Backup to $ROM failed" else cp "$ROM" /tmp/${CONFIG_BOARD}.rom sha256sum /tmp/${CONFIG_BOARD}.rom From 1279e8bd575df68cb70d05100142dadb30baa7d3 Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Tue, 30 Aug 2022 17:53:57 -0400 Subject: [PATCH 2/4] Change patch to git apply --- Makefile | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index 1373bff03..a52df02bd 100644 --- a/Makefile +++ b/Makefile @@ -260,7 +260,7 @@ define define_module = git clone $($1_repo) "$(build)/$($1_base_dir)" cd $(build)/$($1_base_dir) && git reset --hard $($1_commit_hash) && git submodule update --init --checkout if [ -r patches/$($1_patch_name).patch ]; then \ - ( cd $(build)/$($1_base_dir) ; patch -p1 ) \ + ( git apply --verbose --reject --binary --directory build/$(CONFIG_TARGET_ARCH)/$($1_base_dir) ) \ < patches/$($1_patch_name).patch \ || exit 1 ; \ fi @@ -268,7 +268,7 @@ define define_module = [ -r patches/$($1_patch_name) ] ; then \ for patch in patches/$($1_patch_name)/*.patch ; do \ echo "Applying patch file : $$$$patch " ; \ - ( cd $(build)/$($1_base_dir) ; patch -p1 ) \ + ( git apply --verbose --reject --binary --directory build/$(CONFIG_TARGET_ARCH)/$($1_base_dir) ) \ < $$$$patch \ || exit 1 ; \ done ; \ @@ -296,7 +296,7 @@ define define_module = mkdir -p "$$(dir $$@)" tar -xf "$(packages)/$($1_tar)" $(or $($1_tar_opt),--strip 1) -C "$$(dir $$@)" if [ -r patches/$($1_patch_name).patch ]; then \ - ( cd $$(dir $$@) ; patch -p1 ) \ + ( git apply --verbose --reject --binary --directory build/$(CONFIG_TARGET_ARCH)/$($1_base_dir) ) \ < patches/$($1_patch_name).patch \ || exit 1 ; \ fi @@ -304,7 +304,7 @@ define define_module = [ -r patches/$($1_patch_name) ] ; then \ for patch in patches/$($1_patch_name)/*.patch ; do \ echo "Applying patch file : $$$$patch " ; \ - ( cd $$(dir $$@) ; patch -p1 ) \ + ( git apply --verbose --reject --binary --directory build/$(CONFIG_TARGET_ARCH)/$($1_base_dir) ) \ < $$$$patch \ || exit 1 ; \ done ; \ From a8a843ecc80d057e614cef2bf493497bf7270271 Mon Sep 17 00:00:00 2001 From: Jonathon Hall Date: Wed, 2 Nov 2022 11:03:30 -0400 Subject: [PATCH 3/4] mount-usb: Improve reliability with partitioned disks Extract exclusion for unpartitioned block device of partitioned media to gui_functions, and exclude them even if kernel hasn't listed the partitions yet. (Fixes flash/USB boot prompts incorrectly trying to use the whole device for partitioned media the first time.) Ignore block devices of size 0, like empty USB SD card readers. Signed-off-by: Jonathon Hall --- initrd/bin/mount-usb | 28 ++++++---------------------- initrd/etc/functions | 30 ++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 22 deletions(-) diff --git a/initrd/bin/mount-usb b/initrd/bin/mount-usb index 7abeea060..2394951c6 100755 --- a/initrd/bin/mount-usb +++ b/initrd/bin/mount-usb @@ -5,13 +5,12 @@ enable_usb if ! lsmod | grep -q usb_storage; then - count=$(ls /dev/sd* 2>/dev/null | wc -l) timeout=0 echo "Scanning for USB storage devices..." insmod /lib/modules/usb-storage.ko >/dev/null 2>&1 \ || die "usb_storage: module load failed" - while [[ $count == $(ls /dev/sd* 2>/dev/null | wc -l) ]]; do - [[ $timeout -ge 4 ]] && break + while [[ $(list_usb_storage | wc -l) -eq 0 ]]; do + [[ $timeout -ge 8 ]] && break sleep 1 timeout=$(($timeout+1)) done @@ -21,7 +20,7 @@ if [ ! -d /media ]; then mkdir /media fi -stat -c %N /sys/block/sd* 2>/dev/null | grep usb | cut -f1 -d ' ' | sed "s/[']//g;s|/sys/block|/dev|" > /tmp/usb_block_devices +list_usb_storage > /tmp/usb_block_devices if [ -z `cat /tmp/usb_block_devices` ]; then if [ -x /bin/whiptail ]; then whiptail $BG_COLOR --title 'USB Drive Missing' \ @@ -31,7 +30,7 @@ if [ -z `cat /tmp/usb_block_devices` ]; then read fi sleep 1 - stat -c %N /sys/block/sd* 2>/dev/null | grep usb | cut -f1 -d ' ' | sed "s/[']//g;s|/sys/block|/dev|" > /tmp/usb_block_devices + list_usb_storage > /tmp/usb_block_devices if [ -z `cat /tmp/usb_block_devices` ]; then if [ -x /bin/whiptail ]; then whiptail $BG_COLOR_ERROR --title 'ERROR: USB Drive Missing' \ @@ -46,28 +45,13 @@ fi USB_MOUNT_DEVICE="" # Check for the common case: a single USB disk with one partition if [ `cat /tmp/usb_block_devices | wc -l` -eq 1 ]; then - USB_BLOCK_DEVICE=`cat /tmp/usb_block_devices` - # Subtract out block device - let USB_NUM_PARTITIONS=`ls -1 ${USB_BLOCK_DEVICE}* | wc -l`-1 - if [ ${USB_NUM_PARTITIONS} -eq 0 ]; then - USB_MOUNT_DEVICE=${USB_BLOCK_DEVICE} - elif [ ${USB_NUM_PARTITIONS} -eq 1 ]; then - USB_MOUNT_DEVICE=`ls -1 ${USB_BLOCK_DEVICE}* | tail -n1` - fi + USB_MOUNT_DEVICE=`cat /tmp/usb_block_devices` fi # otherwise, let the user pick if [ -z ${USB_MOUNT_DEVICE} ]; then > /tmp/usb_disk_list for i in `cat /tmp/usb_block_devices`; do - # remove block device from list if numeric partitions exist, since not bootable - let USB_NUM_PARTITIONS=`ls -1 $i* | wc -l`-1 - if [ ${USB_NUM_PARTITIONS} -eq 0 ]; then - echo $i $(blkid | grep $i | grep -o 'LABEL=".*"' | cut -f2 -d '"') >> /tmp/usb_disk_list - else - for j in $(ls $i* | tail -${USB_NUM_PARTITIONS}); do - echo $j $(blkid | grep $j | grep -o 'LABEL=".*"' | cut -f2 -d '"') >> /tmp/usb_disk_list - done - fi + echo $i $(blkid | grep $i | grep -o 'LABEL=".*"' | cut -f2 -d '"') >> /tmp/usb_disk_list done if [ -x /bin/whiptail ]; then diff --git a/initrd/etc/functions b/initrd/etc/functions index b134da9c6..a445b25b4 100755 --- a/initrd/etc/functions +++ b/initrd/etc/functions @@ -132,6 +132,36 @@ enable_usb() } +list_usb_storage() +{ + stat -c %N /sys/block/sd* 2>/dev/null | grep usb | + cut -f1 -d ' ' | + sed "s/[']//g" | + while read b; do + # Ignore devices of size 0, such as empty SD card + # readers on laptops attached via USB. + if [ "$(cat "$b/size")" -gt 0 ]; then + echo "$b" + fi + done | + sed "s|/sys/block|/dev|" | + while read b; do + # If the device has a partition table, ignore it and + # include the partitions instead - even if the kernel + # hasn't detected the partitions yet. Such a device is + # never usable directly, and this allows the "wait for + # disks" loop in mount-usb to correctly wait for the + # partitions. + if fdisk -l "$b" | grep -q "doesn't contain a valid partition table"; then + # No partition table, include this device + echo "$b" + else + # Has a partition table, include partitions + ls -1 "$b"* | awk 'NR!=1 {print $0}' + fi + done +} + confirm_gpg_card() { read \ From 297369fd8b68d0d573f671417638c5b54c95ce5b Mon Sep 17 00:00:00 2001 From: Matt DeVillier Date: Fri, 29 Apr 2022 15:58:34 -0500 Subject: [PATCH 4/4] oem-factory-reset: Add missing newline to prompt Signed-off-by: Matt DeVillier --- initrd/bin/oem-factory-reset | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/initrd/bin/oem-factory-reset b/initrd/bin/oem-factory-reset index e479d2f7d..247d9054d 100755 --- a/initrd/bin/oem-factory-reset +++ b/initrd/bin/oem-factory-reset @@ -360,7 +360,7 @@ if ! whiptail --yesno " $TPM_STR * ERASE any keys or passwords on the GPG smart card,\n reset it to a factory state, generate new keys\n - and optionally set custom PIN(s) + and optionally set custom PIN(s)\n * Add the new GPG key to the firmware and reflash it\n * Sign all of the files in /boot with the new GPG key\n\n It requires that you already have an OS installed on a\n