1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313
|
#!/bin/sh
## live-build(7) - System Build Scripts
## Copyright (C) 2016-2020 The Debian Live team
## Copyright (C) 2016 Adrian Gibanel Lopez <adrian15sgd@gmail.com>
##
## This program comes with ABSOLUTELY NO WARRANTY; for details see COPYING.
## This is free software, and you are welcome to redistribute it
## under certain conditions; see COPYING for details.
set -e
# Including common functions
[ -e "${LIVE_BUILD}/scripts/build.sh" ] && . "${LIVE_BUILD}/scripts/build.sh" || . /usr/lib/live/build.sh
# Setting static variables
DESCRIPTION="Prepares and installs Grub based EFI support into binary"
USAGE="${PROGRAM} [--force]"
# Processing arguments and configuration files
Init_config_data "${@}"
if [ "${LB_BOOTLOADER_EFI}" != "grub-efi" ]; then
exit 0
fi
if In_list "${LB_IMAGE_TYPE}" hdd netboot; then
exit 0
fi
Echo_message "Begin preparing Grub based EFI support..."
# NOTE: We rely on `binary_grub_cfg` to generate grub.cfg and other configuration files!
# Requiring stage file
Require_stagefiles config bootstrap
# Checking stage file
Check_stagefile
# Acquire lock file
Acquire_lockfile
# Check architecture
Check_architectures amd64 i386 arm64 armhf
Check_crossarchitectures
# Checking depends
case "${LB_ARCHITECTURE}" in
amd64|i386)
Check_package chroot /usr/lib/grub/x86_64-efi/configfile.mod grub-efi-amd64-bin
Check_package chroot /usr/lib/grub/i386-efi/configfile.mod grub-efi-ia32-bin
;;
arm64)
Check_package chroot /usr/lib/grub/arm64-efi/configfile.mod grub-efi-arm64-bin
;;
armhf)
Check_package chroot /usr/lib/grub/arm-efi/configfile.mod grub-efi-arm-bin
;;
esac
Check_package chroot /usr/bin/grub-mkimage grub-common
Check_package chroot /usr/bin/mcopy mtools
Check_package chroot /sbin/mkfs.msdos dosfstools
# Check UEFI Secure Boot setting and depends
# By default (auto) do a best-effort build: if the signed binaries are available use
# them, but don't fail if they are not, just print a warning.
case "${LB_ARCHITECTURE}" in
amd64)
_SB_EFI_PLATFORM="x86_64"
_SB_EFI_NAME="x64"
_SB_EFI_DEB="amd64"
;;
i386)
_SB_EFI_PLATFORM="i386"
_SB_EFI_NAME="ia32"
_SB_EFI_DEB="ia32"
;;
arm64)
_SB_EFI_PLATFORM="arm64"
_SB_EFI_NAME="aa64"
_SB_EFI_DEB="arm64"
;;
armhf)
_SB_EFI_PLATFORM="arm"
_SB_EFI_NAME="arm"
_SB_EFI_DEB="arm"
;;
esac
_PRE_SB_PACKAGES="${_LB_PACKAGES}"
_LB_PACKAGES="shim-signed grub-efi-${_SB_EFI_DEB}-signed"
case "${LB_UEFI_SECURE_BOOT}" in
auto)
# Use Check_installed, as Check_package will error out immediately
set +e
Install_packages
set -e
Check_installed chroot /usr/lib/grub/${_SB_EFI_PLATFORM}-efi-signed/gcd${_SB_EFI_NAME}.efi.signed \
grub-efi-${_SB_EFI_DEB}-signed
_GRUB_INSTALL_STATUS="${INSTALL_STATUS}"
Check_installed chroot /usr/lib/shim/shim${_SB_EFI_NAME}.efi.signed \
shim-signed
if [ "${INSTALL_STATUS}" -ne 0 -o "${_GRUB_INSTALL_STATUS}" -ne 0 ]
then
Echo_warning "UEFI Secure Boot disabled due to missing signed Grub/Shim."
else
Echo_message "UEFI Secure Boot support enabled."
fi
;;
enable)
Check_package chroot /usr/lib/grub/${_SB_EFI_PLATFORM}-efi-signed/gcd${_SB_EFI_NAME}.efi.signed \
grub-efi-${_SB_EFI_DEB}-signed
Check_package chroot /usr/lib/shim/shim${_SB_EFI_NAME}.efi.signed \
shim-signed
Install_packages
Echo_message "UEFI Secure Boot support enabled."
;;
disable)
Echo_message "UEFI Secure Boot support disabled."
;;
esac
_LB_PACKAGES="${_PRE_SB_PACKAGES}"
# Restoring cache
Restore_package_cache binary
# Installing depends
Install_packages
# Cleanup files that we generate
rm -rf binary/boot/efi.img binary/boot/grub/i386-efi/ binary/boot/grub/x86_64-efi binary/boot/grub/arm64-efi binary/boot/grub/arm-efi
# This is workaround till both efi-image and grub-cpmodules are put into a binary package
case "${LB_BUILD_WITH_CHROOT}" in
true)
if [ ! -e "${LIVE_BUILD}" ] ; then
LIVE_BUILD_PATH="/usr/lib/live/build"
else
LIVE_BUILD_PATH="${LIVE_BUILD}/scripts/build"
fi
mkdir -p chroot/${LIVE_BUILD_PATH}
cp "${LIVE_BUILD_PATH}/efi-image" "chroot/${LIVE_BUILD_PATH}"
cp "${LIVE_BUILD_PATH}/grub-cpmodules" "chroot/${LIVE_BUILD_PATH}"
_CHROOT_DIR=""
;;
false)
_CHROOT_DIR="chroot"
;;
esac
#####
cat >binary.sh <<END
#!/bin/sh
set -e
gen_efi_boot_img(){
local platform="\$1"
local efi_name="\$2"
local netboot_prefix="\$3"
local outdir="grub-efi-temp-\${platform}"
"\${LIVE_BUILD_PATH}/efi-image" "${_CHROOT_DIR}/\$outdir" "\$platform" "\$efi_name" "\$netboot_prefix"
mkdir -p ${_CHROOT_DIR}/grub-efi-temp/EFI/boot
mcopy -m -n -i ${_CHROOT_DIR}/\$outdir/efi.img '::efi/boot/boot*.efi' ${_CHROOT_DIR}/grub-efi-temp/EFI/boot
cp -a "${_CHROOT_DIR}"/\$outdir/* "${_CHROOT_DIR}/grub-efi-temp/"
# Secure Boot support:
# - create the EFI directory in the ESP with uppercase letters to make
# certain firmwares (eg: TianoCore) happy
# - use shim as the boot<arch>.efi that gets loaded first by the firmware
# - drop a grub.cfg (same reason as below) in the cfg directory as configured
# by the signed grub efi binary creation. This is set dynamically when grub2 is
# built with the ouput of dpkg-vendor, and can be overridden by the builder, so
# we do the same here in live-build.
# - the source paths are taken from shim-signed:
# https://packages.debian.org/sid/amd64/shim-signed/filelist
# and grub-efi-amd64-signed, currently in Ubuntu:
# https://packages.ubuntu.com/xenial/amd64/grub-efi-amd64-signed/filelist
# https://packages.ubuntu.com/bionic/arm64/grub-efi-arm64-signed/filelist
# E.g., gcdx64.efi.signed is the boot loader for removable device, like CD or
# USB flash drive, while grubx64.efi.signed is for hard drive.
# Therefore here gcdx64.efi.signed is used for amd64 and gcdaa64.efi.signed is
# for arm64.
if [ -r ${_CHROOT_DIR}/usr/lib/grub/\$platform-signed/gcd\$efi_name.efi.signed -a \
-r ${_CHROOT_DIR}/usr/lib/shim/shim\$efi_name.efi.signed -a \
"${LB_UEFI_SECURE_BOOT}" != "disable" ]; then
cp -a ${_CHROOT_DIR}/usr/lib/grub/\$platform-signed/gcd\$efi_name.efi.signed \
${_CHROOT_DIR}/grub-efi-temp/EFI/boot/grub\$efi_name.efi
cp -a ${_CHROOT_DIR}/usr/lib/shim/shim\$efi_name.efi.signed \
${_CHROOT_DIR}/grub-efi-temp/EFI/boot/boot\$efi_name.efi
fi
}
PRE_EFI_IMAGE_PATH="${PATH}"
if [ ! -e "${LIVE_BUILD}" ] ; then
LIVE_BUILD_PATH="/usr/lib/live/build"
else
LIVE_BUILD_PATH="${LIVE_BUILD}/scripts/build"
fi
PATH="${PATH}:\${LIVE_BUILD_PATH}" # Make sure grub-cpmodules is used as if it was installed in the system
case "${LB_ARCHITECTURE}" in
amd64|i386)
gen_efi_boot_img "x86_64-efi" "x64" "debian-live/amd64"
gen_efi_boot_img "i386-efi" "ia32" "debian-live/i386"
PATH="\${PRE_EFI_IMAGE_PATH}"
;;
arm64)
gen_efi_boot_img "arm64-efi" "aa64" "debian-live/arm64"
PATH="\${PRE_EFI_IMAGE_PATH}"
;;
armhf)
gen_efi_boot_img "arm-efi" "arm" "debian-live/arm"
PATH="\${PRE_EFI_IMAGE_PATH}"
;;
esac
# On some platforms the EFI grub image will be loaded, so grub's root
# variable will be set to the EFI partition. This means that grub will
# look in that partition for a grub.cfg file, and even if it finds it
# it will not be able to find the vmlinuz and initrd.
# Drop a minimal grub.cfg in the EFI partition that sets the root and prefix
# to whatever partition holds the /.disk/info file, and load the grub
# config from that same partition.
mkdir -p ${_CHROOT_DIR}/grub-efi-temp-cfg
cat >${_CHROOT_DIR}/grub-efi-temp-cfg/grub.cfg <<EOF
search --set=root --file /.disk/info
set prefix=(\\\$root)/boot/grub
configfile (\\\$root)/boot/grub/grub.cfg
EOF
# Set the timestamp within the efi.img file
touch ${_CHROOT_DIR}/grub-efi-temp-cfg/grub.cfg -d@${SOURCE_DATE_EPOCH}
# The code below is adapted from tools/boot/jessie/boot-x86
# in debian-cd
# Stuff the EFI boot files into a FAT filesystem, making it as
# small as possible. 24KiB headroom seems to be enough;
# (x+31)/32*32 rounds up to multiple of 32.
# This is the same as in efi-image, but we need to redo it here in
# the case of a multi-arch amd64/i386 image
size=0
for file in ${_CHROOT_DIR}/grub-efi-temp/EFI/boot/*.efi \
${_CHROOT_DIR}/grub-efi-temp-cfg/grub.cfg; do
size=\$((\$size + \$(stat -c %s "\$file")))
done
# directories: EFI EFI/boot boot boot/grub
size=\$((\$size + 4096 * 4))
blocks=\$(((\$size / 1024 + 55) / 32 * 32 ))
rm -f ${_CHROOT_DIR}/grub-efi-temp/boot/grub/efi.img
# The VOLID must be (truncated to) a 32bit hexadecimal number
mkfs.msdos -C "${_CHROOT_DIR}/grub-efi-temp/boot/grub/efi.img" \$blocks -i $(printf "%08x" $((${SOURCE_DATE_EPOCH}%4294967296))) >/dev/null
mmd -i "${_CHROOT_DIR}/grub-efi-temp/boot/grub/efi.img" ::EFI
mmd -i "${_CHROOT_DIR}/grub-efi-temp/boot/grub/efi.img" ::EFI/boot
mcopy -m -o -i "${_CHROOT_DIR}/grub-efi-temp/boot/grub/efi.img" ${_CHROOT_DIR}/grub-efi-temp/EFI/boot/*.efi \
"::EFI/boot"
mmd -i "${_CHROOT_DIR}/grub-efi-temp/boot/grub/efi.img" ::boot
mmd -i "${_CHROOT_DIR}/grub-efi-temp/boot/grub/efi.img" ::boot/grub
mcopy -m -o -i "${_CHROOT_DIR}/grub-efi-temp/boot/grub/efi.img" ${_CHROOT_DIR}/grub-efi-temp-cfg/grub.cfg \
"::boot/grub"
END
case "${LB_BUILD_WITH_CHROOT}" in
true)
mv binary.sh chroot/
Chroot chroot "sh binary.sh"
rm -f chroot/binary.sh
# Saving cache
Save_package_cache binary
# Removing depends. Some bootloader packages are marked as Protected/Important
# in Ubuntu, so temporarily add an apt flag to allow them to be removed
PRE_APT_OPTIONS="${APT_OPTIONS}"
APT_OPTIONS="${APT_OPTIONS} --allow-remove-essential"
Remove_packages
APT_OPTIONS="${PRE_APT_OPTIONS}"
;;
false)
sh binary.sh
rm -f binary.sh
;;
esac
# Remove unnecessary files
rm -f chroot/grub-efi-temp/bootnetia32.efi
rm -f chroot/grub-efi-temp/bootnetx64.efi
rm -f chroot/grub-efi-temp/bootnetaa64.efi
rm -f chroot/grub-efi-temp/bootnetarm.efi
mkdir -p binary
cp -a chroot/grub-efi-temp/* binary/
rm -rf chroot/grub-efi-temp-x86_64-efi
rm -rf chroot/grub-efi-temp-i386-efi
rm -rf chroot/grub-efi-temp-arm64-efi
rm -rf chroot/grub-efi-temp-arm-efi
rm -rf chroot/grub-efi-temp-cfg
rm -rf chroot/grub-efi-temp
# Creating stage file
Create_stagefile
|