blob: 88b73407d7d0b1aca3e01494a97bf02246c6ade2 [file] [log] [blame]
# Copyright 2015 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
# This will add console=ttyS0 kernel cmdline flag, thus rerouting
# dmesg output to ttyS0 (serial port).
FLAGS_enable_serial=ttyS0
# Don't install upstart files.
INSTALL_MASK+=" /etc/init"
# Don't install symbol table for kdump kernel.
INSTALL_MASK+=" /boot/kdump/System.map-*"
# Removes given item from the INSTALL_MASK string
remove_from_install_mask(){
target="$1"
#Disable wildcard expansion and create array from the INSTALL_MASK string.
set -f
INSTALL_MASK_ARRAY=(${INSTALL_MASK})
set +f
INSTALL_MASK_NEW=""
for value in "${INSTALL_MASK_ARRAY[@]}"; do
# Remove target from INSTALL_MASK
if [[ ${value} != "${target}" ]]; then
INSTALL_MASK_NEW+=" ${value}"
fi
done
INSTALL_MASK="${INSTALL_MASK_NEW}"
unset INSTALL_MASK_NEW
}
# /boot/config-* is masked in common.sh through INSTALL_MASK which
# prevents installing already generated kernel config. This function
# removes it from the INSTALL_MASK
remove_from_install_mask "/boot/config-*"
# Temporary directory containing the package list
# files used for creating cos-package-info.json.
TEMP_PACKAGE_DIR=""
cleanup_temp_package_dir() {
if [[ -d "${TEMP_PACKAGE_DIR}" ]]; then
rm -fr "${TEMP_PACKAGE_DIR}"
fi
}
# build_image script calls board_setup on the pristine base image.
board_make_image_bootable() {
local -r image="$1"
local -r script_root="$(readlink -f "$(dirname "${BASH_SOURCE[0]}")")"
. "${script_root}/bootloader_install.sh" || exit 1
if ! bootloader_install "${image}"; then
error "Could not install bootloaders on ${image}"
return 1
fi
}
create_runtime_package_info() {
local -r runtime_pkg_file="$1/runtime_pkg_info"
# The "emerge" command below generates the list of packages that
# virtual/target-os depends on. These are the packages that are
# installed into the image. Its results look like
#
# ...
# [binary R ] app-arch/gzip-1.9 to /build/lakitu/
# [binary R ] dev-libs/popt-1.16-r2 to /build/lakitu/
# [binary R ] app-emulation/docker-credential-helpers-0.6.3-r1 to /build/lakitu/
# ...
#
# This command line is similar to what ListInstalledPackage function (in
# chromite/licensing/licenses_lib.py) does.
#
# The following "grep" command filters out extra messages to leave the package
# list only.
#
# And the "sed" command extracts the category name, the package name, and the
# version from each line. With that, the example above is converted to
#
# ...
# app-arch/gzip-1.9
# dev-libs/popt-1.16-r2
# app-emulation/docker-credential-helpers-0.6.3-r1
# ...
"emerge-${BOARD}" \
--with-bdeps=n --with-bdeps-auto=n --usepkgonly --emptytree --pretend \
--color=n virtual/target-os | \
grep --color=never "^\[" | \
sed -E 's/\[[^]]+R[^]]+\] (.+) to \/build\/.*/\1/' \
> "${runtime_pkg_file}"
echo "${runtime_pkg_file}"
}
create_buildtime_package_info() {
local -r all_pkg_file="$1/all_pkg_info"
# The "emerge" command below generates the list of packages that
# virtual/target-os depends on. It includes both buildtime dependent
# packages and installed packages. Its results look like
#
# ...
# [ebuild R ] virtual/pkgconfig-0-r1 to /build/lakitu/
# [ebuild R ] dev-go/protobuf-1.3.2-r1 to /build/lakitu/
# [binary R ] app-arch/gzip-1.9 to /build/lakitu/
# ...
#
# The following "grep" command filters out extra messages to leave the package
# list only.
# And the "sed" command extracts the category name, the package name, and the
# version from each line. With that, the example above is converted to
#
# ...
# virtual/pkgconfig-0-r1
# dev-go/protobuf-1.3.2-r1
# app-arch/gzip-1.9
# ...
"emerge-${BOARD}" \
--with-bdeps=y --with-bdeps-auto=y \
--emptytree --pretend --color=n \
virtual/target-os | \
grep --color=never "/build/" | \
sed -E 's/\[[^]]+R[^]]+\] (.+) to \/build\/.*/\1/' \
> "${all_pkg_file}"
# Find the buildtime dependent packages.
# Args $2 represent the file containing the installed packages.
local -r buildtime_pkg_file="$1/buildtime_pkg_info"
fgrep -v -f "$2" "${all_pkg_file}" > "${buildtime_pkg_file}"
# Find all the buildtime packages that are present in public
# overlays. This is needed because he buildtime packages will
# be exposed in cos-package-info.json file and it should only
# contain packages from public overlay if it is build time
# dependency.
local -r input_file="${buildtime_pkg_file}"
local -r buildtime_public_pkg_file="$1/buildtime_public_pkg_info"
while IFS= read -r pkg
do
# Output of qlist-${BOARD} -R virtual/pkgconfig is in the below format:
# virtual/pkgconfig::portage-stable
# Below command gets portage-stable for the above output.
overlay=$(qlist-"${BOARD}" -R "${pkg}" | awk -F'::' '{print $2}')
if [[ "${overlay}" != *"-private"* ]]; then
echo "${pkg}" >> "${buildtime_public_pkg_file}"
fi
done < "${input_file}"
echo "${buildtime_public_pkg_file}"
}
create_package_info() {
trap cleanup_temp_package_dir EXIT
TEMP_PACKAGE_DIR="$(mktemp -d -p /tmp package-list.XXXXXXXXXX)"
local -r runtime_pkg_file=$(create_runtime_package_info "${TEMP_PACKAGE_DIR}")
local -r buildtime_pkg_file=$(create_buildtime_package_info \
"${TEMP_PACKAGE_DIR}" \
"${runtime_pkg_file}")
local -r script_root="$(readlink -f "$(dirname "${BASH_SOURCE[0]}")")"
sudo "${script_root}/create_pkg_info.py" \
--input="installedPackages:${runtime_pkg_file},buildTimePackages:${buildtime_pkg_file}" \
--output="${root_fs_dir}"/etc/cos-package-info.json \
--build-id="${CHROMEOS_VERSION_STRING}"
cleanup_temp_package_dir
trap - EXIT
}
write_toolchain_path() {
local -r cros_overlay="/mnt/host/source/src/third_party/chromiumos-overlay"
local -r sdk_ver_file="${cros_overlay}/chromeos/binhost/host/sdk_version.conf"
local -r ctarget="$(portageq-"${BOARD}" envvar CHOST)"
. "${sdk_ver_file}"
local -r toolchain_path="${TC_PATH/\%\(target\)s/${ctarget}}"
# Write toolchain path to image.
echo "${toolchain_path}" | \
sudo tee "${root_fs_dir}/etc/toolchain-path" > /dev/null
# Write toolchain path to build dir so it can be exported as an artifact.
echo "${toolchain_path}" | \
sudo tee "${BUILD_DIR}/toolchain_path" > /dev/null
}
# Moves the given rootfs_file to the given artifact location. The directory
# containing the rootfs_file is deleted if it becomes empty after this move.
# If the rootfs_file doesn't exist, put an empty file at the given artifact
# location.
export_image_artifact() {
local rootfs_file="$1"
local artifact="$2"
if [[ ! -f "${rootfs_file}" ]]; then
touch "${artifact}"
return
fi
cp "${rootfs_file}" "${artifact}"
sudo rm "${rootfs_file}"
if [[ -z "$(ls -A "$(dirname "${rootfs_file}")")" ]]; then
sudo rmdir "$(dirname "${rootfs_file}")"
fi
}
write_toolchain_env() {
# Create toolchain_env file in BUILD_DIR so that it can be exported
# as an artifact.
local artifact="${BUILD_DIR}/toolchain_env"
# File from which kernel compiler information will be copied
# This file is deleted after copying content to artifact
local toolchain_env_file="${root_fs_dir}/etc/toolchain_env"
# Copy kernel compiler info to BUILD artifact
if [[ -f "${toolchain_env_file}" ]]; then
cp "${toolchain_env_file}" "${artifact}"
# Remove toolchain_env from image
sudo rm "${toolchain_env_file}"
else
touch "${artifact}"
fi
}
write_kernel_info() {
# Create kernel_info file in BUILD_DIR so that it can be exported
# as an artifact.
local build_artifact="${BUILD_DIR}/kernel_info"
# File from which kernel information will be copied.
# This file is deleted after copying content to artifact.
local kernel_info_file="${root_fs_dir}/etc/kernel_info"
# Copy kernel_info to BUILD artifact.
if [[ -f "${kernel_info_file}" ]]; then
cp "${kernel_info_file}" "${build_artifact}"
# Remove kernel_info file from image.
sudo rm "${kernel_info_file}"
else
touch "${build_artifact}"
fi
}
write_kernel_commit() {
# Create kernel_commit file in BUILD_DIR so that it can be exported
# as an artifact.
local build_artifact="${BUILD_DIR}/kernel_commit"
# File from which kernel commit will be copied.
# This file is deleted after copying content to artifact.
local kernel_commit_file="${root_fs_dir}/etc/kernel_commit"
# Copy kernel_commit to BUILD artifact.
if [[ -f "${kernel_commit_file}" ]]; then
cp "${kernel_commit_file}" "${build_artifact}"
# Remove kernel_commit file from image.
sudo rm "${kernel_commit_file}"
else
touch "${build_artifact}"
fi
}
# Export kernel config file as a BUILD artifact.
export_kernel_config(){
# Copy config file to BUILD_DIR.
# For example: config-5.10.53
cp "${root_fs_dir}"/boot/config-* "${BUILD_DIR}/kernel_config"
}
# Exports default GPU driver version file as an artifact.
export_gpu_default_version() {
local -r script_root="$1"
local -r default_driver_file="${script_root}/gpu_default_version"
local -r default_driver_artifact="${BUILD_DIR}/gpu_default_version"
# Copy scripts/gpu_default_version to BUILD artifact
cp "${default_driver_file}" "${default_driver_artifact}"
}
# board_finalize_base_image() gets invoked by the build scripts at the
# end of building base image.
board_finalize_base_image() {
local -r script_root="$(readlink -f "$(dirname "${BASH_SOURCE[0]}")")"
info "Generating cos-package-info.json."
(create_package_info)
cp "${root_fs_dir}"/etc/cos-package-info.json \
"${BUILD_DIR}"/cos-package-info.json
write_toolchain_path
export_image_artifact \
"${root_fs_dir}/opt/google/src/kernel-src.tar.gz" \
"${BUILD_DIR}/kernel-src.tar.gz"
export_image_artifact \
"${root_fs_dir}/opt/google/src/kernel-headers.tgz" \
"${BUILD_DIR}/kernel-headers.tgz"
write_toolchain_env
write_kernel_info
write_kernel_commit
export_kernel_config
cp "${BOARD_ROOT}/usr/lib/debug/boot/vmlinux" "${BUILD_DIR}/vmlinux"
export_gpu_default_version "${script_root}"
# /etc/machine-id gets installed by sys-apps/dbus and is a symlink.
# This conflicts with systemd's machine-id generation mechanism,
# so we remove the symlink and recreate it as an empty file.
sudo rm "${root_fs_dir}"/etc/machine-id
sudo touch "${root_fs_dir}"/etc/machine-id
info "Copying shim to bootx64.efi"
sudo cp \
"${root_fs_dir}"/boot/efi/boot/shimx64.efi \
"${root_fs_dir}"/boot/efi/boot/bootx64.efi
info "Successfully copied shim to bootx64.efi"
info "Deleting legacy EFI bootloaders"
# Don't delete bootx64.efi here, since the shim is now there
sudo rm -f "${root_fs_dir}"/boot/efi/boot/bootia32.efi
info "Successfully deleted legacy EFI bootloaders"
info "Populating dbx"
sudo mkdir -p "${esp_fs_dir}"/efi/Google/GSetup/dbx
sudo cp "${script_root}"/dbx/* "${esp_fs_dir}"/efi/Google/GSetup/dbx
sudo chmod -R 755 "${esp_fs_dir}"/efi/Google/GSetup/dbx
info "Successfully populated dbx"
}