1#!/bin/bash
2set -eo pipefail
3
4help=$'Generate PNOR UBI image from a PNOR SquashFS Tarball
5
6Generates a UBI, Unsorted Block Images, PNOR image from a PNOR SquashFS Tarball.
7The PNOR SquashFS Tarball is generated from the generate-tar script.
8
9usage: generate-ubi [OPTION] <PNOR SquashFS Tarball>...
10
11Options:
12-f, --file <file>      Specify destination file. Defaults to
13$(pwd)/<PNOR Tarball FILE, removing .squashfs.tar>.ubi.mtd
14(For example, "generate-ubi my.pnor.squashfs.tar"
15would generate $(pwd)/my.pnor.ubi.mtd output.)
16-s, --size <MiB>       Specify the size of the PNOR UBI image in MiBs.
17Defaults to 128.
18-h, --help             Display this help text and exit.
19'
20# 128MiB is the default image size
21image_size="128"
22
23while [[ $# -gt 0 ]]; do
24  key="$1"
25  case $key in
26    -f|--file)
27      outfile="$2"
28      shift 2
29      ;;
30    -s|--size)
31      image_size="$2"
32      shift 2
33      ;;
34    -h|--help)
35      echo "$help"
36      exit
37      ;;
38    *)
39      tarball="$1"
40      shift 1
41      ;;
42  esac
43done
44
45if [ ! -f "${tarball}" ]; then
46  echo "Please enter a PNOR SquashFS Tarball."
47  echo "To generate PNOR SquashFS Tarball see generate-tar"
48  echo "$help"
49  exit 1
50fi
51
52if [[ -z $outfile ]]; then
53    # Remove .squashfs.tar from end if present and add .ubi.mtd
54    outfile=$(pwd)/${tarball%".squashfs.tar"}.ubi.mtd
55else
56  if [[ $outfile != /* ]]; then
57    outfile=$(pwd)/$outfile
58  fi
59fi
60
61echo "Generating PNOR UBI image."
62
63squashfs_file_name="pnor.xz.squashfs"
64manifest_file_name="MANIFEST"
65
66# Scratch directory for untarring and config file
67scratch_dir=$(mktemp -d)
68
69# Make sure scratch directory always gets cleaned up
70trap '{ rm -r ${scratch_dir}; }' EXIT
71
72squashfs_file=${scratch_dir}/${squashfs_file_name}
73manifest_file=${scratch_dir}/${manifest_file_name}
74# Untar tarball
75tar -xvf "${tarball}" -C "${scratch_dir}" ${squashfs_file_name} ${manifest_file_name}
76
77# All valid PNOR SquashFS Tarballs have a file named "pnor.xz.squashfs"
78if [ ! -f "${squashfs_file}" ]; then
79  echo "No \"${squashfs_file_name}\" file in the tarball!"
80  exit 1
81fi
82
83# Need the manifest file for calculating the version id
84if [ ! -f "${manifest_file}" ]; then
85  echo "No \"${manifest_file_name}\" file in the tarball!"
86  exit 1
87fi
88
89# Flash page size in bytes
90FLASH_PAGE_SIZE="1"
91# kibibyte(KiB)
92FLASH_PEB_SIZE="64"
93
94# Convert image size from MiB to KiB
95image_size=$((image_size * 1024))
96
97# Create UBI volume
98add_volume()
99{
100  config_file=$1
101  vol_id=$2
102  vol_type=$3
103  vol_name=$4
104  image=$5
105  vol_size=$6
106
107{
108  echo \["$vol_name"\]
109  echo mode=ubi
110} >> "$config_file"
111  if [ -n "$image" ]; then
112    echo image="$image" >> "$config_file"
113  fi
114{
115  echo vol_type="$vol_type"
116  echo vol_name="$vol_name"
117  echo vol_id="$vol_id"
118} >> "$config_file"
119  if [ -n "$vol_size" ]; then
120    echo vol_size="$vol_size" >> "$config_file"
121  fi
122}
123
124# Create an image with all 1's
125mk_nor_image()
126{
127  image_dst=$1
128  image_size_kb=$2
129  dd if=/dev/zero bs=1k count="$image_size_kb" | tr '\000' '\377' > "$image_dst"
130}
131
132# Used to temporary hold the UBI image
133tmpfile=$(mktemp "${scratch_dir}"/ubinized.XXXXXX)
134
135# Configuration file used to create UBI image
136config_file=${scratch_dir}/ubinize-PNOR.cfg
137
138# The version is listed in the MANIFEST file as "version=v1.99.10-19"
139# Use the version to calculate the version id, a unique 8 hexadecimal digit id
140version_id=$(sed -ne '/version=/ {s/version=//;p}' "${manifest_file}" | head -n1 | \
141  tr -d '\n' | sha512sum | cut -b 1-8)
142
143add_volume "$config_file" 0 static pnor-ro-"${version_id}" "${squashfs_file}"
144add_volume "$config_file" 1 dynamic pnor-prsv "" 2MiB
145add_volume "$config_file" 2 dynamic pnor-rw-"${version_id}" "" 16MiB
146
147# Build the UBI image
148ubinize -p ${FLASH_PEB_SIZE}KiB -m ${FLASH_PAGE_SIZE} -o "${tmpfile}" "$config_file"
149mk_nor_image "${outfile}" "${image_size}"
150dd bs=1k conv=notrunc seek=0 if="${tmpfile}" of="${outfile}"
151
152echo "PNOR UBI image at ${outfile}"
153