blob: bc44a073d404c712901b4f4f7cbae259df775323 [file] [log] [blame]
Hung-Te Lin5febb1e2013-03-12 17:56:35 +08001# Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
Dave Parker515cdcd2011-03-08 17:58:43 -08002# Distributed under the terms of the GNU General Public License v2
Dave Parker515cdcd2011-03-08 17:58:43 -08003#
4# Original Author: The Chromium OS Authors <chromium-os-dev@chromium.org>
5# Purpose: Generate shell script containing firmware update bundle.
6#
7
Hung-Te Lin2ef30542013-06-04 14:12:59 -07008inherit cros-workon
Dave Parkerd7d4c402011-04-15 08:01:34 -07009
Hung-Te Lin5febb1e2013-03-12 17:56:35 +080010# @ECLASS-VARIABLE: CROS_FIRMWARE_BCS_OVERLAY
11# @DESCRIPTION: (Optional) Name of board overlay on Binary Component Server
12: ${CROS_FIRMWARE_BCS_OVERLAY:=${BOARD_OVERLAY##*/}}
13
Dave Parker914ef512011-05-10 09:55:05 -070014# @ECLASS-VARIABLE: CROS_FIRMWARE_MAIN_IMAGE
Hung-Te Linc8c15d92013-01-10 16:19:40 +080015# @DESCRIPTION: (Optional) Location of system firmware (BIOS) image
Dave Parker914ef512011-05-10 09:55:05 -070016: ${CROS_FIRMWARE_MAIN_IMAGE:=}
Dave Parker515cdcd2011-03-08 17:58:43 -080017
Hung-Te Linc8c15d92013-01-10 16:19:40 +080018# @ECLASS-VARIABLE: CROS_FIRMWARE_MAIN_RW_IMAGE
19# @DESCRIPTION: (Optional) Location of RW system firmware image
20: ${CROS_FIRMWARE_MAIN_RW_IMAGE:=}
21
Hung-Te Lin20c51232013-05-02 12:44:11 +080022# @ECLASS-VARIABLE: CROS_FIRMWARE_BUILD_MAIN_RW_IMAGE
23# @DESCRIPTION: (Optional) Re-sign and generate a RW system firmware image.
24: ${CROS_FIRMWARE_BUILD_MAIN_RW_IMAGE:=}
25
Dave Parker914ef512011-05-10 09:55:05 -070026# @ECLASS-VARIABLE: CROS_FIRMWARE_EC_IMAGE
Dave Parker515cdcd2011-03-08 17:58:43 -080027# @DESCRIPTION: (Optional) Location of EC firmware image
Dave Parker914ef512011-05-10 09:55:05 -070028: ${CROS_FIRMWARE_EC_IMAGE:=}
Dave Parker515cdcd2011-03-08 17:58:43 -080029
Dave Parkerd7d4c402011-04-15 08:01:34 -070030# @ECLASS-VARIABLE: CROS_FIRMWARE_EC_VERSION
Dave Parker914ef512011-05-10 09:55:05 -070031# @DESCRIPTION: (Optional) Version name of EC firmware
Hung-Te Lin0cde8bf2012-08-07 18:22:26 +080032: ${CROS_FIRMWARE_EC_VERSION:=}
Dave Parker515cdcd2011-03-08 17:58:43 -080033
Hung-Te Lin890a2262011-05-19 20:22:41 +080034# @ECLASS-VARIABLE: CROS_FIRMWARE_PLATFORM
35# @DESCRIPTION: (Optional) Platform name of firmware
36: ${CROS_FIRMWARE_PLATFORM:=}
37
Hung-Te Lin35cf1a12011-07-21 23:16:35 +080038# @ECLASS-VARIABLE: CROS_FIRMWARE_SCRIPT
39# @DESCRIPTION: (Optional) Entry script file name of updater
40: ${CROS_FIRMWARE_SCRIPT:=}
41
42# @ECLASS-VARIABLE: CROS_FIRMWARE_UNSTABLE
Hung-Te Lin5febb1e2013-03-12 17:56:35 +080043# @DESCRIPTION: (Optional) Mark firmware as unstable (always RO+RW update)
Hung-Te Lin35cf1a12011-07-21 23:16:35 +080044: ${CROS_FIRMWARE_UNSTABLE:=}
45
Dave Parker515cdcd2011-03-08 17:58:43 -080046# @ECLASS-VARIABLE: CROS_FIRMWARE_BINARY
47# @DESCRIPTION: (Optional) location of custom flashrom tool
48: ${CROS_FIRMWARE_FLASHROM_BINARY:=}
49
50# @ECLASS-VARIABLE: CROS_FIRMWARE_EXTRA_LIST
Hung-Te Line2e4a6b2011-08-31 18:57:26 +080051# @DESCRIPTION: (Optional) Semi-colon separated list of additional resources
Dave Parker515cdcd2011-03-08 17:58:43 -080052: ${CROS_FIRMWARE_EXTRA_LIST:=}
53
Hung-Te Lin0c59d0a2012-08-16 13:18:09 +080054# @ECLASS-VARIABLE: CROS_FIRMWARE_FORCE_UPDATE
55# @DESCRIPTION: (Optional) Always add "force update firmware" tag.
56: ${CROS_FIRMWARE_FORCE_UPDATE:=}
57
Hung-Te Lin5febb1e2013-03-12 17:56:35 +080058# Check for EAPI 2+
59case "${EAPI:-0}" in
60 4|3|2) ;;
61 *) die "unsupported EAPI" ;;
62esac
63
Hung-Te Lin0cde8bf2012-08-07 18:22:26 +080064# $board-overlay/make.conf may contain these flags to always create "firmware
65# from source".
Gabe Black15156612013-03-16 02:47:57 -070066IUSE="bootimage cros_ec depthcharge"
Hung-Te Lin0cde8bf2012-08-07 18:22:26 +080067
Dave Parker515cdcd2011-03-08 17:58:43 -080068# Some tools (flashrom, iotools, mosys, ...) were bundled in the updater so we
69# don't write RDEPEND=$DEPEND. RDEPEND should have an explicit list of what it
70# needs to extract and execute the updater.
Dave Parkerd7d4c402011-04-15 08:01:34 -070071DEPEND="
Dave Parkerd7d4c402011-04-15 08:01:34 -070072 >=chromeos-base/vboot_reference-1.0-r230
Mike Frysinger2d94c622012-09-13 23:59:17 -040073 chromeos-base/vpd
Mike Frysinger877662c2011-10-19 10:45:46 -040074 dev-util/shflags
J. Richard Barnette7a4385c2011-05-03 16:54:57 -070075 >=sys-apps/flashrom-0.9.3-r36
Dave Parker914ef512011-05-10 09:55:05 -070076 sys-apps/mosys
Dave Parkerd7d4c402011-04-15 08:01:34 -070077 "
Dave Parker515cdcd2011-03-08 17:58:43 -080078
Hung-Te Lin0cde8bf2012-08-07 18:22:26 +080079# Build firmware from source.
80DEPEND="$DEPEND
81 bootimage? ( sys-boot/chromeos-bootimage )
82 cros_ec? ( chromeos-base/chromeos-ec )
83 "
84
J. Richard Barnette7a4385c2011-05-03 16:54:57 -070085# Maintenance note: The factory install shim downloads and executes
86# the firmware updater. Consequently, runtime dependencies for the
87# updater are also runtime dependencies for the install shim.
88#
89# The contents of RDEPEND below must also be present in the
90# chromeos-base/chromeos-factoryinstall ebuild in PROVIDED_DEPEND.
91# If you make any change to the list below, you may need to make a
92# matching change in the factory install ebuild.
93#
Dave Parker515cdcd2011-03-08 17:58:43 -080094# TODO(hungte) remove gzip/tar if we have busybox
95RDEPEND="
96 app-arch/gzip
97 app-arch/sharutils
J. Richard Barnette7a4385c2011-05-03 16:54:57 -070098 app-arch/tar
99 chromeos-base/vboot_reference
J. Richard Barnette7a4385c2011-05-03 16:54:57 -0700100 sys-apps/util-linux"
Dave Parker515cdcd2011-03-08 17:58:43 -0800101
Hung-Te Lin5febb1e2013-03-12 17:56:35 +0800102RESTRICT="mirror"
103
104# Local variables.
Dave Parker515cdcd2011-03-08 17:58:43 -0800105
106UPDATE_SCRIPT="chromeos-firmwareupdate"
Dave Parker914ef512011-05-10 09:55:05 -0700107FW_IMAGE_LOCATION=""
Hung-Te Linc8c15d92013-01-10 16:19:40 +0800108FW_RW_IMAGE_LOCATION=""
Dave Parker914ef512011-05-10 09:55:05 -0700109EC_IMAGE_LOCATION=""
Hung-Te Lin5febb1e2013-03-12 17:56:35 +0800110EXTRA_LOCATIONS=()
Hung-Te Linbcecb3e2013-03-13 13:42:56 +0800111
Hung-Te Lin5febb1e2013-03-12 17:56:35 +0800112# New SRC_URI based approach.
Dave Parkerd7d4c402011-04-15 08:01:34 -0700113
Hung-Te Lin5febb1e2013-03-12 17:56:35 +0800114_add_source() {
Hung-Te Linbcecb3e2013-03-13 13:42:56 +0800115 local var="$1"
116 local input="${!var}"
117 local protocol="${input%%://*}"
118 local uri="${input#*://}"
Hung-Te Lin5febb1e2013-03-12 17:56:35 +0800119 local overlay="${CROS_FIRMWARE_BCS_OVERLAY#overlay-}"
120 local user="bcs-${overlay#variant-*-}"
121 local bcs_url="gs://chromeos-binaries/HOME/${user}/overlay-${overlay}"
Dave Parkerd7d4c402011-04-15 08:01:34 -0700122
Hung-Te Linbcecb3e2013-03-13 13:42:56 +0800123 # Input without ${protocol} are local files (ex, ${FILESDIR}/file).
Hung-Te Lin5febb1e2013-03-12 17:56:35 +0800124 case "${protocol}" in
125 bcs)
126 SRC_URI+=" ${bcs_url}/${CATEGORY}/${PN}/${uri}"
Hung-Te Lin5febb1e2013-03-12 17:56:35 +0800127 ;;
128 http|https)
Hung-Te Linbcecb3e2013-03-13 13:42:56 +0800129 SRC_URI+=" ${input}"
Hung-Te Lin5febb1e2013-03-12 17:56:35 +0800130 ;;
131 esac
132}
133
Hung-Te Lin5febb1e2013-03-12 17:56:35 +0800134_unpack_archive() {
Hung-Te Linbcecb3e2013-03-13 13:42:56 +0800135 local var="$1"
136 local input="${!var}"
Hung-Te Lin5febb1e2013-03-12 17:56:35 +0800137 local archive="${input##*/}"
138 local folder="${S}/.dist/${archive}"
Hung-Te Linbcecb3e2013-03-13 13:42:56 +0800139
140 # Remote source files (bcs://, http://, ...) are downloaded into
141 # ${DISTDIR}, which is the default location for command 'unpack'.
142 # For any other files (ex, ${FILESDIR}/file), use complete file path.
143 local unpack_name="${input}"
144 if [[ "${unpack_name}" =~ "://" ]]; then
145 input="${DISTDIR}/${archive}"
146 unpack_name="${archive}"
147 fi
Hung-Te Lin5febb1e2013-03-12 17:56:35 +0800148
149 case "${input##*.}" in
150 tar|tbz2|tbz|bz|gz|tgz|zip|xz) ;;
151 *)
Hung-Te Linbcecb3e2013-03-13 13:42:56 +0800152 eval ${var}="'${input}'"
Hung-Te Lin5febb1e2013-03-12 17:56:35 +0800153 return
154 ;;
155 esac
156
157 mkdir -p "${folder}" || die "Not able to create ${folder}"
158 (cd "${folder}" && unpack "${unpack_name}") ||
159 die "Failed to unpack ${unpack_name}."
160 local contents=($(ls "${folder}"))
161 if [[ ${#contents[@]} -gt 1 ]]; then
162 # Currently we can only serve one file (or directory).
163 ewarn "WARNING: package ${input} contains multiple files."
164 fi
Hung-Te Linbcecb3e2013-03-13 13:42:56 +0800165 eval ${var}="'${folder}/${contents}'"
Hung-Te Lin5febb1e2013-03-12 17:56:35 +0800166}
167
Hung-Te Lin5febb1e2013-03-12 17:56:35 +0800168cros-firmware_src_unpack() {
169 cros-workon_src_unpack
Hung-Te Linbcecb3e2013-03-13 13:42:56 +0800170 local i
Hung-Te Lin5febb1e2013-03-12 17:56:35 +0800171
Hung-Te Linbcecb3e2013-03-13 13:42:56 +0800172 for i in {FW,FW_RW,EC}_IMAGE_LOCATION; do
173 _unpack_archive ${i}
Hung-Te Lin5febb1e2013-03-12 17:56:35 +0800174 done
Hung-Te Linbcecb3e2013-03-13 13:42:56 +0800175
176 for ((i = 0; i < ${#EXTRA_LOCATIONS[@]}; i++)); do
177 _unpack_archive "EXTRA_LOCATIONS[$i]"
178 done
Dave Parkerd7d4c402011-04-15 08:01:34 -0700179}
180
Hung-Te Lin0cde8bf2012-08-07 18:22:26 +0800181_add_param() {
182 local prefix="$1"
183 local value="$2"
184
185 if [[ -n "$value" ]]; then
186 echo "$prefix '$value' "
187 fi
188}
189
190_add_bool_param() {
191 local prefix="$1"
192 local value="$2"
193
194 if [[ -n "$value" ]]; then
195 echo "$prefix "
196 fi
197}
198
Dave Parker515cdcd2011-03-08 17:58:43 -0800199cros-firmware_src_compile() {
Hung-Te Lin0cde8bf2012-08-07 18:22:26 +0800200 local image_cmd="" ext_cmd="" local_image_cmd=""
201 local root="${ROOT%/}"
Dave Parkerd7d4c402011-04-15 08:01:34 -0700202
Dave Parker914ef512011-05-10 09:55:05 -0700203 # Prepare images
Hung-Te Lin0cde8bf2012-08-07 18:22:26 +0800204 image_cmd+="$(_add_param -b "${FW_IMAGE_LOCATION}")"
205 image_cmd+="$(_add_param -e "${EC_IMAGE_LOCATION}")"
Hung-Te Linc8c15d92013-01-10 16:19:40 +0800206 image_cmd+="$(_add_param -w "${FW_RW_IMAGE_LOCATION}")"
Hung-Te Lin0cde8bf2012-08-07 18:22:26 +0800207 image_cmd+="$(_add_param --ec_version "${CROS_FIRMWARE_EC_VERSION}")"
Hung-Te Lin20c51232013-05-02 12:44:11 +0800208 image_cmd+="$(_add_bool_param --create_bios_rw_image \
209 "${CROS_FIRMWARE_BUILD_MAIN_RW_IMAGE}")"
Dave Parker515cdcd2011-03-08 17:58:43 -0800210
Dave Parker914ef512011-05-10 09:55:05 -0700211 # Prepare extra commands
Hung-Te Lin0cde8bf2012-08-07 18:22:26 +0800212 ext_cmd+="$(_add_bool_param --unstable "${CROS_FIRMWARE_UNSTABLE}")"
Hung-Te Lin5febb1e2013-03-12 17:56:35 +0800213 ext_cmd+="$(_add_param --extra "$(IFS=:; echo "${EXTRA_LOCATIONS[*]}")")"
Hung-Te Lin0cde8bf2012-08-07 18:22:26 +0800214 ext_cmd+="$(_add_param --script "${CROS_FIRMWARE_SCRIPT}")"
215 ext_cmd+="$(_add_param --platform "${CROS_FIRMWARE_PLATFORM}")"
216 ext_cmd+="$(_add_param --flashrom "${CROS_FIRMWARE_FLASHROM_BINARY}")"
217 ext_cmd+="$(_add_param --tool_base \
218 "$root/firmware/utils:$root/usr/sbin:$root/usr/bin")"
Dave Parker515cdcd2011-03-08 17:58:43 -0800219
Dave Parker914ef512011-05-10 09:55:05 -0700220 # Pack firmware update script!
Dave Parker515cdcd2011-03-08 17:58:43 -0800221 if [ -z "$image_cmd" ]; then
Dave Parker914ef512011-05-10 09:55:05 -0700222 # Create an empty update script for the generic case
Dave Parker515cdcd2011-03-08 17:58:43 -0800223 # (no need to update)
224 einfo "Building empty firmware update script"
225 echo -n > ${UPDATE_SCRIPT}
226 else
227 # create a new script
Hung-Te Lin5febb1e2013-03-12 17:56:35 +0800228 einfo "Build ${BOARD_USE} firmware updater: $image_cmd $ext_cmd"
Hung-Te Lin0cde8bf2012-08-07 18:22:26 +0800229 ./pack_firmware.sh $image_cmd $ext_cmd -o $UPDATE_SCRIPT ||
Dave Parker914ef512011-05-10 09:55:05 -0700230 die "Cannot pack firmware."
Dave Parker515cdcd2011-03-08 17:58:43 -0800231 fi
Hung-Te Lin0cde8bf2012-08-07 18:22:26 +0800232
233 # Create local updaters
234 local local_image_cmd="" output_bom output_file
235 if use cros_ec; then
236 local_image_cmd+="-e $root/firmware/ec.bin "
237 fi
238 if use bootimage; then
Gabe Black15156612013-03-16 02:47:57 -0700239 if use depthcharge; then
240 einfo "Updater for local fw"
241 ./pack_firmware.sh -b $root/firmware/image.bin \
242 -o updater.sh $local_image_cmd $ext_cmd ||
Hung-Te Lin0cde8bf2012-08-07 18:22:26 +0800243 die "Cannot pack local firmware."
Gabe Black15156612013-03-16 02:47:57 -0700244 else
245 for fw_file in $root/firmware/image-*.bin; do
246 einfo "Updater for local fw - $fw_file"
247 output_bom=${fw_file##*/image-}
248 output_bom=${output_bom%%.bin}
249 output_file=updater-$output_bom.sh
250 ./pack_firmware.sh -b $fw_file -o $output_file \
251 $local_image_cmd $ext_cmd ||
252 die "Cannot pack local firmware."
253 done
254 fi
Hung-Te Lin0cde8bf2012-08-07 18:22:26 +0800255 elif use cros_ec; then
256 # TODO(hungte) Deal with a platform that has only EC and no
257 # BIOS, which is usually incorrect configuration.
258 die "Sorry, platform without local BIOS EC is not supported."
259 fi
Dave Parker515cdcd2011-03-08 17:58:43 -0800260}
261
262cros-firmware_src_install() {
263 # install the main updater program
Dave Parker914ef512011-05-10 09:55:05 -0700264 dosbin $UPDATE_SCRIPT || die "Failed to install update script."
Dave Parker515cdcd2011-03-08 17:58:43 -0800265
Dave Parkerd7d4c402011-04-15 08:01:34 -0700266 # install factory wipe script
267 dosbin firmware-factory-wipe
Hung-Te Lin0cde8bf2012-08-07 18:22:26 +0800268
269 # install updaters for firmware-from-source archive.
270 if use bootimage; then
271 exeinto /firmware
Gabe Black15156612013-03-16 02:47:57 -0700272 doexe updater*.sh
Hung-Te Lin0cde8bf2012-08-07 18:22:26 +0800273 fi
Hung-Te Lin0c59d0a2012-08-16 13:18:09 +0800274
275 # The "force_update_firmware" tag file is used by chromeos-installer.
276 if [ -n "$CROS_FIRMWARE_FORCE_UPDATE" ]; then
277 insinto /root
278 touch .force_update_firmware
279 doins .force_update_firmware
280 fi
Dave Parker515cdcd2011-03-08 17:58:43 -0800281}
282
Hung-Te Linbcecb3e2013-03-13 13:42:56 +0800283# @FUNCTION: _expand_list
284# @USAGE <var> <ifs> <string>
285# @DESCRIPTION:
286# Internal function to expand a string (separated by ifs) into bash array.
287_expand_list() {
288 local var="$1" ifs="$2"
289 IFS="${ifs}" read -r -a ${var} <<<"${*:3}"
290}
Hung-Te Lin5febb1e2013-03-12 17:56:35 +0800291
Hung-Te Linbcecb3e2013-03-13 13:42:56 +0800292# @FUNCTION: cros-firmware_setup_source
293# @DESCRIPTION:
294# Configures all firmware binary source files to SRC_URI, and updates local
295# destination mapping (*_LOCATION). Must be invoked after CROS_FIRMWARE_*_IMAGE
296# are set.
297cros-firmware_setup_source() {
298 local i
299
300 FW_IMAGE_LOCATION="${CROS_FIRMWARE_MAIN_IMAGE}"
301 FW_RW_IMAGE_LOCATION="${CROS_FIRMWARE_MAIN_RW_IMAGE}"
302 EC_IMAGE_LOCATION="${CROS_FIRMWARE_EC_IMAGE}"
303 _expand_list EXTRA_LOCATIONS ";" "${CROS_FIRMWARE_EXTRA_LIST}"
304
305 for i in {FW,FW_RW,EC}_IMAGE_LOCATION; do
306 _add_source ${i}
307 done
308
309 for ((i = 0; i < ${#EXTRA_LOCATIONS[@]}; i++)); do
310 _add_source "EXTRA_LOCATIONS[$i]"
Hung-Te Lin5febb1e2013-03-12 17:56:35 +0800311 done
312}
313
314# If "inherit cros-firmware" appears at end of ebuild file, build source URI
315# automatically. Otherwise, you have to put an explicit call to
316# "cros-firmware_setup_source" at end of ebuild file.
317[[ -n "${CROS_FIRMWARE_MAIN_IMAGE}" ]] && cros-firmware_setup_source
318
Dave Parkerd7d4c402011-04-15 08:01:34 -0700319EXPORT_FUNCTIONS src_unpack src_compile src_install