We had been putting the NVMEM flash where the boot rom would
expect to find RO_B, preventing us from ever being able to update
the bootloader.
With this CL, we're rearranging the flash to support both RO_A
and RO_B. The current flash layout now looks like this:
0x40000 RO_A
0x44000 RW_A
0x7c000 TOP_A
0x80000 RO_B
0x84000 RW_B
0xbc000 NVMEM
0xbffff <end of flash>
BUG=chrome-os-partner:44803
BRANCH=none
TEST=make buildall, also manual tests on Cr50 boards
First, check that our current process still works:
make BOARD=cr50 CR50_RO_KEY=cr50_rom0-dev-blsign.pem.pub
spiflash -i -v build/cr50/ec.hex
Yep, it does, but that only produces RO_A, not RO_B.
To test the dual RO behavior, I used prebuilt RO_A and RO_B blobs
for the bootloaders, signed using Marius' new scheme.
Build the unsigned image, then sign it using Vadim's scripts:
make BOARD=cr50 -j30
~/bin/bs hex
We'll garble various bits of the full image to invalidate each of
the four RO/RW/A/B parts.
Find lines common to both ROs and common to both RWs:
sort B1*.hex | uniq -c | grep ' 2 ' | \
awk '{print $2}' | sort > tmp.ro2
sort build/cr50/RW/ec.RW*.signed.hex | uniq -c | grep ' 2 ' | \
awk '{print $2}' | sort > tmp.rw2
ro=$(diff tmp.ro2 tmp.rw2 | grep '<' | head -1 | awk '{print $2}')
rw=$(diff tmp.ro2 tmp.rw2 | grep '>' | head -1 | awk '{print $2}')
Double-check to be sure we don't have any false matches:
grep -l $ro build/cr50/RW/ec.RW*.signed.hex B1_*.hex
grep -l $rw build/cr50/RW/ec.RW*.signed.hex B1_*.hex
The pre-signed RO_A image is older than RO_B, but both have the
same epoch/major/minor, which is all that the bootrom checks for.
It doesn't look at the timestamp.
The RW_A is older than RW_B because of the sequential signing
process. The RO bootloaders will check their timestamp, so RW_B
should be preferred.
RO_A RO_B RW_A RW_B
good good good good
cat build/cr50/RW/ec.RW*.signed.hex B1_*.hex > foo.hex
spiflash -v -i foo.hex
jump @00040400
jump @00084000
=> boots RO_A -> RW_B
RO_A RO_B RW_A RW_B
good good good bad
cat build/cr50/RW/ec.RW*.signed.hex B1_*.hex > foo.hex
ln=$(grep -n $rw foo.hex | awk -F: 'NR==2 {print $1}')
sed -i "${ln}d" foo.hex
spiflash -v -i foo.hex
jump @00040400
jump @00044000
=> boots RO_A -> RW_A
RO_A RO_B RW_A RW_B
bad good good good
cat build/cr50/RW/ec.RW*.signed.hex B1_*.hex > foo.hex
ln=$(grep -n $ro foo.hex | awk -F: 'NR==1 {print $1}')
sed -i "${ln}d" foo.hex
spiflash -v -i foo.hex
jump @00080400
jump @00084000
=> boots RO_B -> RW_B
RO_A RO_B RW_A RW_B
bad good good bad
cat build/cr50/RW/ec.RW*.signed.hex B1_*.hex > foo.hex
ln=$(grep -n $ro foo.hex | awk -F: 'NR==1 {print $1}')
sed -i "${ln}d" foo.hex
ln=$(grep -n $rw foo.hex | awk -F: 'NR==2 {print $1}')
sed -i "${ln}d" foo.hex
spiflash -v -i foo.hex
jump @00080400
jump @00044000
=> boots RO_B -> RW_A
Yay.
Now make sure RW_A and RW_B can be updated using usb_updater.
\rm -rf build
make BOARD=cr50 -j30
~/bin/bs
./extra/usb_updater/usb_updater build/cr50/ec.bin
I'm running RW_A, it updates and reboots into RW_B. Good.
reboot 5 times, and it reverts to RW_A.
Power cycle and it goes to RW_B again.
Update to RW_A.
\rm -rf build
make BOARD=cr50 -j30
~/bin/bs
./extra/usb_updater/usb_updater build/cr50/ec.bin
I'm running RW_B, it updates and reboots into RW_A. Good.
reboot 5 times, and it reverts to RW_B.
Power cycle and it goes to RW_A again.
Cool.
Change-Id: I6c1689920de06c72c69f58ad2ef1059d9ee0d75f
Signed-off-by: Bill Richardson <wfrichar@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/362521
Reviewed-by: Vadim Bendebury <vbendeb@chromium.org>
loader/key_ladder.c depends on debug_printf(). Refactor
the printf function so that key_ladder.c need not depend
on main.c.
This change being made in preparation for a future
change which introduces a dependency between RW and
key_ladder.o
BRANCH=none
BUG=chrome-os-partner:43025,chrome-os-partner:47524
TEST=build succeeds
Change-Id: I5c9bf7bd6dd9f76ab6410e6e797973bdb072ec16
Signed-off-by: nagendra modadugu <ngm@google.com>
Reviewed-on: https://chromium-review.googlesource.com/351760
Commit-Ready: Nagendra Modadugu <ngm@google.com>
Tested-by: Nagendra Modadugu <ngm@google.com>
Reviewed-by: Bill Richardson <wfrichar@chromium.org>
When deciding which of the two images to start, A or B - consider the
image timestamp if everything else is equal. The later image should
take precedence.
Also, simplify the existing logic, and consider image A to be 'newer'
if both copies are the same otherwise.
BRANCH=none
BUG=chrome-os-partner:37754
TEST=with the rest of the patches applied, verified that the newer
image of the two gets started
Change-Id: I2c7a50ecfc8d254498c8e96f8651b8d53005897c
Signed-off-by: Vadim Bendebury <vbendeb@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/327414
Reviewed-by: Marius Schilder <mschilder@chromium.org>
The launcher should explicitly disable writes to the code space where
the loaded code is going to be running from.
BRANCH=None
BUG=chrome-os-partner:37554
TEST=with the rest of the patches applied firmware updates work as
expected.
Change-Id: I744f7016e4427188f53e8fa3302e8c06cf836e2e
Signed-off-by: Vadim Bendebury <vbendeb@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/327413
Reviewed-by: Marius Schilder <mschilder@chromium.org>
This patch introduces HOST_CPPFLAGS to be used for all
objects being compiled with HOSTCC rather then the target
compiler.
Since glibc is not linked into the EC, no glibc include files
should be included in the EC code base. Hence, create local
definitions for clock_t and wchar_t that match what the glibc
include would have done, and remove some unneeded includes.
Due to very eager optimization, we have to give gcc a little
notch to not kick out memset.
Signed-off-by: Stefan Reinauer <reinauer@chromium.org>
BUG=chrome-os-partner:43025
BUG=chrome-os-partner:49517
BRANCH=none
TEST=compile tested
Change-Id: Idf3a2881fa8352756b0927b09c6a97473358f239
Reviewed-on: https://chromium-review.googlesource.com/322435
Commit-Ready: Patrick Georgi <pgeorgi@chromium.org>
Tested-by: Patrick Georgi <pgeorgi@chromium.org>
Reviewed-by: Patrick Georgi <pgeorgi@chromium.org>
of the two RW images if set.
Imported the Haven "signed_header.h" file into chip/g and fixed prior
references to the util/ copy.
BUG=none
BRANCH=none
TEST=Went through a full update. Simulated a botched update.
Change-Id: I1e4c006ef391270a7e350fea6f43cc1a1b057d0e
Signed-off-by: Nadim Taha <ntaha@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/324109
Reviewed-by: Bill Richardson <wfrichar@chromium.org>
We support two FPGA images with the same firmware. To meet
timing, one image has support for USB but at the cost of reducing
the crypto multiplier to 8x8. The other image has full crypto but
no USB support.
This change displays the FPGA configuration at boot, in addition
to the FPGA image version.
BUG=b:25350751
BRANCH=none
TEST=make buildall, manual
Boot it and watch the console. You should see something like
this:
cr50 bootloader, 20151118_73026@80895, +USB, 8x8 crypto
Valid image found at 0x00044000, jumping
Change-Id: I0e5de453fcd1714fcbb170bf4364747b1e7ba894
Signed-off-by: Bill Richardson <wfrichar@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/314824
Reviewed-by: Vadim Bendebury <vbendeb@chromium.org>
This change includes hardware and software support for SHA1/256 on
CR50. When running in the RO image, only hardware sha256 support is
included. When running in the RW image, the code auto-selects between
the software and hardware implementation. Software implementation path
is taken if the hardware is currently in use by some other context.
Refactor the CR50 loader to use this abstraction.
The existing software implementation for SHA1 and SHA256 is used for
the software path.
CQ-DEPEND=CL:*239385
BRANCH=none
TEST=EC shell boots fine (implies that SHA256 works)
BUG=chrome-os-partner:43025
Change-Id: I7bcefc12fcef869dac2e48793bd0cb5ce8e80d5b
Signed-off-by: nagendra modadugu <ngm@google.com>
Signed-off-by: Vadim Bendebury <vbendeb@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/313011
This is required to be able to consolidate hardware and software hash
implementations.
BRANCH=none
BUG=chrome-os-partner:43025
TEST=the device still boots up.
Change-Id: If420541427bb316b97bc20a21fd3fd8a57708244
Signed-off-by: Vadim Bendebury <vbendeb@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/313654
Reviewed-by: Nagendra Modadugu <ngm@google.com>
Until we update the naming for our various images in the
Makefiles, let's change the bootloader message slighty, so that
instead of seeing two "RO" images:
CR50 RO, 20151104_41733@78962
Valid image found at 0x00044000, jumping
--- UART initialized after reboot ---
[Reset cause: power-on]
[Image: RO, cr50_v1.1.4008-957a842 2015-11-07 00:28:37 wfrichar@wintermute4.mtv.
corp.google.com]
[0.000897 Verifying RW image...]
we see the bootloader, and then what we've been calling the RO
image, and then the RW image:
cr50 bootloader, 20151104_41733@78962
Valid image found at 0x00044000, jumping
--- UART initialized after reboot ---
[Reset cause: power-on]
[Image: RO, cr50_v1.1.4008-957a842 2015-11-07 00:28:37 wfrichar@wintermute4.mtv.
corp.google.com]
[0.000897 Verifying RW image...]
BUG=none
BRANCH=none
TEST=make buildall, try it
No new functionality, just a different message on the console.
Change-Id: Ia8dce600c7d159416dc6dabbbf0c0cc4129a988d
Signed-off-by: Bill Richardson <wfrichar@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/311831
Reviewed-by: Vadim Bendebury <vbendeb@chromium.org>
This code is a port of the sample loader application included in the
FPGA update. Only the pieces relevant to straight verification and
boot were ported.
The loader generates a hash, inputs to which are the image body, state
of fuses and state of flash INFO region, and the output is the value,
which will unlock the region for execution, if it is correct.
Only one image load is attempted, the image is supposed to be located
in the flash at the offset of CONFIG_RW_MEM_OFF.
BRANCH=none
BUG=chrome-os-partner:43025
TEST=with the rest of the patches applied the RO image successfully
verifies and starts up the RW image.
Change-Id: I26e1fbdaeb8b23d519c1a328526a3422231bb322
Signed-off-by: Vadim Bendebury <vbendeb@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/311316
Reviewed-by: Bill Richardson <wfrichar@chromium.org>
The CR50 board will have to have a very different RO image, let's make
it possible to override the default list of objects compiled by the
top level makefile with a board/chip specific list compiled in the
appropriate build.mk file.
The CR50 RO will never run on its own for long time, it will always
load an RW and go straight to it, so there is no need in running under
the OS control, using sophisticated console channel controls, etc.
The gist of the functionality is verifying the RW image to run and
setting up the hardware to allow the picked image to execute, it will
be added in the following patches. This change just provides the
plumbing and shows the 'hello world' implementation for the customized
RO image.
A better solution could be the ability to create distinct sets of make
variables for RO and RW, a tracker item was created to look into this.
BRANCH=None
BUG=chrome-os-partner:43025, chromium:551151
TEST=built and started ec.RO.hex on cr50, observed the 'hello world'
message on the console.
Change-Id: Ie67ff28bec3a9788898e99483eedb0ef77de38cd
Signed-off-by: Vadim Bendebury <vbendeb@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/310410
Reviewed-by: Randall Spangler <rspangler@chromium.org>
Reviewed-by: Bill Richardson <wfrichar@chromium.org>