| #!/bin/bash | 
 | set -eo pipefail | 
 |  | 
 | help=$'Generate Tarball with PNOR SquashFS image and MANIFEST Script | 
 |  | 
 | Generates a PNOR SquashFS image from the PNOR image | 
 | Creates a MANIFEST for image verification and recreation | 
 | Packages the SquashFS image and MANIFEST together in a tarball | 
 |  | 
 | usage: generate-squashfs [OPTION] <PNOR FILE>... | 
 |  | 
 | Options: | 
 |    -f, --file <file>      Specify destination file. Defaults to | 
 |                           `pwd`/<PNOR FILE>.pnor.squashfs.tar if unspecified. | 
 |                           (For example, "generate-squashfs my.pnor" would | 
 |                           generate `pwd`/my.pnor.squashfs.tar output.) | 
 |    -h, --help             Display this help text and exit. | 
 | ' | 
 | # Reference the ffs structures at: | 
 | # https://github.com/open-power/hostboot/blob/master/src/usr/pnor/common/ffs_hb.H | 
 | # https://github.com/open-power/hostboot/blob/master/src/usr/pnor/ffs.h | 
 | let ffs_entry_size=128 | 
 | let vercheck_offset=112 | 
 | outfile="" | 
 | declare -a partitions=() | 
 | tocfile="pnor.toc" | 
 |  | 
 | while [[ $# -gt 0 ]]; do | 
 |   key="$1" | 
 |   case $key in | 
 |     -f|--file) | 
 |       outfile="$2" | 
 |       shift 2 | 
 |       ;; | 
 |     -h|--help) | 
 |       echo "$help" | 
 |       exit | 
 |       ;; | 
 |     *) | 
 |       pnorfile="$1" | 
 |       shift 1 | 
 |       ;; | 
 |   esac | 
 | done | 
 |  | 
 | if [ ! -f "${pnorfile}" ]; then | 
 |   echo "Please enter a valid PNOR file." | 
 |   echo "$help" | 
 |   exit 1 | 
 | fi | 
 |  | 
 | if [[ -z $outfile ]]; then | 
 |     if [[ ${pnorfile##*.} == "pnor" ]]; then | 
 |         outfile=`pwd`/${pnorfile##*/}.squashfs.tar | 
 |     else | 
 |         outfile=`pwd`/${pnorfile##*/}.pnor.squashfs.tar | 
 |     fi | 
 | else | 
 |     if [[ $outfile != /* ]]; then | 
 |         outfile=`pwd`/$outfile | 
 |     fi | 
 | fi | 
 |  | 
 | scratch_dir=`mktemp -d` | 
 |  | 
 | echo "Parsing PNOR TOC..." | 
 |  | 
 | pflash --partition=part --read=${scratch_dir}/part -F ${pnorfile} | 
 | pflash --partition=VERSION --read=${scratch_dir}/VERSION -F ${pnorfile} | 
 | { | 
 |   version=$(head -n 1 ${scratch_dir}/VERSION) | 
 |   echo "version=$version" | 
 |   extended_version=$(echo $(tail -n +2 ${scratch_dir}/VERSION)|tr ' ' ',') | 
 |   echo "extended_version=$extended_version" | 
 |   while read line; do | 
 |     if [[ $line == "ID="* ]]; then | 
 |         # This line looks like | 
 |         # "ID=05 MVPD 000d9000..00169000 (actual=00090000) [ECC]" | 
 |         read -r -a fields <<< "$line" | 
 |  | 
 |         id=${fields[0]##*=} | 
 |         offset=$((${ffs_entry_size} * 10#${id} + ${vercheck_offset})) | 
 |         vercheck=$(xxd -p -l  0x1 -seek ${offset} ${scratch_dir}/part) | 
 |         export flags=$(pflash --detail=$((10#$id)) -F ${pnorfile} | grep "\[" | | 
 |                 sed 's/....$//' | tr '\n' ',' | sed 's/.$//') | 
 |         if [[ $flags != "" ]]; then | 
 |             flags=,$flags | 
 |         fi | 
 |  | 
 |         if [[ $(echo $flags | grep "READONLY") == "" && | 
 |               $(echo $flags | grep "PRESERVED") == "" ]]; then | 
 |             flags=$flags,READWRITE | 
 |         fi | 
 |  | 
 |         # Need the partition ID, name, start location, end location, and flags | 
 |         echo  "partition${id}=${fields[1]},${fields[2]/../,},${vercheck}${flags}" | 
 |  | 
 |         # Save the partition name | 
 |         partitions+=(${fields[1]}) | 
 |     fi | 
 |   # Don't need the BACKUP_PART partition | 
 |   done < <(pflash --info -F ${pnorfile} | grep -v "BACKUP") | 
 | } > ${scratch_dir}/${tocfile} | 
 |  | 
 | for partition in "${partitions[@]}"; do | 
 |   echo "Reading ${partition}..." | 
 |   pflash --partition=${partition} \ | 
 |     --read=${scratch_dir}/${partition} \ | 
 |     -F ${pnorfile} | 
 | done | 
 |  | 
 | echo "Creating SquashFS image..." | 
 | cd "${scratch_dir}" | 
 | mksquashfs ${tocfile} ${partitions[*]} pnor.xz.squashfs | 
 |  | 
 | echo "Creating MANIFEST for the image" | 
 | manifest_location="MANIFEST" | 
 | echo -e "purpose=xyz.openbmc_project.Software.Version.VersionPurpose.Host\nversion=$version\n\ | 
 | extended_version=$extended_version" >> $manifest_location | 
 |  | 
 | echo "Generating tarball to contain the SquashFS image and its MANIFEST" | 
 | tar -cvf $outfile $manifest_location pnor.xz.squashfs | 
 |  | 
 | echo "SquashFSTarball at ${outfile}" | 
 | rm -r "${scratch_dir}" |