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 |