| OLD | NEW |
| 1 #!/bin/bash | 1 #!/bin/bash |
| 2 | 2 |
| 3 # Copyright (c) 2009 The Chromium OS Authors. All rights reserved. | 3 # Copyright (c) 2009 The Chromium OS Authors. All rights reserved. |
| 4 # Use of this source code is governed by a BSD-style license that can be | 4 # Use of this source code is governed by a BSD-style license that can be |
| 5 # found in the LICENSE file. | 5 # found in the LICENSE file. |
| 6 | 6 |
| 7 # Script to convert the output of build_image.sh to a usb image. | 7 # Script to convert the output of build_image.sh to a usb image. |
| 8 | 8 |
| 9 # Load common constants. This should be the first executable line. | 9 # Load common constants. This should be the first executable line. |
| 10 # The path to common.sh should be relative to your script's location. | 10 # The path to common.sh should be relative to your script's location. |
| 11 . "$(dirname "$0")/common.sh" | 11 . "$(dirname "$0")/common.sh" |
| 12 | 12 |
| 13 get_default_board | 13 get_default_board |
| 14 | 14 |
| 15 # Flags | 15 # Flags |
| 16 DEFINE_string board "$DEFAULT_BOARD" "Board for which the image was built" | 16 DEFINE_string board "${DEFAULT_BOARD}" "Board for which the image was built" |
| 17 DEFINE_string from "" \ | 17 DEFINE_string from "" \ |
| 18 "Directory containing rootfs.image and mbr.image" | 18 "Directory containing rootfs.image and mbr.image" |
| 19 DEFINE_string to "" "$DEFAULT_TO_HELP" | 19 DEFINE_string to "" "${DEFAULT_TO_HELP}" |
| 20 DEFINE_boolean yes $FLAGS_FALSE "Answer yes to all prompts" "y" | 20 DEFINE_boolean yes ${FLAGS_FALSE} "Answer yes to all prompts" "y" |
| 21 DEFINE_boolean install_autotest $FLAGS_FALSE \ | 21 DEFINE_boolean install_autotest ${FLAGS_FALSE} \ |
| 22 "Whether to install autotest to the stateful partition." | 22 "Whether to install autotest to the stateful partition." |
| 23 DEFINE_boolean copy_kernel $FLAGS_FALSE \ | 23 DEFINE_boolean copy_kernel ${FLAGS_FALSE} \ |
| 24 "Copy the kernel to the fourth partition." | 24 "Copy the kernel to the fourth partition." |
| 25 DEFINE_boolean test_image "${FLAGS_FALSE}" \ |
| 26 "Uses test image if available, otherwise creates one as rootfs_test.image." |
| 25 | 27 |
| 26 # Parse command line | 28 # Parse command line |
| 27 FLAGS "$@" || exit 1 | 29 FLAGS "$@" || exit 1 |
| 28 eval set -- "${FLAGS_ARGV}" | 30 eval set -- "${FLAGS_ARGV}" |
| 29 | 31 |
| 30 # Inside the chroot, so output to usb.img in the same dir as the other | 32 # Inside the chroot, so output to usb.img in the same dir as the other |
| 31 # Script can be run either inside or outside the chroot. | 33 # Script can be run either inside or outside the chroot. |
| 32 if [ $INSIDE_CHROOT -eq 1 ] | 34 if [ ${INSIDE_CHROOT} -eq 1 ] |
| 33 then | 35 then |
| 34 AUTOTEST_SRC="/usr/local/autotest/${FLAGS_board}" | 36 AUTOTEST_SRC="/usr/local/autotest/${FLAGS_board}" |
| 35 else | 37 else |
| 36 AUTOTEST_SRC="${DEFAULT_CHROOT_DIR}/usr/local/autotest/${FLAGS_board}" | 38 AUTOTEST_SRC="${DEFAULT_CHROOT_DIR}/usr/local/autotest/${FLAGS_board}" |
| 37 fi | 39 fi |
| 38 | 40 |
| 39 # Die on any errors. | 41 # Die on any errors. |
| 40 set -e | 42 set -e |
| 41 | 43 |
| 42 # No board, no default and no image set then we can't find the image | 44 # No board, no default and no image set then we can't find the image |
| 43 if [ -z $FLAGS_from ] && [ -z $FLAGS_board ] ; then | 45 if [ -z ${FLAGS_from} ] && [ -z ${FLAGS_board} ] ; then |
| 44 setup_board_warning | 46 setup_board_warning |
| 45 exit 1 | 47 exit 1 |
| 46 fi | 48 fi |
| 47 | 49 |
| 48 # We have a board name but no image set. Use image at default location | 50 # We have a board name but no image set. Use image at default location |
| 49 if [ -z "$FLAGS_from" ]; then | 51 if [ -z "${FLAGS_from}" ]; then |
| 50 IMAGES_DIR="${DEFAULT_BUILD_ROOT}/images/${FLAGS_board}" | 52 IMAGES_DIR="${DEFAULT_BUILD_ROOT}/images/${FLAGS_board}" |
| 51 FLAGS_from="${IMAGES_DIR}/$(ls -t $IMAGES_DIR 2>&-| head -1)" | 53 FLAGS_from="${IMAGES_DIR}/$(ls -t ${IMAGES_DIR} 2>&-| head -1)" |
| 52 fi | 54 fi |
| 53 | 55 |
| 54 if [ ! -d "$FLAGS_from" ] ; then | 56 if [ ! -d "${FLAGS_from}" ] ; then |
| 55 echo "Cannot find image directory $FLAGS_from" | 57 echo "Cannot find image directory ${FLAGS_from}" |
| 56 exit 1 | 58 exit 1 |
| 57 fi | 59 fi |
| 58 | 60 |
| 59 # If to isn't explicitly set | 61 # If to isn't explicitly set |
| 60 if [ -z "$FLAGS_to" ]; then | 62 if [ -z "${FLAGS_to}" ]; then |
| 61 # Script can be run either inside or outside the chroot. | 63 # Script can be run either inside or outside the chroot. |
| 62 if [ $INSIDE_CHROOT -eq 1 ] | 64 if [ ${INSIDE_CHROOT} -eq 1 ] |
| 63 then | 65 then |
| 64 # Inside the chroot, so output to usb.img in the same dir as the other | 66 # Inside the chroot, so output to usb.img in the same dir as the other |
| 65 # images. | 67 # images. |
| 66 FLAGS_to="${FLAGS_from}/usb.img" | 68 FLAGS_to="${FLAGS_from}/usb.img" |
| 67 else | 69 else |
| 68 # Outside the chroot, so output to the default device for a usb key. | 70 # Outside the chroot, so output to the default device for a usb key. |
| 69 FLAGS_to="/dev/sdb" | 71 FLAGS_to="/dev/sdb" |
| 70 fi | 72 fi |
| 71 fi | 73 fi |
| 72 | 74 |
| 73 # Convert args to paths. Need eval to un-quote the string so that shell | 75 # Convert args to paths. Need eval to un-quote the string so that shell |
| 74 # chars like ~ are processed; just doing FOO=`readlink -f $FOO` won't work. | 76 # chars like ~ are processed; just doing FOO=`readlink -f ${FOO}` won't work. |
| 75 FLAGS_from=`eval readlink -f $FLAGS_from` | 77 FLAGS_from=`eval readlink -f ${FLAGS_from}` |
| 76 FLAGS_to=`eval readlink -f $FLAGS_to` | 78 FLAGS_to=`eval readlink -f ${FLAGS_to}` |
| 79 |
| 80 # Uses this rootfs image as the source image to copy |
| 81 ROOTFS_IMAGE="${FLAGS_from}/rootfs.image" |
| 82 |
| 83 # Modifies image for test if requested |
| 84 if [ ${FLAGS_test_image} -eq ${FLAGS_TRUE} ] ; then |
| 85 if [ ! -f "${FLAGS_from}/rootfs_test.image" ] ; then |
| 86 echo "Test image not found, creating test image from original ... " |
| 87 cp "${FLAGS_from}/rootfs.image" "${FLAGS_from}/rootfs_test.image" |
| 88 "${SCRIPTS_DIR}/mod_image_for_test.sh" \ |
| 89 --image "${FLAGS_from}/rootfs_test.image" |
| 90 fi |
| 91 # Use the test image instead |
| 92 ROOTFS_IMAGE="${FLAGS_from}/rootfs_test.image" |
| 93 fi |
| 77 | 94 |
| 78 function do_cleanup { | 95 function do_cleanup { |
| 79 sudo losetup -d "$LOOP_DEV" | 96 sudo losetup -d "${LOOP_DEV}" |
| 80 } | 97 } |
| 81 | 98 |
| 82 STATEFUL_DIR=${FLAGS_from}/stateful_partition | 99 STATEFUL_DIR=${FLAGS_from}/stateful_partition |
| 83 mkdir -p "${STATEFUL_DIR}" | 100 mkdir -p "${STATEFUL_DIR}" |
| 84 | 101 |
| 85 function install_autotest { | 102 function install_autotest { |
| 86 if [ -d ${AUTOTEST_SRC} ] | 103 if [ -d ${AUTOTEST_SRC} ] |
| 87 then | 104 then |
| 88 echo -ne "Install autotest into stateful partition..." | 105 echo -ne "Install autotest into stateful partition..." |
| 89 local autotest_client="/home/autotest-client" | 106 local autotest_client="/home/autotest-client" |
| 90 sudo mkdir -p "${STATEFUL_DIR}${autotest_client}" | 107 sudo mkdir -p "${STATEFUL_DIR}${autotest_client}" |
| 91 sudo cp -fpru ${AUTOTEST_SRC}/client/* \ | 108 sudo cp -fpru ${AUTOTEST_SRC}/client/* \ |
| 92 "${STATEFUL_DIR}${autotest_client}" | 109 "${STATEFUL_DIR}${autotest_client}" |
| 93 sudo chmod 755 "${STATEFUL_DIR}${autotest_client}" | 110 sudo chmod 755 "${STATEFUL_DIR}${autotest_client}" |
| 94 sudo chown -R 1000:1000 "${STATEFUL_DIR}${autotest_client}" | 111 sudo chown -R 1000:1000 "${STATEFUL_DIR}${autotest_client}" |
| 95 echo "Done." | 112 echo "Done." |
| 96 sudo umount "${STATEFUL_DIR}" | 113 sudo umount "${STATEFUL_DIR}" |
| 97 else | 114 else |
| 98 echo "/usr/local/autotest under ${DEFAULT_CHROOT_DIR} is not installed." | 115 echo "/usr/local/autotest under ${DEFAULT_CHROOT_DIR} is not installed." |
| 99 echo "Please call make_autotest.sh inside chroot first." | 116 echo "Please call make_autotest.sh inside chroot first." |
| 100 sudo umount "${STATEFUL_DIR}" | 117 sudo umount "${STATEFUL_DIR}" |
| 101 exit -1 | 118 exit -1 |
| 102 fi | 119 fi |
| 103 } | 120 } |
| 104 | 121 |
| 105 # Copy MBR and rootfs to output image | 122 # Copy MBR and rootfs to output image |
| 106 if [ -b "$FLAGS_to" ] | 123 if [ -b "${FLAGS_to}" ] |
| 107 then | 124 then |
| 108 # Output to a block device (i.e., a real USB key), so need sudo dd | 125 # Output to a block device (i.e., a real USB key), so need sudo dd |
| 109 echo "Copying USB image ${FLAGS_from} to device ${FLAGS_to}..." | 126 echo "Copying USB image ${FLAGS_from} to device ${FLAGS_to}..." |
| 110 | 127 |
| 111 # Warn if it looks like they supplied a partition as the destination. | 128 # Warn if it looks like they supplied a partition as the destination. |
| 112 if echo $FLAGS_to | grep -q '[0-9]$'; then | 129 if echo ${FLAGS_to} | grep -q '[0-9]$'; then |
| 113 drive=$(echo $FLAGS_to | sed -re 's/[0-9]+$//') | 130 local drive=$(echo ${FLAGS_to} | sed -re 's/[0-9]+$//') |
| 114 if [ -b "$drive" ]; then | 131 if [ -b "${drive}" ]; then |
| 115 echo | 132 echo |
| 116 echo "NOTE: It looks like you may have supplied a partition as the " | 133 echo "NOTE: It looks like you may have supplied a partition as the " |
| 117 echo "destination. This script needs to write to the drive's device " | 134 echo "destination. This script needs to write to the drive's device " |
| 118 echo "node instead (i.e. ${drive} rather than ${FLAGS_to})." | 135 echo "node instead (i.e. ${drive} rather than ${FLAGS_to})." |
| 119 echo | 136 echo |
| 120 fi | 137 fi |
| 121 fi | 138 fi |
| 122 | 139 |
| 123 # Make sure this is really what the user wants, before nuking the device | 140 # Make sure this is really what the user wants, before nuking the device |
| 124 if [ $FLAGS_yes -ne $FLAGS_TRUE ] | 141 if [ ${FLAGS_yes} -ne ${FLAGS_TRUE} ] |
| 125 then | 142 then |
| 126 echo "This will erase all data on this device:" | 143 echo "This will erase all data on this device:" |
| 127 sudo fdisk -l "$FLAGS_to" | grep Disk | head -1 | 144 sudo fdisk -l "${FLAGS_to}" | grep Disk | head -1 |
| 128 read -p "Are you sure (y/N)? " SURE | 145 read -p "Are you sure (y/N)? " SURE |
| 129 SURE="${SURE:0:1}" # Get just the first character | 146 SURE="${SURE:0:1}" # Get just the first character |
| 130 if [ "$SURE" != "y" ] | 147 if [ "${SURE}" != "y" ] |
| 131 then | 148 then |
| 132 echo "Ok, better safe than sorry." | 149 echo "Ok, better safe than sorry." |
| 133 exit 1 | 150 exit 1 |
| 134 fi | 151 fi |
| 135 fi | 152 fi |
| 136 | 153 |
| 137 echo "attempting to unmount any mounts on the USB device" | 154 echo "attempting to unmount any mounts on the USB device" |
| 138 for i in "$FLAGS_to"* | 155 for i in "${FLAGS_to}"* |
| 139 do | 156 do |
| 140 ! sudo umount "$i" | 157 ! sudo umount "$i" |
| 141 done | 158 done |
| 142 sleep 3 | 159 sleep 3 |
| 143 | 160 |
| 144 PART_SIZE=$(stat -c%s "${FLAGS_from}/rootfs.image") # Bytes | 161 PART_SIZE=$(stat -c%s "${ROOTFS_IMAGE}") # Bytes |
| 145 | 162 |
| 146 echo "Copying root fs..." | 163 echo "Copying root fs..." |
| 147 sudo "${SCRIPTS_DIR}"/file_copy.py \ | 164 sudo "${SCRIPTS_DIR}"/file_copy.py \ |
| 148 if="${FLAGS_from}/rootfs.image" \ | 165 if="${ROOTFS_IMAGE}" \ |
| 149 of="$FLAGS_to" bs=4M \ | 166 of="${FLAGS_to}" bs=4M \ |
| 150 seek_bytes=$(( ($PART_SIZE * 2) + 512 )) | 167 seek_bytes=$(( (${PART_SIZE} * 2) + 512 )) |
| 151 | 168 |
| 152 # Set up loop device | 169 # Set up loop device |
| 153 LOOP_DEV=$(sudo losetup -f) | 170 LOOP_DEV=$(sudo losetup -f) |
| 154 if [ -z "$LOOP_DEV" ] | 171 if [ -z "${LOOP_DEV}" ] |
| 155 then | 172 then |
| 156 echo "No free loop device. Free up a loop device or reboot. exiting." | 173 echo "No free loop device. Free up a loop device or reboot. exiting." |
| 157 exit 1 | 174 exit 1 |
| 158 fi | 175 fi |
| 159 | 176 |
| 160 trap do_cleanup EXIT | 177 trap do_cleanup EXIT |
| 161 | 178 |
| 162 echo "Creating stateful partition..." | 179 echo "Creating stateful partition..." |
| 163 sudo losetup -o 512 "$LOOP_DEV" "$FLAGS_to" | 180 sudo losetup -o 512 "${LOOP_DEV}" "${FLAGS_to}" |
| 164 sudo mkfs.ext3 -F -b 4096 -L C-STATE "$LOOP_DEV" $(( $PART_SIZE / 4096 )) | 181 sudo mkfs.ext3 -F -b 4096 -L C-STATE "${LOOP_DEV}" $(( ${PART_SIZE} / 4096 )) |
| 165 if [ $FLAGS_install_autotest -eq $FLAGS_TRUE ] | 182 if [ ${FLAGS_install_autotest} -eq ${FLAGS_TRUE} ] |
| 166 then | 183 then |
| 167 sudo mount "${LOOP_DEV}" "${STATEFUL_DIR}" | 184 sudo mount "${LOOP_DEV}" "${STATEFUL_DIR}" |
| 168 install_autotest | 185 install_autotest |
| 169 fi | 186 fi |
| 170 sync | 187 sync |
| 171 sudo losetup -d "$LOOP_DEV" | 188 sudo losetup -d "${LOOP_DEV}" |
| 172 sync | 189 sync |
| 173 | 190 |
| 174 trap - EXIT | 191 trap - EXIT |
| 175 | 192 |
| 176 if [ $FLAGS_copy_kernel -eq $FLAGS_TRUE ] | 193 if [ ${FLAGS_copy_kernel} -eq ${FLAGS_TRUE} ] |
| 177 then | 194 then |
| 178 echo "Copying Kernel..." | 195 echo "Copying Kernel..." |
| 179 "${SCRIPTS_DIR}"/kernel_fetcher.sh \ | 196 "${SCRIPTS_DIR}"/kernel_fetcher.sh \ |
| 180 --from "${FLAGS_from}" \ | 197 --from "${FLAGS_from}" \ |
| 181 --to "${FLAGS_to}" \ | 198 --to "${FLAGS_to}" \ |
| 182 --offset "$(( ($PART_SIZE * 3) + 512 ))" | 199 --offset "$(( (${PART_SIZE} * 3) + 512 ))" |
| 183 fi | 200 fi |
| 184 | 201 |
| 185 echo "Copying MBR..." | 202 echo "Copying MBR..." |
| 186 sudo "${SCRIPTS_DIR}"/file_copy.py \ | 203 sudo "${SCRIPTS_DIR}"/file_copy.py \ |
| 187 if="${FLAGS_from}/mbr.image" of="$FLAGS_to" | 204 if="${FLAGS_from}/mbr.image" of="${FLAGS_to}" |
| 188 sync | 205 sync |
| 189 echo "Done." | 206 echo "Done." |
| 190 else | 207 else |
| 191 # Output to a file, so just cat the source images together | 208 # Output to a file, so just cat the source images together |
| 192 | 209 |
| 193 PART_SIZE=$(stat -c%s "${FLAGS_from}/rootfs.image") | 210 PART_SIZE=$(stat -c%s "${ROOTFS_IMAGE}") |
| 194 | 211 |
| 195 echo "Creating empty stateful partition" | 212 echo "Creating empty stateful partition" |
| 196 dd if=/dev/zero of="${FLAGS_from}/stateful_partition.image" bs=1 count=1 \ | 213 dd if=/dev/zero of="${FLAGS_from}/stateful_partition.image" bs=1 count=1 \ |
| 197 seek=$(($PART_SIZE - 1)) | 214 seek=$((${PART_SIZE} - 1)) |
| 198 mkfs.ext3 -F -L C-STATE "${FLAGS_from}/stateful_partition.image" | 215 mkfs.ext3 -F -L C-STATE "${FLAGS_from}/stateful_partition.image" |
| 199 | 216 |
| 200 if [ $FLAGS_install_autotest -eq $FLAGS_TRUE ] | 217 if [ ${FLAGS_install_autotest} -eq ${FLAGS_TRUE} ] |
| 201 then | 218 then |
| 202 sudo mount -o loop "${FLAGS_from}/stateful_partition.image" \ | 219 sudo mount -o loop "${FLAGS_from}/stateful_partition.image" \ |
| 203 "${STATEFUL_DIR}" | 220 "${STATEFUL_DIR}" |
| 204 install_autotest | 221 install_autotest |
| 205 fi | 222 fi |
| 206 | 223 |
| 207 # Create a sparse output file | 224 # Create a sparse output file |
| 208 dd if=/dev/zero of="${FLAGS_to}" bs=1 count=1 \ | 225 dd if=/dev/zero of="${FLAGS_to}" bs=1 count=1 \ |
| 209 seek=$(( ($PART_SIZE * 2) + 512 - 1)) | 226 seek=$(( (${PART_SIZE} * 2) + 512 - 1)) |
| 210 | 227 |
| 211 echo "Copying USB image to file ${FLAGS_to}..." | 228 echo "Copying USB image to file ${FLAGS_to}..." |
| 212 | 229 |
| 213 dd if="${FLAGS_from}/mbr.image" of="$FLAGS_to" conv=notrunc | 230 dd if="${FLAGS_from}/mbr.image" of="${FLAGS_to}" conv=notrunc |
| 214 dd if="${FLAGS_from}/stateful_partition.image" of="$FLAGS_to" seek=1 bs=512 \ | 231 dd if="${FLAGS_from}/stateful_partition.image" of="${FLAGS_to}" seek=1 bs=512
\ |
| 215 conv=notrunc | 232 conv=notrunc |
| 216 cat "${FLAGS_from}/rootfs.image" >> "$FLAGS_to" | 233 cat "${ROOTFS_IMAGE}" >> "${FLAGS_to}" |
| 217 | 234 |
| 218 echo "Done. To copy to USB keyfob, outside the chroot, do something like:" | 235 echo "Done. To copy to USB keyfob, outside the chroot, do something like:" |
| 219 echo " sudo dd if=${FLAGS_to} of=/dev/sdb bs=4M" | 236 echo " sudo dd if=${FLAGS_to} of=/dev/sdb bs=4M" |
| 220 echo "where /dev/sdb is the entire keyfob." | 237 echo "where /dev/sdb is the entire keyfob." |
| 221 if [ $INSIDE_CHROOT -eq 1 ] | 238 if [ ${INSIDE_CHROOT} -eq 1 ] |
| 222 then | 239 then |
| 223 echo "NOTE: Since you are currently inside the chroot, and you'll need to" | 240 echo "NOTE: Since you are currently inside the chroot, and you'll need to" |
| 224 echo "run dd outside the chroot, the path to the USB image will be" | 241 echo "run dd outside the chroot, the path to the USB image will be" |
| 225 echo "different (ex: ~/chromeos/trunk/src/build/images/SOME_DIR/usb.img)." | 242 echo "different (ex: ~/chromeos/trunk/src/build/images/SOME_DIR/usb.img)." |
| 226 fi | 243 fi |
| 227 fi | 244 fi |
| OLD | NEW |