blob: 7303e9d4a942b8413dba22e06961842aecb4c01b [file] [log] [blame]
Bill Richardsonc09b94f2010-03-15 11:40:30 -07001#!/bin/bash
2
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
5# found in the LICENSE file.
6
7# Script to build a bootable keyfob-based chromeos system image from within
8# a chromiumos setup. This assumes that all needed packages have been built into
9# the given target's root with binary packages turned on. This script will
10# build the Chrome OS image using only pre-built binary packages.
11
12# Load common constants. This should be the first executable line.
13# The path to common.sh should be relative to your script's location.
14. "$(dirname "$0")/common.sh"
15
16# Script must be run inside the chroot.
Don Garrett640a0582010-05-04 16:54:28 -070017restart_in_chroot_if_needed $*
Bill Richardsonc09b94f2010-03-15 11:40:30 -070018
19get_default_board
20
21# Flags.
Don Garrette0020b12010-06-17 15:55:35 -070022DEFINE_string board "${DEFAULT_BOARD}" \
Bill Richardsonc09b94f2010-03-15 11:40:30 -070023 "The board to build an image for."
24DEFINE_string build_root "/build" \
25 "The root location for board sysroots."
26DEFINE_integer build_attempt 1 \
27 "The build attempt for this image build."
28DEFINE_string output_root "${DEFAULT_BUILD_ROOT}/images" \
29 "Directory in which to place image result directories (named by version)"
Don Garrette0020b12010-06-17 15:55:35 -070030DEFINE_boolean replace ${FLAGS_FALSE} \
Bill Richardsonc09b94f2010-03-15 11:40:30 -070031 "Overwrite existing output, if any."
Don Garrette0020b12010-06-17 15:55:35 -070032DEFINE_boolean withdev ${FLAGS_TRUE} \
Bill Richardsonc09b94f2010-03-15 11:40:30 -070033 "Include useful developer friendly utilities in the image."
Don Garrette0020b12010-06-17 15:55:35 -070034DEFINE_boolean installmask ${FLAGS_TRUE} \
Bill Richardsonc09b94f2010-03-15 11:40:30 -070035 "Use INSTALL_MASK to shrink the resulting image."
36DEFINE_integer jobs -1 \
37 "How many packages to build in parallel at maximum."
Don Garrette0020b12010-06-17 15:55:35 -070038DEFINE_boolean statefuldev ${FLAGS_TRUE} \
Chris Sosa4bffb8b2010-04-07 17:23:54 -070039 "Install development packages on stateful partition rather than the rootfs"
Antoine Laboure9e585f2010-04-01 15:57:57 -070040DEFINE_string to "" \
41 "The target image file or device"
Don Garrette0020b12010-06-17 15:55:35 -070042DEFINE_boolean factory_install ${FLAGS_FALSE} \
Tom Wai-Hong Tamf87a3672010-05-17 16:06:33 +080043 "Build a smaller image to overlay the factory install shim on; this argument \
44is also required in image_to_usb."
robotboyb75eee32010-04-30 09:51:23 -070045DEFINE_string arm_extra_bootargs "" \
46 "Additional command line options to pass to the ARM kernel."
Zelidrag Hornung1d12c1a2010-06-02 10:20:29 -070047DEFINE_integer rootfs_partition_size 1024 \
48 "rootfs parition size in MBs."
49DEFINE_integer rootfs_size 720 \
50 "rootfs filesystem size in MBs."
Eric Li5cf288f2010-06-28 12:46:26 -070051DEFINE_integer statefulfs_size 1024 \
52 "stateful filesystem size in MBs."
David James868d7bb2010-06-24 21:48:14 -070053DEFINE_boolean preserve ${FLAGS_FALSE} \
54 "Attempt to preserve the previous build image if one can be found (unstable, \
55kernel/firmware not updated)"
Bill Richardsonc09b94f2010-03-15 11:40:30 -070056
57# Parse command line.
58FLAGS "$@" || exit 1
59eval set -- "${FLAGS_ARGV}"
60
61# Only now can we die on error. shflags functions leak non-zero error codes,
62# so will die prematurely if 'set -e' is specified before now.
63set -e
64
Don Garrette0020b12010-06-17 15:55:35 -070065if [ -z "${FLAGS_board}" ] ; then
Bill Richardsonc09b94f2010-03-15 11:40:30 -070066 error "--board is required."
67 exit 1
68fi
69
Don Garrette0020b12010-06-17 15:55:35 -070070if [ "${FLAGS_rootfs_size}" -gt "${FLAGS_rootfs_partition_size}" ] ; then
Zelidrag Hornung1d12c1a2010-06-02 10:20:29 -070071 error "rootfs (${FLAGS_rootfs_size} MB) is bigger than partition (${FLAGS_rootfs_partition_size} MB)."
72 exit 1
73fi
74
Nick Sanders8ab729a2010-06-16 03:15:17 -070075EMERGE_CMD="emerge"
76EMERGE_BOARD_CMD="emerge-${FLAGS_board}"
77TOP_SCRIPTS_DIR="$(dirname $0)"
78if [ -e "${TOP_SCRIPTS_DIR}/.emerge" ]; then
79 echo "Using alternate emerge"
80 . "${TOP_SCRIPTS_DIR}/.emerge"
81fi
82
Bill Richardsonc09b94f2010-03-15 11:40:30 -070083# Determine build version.
84. "${SCRIPTS_DIR}/chromeos_version.sh"
85
86# Use canonical path since some tools (e.g. mount) do not like symlinks.
87# Append build attempt to output directory.
88IMAGE_SUBDIR="${CHROMEOS_VERSION_STRING}-a${FLAGS_build_attempt}"
89OUTPUT_DIR="${FLAGS_output_root}/${FLAGS_board}/${IMAGE_SUBDIR}"
Don Garrett3f41e152010-06-21 14:54:34 -070090
91OUTSIDE_OUTPUT_DIR="../build/images/${FLAGS_board}/${IMAGE_SUBDIR}"
Chris Sosa9673f3b2010-05-18 13:24:40 -070092
93# If we are creating a developer image, also create a pristine image with a
94# different name.
95DEVELOPER_IMAGE_NAME=
96PRISTINE_IMAGE_NAME=chromiumos_image.bin
Don Garrette0020b12010-06-17 15:55:35 -070097if [ "${FLAGS_withdev}" -eq "${FLAGS_TRUE}" ]; then
Chris Sosa9673f3b2010-05-18 13:24:40 -070098 PRISTINE_IMAGE_NAME=chromiumos_base_image.bin
99 DEVELOPER_IMAGE_NAME=chromiumos_image.bin
100fi
Tan Gaoa40ed442010-06-02 15:45:19 -0700101
David James868d7bb2010-06-24 21:48:14 -0700102PRISTINE_IMG="${OUTPUT_DIR}/${PRISTINE_IMAGE_NAME}"
103DEVELOPER_IMG="${OUTPUT_DIR}/${DEVELOPER_IMAGE_NAME}"
Bill Richardsonc09b94f2010-03-15 11:40:30 -0700104
105BOARD="${FLAGS_board}"
106BOARD_ROOT="${FLAGS_build_root}/${BOARD}"
107
Don Garrett3f41e152010-06-21 14:54:34 -0700108ROOT_FS_IMG="${OUTPUT_DIR}/rootfs.image"
109ROOT_FS_DIR="${OUTPUT_DIR}/rootfs"
110
111STATEFUL_FS_IMG="${OUTPUT_DIR}/stateful_partition.image"
112STATEFUL_FS_DIR="${OUTPUT_DIR}/stateful_partition"
113
114ESP_FS_IMG=${OUTPUT_DIR}/esp.image
115ESP_FS_DIR=${OUTPUT_DIR}/esp
116
Bill Richardsonc09b94f2010-03-15 11:40:30 -0700117LOOP_DEV=
Chris Sosa4bffb8b2010-04-07 17:23:54 -0700118STATEFUL_LOOP_DEV=
Bill Richardsona81df762010-04-09 08:12:05 -0700119ESP_LOOP_DEV=
Bill Richardsonc09b94f2010-03-15 11:40:30 -0700120
Don Garrett3f41e152010-06-21 14:54:34 -0700121# ${DEV_IMAGE_ROOT} specifies the location of where developer packages will
122# be installed on the stateful dir. On a Chromium OS system, this will
123# translate to /usr/local.
124DEV_IMAGE_ROOT="${STATEFUL_FS_DIR}/dev_image"
125
Bill Richardsonc09b94f2010-03-15 11:40:30 -0700126# What cross-build are we targeting?
127. "${BOARD_ROOT}/etc/make.conf.board_setup"
128LIBC_VERSION=${LIBC_VERSION:-"2.10.1-r1"}
129
Don Garrett3f41e152010-06-21 14:54:34 -0700130INSTALL_MASK=""
131if [[ ${FLAGS_installmask} -eq ${FLAGS_TRUE} ]] ; then
132 INSTALL_MASK="${DEFAULT_INSTALL_MASK}"
133fi
134
135# Reduce the size of factory install shim.
136# TODO: Build a separated ebuild for the factory install shim to reduce size.
137if [[ ${FLAGS_factory_install} -eq ${FLAGS_TRUE} ]] ; then
138 INSTALL_MASK="${INSTALL_MASK} ${FACTORY_INSTALL_MASK}"
139fi
140
141if [[ ${FLAGS_jobs} -ne -1 ]]; then
142 EMERGE_JOBS="--jobs=${FLAGS_jobs}"
143fi
144
Bill Richardsonc09b94f2010-03-15 11:40:30 -0700145# Figure out ARCH from the given toolchain.
146# TODO: Move to common.sh as a function after scripts are switched over.
Don Garrette0020b12010-06-17 15:55:35 -0700147TC_ARCH=$(echo "${CHOST}" | awk -F'-' '{ print $1 }')
148case "${TC_ARCH}" in
Bill Richardsonc09b94f2010-03-15 11:40:30 -0700149 arm*)
150 ARCH="arm"
151 ;;
152 *86)
153 ARCH="x86"
154 ;;
155 *)
Don Garrette0020b12010-06-17 15:55:35 -0700156 error "Unable to determine ARCH from toolchain: ${CHOST}"
Bill Richardsonc09b94f2010-03-15 11:40:30 -0700157 exit 1
158esac
159
160# Hack to fix bug where x86_64 CHOST line gets incorrectly added.
161# ToDo(msb): remove this hack.
162PACKAGES_FILE="${BOARD_ROOT}/packages/Packages"
163sudo sed -e "s/CHOST: x86_64-pc-linux-gnu//" -i "${PACKAGES_FILE}"
164
165# Handle existing directory.
Don Garrette0020b12010-06-17 15:55:35 -0700166if [[ -e "${OUTPUT_DIR}" ]]; then
167 if [[ ${FLAGS_replace} -eq ${FLAGS_TRUE} ]]; then
168 sudo rm -rf "${OUTPUT_DIR}"
Bill Richardsonc09b94f2010-03-15 11:40:30 -0700169 else
Don Garrette0020b12010-06-17 15:55:35 -0700170 echo "Directory ${OUTPUT_DIR} already exists."
Bill Richardsonc09b94f2010-03-15 11:40:30 -0700171 echo "Use --build_attempt option to specify an unused attempt."
172 echo "Or use --replace if you want to overwrite this directory."
173 exit 1
174 fi
175fi
176
David James868d7bb2010-06-24 21:48:14 -0700177# Find previous build, if any...
178PREVIOUS_DIR=$($SCRIPTS_DIR/get_latest_image.sh --board="$BOARD")
179
Bill Richardsonc09b94f2010-03-15 11:40:30 -0700180cleanup_rootfs_loop() {
Don Garrette0020b12010-06-17 15:55:35 -0700181 sudo umount -d "${ROOT_FS_DIR}"
Bill Richardsonc09b94f2010-03-15 11:40:30 -0700182}
183
184cleanup_stateful_fs_loop() {
Chris Sosa4bffb8b2010-04-07 17:23:54 -0700185 sudo umount "${ROOT_FS_DIR}/usr/local"
186 sudo umount "${ROOT_FS_DIR}/var"
Don Garrett3f41e152010-06-21 14:54:34 -0700187 sudo umount -d "${STATEFUL_FS_DIR}"
Bill Richardsonc09b94f2010-03-15 11:40:30 -0700188}
189
Bill Richardson8b3bd102010-04-06 15:00:10 -0700190cleanup_esp_loop() {
Don Garrett3f41e152010-06-21 14:54:34 -0700191 sudo umount -d "${ESP_FS_DIR}"
Bill Richardson8b3bd102010-04-06 15:00:10 -0700192}
193
Bill Richardsonc09b94f2010-03-15 11:40:30 -0700194cleanup() {
195 # Disable die on error.
196 set +e
197
Don Garrette0020b12010-06-17 15:55:35 -0700198 if [[ -n "${STATEFUL_LOOP_DEV}" ]]; then
Bill Richardsonc09b94f2010-03-15 11:40:30 -0700199 cleanup_stateful_fs_loop
200 fi
201
Don Garrette0020b12010-06-17 15:55:35 -0700202 if [[ -n "${LOOP_DEV}" ]]; then
Bill Richardsonc09b94f2010-03-15 11:40:30 -0700203 cleanup_rootfs_loop
204 fi
205
Don Garrette0020b12010-06-17 15:55:35 -0700206 if [[ -n "${ESP_LOOP_DEV}" ]]; then
Bill Richardson8b3bd102010-04-06 15:00:10 -0700207 cleanup_esp_loop
208 fi
209
Bill Richardsonc09b94f2010-03-15 11:40:30 -0700210 # Turn die on error back on.
211 set -e
212}
213
Chris Sosabde8c1b2010-04-29 14:02:35 -0700214delete_prompt() {
215 echo "An error occurred in your build so your latest output directory" \
216 "is invalid."
217 read -p "Would you like to delete the output directory (y/N)? " SURE
Don Garrette0020b12010-06-17 15:55:35 -0700218 SURE="${SURE:0:1}" # Get just the first character.
Chris Sosabde8c1b2010-04-29 14:02:35 -0700219 if [ "${SURE}" == "y" ] ; then
Don Garrette0020b12010-06-17 15:55:35 -0700220 sudo rm -rf "${OUTPUT_DIR}"
221 echo "Deleted ${OUTPUT_DIR}"
Chris Sosabde8c1b2010-04-29 14:02:35 -0700222 else
Don Garrette0020b12010-06-17 15:55:35 -0700223 echo "Not deleting ${OUTPUT_DIR}. Note dev server updates will not work" \
Chris Sosabde8c1b2010-04-29 14:02:35 -0700224 "until you successfully build another image or delete this directory"
225 fi
226}
227
Chris Sosa9673f3b2010-05-18 13:24:40 -0700228# $1 - Directory where developer rootfs is mounted.
229# $2 - Directory where developer stateful_partition is mounted.
Don Garrett3f41e152010-06-21 14:54:34 -0700230mount_gpt_cleanup() {
Don Garrette0020b12010-06-17 15:55:35 -0700231 "${SCRIPTS_DIR}/mount_gpt_image.sh" -u -r "$1" -s "$2"
Chris Sosa9673f3b2010-05-18 13:24:40 -0700232 delete_prompt
233}
234
Don Garrett3f41e152010-06-21 14:54:34 -0700235# Modifies an existing image to add development packages
236update_dev_packages() {
237 local image_name=$1
Chris Sosa9673f3b2010-05-18 13:24:40 -0700238
Don Garrett3f41e152010-06-21 14:54:34 -0700239 echo "Adding developer packages to ${image_name}"
Chris Sosa9673f3b2010-05-18 13:24:40 -0700240
Don Garrett3f41e152010-06-21 14:54:34 -0700241 trap "mount_gpt_cleanup \"${ROOT_FS_DIR}\" \"${STATEFUL_FS_DIR}\"" EXIT
Tan Gaoa40ed442010-06-02 15:45:19 -0700242
Don Garrette0020b12010-06-17 15:55:35 -0700243 ${SCRIPTS_DIR}/mount_gpt_image.sh --from "${OUTPUT_DIR}" \
David James868d7bb2010-06-24 21:48:14 -0700244 --image "${image_name}" -r "${ROOT_FS_DIR}" \
Chris Sosa6c587b02010-06-21 17:36:18 -0700245 -s "${STATEFUL_FS_DIR}"
Chris Sosa9673f3b2010-05-18 13:24:40 -0700246
Don Garrett3f41e152010-06-21 14:54:34 -0700247 # Determine the root dir for developer packages.
248 local root_dev_dir="${ROOT_FS_DIR}"
249 [ ${FLAGS_statefuldev} -eq ${FLAGS_TRUE} ] && \
250 root_dev_dir="${ROOT_FS_DIR}/usr/local"
Chris Sosa9673f3b2010-05-18 13:24:40 -0700251
Don Garrett3f41e152010-06-21 14:54:34 -0700252 # Install developer packages described in chromeos-dev.
253 sudo INSTALL_MASK="${INSTALL_MASK}" ${EMERGE_BOARD_CMD} \
254 --root="${root_dev_dir}" --root-deps=rdeps \
David James868d7bb2010-06-24 21:48:14 -0700255 --usepkg -uDNv chromeos-dev ${EMERGE_JOBS}
256
257 if [[ $FLAGS_preserve -eq ${FLAGS_TRUE} ]] ; then
258 # Clean out unused packages
259 sudo INSTALL_MASK="${INSTALL_MASK}" ${EMERGE_BOARD_CMD} \
260 --root="${ROOT_FS_DIR}" --root-deps=rdeps \
261 --usepkg --depclean ${EMERGE_JOBS}
262 fi
Chris Sosa9673f3b2010-05-18 13:24:40 -0700263
264 # Re-run ldconfig to fix /etc/ldconfig.so.cache.
Don Garrett3f41e152010-06-21 14:54:34 -0700265 sudo /sbin/ldconfig -r "${ROOT_FS_DIR}"
Chris Sosa9673f3b2010-05-18 13:24:40 -0700266
267 # Mark the image as a developer image (input to chromeos_startup).
Don Garrett3f41e152010-06-21 14:54:34 -0700268 sudo mkdir -p "${ROOT_FS_DIR}/root"
269 sudo touch "${ROOT_FS_DIR}/root/.dev_mode"
Chris Sosa9673f3b2010-05-18 13:24:40 -0700270
Don Garrett3f41e152010-06-21 14:54:34 -0700271 # Additional changes to developer image.
Chris Sosa9673f3b2010-05-18 13:24:40 -0700272
Don Garrett3f41e152010-06-21 14:54:34 -0700273 # The ldd tool is a useful shell script but lives in glibc; just copy it.
274 sudo cp -a "$(which ldd)" "${root_dev_dir}/usr/bin"
Chris Sosa9673f3b2010-05-18 13:24:40 -0700275
Don Garrett3f41e152010-06-21 14:54:34 -0700276 # If vim is installed, then a vi symlink would probably help.
277 if [[ -x "${ROOT_FS_DIR}/usr/local/bin/vim" ]]; then
278 sudo ln -sf vim "${ROOT_FS_DIR}/usr/local/bin/vi"
Girts Folkmanis7a8a8382010-05-18 22:52:25 -0700279 fi
Chris Sosa9673f3b2010-05-18 13:24:40 -0700280
Don Garrett3f41e152010-06-21 14:54:34 -0700281 # Check that the image has been correctly created. Only do it if not
282 # building a factory install image, as the INSTALL_MASK for it will
283 # make test_image fail.
284 if [[ ${FLAGS_factory_install} -eq ${FLAGS_FALSE} ]] ; then
285 "${SCRIPTS_DIR}/test_image" \
286 --root="${ROOT_FS_DIR}" \
287 --target="${ARCH}"
288 fi
289 echo "Developer image built and stored at ${image_name}"
290
Chris Sosa9673f3b2010-05-18 13:24:40 -0700291 trap - EXIT
David James868d7bb2010-06-24 21:48:14 -0700292 ${SCRIPTS_DIR}/mount_gpt_image.sh -u -r "${ROOT_FS_DIR}" \
293 -s "${STATEFUL_FS_DIR}"
294}
295
296# Update the base package on an existing image.
297update_base_packages() {
298 local image_name=$1
299
300 echo "Updating base packages on ${image_name}"
301
302 # Create stateful partition of the same size as the rootfs.
303 trap "mount_gpt_cleanup \"${ROOT_FS_DIR}\" \"${STATEFUL_FS_DIR}\"" EXIT
304
305 ${SCRIPTS_DIR}/mount_gpt_image.sh --from "${OUTPUT_DIR}" \
306 --image "${image_name}" -r "${ROOT_FS_DIR}" \
307 -s "${STATEFUL_FS_DIR}"
308
309 # Emerge updated packages, exactly like when creating base image
310 sudo INSTALL_MASK="${INSTALL_MASK}" ${EMERGE_BOARD_CMD} \
311 --root="${ROOT_FS_DIR}" --root-deps=rdeps \
312 --usepkg -uDNv chromeos ${EMERGE_JOBS}
313
314 # Clean out unused packages
315 sudo INSTALL_MASK="${INSTALL_MASK}" ${EMERGE_BOARD_CMD} \
316 --root="${ROOT_FS_DIR}" --root-deps=rdeps \
317 --usepkg --depclean ${EMERGE_JOBS}
318
319 trap - EXIT
320 ${SCRIPTS_DIR}/mount_gpt_image.sh -u -r "${ROOT_FS_DIR}" \
321 -s "${STATEFUL_FS_DIR}"
Chris Sosa9673f3b2010-05-18 13:24:40 -0700322}
323
Don Garrett3f41e152010-06-21 14:54:34 -0700324create_base_image() {
David James868d7bb2010-06-24 21:48:14 -0700325 local image_name=$1
Bill Richardsonc09b94f2010-03-15 11:40:30 -0700326
Don Garrett3f41e152010-06-21 14:54:34 -0700327 trap "cleanup && delete_prompt" EXIT
Chris Sosa4bffb8b2010-04-07 17:23:54 -0700328
David James868d7bb2010-06-24 21:48:14 -0700329 UUID=$(uuidgen)
330
Don Garrett3f41e152010-06-21 14:54:34 -0700331 # Create and format the root file system.
332
333 # Check for loop device before creating image.
334 LOOP_DEV=$(sudo losetup -f)
335 if [ -z "${LOOP_DEV}" ] ; then
336 echo "No free loop device. Free up a loop device or reboot. exiting. "
337 exit 1
338 fi
339
340 # Create root file system disk image to fit on a 1GB memory stick.
341 # 1 GB in hard-drive-manufacturer-speak is 10^9, not 2^30. 950MB < 10^9 bytes.
342 if [[ ${FLAGS_factory_install} -eq ${FLAGS_TRUE} ]] ; then
343 ROOT_SIZE_BYTES=$((1024 * 1024 * 300))
344 else
345 ROOT_SIZE_BYTES=$((1024 * 1024 * ${FLAGS_rootfs_size}))
346 fi
347
348 dd if=/dev/zero of="${ROOT_FS_IMG}" bs=1 count=1 seek=$((ROOT_SIZE_BYTES - 1))
349 sudo losetup "${LOOP_DEV}" "${ROOT_FS_IMG}"
350 sudo mkfs.ext3 "${LOOP_DEV}"
351
352 # Tune and mount rootfs.
Don Garrett3f41e152010-06-21 14:54:34 -0700353 DISK_LABEL="C-KEYFOB"
354 sudo tune2fs -L "${DISK_LABEL}" -U "${UUID}" -c 0 -i 0 "${LOOP_DEV}"
355 sudo mount "${LOOP_DEV}" "${ROOT_FS_DIR}"
356
357 # Create stateful partition of the same size as the rootfs.
358 STATEFUL_LOOP_DEV=$(sudo losetup -f)
359 if [ -z "${STATEFUL_LOOP_DEV}" ] ; then
360 echo "No free loop device. Free up a loop device or reboot. exiting. "
361 exit 1
362 fi
Eric Li5cf288f2010-06-28 12:46:26 -0700363 STATEFUL_SIZE_BYTES=$((1024 * 1024 * ${FLAGS_statefulfs_size}))
364 dd if=/dev/zero of="${STATEFUL_FS_IMG}" bs=1 count=1 \
365 seek=$((STATEFUL_SIZE_BYTES - 1))
Don Garrett3f41e152010-06-21 14:54:34 -0700366 sudo losetup "${STATEFUL_LOOP_DEV}" "${STATEFUL_FS_IMG}"
367 sudo mkfs.ext3 "${STATEFUL_LOOP_DEV}"
368 sudo tune2fs -L "C-STATE" -U "${UUID}" -c 0 -i 0 \
369 "${STATEFUL_LOOP_DEV}"
370
371 # Mount the stateful partition.
372 sudo mount "${STATEFUL_LOOP_DEV}" "${STATEFUL_FS_DIR}"
373
374 # Turn root file system into bootable image.
375 if [[ "${ARCH}" = "x86" ]]; then
376 # Setup extlinux configuration.
377 # TODO: For some reason the /dev/disk/by-uuid is not being generated by udev
378 # in the initramfs. When we figure that out, switch to root=UUID=${UUID}.
379 sudo mkdir -p "${ROOT_FS_DIR}"/boot
380 # TODO(adlr): use initramfs for booting.
381 cat <<EOF | sudo dd of="${ROOT_FS_DIR}"/boot/extlinux.conf
Bill Richardsonc09b94f2010-03-15 11:40:30 -0700382DEFAULT chromeos-usb
383PROMPT 0
384TIMEOUT 0
385
386label chromeos-usb
387 menu label chromeos-usb
388 kernel vmlinuz
Bill Richardson25e4c182010-06-17 12:50:49 -0700389 append quiet console=tty2 init=/sbin/init boot=local rootwait root=/dev/sdb3 ro noresume noswap i915.modeset=1 loglevel=1 cros_legacy
Bill Richardsonc09b94f2010-03-15 11:40:30 -0700390
391label chromeos-hd
392 menu label chromeos-hd
393 kernel vmlinuz
Bill Richardson25e4c182010-06-17 12:50:49 -0700394 append quiet console=tty2 init=/sbin/init boot=local rootwait root=HDROOT ro noresume noswap i915.modeset=1 loglevel=1 cros_legacy
Bill Richardsonc09b94f2010-03-15 11:40:30 -0700395EOF
396
Don Garrett3f41e152010-06-21 14:54:34 -0700397 # Make partition bootable and label it.
398 sudo extlinux -z --install "${ROOT_FS_DIR}/boot"
399 fi
Bill Richardsonc09b94f2010-03-15 11:40:30 -0700400
Don Garrett3f41e152010-06-21 14:54:34 -0700401 # -- Install packages into the root file system --
Bill Richardsonc09b94f2010-03-15 11:40:30 -0700402
Don Garrett3f41e152010-06-21 14:54:34 -0700403 # We need to install libc manually from the cross toolchain.
404 # TODO: Improve this? We only want libc and not the whole toolchain.
405 PKGDIR="/var/lib/portage/pkgs/cross/"
406 sudo tar jxvpf \
407 "${PKGDIR}/${CHOST}/cross-${CHOST}"/glibc-${LIBC_VERSION}.tbz2 \
408 -C "${ROOT_FS_DIR}" --strip-components=3 \
409 --exclude=usr/include --exclude=sys-include --exclude=*.a --exclude=*.o
Bill Richardsonc09b94f2010-03-15 11:40:30 -0700410
Don Garrett3f41e152010-06-21 14:54:34 -0700411 # We need to install libstdc++ manually from the cross toolchain.
412 # TODO: Figure out a better way of doing this?
413 sudo cp -a "${BOARD_ROOT}"/lib/libgcc_s.so* "${ROOT_FS_DIR}/lib"
414 sudo cp -a "${BOARD_ROOT}"/usr/lib/libstdc++.so* "${ROOT_FS_DIR}/usr/lib"
Bill Richardsonc09b94f2010-03-15 11:40:30 -0700415
Don Garrett3f41e152010-06-21 14:54:34 -0700416 # Prepare stateful partition with some pre-created directories.
417 sudo mkdir -p "${DEV_IMAGE_ROOT}"
418 sudo mkdir -p "${STATEFUL_FS_DIR}/var"
Bill Richardsonc09b94f2010-03-15 11:40:30 -0700419
Don Garrett3f41e152010-06-21 14:54:34 -0700420 # Create symlinks so that /usr/local/usr based directories are symlinked to
421 # /usr/local/ directories e.g. /usr/local/usr/bin -> /usr/local/bin, etc.
422 setup_symlinks_on_root "${DEV_IMAGE_ROOT}" "${STATEFUL_FS_DIR}/var" \
423 "${STATEFUL_FS_DIR}"
Tom Wai-Hong Tamf87a3672010-05-17 16:06:33 +0800424
Don Garrett3f41e152010-06-21 14:54:34 -0700425 # Perform binding rather than symlinking because directories must exist
426 # on rootfs so that we can bind at run-time since rootfs is read-only.
427 echo "Binding directories from stateful partition onto the rootfs"
428 sudo mkdir -p "${ROOT_FS_DIR}/usr/local"
429 sudo mount --bind "${DEV_IMAGE_ROOT}" "${ROOT_FS_DIR}/usr/local"
430 sudo mkdir -p "${ROOT_FS_DIR}/var"
431 sudo mount --bind "${STATEFUL_FS_DIR}/var" "${ROOT_FS_DIR}/var"
432 sudo mkdir -p "${ROOT_FS_DIR}/dev"
Bill Richardsonc09b94f2010-03-15 11:40:30 -0700433
Mandeep Singh Baines3dfa8522010-06-24 15:00:49 -0700434 # We "emerge --root=${ROOT_FS_DIR} --root-deps=rdeps --usepkg" all of the
Don Garrett3f41e152010-06-21 14:54:34 -0700435 # runtime packages for chrome os. This builds up a chrome os image from
436 # binary packages with runtime dependencies only. We use INSTALL_MASK to
437 # trim the image size as much as possible.
438 sudo INSTALL_MASK="${INSTALL_MASK}" ${EMERGE_BOARD_CMD} \
439 --root="${ROOT_FS_DIR}" --root-deps=rdeps \
Mandeep Singh Baines3dfa8522010-06-24 15:00:49 -0700440 --usepkg chromeos ${EMERGE_JOBS}
Bill Richardson8b3bd102010-04-06 15:00:10 -0700441
Don Garrett3f41e152010-06-21 14:54:34 -0700442 # Create EFI System Partition to boot stock EFI BIOS (but not ChromeOS EFI
443 # BIOS). We only need this for x86, but it's simpler and safer to keep the
444 # disk images the same for both x86 and ARM.
445 # NOTE: The size argument for mkfs.vfat is in 1024-byte blocks.
446 # We'll hard-code it to 16M for now.
447 ESP_BLOCKS=16384
448 /usr/sbin/mkfs.vfat -C ${OUTPUT_DIR}/esp.image ${ESP_BLOCKS}
449 ESP_LOOP_DEV=$(sudo losetup -f)
450 if [ -z "${ESP_LOOP_DEV}" ] ; then
451 echo "No free loop device. Free up a loop device or reboot. exiting. "
452 exit 1
453 fi
454 sudo losetup "${ESP_LOOP_DEV}" "${ESP_FS_IMG}"
455 sudo mount "${ESP_LOOP_DEV}" "${ESP_FS_DIR}"
456 sudo mkdir -p "${ESP_FS_DIR}/efi/boot"
457 sudo grub-mkimage -p /efi/boot -o "${ESP_FS_DIR}/efi/boot/bootx64.efi" \
458 part_gpt fat ext2 normal boot sh chain configfile linux
459 cat <<'EOF' | sudo dd of="${ESP_FS_DIR}/efi/boot/grub.cfg"
Bill Richardson8b3bd102010-04-06 15:00:10 -0700460set default=0
Bill Richardson9c5e5ec2010-05-14 17:00:21 -0700461set timeout=2
Bill Richardson8b3bd102010-04-06 15:00:10 -0700462
Bill Richardson9c5e5ec2010-05-14 17:00:21 -0700463# NOTE: These magic grub variables are a Chrome OS hack. They are not portable.
464
465menuentry "local image A" {
Bill Richardson25e4c182010-06-17 12:50:49 -0700466 linux $grubpartA/boot/vmlinuz quiet console=tty2 init=/sbin/init boot=local rootwait root=/dev/$linuxpartA ro noresume noswap i915.modeset=1 loglevel=1 cros_efi
Bill Richardsona81df762010-04-09 08:12:05 -0700467}
468
Bill Richardson9c5e5ec2010-05-14 17:00:21 -0700469menuentry "local image B" {
Bill Richardson25e4c182010-06-17 12:50:49 -0700470 linux $grubpartB/boot/vmlinuz quiet console=tty2 init=/sbin/init boot=local rootwait root=/dev/$linuxpartB ro noresume noswap i915.modeset=1 loglevel=1 cros_efi
Bill Richardson041bd712010-04-27 09:36:14 -0700471}
472
Nick Sanders9e305db2010-06-11 15:18:35 -0700473menuentry "Alternate USB Boot" {
Bill Richardson25e4c182010-06-17 12:50:49 -0700474 linux (hd0,3)/boot/vmlinuz quiet console=tty2 init=/sbin/init boot=local rootwait root=/dev/sdb3 ro noresume noswap i915.modeset=1 loglevel=1 cros_efi
Nick Sanders9e305db2010-06-11 15:18:35 -0700475}
476
Bill Richardson8b3bd102010-04-06 15:00:10 -0700477EOF
Will Drewry69563b72010-06-24 16:12:58 -0500478 # TODO(wad) add baseline syslinux files to ESP and install the syslinux loader
Bill Richardson8b3bd102010-04-06 15:00:10 -0700479
Will Drewry69563b72010-06-24 16:12:58 -0500480 # Builds the kernel partition image. The temporary files are kept around
481 # so that we can perform a load_kernel_test later on the final image.
482 # TODO(wad) add dm-verity boot args (--boot_args, --root)
483 ${SCRIPTS_DIR}/build_kernel_image.sh \
484 --arch="${ARCH}" \
485 --to="${OUTPUT_DIR}/vmlinuz.image" \
486 --vmlinuz="${ROOT_FS_DIR}/boot/vmlinuz" \
487 --working_dir="${OUTPUT_DIR}" \
488 --keep_work \
489 --keys_dir="${SRC_ROOT}/platform/vboot_reference/tests/testkeys"
Bill Richardson67956222010-05-28 15:38:56 -0700490
Don Garrett3f41e152010-06-21 14:54:34 -0700491 # Perform any customizations on the root file system that are needed.
492 "${SCRIPTS_DIR}/customize_rootfs" \
Don Garrette0020b12010-06-17 15:55:35 -0700493 --root="${ROOT_FS_DIR}" \
Don Garrett3f41e152010-06-21 14:54:34 -0700494 --target="${ARCH}" \
495 --board="${BOARD}"
Chris Sosa503efe12010-04-08 10:05:46 -0700496
Don Garrett3f41e152010-06-21 14:54:34 -0700497 # Don't test the factory install shim.
498 if [[ ${FLAGS_factory_install} -eq ${FLAGS_FALSE} ]] ; then
499 # Check that the image has been correctly created.
500 "${SCRIPTS_DIR}/test_image" \
501 --root="${ROOT_FS_DIR}" \
502 --target="${ARCH}"
503 fi
Bill Richardsonc09b94f2010-03-15 11:40:30 -0700504
Don Garrett3f41e152010-06-21 14:54:34 -0700505 # Clean up symlinks so they work on a running target rooted at "/".
506 # Here development packages are rooted at /usr/local. However, do not
507 # create /usr/local or /var on host (already exist on target).
508 setup_symlinks_on_root "/usr/local" "/var" "${STATEFUL_FS_DIR}"
Bill Richardsonc09b94f2010-03-15 11:40:30 -0700509
Don Garrett3f41e152010-06-21 14:54:34 -0700510 # Cleanup loop devices.
511 cleanup
Chris Sosabde8c1b2010-04-29 14:02:35 -0700512
Don Garrett3f41e152010-06-21 14:54:34 -0700513 trap delete_prompt EXIT
Tan Gao6df5aee2010-05-19 14:19:55 -0700514
Don Garrett3f41e152010-06-21 14:54:34 -0700515 # Create the GPT-formatted image.
516 ${SCRIPTS_DIR}/build_gpt.sh \
517 --arch=${ARCH} \
518 --board=${FLAGS_board} \
519 --arm_extra_bootargs="${FLAGS_arm_extra_bootargs}" \
520 --rootfs_partition_size=${FLAGS_rootfs_partition_size} \
Don Garrett3f41e152010-06-21 14:54:34 -0700521 "${OUTPUT_DIR}" \
David James868d7bb2010-06-24 21:48:14 -0700522 "${OUTPUT_DIR}/${image_name}"
523
524 trap - EXIT
525
526 # FIXME: only signing things for x86 right now.
527 if [[ "${ARCH}" = "x86" ]]; then
528 # Verify the final image.
529 load_kernel_test "${OUTPUT_DIR}/${image_name}" \
530 "${OUTPUT_DIR}/key_alg8.vbpubk"
531 fi
Don Garrett3f41e152010-06-21 14:54:34 -0700532}
533
534# Create the output directory.
535mkdir -p "${OUTPUT_DIR}"
536mkdir -p "${ROOT_FS_DIR}"
537mkdir -p "${STATEFUL_FS_DIR}"
538mkdir -p "${ESP_FS_DIR}"
539
David James868d7bb2010-06-24 21:48:14 -0700540# Preserve old images by copying them forward for --preserve.
541if [[ $FLAGS_preserve -eq ${FLAGS_TRUE} ]] ; then
542 if [[ -f ${PREVIOUS_DIR}/${PRISTINE_IMAGE_NAME} ]] ; then
543 # Copy forward pristine image, and associated files
544 cp ${PREVIOUS_DIR}/*.sh ${PREVIOUS_DIR}/config.txt ${OUTPUT_DIR}
545 cp ${PREVIOUS_DIR}/${PRISTINE_IMAGE_NAME} ${OUTPUT_DIR}
546
547 # Copy forward the developer image, if we already copied forward the base.
548 if [[ ${FLAGS_withdev} -eq ${FLAGS_TRUE} ]] && \
549 [[ -f ${PREVIOUS_DIR}/${DEVELOPER_IMAGE_NAME} ]] ; then
550 cp ${PREVIOUS_DIR}/${DEVELOPER_IMAGE_NAME} ${OUTPUT_DIR}
551 fi
552 fi
553fi
554
555if [[ -f ${PRISTINE_IMG} ]] ; then
556 update_base_packages ${PRISTINE_IMAGE_NAME}
557else
558 create_base_image ${PRISTINE_IMAGE_NAME}
559fi
Bill Richardson4364a2e2010-03-30 14:17:34 -0700560
Don Garrette0020b12010-06-17 15:55:35 -0700561# Create a developer image based on the chromium os base image.
Don Garrett3f41e152010-06-21 14:54:34 -0700562if [ "${FLAGS_withdev}" -eq "${FLAGS_TRUE}" ] ; then
David James868d7bb2010-06-24 21:48:14 -0700563 if [[ ! -f ${DEVELOPER_IMG} ]] ; then
564 echo "Creating developer image from base image ${PRISTINE_IMAGE_NAME}"
565 cp ${PRISTINE_IMG} ${DEVELOPER_IMG}
566 fi
Don Garrett3f41e152010-06-21 14:54:34 -0700567
David James868d7bb2010-06-24 21:48:14 -0700568 update_dev_packages ${DEVELOPER_IMAGE_NAME}
Bill Richardson6ed13582010-06-16 21:38:15 -0700569fi
570
571# Clean up temporary files.
Don Garrett3f41e152010-06-21 14:54:34 -0700572rm -f "${ROOT_FS_IMG}" "${STATEFUL_FS_IMG}" "${OUTPUT_DIR}/vmlinuz.image" \
573 "${ESP_FS_IMG}" "${OUTPUT_DIR}/data4_sign8.keyblock" \
Don Garrette0020b12010-06-17 15:55:35 -0700574 "${OUTPUT_DIR}/key_alg4.vbpubk" "${OUTPUT_DIR}/key_alg8.vbpubk"
Don Garrett3f41e152010-06-21 14:54:34 -0700575rmdir "${ROOT_FS_DIR}" "${STATEFUL_FS_DIR}" "${ESP_FS_DIR}"
Bill Richardson67956222010-05-28 15:38:56 -0700576
Bill Richardsonc09b94f2010-03-15 11:40:30 -0700577echo "Done. Image created in ${OUTPUT_DIR}"
Don Garrette0020b12010-06-17 15:55:35 -0700578echo "Chromium OS image created as ${PRISTINE_IMAGE_NAME}"
Don Garrette0020b12010-06-17 15:55:35 -0700579if [ "${FLAGS_withdev}" -eq "${FLAGS_TRUE}" ]; then
580 echo "Developer image created as ${DEVELOPER_IMAGE_NAME}"
Chris Sosa9673f3b2010-05-18 13:24:40 -0700581fi
Nick Sanders8ab729a2010-06-16 03:15:17 -0700582
Nick Sandersd2509272010-06-16 03:50:04 -0700583print_time_elapsed
584
Bill Richardsonc09b94f2010-03-15 11:40:30 -0700585echo "To copy to USB keyfob, OUTSIDE the chroot, do something like:"
Daniel Eratdd9818a2010-04-26 09:16:44 -0700586echo " ./image_to_usb.sh --from=${OUTSIDE_OUTPUT_DIR} --to=/dev/sdX"
Bill Richardsonc09b94f2010-03-15 11:40:30 -0700587echo "To convert to VMWare image, OUTSIDE the chroot, do something like:"
588echo " ./image_to_vmware.sh --from=${OUTSIDE_OUTPUT_DIR}"
589echo "from the scripts directory where you entered the chroot."