Create EFI System Partition on USB image during build.

The EFI System Partition is a special disk partition where EFI BIOS expects
to find the platform-specific bootloader. We need this in order to work on
the BIOS/kernel handoff. It's not needed for the final ChromeOS image and it
isn't useful for legacy BIOS systems, so right now it only makes any difference on x86
devices with development BIOSes.

This change creates the partition for ARM builds as well; it has no effect
there, either.

Review URL: http://codereview.chromium.org/1513019
This commit is contained in:
Bill Richardson 2010-04-06 15:00:10 -07:00
parent e450333e3f
commit 8b3bd10b91
3 changed files with 63 additions and 17 deletions

View File

@ -99,6 +99,12 @@ if [[ ! -s ${STATEFUL_IMG} ]]; then
exit 1
fi
ESP_IMG="${IMAGEDIR}/esp.image"
if [[ ! -s ${ESP_IMG} ]]; then
error "Can't find ${ESP_IMG}"
exit 1
fi
# We'll need some code to put in the PMBR, for booting on legacy BIOS. Some ARM
# systems will use a U-Boot script temporarily, but it goes in the same place.
if [[ "$ARCH" = "arm" ]]; then
@ -107,7 +113,7 @@ if [[ "$ARCH" = "arm" ]]; then
# set the appropriate environment variables. Then we can create the correct
# script and install it for real. A bit awkward, but this is only temporary.
echo "Installing fake GPT first, to calculate locations..."
install_gpt $OUTDEV $ROOTFS_IMG $KERNEL_IMG $STATEFUL_IMG /dev/zero
install_gpt $OUTDEV $ROOTFS_IMG $KERNEL_IMG $STATEFUL_IMG /dev/zero $ESP_IMG
# Create the U-Boot script to copy the kernel into memory and boot it.
KERNEL_OFFSET=$(printf "0x%08x" ${START_KERN_A})
@ -147,7 +153,7 @@ fi
# Create the GPT. This has the side-effect of setting some global vars
# describing the partition table entries (see the comments in the source).
install_gpt $OUTDEV $ROOTFS_IMG $KERNEL_IMG $STATEFUL_IMG $PMBRCODE
install_gpt $OUTDEV $ROOTFS_IMG $KERNEL_IMG $STATEFUL_IMG $PMBRCODE $ESP_IMG
# Emit helpful scripts for testers, etc.
${SCRIPTS_DIR}/emit_gpt_scripts.sh "${OUTDEV}" "${IMAGEDIR}"
@ -169,6 +175,9 @@ $sudo dd if=${KERNEL_IMG} of=${OUTDEV} conv=notrunc bs=512 seek=${START_KERN_A}
echo "Copying rootfs..."
$sudo dd if=${ROOTFS_IMG} of=${OUTDEV} conv=notrunc bs=512 seek=${START_ROOTFS_A}
echo "Copying EFI system partition..."
dd if=${ESP_IMG} of=${OUTDEV} conv=notrunc bs=512 seek=${START_ESP}
# Clean up temporary files.
if [[ -n "${MBR_IMG:-}" ]]; then
rm "${MBR_IMG}"

View File

