blob: b517bc102c4f3a55cd375a4cf695c4968ece0194 [file] [log] [blame]
Rahul Chaturvedib5643e82010-07-09 10:46:05 +05301#!/bin/bash
2
3# Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
4# Use of this source code is governed by a BSD-style license that can be
5# found in the LICENSE file.
6
7# Script to convert the output of build_image.sh to a VMware image and write a
8# corresponding VMware config file.
9
Greg Spencer798d75f2011-02-01 22:04:49 -080010# --- BEGIN COMMON.SH BOILERPLATE ---
11# Load common CrOS utilities. Inside the chroot this file is installed in
12# /usr/lib/crosutils. Outside the chroot we find it relative to the script's
13# location.
14find_common_sh() {
15 local common_paths=(/usr/lib/crosutils $(dirname "$(readlink -f "$0")"))
16 local path
17
18 SCRIPT_ROOT=
19 for path in "${common_paths[@]}"; do
20 if [ -r "${path}/common.sh" ]; then
21 SCRIPT_ROOT=${path}
22 break
23 fi
24 done
25}
26
27find_common_sh
28. "${SCRIPT_ROOT}/common.sh" || (echo "Unable to load common.sh" && exit 1)
29# --- END COMMON.SH BOILERPLATE ---
30
31# Need to be inside the chroot to load chromeos-common.sh
32assert_inside_chroot
33
34# Load functions and constants for chromeos-install
35. "/usr/lib/installer/chromeos-common.sh" || \
36 die "Unable to load /usr/lib/installer/chromeos-common.sh"
37
38. "${SCRIPT_ROOT}/lib/cros_vm_constants.sh" || \
39 die "Unable to load ${SCRIPT_ROOT}/lib/cros_vm_constants.sh"
Rahul Chaturvedib5643e82010-07-09 10:46:05 +053040
41get_default_board
42
Rahul Chaturvedib5643e82010-07-09 10:46:05 +053043# Flags
44DEFINE_string board "${DEFAULT_BOARD}" \
45 "Board for which the image was built"
46DEFINE_boolean factory $FLAGS_FALSE \
47 "Modify the image for manufacturing testing"
48DEFINE_boolean factory_install $FLAGS_FALSE \
49 "Modify the image for factory install shim"
Simon Glass142ca062011-02-09 13:39:43 -080050
51# We default to TRUE so the buildbot gets its image. Note this is different
52# behavior from image_to_usb.sh
53DEFINE_boolean force_copy ${FLAGS_TRUE} "Always rebuild test image"
Rahul Chaturvedib5643e82010-07-09 10:46:05 +053054DEFINE_string format "qemu" \
55 "Output format, either qemu, vmware or virtualbox"
56DEFINE_string from "" \
57 "Directory containing rootfs.image and mbr.image"
Chris Sosacc09f842010-09-21 17:09:51 -070058DEFINE_boolean full "${FLAGS_FALSE}" "Build full image with all partitions."
Rahul Chaturvedib5643e82010-07-09 10:46:05 +053059DEFINE_boolean make_vmx ${FLAGS_TRUE} \
60 "Create a vmx file for use with vmplayer (vmware only)."
61DEFINE_integer mem "${DEFAULT_MEM}" \
62 "Memory size for the vm config in MBs (vmware only)."
63DEFINE_integer rootfs_partition_size 1024 \
64 "rootfs parition size in MBs."
65DEFINE_string state_image "" \
66 "Stateful partition image (defaults to creating new statful partition)"
Chris Masone7d04c7a2010-11-09 08:24:13 -080067DEFINE_integer statefulfs_size 2048 \
Rahul Chaturvedie770e162010-07-15 00:35:11 +053068 "Stateful partition size in MBs."
Rahul Chaturvedib5643e82010-07-09 10:46:05 +053069DEFINE_boolean test_image "${FLAGS_FALSE}" \
Simon Glass142ca062011-02-09 13:39:43 -080070 "Copies normal image to ${CHROMEOS_TEST_IMAGE_NAME}, modifies it for test."
Rahul Chaturvedib5643e82010-07-09 10:46:05 +053071DEFINE_string to "" \
72 "Destination folder for VM output file(s)"
73DEFINE_string vbox_disk "${DEFAULT_VBOX_DISK}" \
74 "Filename for the output disk (virtualbox only)."
75DEFINE_integer vdisk_size 3072 \
76 "virtual disk size in MBs."
77DEFINE_string vmdk "${DEFAULT_VMDK}" \
78 "Filename for the vmware disk image (vmware only)."
79DEFINE_string vmx "${DEFAULT_VMX}" \
80 "Filename for the vmware config (vmware only)."
81
82# Parse command line
83FLAGS "$@" || exit 1
84eval set -- "${FLAGS_ARGV}"
85
86# Die on any errors.
87set -e
88
89if [ -z "${FLAGS_board}" ] ; then
90 die "--board is required."
91fi
92
Chris Sosacc09f842010-09-21 17:09:51 -070093if [ "${FLAGS_full}" -eq "${FLAGS_TRUE}" ] && \
94 ( [[ ${FLAGS_vdisk_size} < ${MIN_VDISK_SIZE_FULL} ]] || \
95 [[ ${FLAGS_statefulfs_size} < ${MIN_STATEFUL_FS_SIZE_FULL} ]]); then
Chris Sosa9fe00b92010-10-22 12:34:16 -070096 warn "Disk is too small for full, using minimum: vdisk size equal to \
97${MIN_VDISK_SIZE_FULL} and statefulfs size equal to \
Chris Sosacc09f842010-09-21 17:09:51 -070098${MIN_STATEFUL_FS_SIZE_FULL}."
Chris Sosa9fe00b92010-10-22 12:34:16 -070099 FLAGS_vdisk_size=${MIN_VDISK_SIZE_FULL}
100 FLAGS_statefulfs_size=${MIN_STATEFUL_FS_SIZE_FULL}
Chris Sosacc09f842010-09-21 17:09:51 -0700101fi
102
Rahul Chaturvedib5643e82010-07-09 10:46:05 +0530103IMAGES_DIR="${DEFAULT_BUILD_ROOT}/images/${FLAGS_board}"
104# Default to the most recent image
105if [ -z "${FLAGS_from}" ] ; then
Chris Sosabd613042010-10-04 13:29:23 -0700106 FLAGS_from="$(./get_latest_image.sh --board=${FLAGS_board})"
Zelidrag Hornung42ca8182010-07-12 18:08:44 -0700107else
108 pushd "${FLAGS_from}" && FLAGS_from=`pwd` && popd
Rahul Chaturvedib5643e82010-07-09 10:46:05 +0530109fi
110if [ -z "${FLAGS_to}" ] ; then
111 FLAGS_to="${FLAGS_from}"
112fi
113
Rahul Chaturvedib5643e82010-07-09 10:46:05 +0530114if [ ${FLAGS_test_image} -eq ${FLAGS_TRUE} ] ; then
Simon Glass142ca062011-02-09 13:39:43 -0800115 # Make a test image - this returns the test filename in CHROMEOS_RETURN_VAL
116 prepare_test_image "${FLAGS_from}" "${CHROMEOS_IMAGE_NAME}"
117 SRC_IMAGE="${CHROMEOS_RETURN_VAL}"
118else
119 # Use the standard image
120 SRC_IMAGE="${FLAGS_from}/${CHROMEOS_IMAGE_NAME}"
Rahul Chaturvedib5643e82010-07-09 10:46:05 +0530121fi
122
123# Memory units are in MBs
Greg Spencer798d75f2011-02-01 22:04:49 -0800124TEMP_IMG="$(dirname "${SRC_IMAGE}")/vm_temp_image.bin"
Rahul Chaturvedib5643e82010-07-09 10:46:05 +0530125
126# If we're not building for VMWare, don't build the vmx
127if [ "${FLAGS_format}" != "vmware" ]; then
128 FLAGS_make_vmx="${FLAGS_FALSE}"
129fi
130
131# Convert args to paths. Need eval to un-quote the string so that shell
132# chars like ~ are processed; just doing FOO=`readlink -f $FOO` won't work.
133FLAGS_from=`eval readlink -f $FLAGS_from`
134FLAGS_to=`eval readlink -f $FLAGS_to`
135
136# Split apart the partitions and make some new ones
137TEMP_DIR=$(mktemp -d)
138(cd "${TEMP_DIR}" &&
139 "${FLAGS_from}/unpack_partitions.sh" "${SRC_IMAGE}")
140
141# Fix the kernel command line
142TEMP_ESP="${TEMP_DIR}"/part_12
143TEMP_ROOTFS="${TEMP_DIR}"/part_3
144TEMP_STATE="${TEMP_DIR}"/part_1
Will Drewryefce6682010-07-23 19:43:27 -0500145TEMP_KERN="${TEMP_DIR}"/part_2
Rahul Chaturvedib5643e82010-07-09 10:46:05 +0530146if [ -n "${FLAGS_state_image}" ]; then
147 TEMP_STATE="${FLAGS_state_image}"
Rahul Chaturvedie770e162010-07-15 00:35:11 +0530148else
149 # If we have a stateful fs size specified create a new state partition
150 # of the specified size.
151 if [ "${FLAGS_statefulfs_size}" -ne -1 ]; then
152 STATEFUL_SIZE_BYTES=$((1024 * 1024 * ${FLAGS_statefulfs_size}))
153 original_image_size=$(stat -c%s "${TEMP_STATE}")
154 if [ "${original_image_size}" -gt "${STATEFUL_SIZE_BYTES}" ]; then
155 die "Cannot resize stateful image to smaller than original. Exiting."
156 fi
157
158 echo "Resizing stateful partition to ${FLAGS_statefulfs_size}MB"
159 STATEFUL_LOOP_DEV=$(sudo losetup -f)
160 if [ -z "${STATEFUL_LOOP_DEV}" ]; then
161 die "No free loop device. Free up a loop device or reboot. Exiting."
162 fi
163
164 # Extend the original file size to the new size.
165 dd if=/dev/zero of="${TEMP_STATE}" bs=1 count=1 \
166 seek=$((STATEFUL_SIZE_BYTES - 1))
167 # Resize the partition.
168 sudo losetup "${STATEFUL_LOOP_DEV}" "${TEMP_STATE}"
Chris Sosa020aa692010-10-08 16:36:20 -0700169 sudo e2fsck -pf "${STATEFUL_LOOP_DEV}"
Rahul Chaturvedie770e162010-07-15 00:35:11 +0530170 sudo resize2fs "${STATEFUL_LOOP_DEV}"
Chris Sosa1b11f382010-10-25 15:10:26 -0700171 sync
Rahul Chaturvedie770e162010-07-15 00:35:11 +0530172 sudo losetup -d "${STATEFUL_LOOP_DEV}"
173 fi
Rahul Chaturvedib5643e82010-07-09 10:46:05 +0530174fi
Rahul Chaturvedib5643e82010-07-09 10:46:05 +0530175TEMP_PMBR="${TEMP_DIR}"/pmbr
176dd if="${SRC_IMAGE}" of="${TEMP_PMBR}" bs=512 count=1
177
178TEMP_MNT=$(mktemp -d)
Will Drewryefce6682010-07-23 19:43:27 -0500179TEMP_ESP_MNT=$(mktemp -d)
Rahul Chaturvedib5643e82010-07-09 10:46:05 +0530180cleanup() {
181 sudo umount -d "${TEMP_MNT}"
Will Drewryefce6682010-07-23 19:43:27 -0500182 sudo umount -d "${TEMP_ESP_MNT}"
183 rmdir "${TEMP_MNT}" "${TEMP_ESP_MNT}"
Rahul Chaturvedib5643e82010-07-09 10:46:05 +0530184}
185trap cleanup INT TERM EXIT
186mkdir -p "${TEMP_MNT}"
Will Drewryf929c302010-10-20 18:48:20 -0500187enable_rw_mount "${TEMP_ROOTFS}"
Rahul Chaturvedib5643e82010-07-09 10:46:05 +0530188sudo mount -o loop "${TEMP_ROOTFS}" "${TEMP_MNT}"
Will Drewryefce6682010-07-23 19:43:27 -0500189mkdir -p "${TEMP_ESP_MNT}"
190sudo mount -o loop "${TEMP_ESP}" "${TEMP_ESP_MNT}"
191
Rahul Chaturvedib5643e82010-07-09 10:46:05 +0530192if [ "${FLAGS_format}" = "qemu" ]; then
Greg Spencer798d75f2011-02-01 22:04:49 -0800193 sudo python "${SCRIPTS_DIR}/fixup_image_for_qemu.py" \
Chris Sosacc09f842010-09-21 17:09:51 -0700194 --mounted_dir="${TEMP_MNT}" \
195 --enable_tablet=true
Rahul Chaturvedib5643e82010-07-09 10:46:05 +0530196else
Greg Spencer798d75f2011-02-01 22:04:49 -0800197 sudo python "${SCRIPTS_DIR}/fixup_image_for_qemu.py" \
Chris Sosacc09f842010-09-21 17:09:51 -0700198 --mounted_dir="${TEMP_MNT}" \
199 --enable_tablet=false
Rahul Chaturvedib5643e82010-07-09 10:46:05 +0530200fi
Will Drewry537caa92010-08-20 20:30:56 -0500201
202# Modify the unverified usb template which uses a default usb_disk of sdb3
203sudo sed -i -e 's/sdb3/sda3/g' "${TEMP_MNT}/boot/syslinux/usb.A.cfg"
204
205# Unmount everything prior to building a final image
Will Drewryefce6682010-07-23 19:43:27 -0500206sync
Rahul Chaturvedib5643e82010-07-09 10:46:05 +0530207trap - INT TERM EXIT
208cleanup
209
Chris Sosacc09f842010-09-21 17:09:51 -0700210# TOOD(adlr): pick a size that will for sure accomodate the partitions.
Will Drewry537caa92010-08-20 20:30:56 -0500211dd if=/dev/zero of="${TEMP_IMG}" bs=1 count=1 \
Rahul Chaturvedib5643e82010-07-09 10:46:05 +0530212 seek=$((${FLAGS_vdisk_size} * 1024 * 1024 - 1))
213
Chris Sosacc09f842010-09-21 17:09:51 -0700214GPT_FULL="false"
215[ "${FLAGS_full}" -eq "${FLAGS_TRUE}" ] && GPT_FULL="true"
216
Rahul Chaturvedib5643e82010-07-09 10:46:05 +0530217# Set up the partition table
Tan Gao0d5f9482010-08-06 08:28:20 -0700218install_gpt "${TEMP_IMG}" "$(numsectors $TEMP_ROOTFS)" \
219 "$(numsectors $TEMP_STATE)" "${TEMP_PMBR}" "$(numsectors $TEMP_ESP)" \
Chris Sosacc09f842010-09-21 17:09:51 -0700220 "${GPT_FULL}" ${FLAGS_rootfs_partition_size}
Rahul Chaturvedib5643e82010-07-09 10:46:05 +0530221# Copy into the partition parts of the file
222dd if="${TEMP_ROOTFS}" of="${TEMP_IMG}" conv=notrunc bs=512 \
223 seek="${START_ROOTFS_A}"
224dd if="${TEMP_STATE}" of="${TEMP_IMG}" conv=notrunc bs=512 \
225 seek="${START_STATEFUL}"
226dd if="${TEMP_KERN}" of="${TEMP_IMG}" conv=notrunc bs=512 \
227 seek="${START_KERN_A}"
228dd if="${TEMP_ESP}" of="${TEMP_IMG}" conv=notrunc bs=512 \
229 seek="${START_ESP}"
230
Will Drewry537caa92010-08-20 20:30:56 -0500231# Make the built-image bootable and ensure that the legacy default usb boot
232# uses /dev/sda instead of /dev/sdb3.
233# NOTE: The TEMP_IMG must live in the same image dir as the original image
234# to operate automatically below.
235${SCRIPTS_DIR}/bin/cros_make_image_bootable $(dirname "${TEMP_IMG}") \
236 $(basename "${TEMP_IMG}") \
237 --usb_disk /dev/sda3
238
Rahul Chaturvedib5643e82010-07-09 10:46:05 +0530239echo Creating final image
240# Convert image to output format
241if [ "${FLAGS_format}" = "virtualbox" -o "${FLAGS_format}" = "qemu" ]; then
242 if [ "${FLAGS_format}" = "virtualbox" ]; then
243 VBoxManage convertdd "${TEMP_IMG}" "${FLAGS_to}/${FLAGS_vbox_disk}"
244 else
245 mv ${TEMP_IMG} ${FLAGS_to}/${DEFAULT_QEMU_IMAGE}
246 fi
247elif [ "${FLAGS_format}" = "vmware" ]; then
248 qemu-img convert -f raw "${TEMP_IMG}" \
249 -O vmdk "${FLAGS_to}/${FLAGS_vmdk}"
250else
251 die "Invalid format: ${FLAGS_format}"
252fi
253
254rm -rf "${TEMP_DIR}" "${TEMP_IMG}"
255if [ -z "${FLAGS_state_image}" ]; then
256 rm -f "${STATE_IMAGE}"
257fi
258
259echo "Created image at ${FLAGS_to}"
260
261# Generate the vmware config file
262# A good reference doc: http://www.sanbarrow.com/vmx.html
263VMX_CONFIG="#!/usr/bin/vmware
264.encoding = \"UTF-8\"
265config.version = \"8\"
266virtualHW.version = \"4\"
267memsize = \"${FLAGS_mem}\"
268ide0:0.present = \"TRUE\"
269ide0:0.fileName = \"${FLAGS_vmdk}\"
270ethernet0.present = \"TRUE\"
271usb.present = \"TRUE\"
272sound.present = \"TRUE\"
273sound.virtualDev = \"es1371\"
274displayName = \"Chromium OS\"
275guestOS = \"otherlinux\"
276ethernet0.addressType = \"generated\"
277floppy0.present = \"FALSE\""
278
279if [[ "${FLAGS_make_vmx}" = "${FLAGS_TRUE}" ]]; then
280 echo "${VMX_CONFIG}" > "${FLAGS_to}/${FLAGS_vmx}"
281 echo "Wrote the following config to: ${FLAGS_to}/${FLAGS_vmx}"
282 echo "${VMX_CONFIG}"
283fi
284
Olof Johansson3ed8d122010-09-27 13:29:40 -0500285
286if [ "${FLAGS_format}" == "qemu" ]; then
287 echo "If you have qemu-kvm installed, you can start the image by:"
Anush Elangovan0de6de62010-12-07 17:31:48 -0800288 echo "sudo kvm -m ${FLAGS_mem} -vga std -pidfile /tmp/kvm.pid -net nic,model=virtio " \
Chris Masone7d04c7a2010-11-09 08:24:13 -0800289 "-net user,hostfwd=tcp::9222-:22 \\"
Olof Johansson3ed8d122010-09-27 13:29:40 -0500290 echo " -hda ${FLAGS_to}/${DEFAULT_QEMU_IMAGE}"
291fi