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 # Load functions and constants for chromeos-install |
| 14 . "$(dirname "$0")/chromeos-common.sh" |
| 15 |
13 get_default_board | 16 get_default_board |
14 | 17 |
15 # Flags | 18 # Flags |
16 DEFINE_string board "${DEFAULT_BOARD}" "Board for which the image was built" | 19 DEFINE_string board "${DEFAULT_BOARD}" "Board for which the image was built" |
17 DEFINE_string from "" \ | 20 DEFINE_string from "" \ |
18 "Directory containing rootfs.image and mbr.image" | 21 "Directory containing rootfs.image and mbr.image" |
19 DEFINE_string to "" "${DEFAULT_TO_HELP}" | 22 DEFINE_string to "" "${DEFAULT_TO_HELP}" |
20 DEFINE_boolean yes ${FLAGS_FALSE} "Answer yes to all prompts" "y" | 23 DEFINE_boolean yes ${FLAGS_FALSE} "Answer yes to all prompts" "y" |
21 DEFINE_boolean install_autotest ${FLAGS_FALSE} \ | 24 DEFINE_boolean install_autotest ${FLAGS_FALSE} \ |
22 "Whether to install autotest to the stateful partition." | 25 "Whether to install autotest to the stateful partition." |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
59 if [ ! -d "${FLAGS_from}" ] ; then | 62 if [ ! -d "${FLAGS_from}" ] ; then |
60 echo "Cannot find image directory ${FLAGS_from}" | 63 echo "Cannot find image directory ${FLAGS_from}" |
61 exit 1 | 64 exit 1 |
62 fi | 65 fi |
63 | 66 |
64 # If to isn't explicitly set | 67 # If to isn't explicitly set |
65 if [ -z "${FLAGS_to}" ]; then | 68 if [ -z "${FLAGS_to}" ]; then |
66 # Script can be run either inside or outside the chroot. | 69 # Script can be run either inside or outside the chroot. |
67 if [ ${INSIDE_CHROOT} -eq 1 ] | 70 if [ ${INSIDE_CHROOT} -eq 1 ] |
68 then | 71 then |
69 # Inside the chroot, so output to usb.img in the same dir as the other | 72 # Inside the chroot, we'll only output to a file, and we probably already |
70 # images. | 73 # have a valid image. Make the user specify a filename. |
71 FLAGS_to="${FLAGS_from}/usb.img" | 74 echo "ERROR: Inside the chroot, you must specify a --to FILE to create." |
| 75 exit 1 |
72 else | 76 else |
73 # Outside the chroot, so output to the default device for a usb key. | 77 # Outside the chroot, so output to the default device for a usb key. |
74 FLAGS_to="/dev/sdb" | 78 FLAGS_to="/dev/sdb" |
75 fi | 79 fi |
76 fi | 80 fi |
77 | 81 |
78 # Convert args to paths. Need eval to un-quote the string so that shell | 82 # Convert args to paths. Need eval to un-quote the string so that shell |
79 # chars like ~ are processed; just doing FOO=`readlink -f ${FOO}` won't work. | 83 # chars like ~ are processed; just doing FOO=`readlink -f ${FOO}` won't work. |
80 FLAGS_from=`eval readlink -f ${FLAGS_from}` | 84 FLAGS_from=`eval readlink -f ${FLAGS_from}` |
81 FLAGS_to=`eval readlink -f ${FLAGS_to}` | 85 FLAGS_to=`eval readlink -f ${FLAGS_to}` |
82 | 86 |
83 # Uses this rootfs image as the source image to copy | 87 # Use this image as the source image to copy |
84 ROOTFS_IMAGE="${FLAGS_from}/rootfs.image" | 88 SRC_IMAGE="${FLAGS_from}/chromiumos_image.bin" |
85 PART_SIZE=$(stat -c%s "${ROOTFS_IMAGE}") # Bytes | |
86 | 89 |
87 # Setup stateful partition variables | 90 # If we're asked to modify the image for test, then let's make a copy and |
88 STATEFUL_IMG="${FLAGS_from}/stateful_partition.image" | 91 # modify that instead. |
89 STATEFUL_DIR="${FLAGS_from}/stateful_partition" | 92 if [ ${FLAGS_test_image} -eq ${FLAGS_TRUE} ] ; then |
90 | 93 # Copy it. |
91 # TODO(sosa@chromium.org) - Remove legacy support. | 94 echo "Creating test image from original..." |
92 if [ ! -f "${STATEFUL_IMG}" ] ; then | 95 cp -f "${SRC_IMAGE}" "${FLAGS_from}/chromiumos_test_image.bin" |
93 echo "WARNING! Stateful partition not found. Creating clean stateful" | 96 # Use it. |
94 STATEFUL_LOOP_DEV=$(sudo losetup -f) | 97 SRC_IMAGE="${FLAGS_from}/chromiumos_test_image.bin" |
95 if [ -z "${STATEFUL_LOOP_DEV}" ] ; then | 98 # Modify it. |
96 echo "No free loop device. Free up a loop device or reboot. exiting. " | 99 "${SCRIPTS_DIR}/mod_image_for_test.sh" --image "${SRC_IMAGE}" |
97 exit 1 | |
98 fi | |
99 set -x | |
100 dd if=/dev/zero of="${STATEFUL_IMG}" bs=1 count=1 \ | |
101 seek=$(( (${PART_SIZE} - 1) )) | |
102 set +x | |
103 trap do_cleanup INT TERM EXIT | |
104 sudo losetup "$STATEFUL_LOOP_DEV" "$STATEFUL_IMG" | |
105 sudo mkfs.ext3 "$STATEFUL_LOOP_DEV" | |
106 sudo tune2fs -L "C-STATE" -c 0 -i 0 "$STATEFUL_LOOP_DEV" | |
107 sudo losetup -d "${STATEFUL_LOOP_DEV}" | |
108 trap - INT TERM EXIT | |
109 fi | 100 fi |
110 | 101 |
111 # Modifies image for test if requested | 102 STATEFUL_DIR="${FLAGS_from}/stateful_partition" |
112 if [ ${FLAGS_test_image} -eq ${FLAGS_TRUE} ] ; then | |
113 if [ ! -f "${FLAGS_from}/rootfs_test.image" ] ; then | |
114 echo "Test image not found, creating test image from original ... " | |
115 cp "${FLAGS_from}/rootfs.image" "${FLAGS_from}/rootfs_test.image" | |
116 "${SCRIPTS_DIR}/mod_image_for_test.sh" \ | |
117 --image "${FLAGS_from}/rootfs_test.image" | |
118 fi | |
119 # Use the test image instead | |
120 ROOTFS_IMAGE="${FLAGS_from}/rootfs_test.image" | |
121 fi | |
122 | 103 |
123 function do_cleanup { | 104 function do_cleanup { |
124 echo "Cleaning loopback devices: ${STATEFUL_LOOP_DEV}" | 105 echo "Cleaning loopback devices: ${STATEFUL_LOOP_DEV}" |
125 if [ "${STATEFUL_LOOP_DEV}" != "" ]; then | 106 if [ "${STATEFUL_LOOP_DEV}" != "" ]; then |
126 sudo umount "${STATEFUL_DIR}" | 107 sudo umount "${STATEFUL_DIR}" |
127 sudo losetup -d "${STATEFUL_LOOP_DEV}" | 108 sudo losetup -d "${STATEFUL_LOOP_DEV}" |
128 echo "Cleaned" | 109 echo "Cleaned" |
129 fi | 110 fi |
130 } | 111 } |
131 | 112 |
132 function install_autotest { | 113 if [ ${FLAGS_install_autotest} -eq ${FLAGS_TRUE} ] ; then |
133 echo "Detecting autotest at ${AUTOTEST_SRC}" | 114 echo "Detecting autotest at ${AUTOTEST_SRC}" |
134 if [ -d ${AUTOTEST_SRC} ] | 115 if [ -d ${AUTOTEST_SRC} ] |
135 then | 116 then |
136 local stateful_loop_dev=$(sudo losetup -f) | 117 # Figure out how to loop mount the stateful partition. It's always |
137 local stateful_root="${STATEFUL_DIR}/dev_image" | 118 # partition 1 on the disk image. |
| 119 offset=$(partoffset "${SRC_IMAGE}" 1) |
| 120 |
| 121 stateful_loop_dev=$(sudo losetup -f) |
138 if [ -z "${stateful_loop_dev}" ] | 122 if [ -z "${stateful_loop_dev}" ] |
139 then | 123 then |
140 echo "No free loop device. Free up a loop device or reboot. exiting." | 124 echo "No free loop device. Free up a loop device or reboot. exiting." |
141 exit 1 | 125 exit 1 |
142 fi | 126 fi |
| 127 STATEFUL_LOOP_DEV=$stateful_loop_dev |
143 trap do_cleanup INT TERM EXIT | 128 trap do_cleanup INT TERM EXIT |
144 STATEFUL_LOOP_DEV=$stateful_loop_dev | 129 |
145 echo "Mounting ${STATEFUL_DIR} loopback" | 130 echo "Mounting ${STATEFUL_DIR} loopback" |
146 sudo losetup "${stateful_loop_dev}" "${STATEFUL_DIR}.image" | 131 sudo losetup -o $(( $offset * 512 )) "${stateful_loop_dev}" "${SRC_IMAGE}" |
147 sudo mount "${stateful_loop_dev}" "${STATEFUL_DIR}" | 132 sudo mount "${stateful_loop_dev}" "${STATEFUL_DIR}" |
148 | 133 stateful_root="${STATEFUL_DIR}/dev_image" |
149 echo -ne "Install autotest into stateful partition..." | 134 |
150 local autotest_client="/home/autotest-client" | 135 echo "Install autotest into stateful partition..." |
151 sudo mkdir -p "${stateful_root}/${autotest_client}" | 136 autotest_client="/home/autotest-client" |
| 137 sudo mkdir -p "${stateful_root}${autotest_client}" |
| 138 |
152 sudo cp -fpru ${AUTOTEST_SRC}/client/* \ | 139 sudo cp -fpru ${AUTOTEST_SRC}/client/* \ |
153 "${stateful_root}/${autotest_client}" | 140 "${stateful_root}/${autotest_client}" |
154 sudo chmod 755 "${stateful_root}/${autotest_client}" | 141 sudo chmod 755 "${stateful_root}/${autotest_client}" |
155 sudo chown -R 1000:1000 "${stateful_root}/${autotest_client}" | 142 sudo chown -R 1000:1000 "${stateful_root}/${autotest_client}" |
156 | 143 |
157 sudo umount ${STATEFUL_DIR} | 144 sudo umount ${STATEFUL_DIR} |
158 sudo losetup -d "${stateful_loop_dev}" | 145 sudo losetup -d "${stateful_loop_dev}" |
159 trap - INT TERM EXIT | 146 trap - INT TERM EXIT |
160 else | 147 else |
161 echo "/usr/local/autotest under ${DEFAULT_CHROOT_DIR} is not installed." | 148 echo "/usr/local/autotest under ${DEFAULT_CHROOT_DIR} is not installed." |
162 echo "Please call make_autotest.sh inside chroot first." | 149 echo "Please call make_autotest.sh inside chroot first." |
163 exit -1 | 150 exit -1 |
164 fi | 151 fi |
165 } | 152 fi |
166 | 153 |
167 # Copy MBR and rootfs to output image | 154 |
| 155 # Let's do it. |
168 if [ -b "${FLAGS_to}" ] | 156 if [ -b "${FLAGS_to}" ] |
169 then | 157 then |
170 # Output to a block device (i.e., a real USB key), so need sudo dd | 158 # Output to a block device (i.e., a real USB key), so need sudo dd |
171 echo "Copying USB image ${FLAGS_from} to device ${FLAGS_to}..." | 159 echo "Copying USB image ${SRC_IMAGE} to device ${FLAGS_to}..." |
172 | 160 |
173 # Warn if it looks like they supplied a partition as the destination. | 161 # Warn if it looks like they supplied a partition as the destination. |
174 if echo ${FLAGS_to} | grep -q '[0-9]$'; then | 162 if echo "${FLAGS_to}" | grep -q '[0-9]$'; then |
175 local drive=$(echo ${FLAGS_to} | sed -re 's/[0-9]+$//') | 163 local drive=$(echo "${FLAGS_to}" | sed -re 's/[0-9]+$//') |
176 if [ -b "${drive}" ]; then | 164 if [ -b "${drive}" ]; then |
177 echo | 165 echo |
178 echo "NOTE: It looks like you may have supplied a partition as the " | 166 echo "NOTE: It looks like you may have supplied a partition as the " |
179 echo "destination. This script needs to write to the drive's device " | 167 echo "destination. This script needs to write to the drive's device " |
180 echo "node instead (i.e. ${drive} rather than ${FLAGS_to})." | 168 echo "node instead (i.e. ${drive} rather than ${FLAGS_to})." |
181 echo | 169 echo |
182 fi | 170 fi |
183 fi | 171 fi |
184 | 172 |
185 # Make sure this is really what the user wants, before nuking the device | 173 # Make sure this is really what the user wants, before nuking the device |
186 if [ ${FLAGS_yes} -ne ${FLAGS_TRUE} ] | 174 if [ ${FLAGS_yes} -ne ${FLAGS_TRUE} ] |
187 then | 175 then |
| 176 sudo fdisk -l "${FLAGS_to}" 2>/dev/null | grep Disk | head -1 |
188 echo "This will erase all data on this device:" | 177 echo "This will erase all data on this device:" |
189 sudo fdisk -l "${FLAGS_to}" | grep Disk | head -1 | |
190 read -p "Are you sure (y/N)? " SURE | 178 read -p "Are you sure (y/N)? " SURE |
191 SURE="${SURE:0:1}" # Get just the first character | 179 SURE="${SURE:0:1}" # Get just the first character |
192 if [ "${SURE}" != "y" ] | 180 if [ "${SURE}" != "y" ] |
193 then | 181 then |
194 echo "Ok, better safe than sorry." | 182 echo "Ok, better safe than sorry." |
195 exit 1 | 183 exit 1 |
196 fi | 184 fi |
197 fi | 185 fi |
198 | 186 |
199 echo "attempting to unmount any mounts on the USB device" | 187 echo "Attempting to unmount any mounts on the USB device..." |
200 for i in "${FLAGS_to}"* | 188 for i in $(mount | grep ^"${FLAGS_to}" | awk '{print $1}') |
201 do | 189 do |
202 ! sudo umount "$i" | 190 sudo umount "$i" |
203 done | 191 done |
204 sleep 3 | 192 sleep 3 |
205 | 193 |
206 if [ ${FLAGS_install_autotest} -eq ${FLAGS_TRUE} ] ; then | 194 echo "Copying ${SRC_IMAGE} to ${FLAGS_to}..." |
207 install_autotest | 195 sudo dd if="${SRC_IMAGE}" of="${FLAGS_to}" bs=4M |
208 fi | |
209 | 196 |
210 # Write stateful partition to first partition. | |
211 echo "Copying stateful partition ..." | |
212 sudo "${SCRIPTS_DIR}"/file_copy.py \ | |
213 if="${STATEFUL_IMG}" of="${FLAGS_to}" bs=4M \ | |
214 seek_bytes=512 | |
215 | |
216 # Write root fs to third partition. | |
217 echo "Copying root fs partition ..." | |
218 sudo "${SCRIPTS_DIR}"/file_copy.py \ | |
219 if="${ROOTFS_IMAGE}" of="${FLAGS_to}" bs=4M \ | |
220 seek_bytes=$(( (${PART_SIZE} * 2) + 512 )) | |
221 | |
222 trap - EXIT | |
223 | |
224 if [ ${FLAGS_copy_kernel} -eq ${FLAGS_TRUE} ] | |
225 then | |
226 echo "Copying Kernel..." | |
227 "${SCRIPTS_DIR}"/kernel_fetcher.sh \ | |
228 --from "${FLAGS_from}" \ | |
229 --to "${FLAGS_to}" \ | |
230 --offset "$(( (${PART_SIZE} * 3) + 512 ))" | |
231 fi | |
232 | |
233 echo "Copying MBR..." | |
234 sudo "${SCRIPTS_DIR}"/file_copy.py \ | |
235 if="${FLAGS_from}/mbr.image" of="${FLAGS_to}" | |
236 sync | |
237 echo "Done." | 197 echo "Done." |
238 else | 198 else |
239 # Output to a file, so just cat the source images together | 199 # Output to a file, so just make a copy. |
240 | 200 echo "Copying ${SRC_IMAGE} to ${FLAGS_to}..." |
241 PART_SIZE=$(stat -c%s "${ROOTFS_IMAGE}") | 201 cp -f "${SRC_IMAGE}" "${FLAGS_to}" |
242 | |
243 if [ ${FLAGS_install_autotest} -eq ${FLAGS_TRUE} ] ; then | |
244 install_autotest | |
245 fi | |
246 | |
247 # Create a sparse output file | |
248 dd if=/dev/zero of="${FLAGS_to}" bs=1 count=1 \ | |
249 seek=$(( (${PART_SIZE} * 2) + 512 - 1)) | |
250 | |
251 echo "Copying USB image to file ${FLAGS_to}..." | |
252 | |
253 dd if="${FLAGS_from}/mbr.image" of="${FLAGS_to}" conv=notrunc | |
254 dd if="${FLAGS_from}/stateful_partition.image" of="${FLAGS_to}" seek=1 bs=512
\ | |
255 conv=notrunc | |
256 cat "${ROOTFS_IMAGE}" >> "${FLAGS_to}" | |
257 | 202 |
258 echo "Done. To copy to USB keyfob, outside the chroot, do something like:" | 203 echo "Done. To copy to USB keyfob, outside the chroot, do something like:" |
259 echo " sudo dd if=${FLAGS_to} of=/dev/sdb bs=4M" | 204 echo " sudo dd if=${FLAGS_to} of=/dev/sdb bs=4M" |
260 echo "where /dev/sdb is the entire keyfob." | 205 echo "where /dev/sdb is the entire keyfob." |
261 if [ ${INSIDE_CHROOT} -eq 1 ] | 206 if [ ${INSIDE_CHROOT} -eq 1 ] |
262 then | 207 then |
| 208 example=$(basename "${FLAGS_to}") |
263 echo "NOTE: Since you are currently inside the chroot, and you'll need to" | 209 echo "NOTE: Since you are currently inside the chroot, and you'll need to" |
264 echo "run dd outside the chroot, the path to the USB image will be" | 210 echo "run dd outside the chroot, the path to the USB image will be" |
265 echo "different (ex: ~/chromeos/trunk/src/build/images/SOME_DIR/usb.img)." | 211 echo "different (ex: ~/chromeos/trunk/src/build/images/SOME_DIR/$example)." |
266 fi | 212 fi |
267 fi | 213 fi |
OLD | NEW |