@ -129,6 +129,10 @@ cleanup_stateful_fs_loop() {
sudo losetup -d "$STATEFUL_LOOP_DEV"
}
cleanup_esp_loop() {
sudo umount "$ESP_DIR"
}
cleanup() {
# Disable die on error.
set +e
@ -146,6 +150,10 @@ cleanup() {
cleanup_rootfs_loop
fi
if [[ -n "$ESP_DIR" ]]; then
cleanup_esp_loop
fi
# Turn die on error back on.
set -e
}
@ -322,10 +330,34 @@ if [[ $FLAGS_withdev -eq $FLAGS_TRUE ]]; then
fi
# Extract the kernel from the root filesystem for use by the GPT image. Legacy
# BIOS will use the kernel in the rootfs (via syslinux), ChromeOS BIOS will use
# the kernel partition.
# BIOS will use the kernel in the rootfs (via syslinux), Chrome OS BIOS will
# use the kernel partition.
sudo cp -f "${ROOT_FS_DIR}/boot/vmlinuz" "${OUTPUT_DIR}/vmlinuz.image"
# Create EFI System Partition to boot stock EFI BIOS (but not ChromeOS EFI
# BIOS). We only need this for x86, but it's simpler and safer to keep the disk
# images the same for both x86 and ARM.
ESP_IMG=${OUTPUT_DIR}/esp.image
# NOTE: The size argument for mkfs.vfat is in 1024-byte blocks. We'll hard-code
# it to 16M for now.
ESP_BLOCKS=16384
/usr/sbin/mkfs.vfat -C ${OUTPUT_DIR}/esp.image ${ESP_BLOCKS}
ESP_DIR=${OUTPUT_DIR}/esp
mkdir -p ${ESP_DIR}
sudo mount -o loop ${ESP_IMG} ${ESP_DIR}
sudo mkdir -p ${ESP_DIR}/efi/boot
sudo grub-mkimage -p /efi/boot -o ${ESP_DIR}/efi/boot/bootx64.efi \
part_gpt fat ext2 normal boot sh chain configfile linux
sudo cp ${ROOT_FS_DIR}/boot/vmlinuz ${ESP_DIR}/efi/boot/vmlinuz
cat <<EOF | sudo dd of=${ESP_DIR}/efi/boot/grub.cfg
set timeout=2
set default=0
menuentry "32-bit serial" {
linux /efi/boot/vmlinuz earlyprintk=serial,ttyS0,115200 i915.modeset=0 console=ttyS0,115200 acpi=off init=/sbin/init boot=local rootwait root=/dev/sda3 ro noresume noswap loglevel=7
}
EOF
#TODO(sosa@chromium.org) - Does it make sense to leave /usr/local bound here?
"${SCRIPTS_DIR}/customize_rootfs" \
--root="$ROOT_FS_DIR" \
@ -350,6 +382,7 @@ if [ $FLAGS_statefuldev -eq $FLAGS_TRUE ] ; then
fi
# Cleanup loop devices.
cleanup_esp_loop
cleanup_stateful_fs_loop
cleanup_rootfs_loop
@ -359,8 +392,9 @@ ${SCRIPTS_DIR}/build_gpt.sh \
"${OUTPUT_DIR}" "${OUTPUT_IMG}"
# Clean up temporary files.
rm -f "${ROOT_FS_IMG}" "${STATEFUL_IMG}" "${OUTPUT_DIR}/vmlinuz.image"
rmdir "${ROOT_FS_DIR}" "${STATEFUL_DIR}"
rm -f "${ROOT_FS_IMG}" "${STATEFUL_IMG}" "${OUTPUT_DIR}/vmlinuz.image" \
"${ESP_IMG}"
rmdir "${ROOT_FS_DIR}" "${STATEFUL_DIR}" "${ESP_DIR}"
OUTSIDE_OUTPUT_DIR="../build/images/${FLAGS_board}/${IMAGE_SUBDIR}"
echo "Done. Image created in ${OUTPUT_DIR}"

View File

@ -68,6 +68,8 @@ TEMP_DIR=$(mktemp -d)
"${FLAGS_from}/unpack_partitions.sh" "${FLAGS_from}/chromiumos_image.bin")
# Fix the kernel command line
# FIXME: TEMP_ESP is only partition 4 at the moment. It may change!
TEMP_ESP="$TEMP_DIR"/part_4
TEMP_ROOTFS="$TEMP_DIR"/part_3
TEMP_STATE="$TEMP_DIR"/part_1
if [ -n "${FLAGS_state_image}" ]; then
@ -97,11 +99,12 @@ sudo dd if=/dev/zero of="${TEMP_IMG}" bs=1 count=1 \
# Set up the partition table
install_gpt "$TEMP_IMG" "$TEMP_ROOTFS" "$TEMP_KERN" "$TEMP_STATE" \
"$TEMP_PMBR" true
"$TEMP_PMBR" "$TEMP_ESP" true
# Copy into the partition parts of the file
dd if="$TEMP_ROOTFS" of="$TEMP_IMG" conv=notrunc bs=512 seek="$START_ROOTFS_A"
dd if="$TEMP_STATE" of="$TEMP_IMG" conv=notrunc bs=512 seek="$START_STATEFUL"
dd if="$TEMP_KERN" of="$TEMP_IMG" conv=notrunc bs=512 seek="$START_KERN_A"
dd if="$TEMP_ESP" of="$TEMP_IMG" conv=notrunc bs=512 seek="$START_ESP"
echo Creating final image
# Convert image to output format