blob: 51cc608d41f4c08231c307af85d0171349efd3cf [file] [log] [blame]
# Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
# Distributed under the terms of the GNU General Public License v2
EAPI=4
CROS_WORKON_COMMIT="01e9bce4b239ad1d877e40e000e5ac046cb8509e"
CROS_WORKON_TREE="0a928a35446939f8691bbd8367332704d2badfcb"
CROS_WORKON_PROJECT="chromiumos/platform/initramfs"
CROS_WORKON_OUTOFTREE_BUILD="1"
inherit cros-workon cros-board
DESCRIPTION="Create Chrome OS initramfs"
HOMEPAGE="http://www.chromium.org/"
LICENSE="GPL-2"
SLOT="0"
KEYWORDS="amd64 arm x86"
IUSE="netboot_ramfs"
DEPEND="chromeos-base/chromeos-assets
chromeos-base/chromeos-assets-split
chromeos-base/vboot_reference
chromeos-base/vpd
media-gfx/ply-image
sys-apps/busybox[-make-symlinks]
sys-apps/flashrom
sys-apps/pv
sys-fs/lvm2
netboot_ramfs? ( chromeos-base/chromeos-installshim )"
RDEPEND=""
CROS_WORKON_LOCALNAME="../platform/initramfs"
# dobin for initramfs
idobin() {
local src
for src in "$@"; do
"${FILESDIR}/copy_elf" "${ROOT}" "${INITRAMFS_TMP_S}" "${src}" ||
die "Cannot install: ${src}"
elog "Copied: ${src}"
done
}
# Special handling for futility wrapper. This will go away once futility is
# converted to a single binary.
idofutility() {
local src
local base
for src in "$@"; do
"${FILESDIR}/copy_elf" "${ROOT}" "${INITRAMFS_TMP_S}" "${src}" ||
die "Cannot install: ${src}"
base=$(basename "${src}")
mv -f "${INITRAMFS_TMP_S}/bin/${base}" \
"${INITRAMFS_TMP_S}/bin/old_bins/${base}" ||
die "Cannot mv: ${src}"
ln -sf futility "${INITRAMFS_TMP_S}/bin/${base}" ||
die "Cannot symlink: ${src}"
elog "Symlinked: /bin/${base} -> futility"
done
}
# only copy library dependencies
idodep() {
local src
for src in "$@"; do
"${FILESDIR}/copy_elf" "--lib-only" "${ROOT}" \
"${INITRAMFS_TMP_S}" "${src}" || \
die "Cannot install: ${src}"
elog "Copied dependency for: ${src}"
done
}
# install a list of images (presumably .png files) in /etc/screens
insimage() {
cp "$@" "${INITRAMFS_TMP_S}"/etc/screens || die
}
pull_initramfs_binary() {
# For busybox and sh
idobin /bin/busybox
ln -s busybox "${INITRAMFS_TMP_S}/bin/sh"
# For verified rootfs
idobin /sbin/dmsetup
# For message screen display and progress bars
idobin /usr/bin/ply-image
idobin /usr/bin/pv
idobin /usr/sbin/vpd
# /usr/sbin/vpd invokes 'flashrom' via system()
idobin /usr/sbin/flashrom
# For recovery behavior
idobin /usr/bin/futility
idofutility /usr/bin/old_bins/cgpt
idofutility /usr/bin/old_bins/crossystem
idofutility /usr/bin/old_bins/dump_kernel_config
idofutility /usr/bin/old_bins/tpmc
idofutility /usr/bin/old_bins/vbutil_kernel
}
pull_netboot_ramfs_binary() {
# We want to keep GNU sh at /bin/sh, so let's change shebang for init
# to busybox explicitly.
sed -i '1s|.*|#!/bin/busybox sh\nset -x|' "${INITRAMFS_TMP_S}/init" || die
# Busybox and utilities
idobin /bin/busybox
local bin_name
local busybox_bins=(
awk
basename
cat
chmod
chroot
cp
cut
date
dirname
expr
find
grep
gzip
id
ifconfig
mkdir
mkfs.vfat
mktemp
modprobe
mount
rm
rmdir
sed
sleep
sync
tee
tr
true
udhcpc
umount
uname
uniq
)
for bin_name in ${busybox_bins[@]}; do
ln -s busybox "${INITRAMFS_TMP_S}/bin/${bin_name}" || die
done
# Factory installer
idobin /usr/sbin/factory_install.sh
idobin /usr/sbin/chromeos-common.sh
idobin /usr/sbin/netboot_postinst.sh
idobin /usr/sbin/chromeos-install
cp "${ROOT}"/usr/share/misc/shflags "${INITRAMFS_TMP_S}"/usr/share/misc
# Binaries used by factory installer
idobin /bin/bash
idobin /bin/dd
idobin /bin/sh
idobin /bin/xxd
idobin /sbin/blockdev
idobin /sbin/fsck.vfat
idobin /sbin/sfdisk
idofutility /usr/bin/old_bins/cgpt
idofutility /usr/bin/old_bins/crossystem
idobin /usr/bin/futility
idobin /usr/bin/getopt
idobin /usr/bin/openssl
idobin /usr/bin/uudecode
idobin /usr/bin/wget
idobin /usr/sbin/flashrom
idobin /usr/sbin/htpdate
idobin /usr/sbin/lightup_screen
idobin /usr/sbin/partprobe
ln -s "/bin/cgpt" "${INITRAMFS_TMP_S}/usr/bin/cgpt" || die
# For message screen display
idobin /usr/bin/ply-image
idobin /usr/sbin/vpd
# Network support
cp "${FILESDIR}"/udhcpc.script "${INITRAMFS_TMP_S}/etc" || die
chmod +x "${INITRAMFS_TMP_S}/etc/udhcpc.script"
# USB Ethernet kernel module
USBNET_MOD_PATH=$(find "${ROOT}"/lib/modules/ -name usbnet.ko)
[ -n "$USBNET_MOD_PATH" ] || die
USBNET_DIR_PATH=$(dirname "${USBNET_MOD_PATH}")
USBNET_INSTALL_PATH="${USBNET_DIR_PATH#${ROOT}}"
mkdir -p "${INITRAMFS_TMP_S}/${USBNET_INSTALL_PATH}"
for module in $(find "${USBNET_DIR_PATH}" -name "*.ko"); do
cp -p "${module}" "${INITRAMFS_TMP_S}/${USBNET_INSTALL_PATH}/"
elog "Copied: ${module#${ROOT}}"
done
# Generates lsb-factory
LSBDIR="mnt/stateful_partition/dev_image/etc"
GENERATED_LSB_FACTORY="${INITRAMFS_TMP_S}/${LSBDIR}/lsb-factory"
SERVER_ADDR="${SERVER_ADDR-10.0.0.1}"
BOARD="$(get_current_board_with_variant)"
mkdir -p "${INITRAMFS_TMP_S}/${LSBDIR}"
cat "${FILESDIR}"/lsb-factory.template | \
sed "s/%BOARD%/${BOARD}/g" |
sed "s/%SERVER_ADDR%/${SERVER_ADDR}/g" \
>"${GENERATED_LSB_FACTORY}"
ln -s "/$LSBDIR/lsb-factory" "${INITRAMFS_TMP_S}/etc/lsb-release"
# Partition table
cp "${ROOT}"/root/.gpt_layout "${INITRAMFS_TMP_S}"/root/
cp "${ROOT}"/root/.pmbr_code "${INITRAMFS_TMP_S}"/root/
# Generates write_gpt.sh
INSTALLED_SCRIPT="${INITRAMFS_TMP_S}"/usr/sbin/write_gpt.sh
BUILD_LIBRARY_DIR="${PORTDIR}"/../../scripts/build_library
BINPATH="${PORTDIR}"/../../../chromite/bin:"${PATH}"
BOARD=$(get_current_board_with_variant)
. "${BUILD_LIBRARY_DIR}"/disk_layout_util.sh || die
PATH="${BINPATH}" write_partition_script usb "${INSTALLED_SCRIPT}" || die
# Install Memento updater
MEMENTO_PATH="opt/google/memento_updater"
mkdir -p "${INITRAMFS_TMP_S}/${MEMENTO_PATH}"
cp "${ROOT}/${MEMENTO_PATH}"/* "${INITRAMFS_TMP_S}/${MEMENTO_PATH}" || \
die "Failed copying memento_updater"
idodep $(cd "${ROOT}"; find "${MEMENTO_PATH}" -type f)
}
build_initramfs_file() {
local dir
local subdirs=(
bin
bin/old_bins
dev
etc
etc/screens
lib
log
newroot
proc
root
stateful
sys
tmp
usb
usr/bin
usr/sbin
usr/share/misc
)
for dir in ${subdirs[@]}; do
mkdir -p "${INITRAMFS_TMP_S}/$dir" || die
done
# On amd64, shared libraries must live in /lib64. More generally,
# $(get_libdir) tells us the directory name we need for the target
# platform's libraries. The 'copy_elf' script installs in /lib; to
# keep that script simple we just create a symlink to /lib, if
# necessary.
local libdir=$(get_libdir)
if [ "${libdir}" != "lib" ]; then
ln -s lib "${INITRAMFS_TMP_S}/${libdir}"
fi
# Copy source files not merged from our dependencies.
cp "${S}"/init "${INITRAMFS_TMP_S}/init" || die
chmod +x "${INITRAMFS_TMP_S}/init"
cp "${S}"/*.sh "${INITRAMFS_TMP_S}/lib" || die
# PNG image assets
local shared_assets="${ROOT}"/usr/share/chromeos-assets
insimage "${shared_assets}"/images/boot_message.png
insimage "${S}"/assets/spinner_*.png
insimage "${S}"/assets/icon_check.png
insimage "${S}"/assets/icon_warning.png
${S}/make_images "${S}/localized_text" \
"${INITRAMFS_TMP_S}/etc/screens" || die
if use netboot_ramfs; then
pull_netboot_ramfs_binary
else
pull_initramfs_binary
fi
# The kernel emake expects the file in cpio format.
( cd "${INITRAMFS_TMP_S}"
find . | cpio -o -H newc |
xz -9 --check=crc32 --lzma2=dict=512KiB > \
"${WORKDIR}/${INITRAMFS_FILE}" ) ||
die "cannot package initramfs"
}
src_compile() {
INITRAMFS_TMP_S=${WORKDIR}/initramfs_tmp
if use netboot_ramfs; then
INITRAMFS_FILE="netboot_ramfs.cpio.xz"
else
INITRAMFS_FILE="initramfs.cpio.xz"
fi
einfo "Creating ${INITRAMFS_FILE}"
build_initramfs_file
INITRAMFS_FILE_SIZE=$(stat --printf="%s" "${WORKDIR}/${INITRAMFS_FILE}")
einfo "${INITRAMFS_FILE}: ${INITRAMFS_FILE_SIZE} bytes"
}
src_install() {
insinto /var/lib/misc
doins "${WORKDIR}/${INITRAMFS_FILE}"
}