4 # See README and https://www.coreboot.org/Board_Status for instructions.
9 # Stuff from command-line switches
10 COREBOOT_IMAGE
="build/coreboot.rom"
15 SERIAL_PORT_SPEED
=115200
17 # Used to specify whether a command should always be run locally or
18 # if command should be run remoteley when a remote host is specified.
24 # Used if cbmem is not in default $PATH, e.g. not installed or when using `sudo`
27 # Used if nvramtool is not in default $PATH, e.g. not installed or when using `sudo`
32 if [ ! -x /usr
/local
/bin
/gmake
]; then
33 echo "Please install gmake, or build and install devel/gmake from ports."
46 # $1: 0 ($LOCAL) to run command locally,
47 # 1 ($REMOTE) to run remotely if remote host defined
49 # $3: 0 ($FATAL) Exit with an error if the command fails
50 # 1 ($NONFATAL) Don't exit on command test failure
59 if [ "$1" -eq "$REMOTE" ] && [ -n "$REMOTE_HOST" ]; then
60 ssh $REMOTE_PORT_OPTION root@
${REMOTE_HOST} command -v "$2" > /dev
/null
63 command -v "$2" >/dev
/null
67 if [ $rc -eq 0 ]; then
71 if [ "$3" = "1" ]; then
88 pipe_location
="/dev/null"
91 if [ "$1" -eq "$REMOTE" ] && [ -n "$REMOTE_HOST" ]; then
92 ssh $REMOTE_PORT_OPTION "root@${REMOTE_HOST}" "$2" > "$pipe_location" 2>&1
94 $2 > "$pipe_location" 2>&1
102 # $1: 0 ($LOCAL) to run command locally,
103 # 1 ($REMOTE) to run remotely if remote host defined
105 # $3: filename to direct output of command into
110 if [ $?
-eq 0 ]; then
114 echo "Failed to run \"$2\", aborting"
115 rm -f "$3" # don't leave an empty file
119 # run a command where failure is considered to be non-fatal
121 # $1: 0 ($LOCAL) to run command locally,
122 # 1 ($REMOTE) to run remotely if remote host defined
124 # $3: filename to direct output of command into
129 if [ $?
-eq 0 ]; then
133 echo "Failed to run \"$2\", ignoring"
134 rm -f "$3" # don't leave an empty file
137 # read from a serial port device
139 # $1: serial device to read from
140 # $2: serial port speed
141 # $3: filename to direct output of command into
142 get_serial_bootlog
() {
148 if [ ! -c "$TTY" ]; then
149 echo "$TTY is not a valid serial device"
153 # make the text more noticible
154 test_cmd
$LOCAL "tput" $NONFATAL
155 tput_not_available
=$?
156 if [ $tput_not_available -eq 0 ]; then
158 tput setaf
10 # set bright green
162 echo "Waiting to receive boot log from $TTY"
163 echo "Press [Enter] when the boot is complete."
166 if [ $tput_not_available -eq 0 ]; then
170 # set up the serial port
171 stty
-F $TTY $SPEED cs8
-cstopb -parenb clocal
173 # read from the serial port - user must press enter when complete
174 test_cmd
$LOCAL "tee"
176 echo "$LINE" |
tee -a "$FILENAME"
177 done < "$SERIAL_DEVICE" &
181 kill "$PID" 2>/dev
/null
183 echo "Finished reading boot log."
192 Path to cbmem on device under test (DUT).
194 Path to nvramtool on device under test (DUT).
196 Clobber temporary output when finished. Useful for debugging.
200 Path to coreboot image (Default is $COREBOOT_IMAGE).
201 -r, --remote-host <host>
202 Obtain machine information from remote host (using ssh).
203 -s, --serial-device </dev/xxx>
204 Obtain boot log via serial device.
205 -S, --serial-speed <speed>
206 Set the port speed for the serial device (Default is $SERIAL_PORT_SPEED).
208 Upload results to coreboot.org.
212 Use a specific SSH port.
218 if [ ! -x /usr
/local
/bin
/getopt
]; then
219 echo "Please install getopt, or build and install misc/getopt from ports."
222 GETOPT
=/usr
/local
/bin
/getopt
226 GETOPT
=/usr
/bin
/getopt
231 if [ $?
-ne 4 ]; then
232 echo "GNU-compatible getopt(1) required."
236 LONGOPTS
="cbmem:,clobber,help,image:,remote-host:,upload-results"
237 LONGOPTS
="${LONGOPTS},serial-device:,serial-speed:"
238 LONGOPTS
="${LONGOPTS},ssh-port:"
240 ARGS
=$
($GETOPT -o c
:n
:Chi
:r
:s
:S
:u
-l "$LONGOPTS" -n "$0" -- "$@");
241 if [ $?
!= 0 ] ; then echo "Terminating..." >&2 ; exit 1 ; fi
273 # serial port options
280 SERIAL_PORT_SPEED
="$1"
286 REMOTE_PORT_OPTION
="-p $1"
293 echo "Non-option parameters detected: '$*'"
299 echo "error processing options at '$1'"
305 grep -rH 'coreboot.org' .git
/config
>/dev
/null
2>&1
306 if [ $?
-ne 0 ]; then
307 echo "Script must be run from root of coreboot directory"
311 if [ ! -e "$COREBOOT_IMAGE" ]; then
312 echo "board_status needs $COREBOOT_IMAGE, but it does not exist."
313 echo "Use \"-i IMAGE_FILE\" to select a different image, or \"--help\" for more options."
317 # Results will be placed in a temporary location until we're ready to upload.
318 # If the user does not wish to upload, results will remain in /tmp.
321 tmpdir
=$
(mktemp
-d -t coreboot_board_status
)
324 tmpdir
=$
(mktemp
-d --tmpdir coreboot_board_status.XXXXXXXX
)
328 # Obtain coreboot config by running cbfstool on the ROM image. cbfstool may
329 # already exist in build/ or util/cbfstool/, but if not then we'll build it
330 # now and clean it when we're done.
331 cbfstool_cmd
="build/cbfstool"
333 if [ ! -x $cbfstool_cmd ]; then
334 cbfstool_cmd
="util/cbfstool/cbfstool"
335 if [ -e $cbfstool_cmd ]; then
336 if test ! -x $cbfstool_cmd; then
337 echo "Cannot execute $cbfstool_cmd."
341 $MAKE -C util
/cbfstool
/
345 test_cmd
$LOCAL "$cbfstool_cmd"
347 tmpcfg
=$
(mktemp coreboot_config.XXXXXX
)
348 echo "Extracting config.txt from $COREBOOT_IMAGE"
349 $cbfstool_cmd "$COREBOOT_IMAGE" extract
-n config
-f "${tmpdir}/config.txt" >/dev
/null
2>&1
350 mv "${tmpdir}/config.txt" "${tmpdir}/config.short.txt"
351 cp "${tmpdir}/config.short.txt" "${tmpcfg}"
352 yes "" |
$MAKE "DOTCONFIG=${tmpcfg}" oldconfig
2>/dev
/null
>/dev
/null
353 mv "${tmpcfg}" "${tmpdir}/config.txt"
354 rm -f "${tmpcfg}.old"
355 $cbfstool_cmd "$COREBOOT_IMAGE" print
> "${tmpdir}/cbfs.txt"
356 rom_contents
=$
($cbfstool_cmd "$COREBOOT_IMAGE" print
2>&1)
357 if [ -n "$(echo $rom_contents | grep payload_config)" ]; then
358 echo "Extracting payload_config from $COREBOOT_IMAGE"
359 $cbfstool_cmd "$COREBOOT_IMAGE" extract
-n payload_config
-f "${tmpdir}/payload_config.txt" >/dev
/null
2>&1
361 if [ -n "$(echo $rom_contents | grep payload_version)" ]; then
362 echo "Extracting payload_version from $COREBOOT_IMAGE"
363 $cbfstool_cmd "$COREBOOT_IMAGE" extract
-n payload_version
-f "${tmpdir}/payload_version.txt" >/dev
/null
2>&1
367 md5
"$COREBOOT_IMAGE" > "${tmpdir}/rom_checksum.txt"
370 md5sum -b "$COREBOOT_IMAGE" > "${tmpdir}/rom_checksum.txt"
374 if test $do_clean_cbfstool -eq 1; then
375 $MAKE -C util
/cbfstool clean
378 # Obtain board and revision info to form the directory structure:
379 # <vendor>/<board>/<revision>/<timestamp>
380 mainboard_dir
="$(grep CONFIG_MAINBOARD_DIR "${tmpdir}/config.txt
" | awk -F '"' '{ print
$2 }')"
381 vendor=$(echo "$mainboard_dir" | awk -F '/' '{ print
$1 }')
382 mainboard=$(echo "$mainboard_dir" | awk -F '/' '{ print
$2 }')
384 getrevision="util/board_status/getrevision.sh"
385 test_cmd $LOCAL $getrevision
386 tagged_version=$($getrevision -T)
387 timestamp=$($getrevision -t)
389 results="${vendor}/${mainboard}/${tagged_version}/${timestamp}"
391 if [ -n "$(echo $tagged_version | grep dirty)" ]; then
392 echo "The repository is in a dirty state. Please see the output of"
393 echo "'git status
' below."
398 echo "Temporarily placing output in ${tmpdir}/${results}"
399 mkdir -p "${tmpdir}/${results}"
401 mv "${tmpdir}/config.txt" "${tmpdir}/${results}"
402 test -f "${tmpdir}/payload_config.txt" && mv "${tmpdir}/payload_config.txt" "${tmpdir}/${results}"
403 test -f "${tmpdir}/payload_version.txt" && mv "${tmpdir}/payload_version.txt" "${tmpdir}/${results}"
404 mv "${tmpdir}/config.short.txt" "${tmpdir}/${results}"
405 mv "${tmpdir}/cbfs.txt" "${tmpdir}/${results}"
406 mv "${tmpdir}/rom_checksum.txt" "${tmpdir}/${results}"
408 touch "${tmpdir}/${results}/revision.txt"
409 printf "Local revision: %s\n" "$($getrevision -l)" >> "${tmpdir}/${results}/revision.txt"
410 printf "Tagged revision: %s\n" "${tagged_version}" >> "${tmpdir}/${results}/revision.txt"
411 printf "Upstream revision: %s\n" "$($getrevision -u)" >> "${tmpdir}/${results}/revision.txt"
412 printf "Upstream URL: %s\n" "$($getrevision -U)" >> "${tmpdir}/${results}/revision.txt"
413 printf "Timestamp: %s\n" "$timestamp" >> "${tmpdir}/${results}/revision.txt"
415 if [ -n "$CBMEM_PATH" ]; then
416 cbmem_cmd="$CBMEM_PATH"
422 if grep -q "CONFIG_USE_OPTION_TABLE=y" "${tmpdir}/${results}/config.short.txt" > /dev/null; then
426 if [ -n "$NVRAMTOOL_PATH" ]; then
427 nvramtool_cmd="$NVRAMTOOL_PATH"
429 nvramtool_cmd="nvramtool"
432 if [ -n "$SERIAL_DEVICE" ]; then
433 get_serial_bootlog "$SERIAL_DEVICE" "$SERIAL_PORT_SPEED" "${tmpdir}/${results}/coreboot_console.txt"
434 elif [ -n "$REMOTE_HOST" ]; then
435 echo "Verifying that CBMEM is available on remote device"
436 test_cmd $REMOTE "$cbmem_cmd"
437 echo "Getting coreboot boot log"
438 cmd $REMOTE "$cbmem_cmd -1" "${tmpdir}/${results}/coreboot_console.txt"
439 echo "Getting timestamp data"
440 cmd_nonfatal $REMOTE "$cbmem_cmd -t" "${tmpdir}/${results}/coreboot_timestamps.txt"
442 if [ "$cmos_enabled" -eq 1 ]; then
443 echo "Verifying that nvramtool is available on remote device"
444 test_cmd $REMOTE "$nvramtool_cmd"
445 echo "Getting all CMOS values"
446 cmd $REMOTE "$nvramtool_cmd -a" "${tmpdir}/${results}/cmos_values.txt"
449 echo "Getting remote dmesg"
450 cmd $REMOTE dmesg "${tmpdir}/${results}/kernel_log.txt"
452 echo "Verifying that CBMEM is available"
453 if [ $(id -u) -ne 0 ]; then
454 command -v "$cbmem_cmd" >/dev/null
455 if [ $? -ne 0 ]; then
456 echo "Failed to run $cbmem_cmd. Check \$PATH or" \
457 "use -c to specify path to cbmem binary."
460 cbmem_cmd="sudo $cbmem_cmd"
463 test_cmd $LOCAL "$cbmem_cmd"
466 echo "Getting coreboot boot log"
467 cmd $LOCAL "$cbmem_cmd -1" "${tmpdir}/${results}/coreboot_console.txt"
469 echo "Getting timestamp data"
470 cmd_nonfatal $LOCAL "$cbmem_cmd -t" "${tmpdir}/${results}/coreboot_timestamps.txt"
472 if [ "$cmos_enabled" -eq 1 ]; then
473 echo "Verifying that nvramtool is available"
474 if [ $(id -u) -ne 0 ]; then
475 command -v "$nvramtool_cmd" >/dev/null
476 if [ $? -ne 0 ]; then
477 echo "Failed to run $nvramtool_cmd. Check \$PATH or" \
478 "use -n to specify path to nvramtool binary."
481 nvramtool_cmd="sudo $nvramtool_cmd"
484 test_cmd $LOCAL "$nvramtool_cmd"
487 echo "Getting all CMOS values"
488 cmd $LOCAL "$nvramtool_cmd -a" "${tmpdir}/${results}/cmos_values.txt"
491 echo "Getting local dmesg"
492 cmd $LOCAL "sudo dmesg" "${tmpdir}/${results}/kernel_log.txt"
498 if [ $(grep -- -dirty "${tmpdir}/${results}/coreboot_console.txt") ]; then
499 echo "coreboot or the payload are built from a source tree in a" \
500 "dirty state, making it hard to reproduce the result. Please" \
501 "check in your source tree with 'git status
'."
505 if [ $(grep -- unknown "${tmpdir}/${results}/coreboot_timestamps.txt" >/dev/null 2>&1) ]; then
506 echo "Unknown timestamps found in 'coreboot_timestamps.txt
'." \
507 "Please rebuild the 'cbmem
' utility and try again."
515 if [ $UPLOAD_RESULTS -eq 1 ]; then
516 # extract username from ssh://<username>@review.coreboot.org/blah
517 bsrepo=$(git config --get remote.origin.url | sed "s,\(.*\)/coreboot,\1/board-status,")
519 cd "util/board_status/"
520 if [ ! -e "board-status" ]; then
521 # FIXME: the board-status directory might get big over time.
522 # Is there a way we can push the results without fetching the
525 if [ $? -ne 0 ]; then
526 echo "Error cloning board-status repo, aborting."
533 echo "Checking for duplicate results"
534 # get any updates to board-status
537 echo "${tagged_version}" | grep dirty >/dev/null 2>&1
539 existing_results=$(git ls-files "${mainboard_dir}/${tagged_version}")
541 # reject duplicate results of non-dirty versions
542 if [ "${clean_version}" -eq 1 ] && [ -n "${existing_results}" ] ; then
543 echo "Result is a duplicate, aborting"
547 echo "Copying results to $(pwd)/${results}"
549 # Note: Result directory should be unique due to the timestamp.
550 cp -R "${tmpdir}/${vendor}" .
552 echo "Uploading results"
554 git commit -a -m "${mainboard_dir}/${tagged_version}/${timestamp}"
556 until git push origin main || test $count -eq 3; do
561 # Results have been uploaded so it's pointless to keep the
562 # temporary files around.
564 if test $count -eq 3; then
565 echo "Error uploading to board-status repo, aborting."
571 if [ $CLOBBER_OUTPUT -eq 1 ]; then
574 if [ $UPLOAD_RESULTS -eq 1 ]; then
576 echo "output files are in $(dirname $0)/board-status/${mainboard_dir}/${tagged_version}/${timestamp}"
579 echo "output files are in ${tmpdir}/${results}"