cros_bundle/write_firmware: Check U-Boot text base in image
This is only meaningful on ARM.
Normally text base is in the fdt, so we just read it from there. But as
a second check we look at the image itself in case this is different, and
switch to that if it is.
We will move over to a new address on the next rebase, but this keeps
us running for now.
BUG=chromium-os:19724
TEST=emerge chromeos-bootimage on Seaboard and Alex
Change-Id: I322169f0dd6054a9decd1bac5dde09301d805285
Reviewed-on: https://gerrit.chromium.org/gerrit/11744
Reviewed-by: Randall Spangler <rspangler@chromium.org>
Reviewed-by: Che-Liang Chiou <clchiou@chromium.org>
Commit-Ready: Simon Glass <sjg@chromium.org>
Tested-by: Simon Glass <sjg@chromium.org>
diff --git a/host/lib/bundle_firmware.py b/host/lib/bundle_firmware.py
index 9a96736..ede3e2a 100644
--- a/host/lib/bundle_firmware.py
+++ b/host/lib/bundle_firmware.py
@@ -23,6 +23,7 @@
from fdt import Fdt
from pack_firmware import PackFirmware
import shutil
+import struct
import tempfile
from tools import Tools
from write_firmware import WriteFirmware
@@ -264,6 +265,56 @@
else:
self.fdt.PutString('/config/%s' % config[0], value)
+ def DecodeTextBase(self, data):
+ """Look at a U-Boot image and try to decode its TEXT_BASE.
+
+ This works because U-Boot has a header with the value 0x12345678
+ immediately followed by the TEXT_BASE value. We can therefore read this
+ from the image with some certainty. We check only the first 40 words
+ since the header should be within that region.
+
+ Args:
+ data: U-Boot binary data
+
+ Returns:
+ Text base (integer) or None if none was found
+ """
+ found = False
+ for i in range(0, 160, 4):
+ word = data[i:i + 4]
+
+ # TODO(sjg): This does not cope with a big-endian target
+ value = struct.unpack('<I', word)[0]
+ if found:
+ return value
+ if value == 0x12345678:
+ found = True
+
+ return None
+
+ def CalcTextBase(self, name, fdt, fname):
+ """Calculate the TEXT_BASE to use for U-Boot.
+
+ Normally this value is in the fdt, so we just read it from there. But as
+ a second check we look at the image itself in case this is different, and
+ switch to that if it is.
+
+ This allows us to flash any U-Boot even if its TEXT_BASE is different.
+ This is particularly useful with upstream U-Boot which uses a different
+ value (which we will move to).
+ """
+ data = self._tools.ReadFile(fname)
+ fdt_text_base = fdt.GetInt('/chromeos-config/textbase')
+ text_base = self.DecodeTextBase(data)
+
+ # If they are different, issue a warning and switch over.
+ if text_base and text_base != fdt_text_base:
+ self._out.Warning("TEXT_BASE %x in %sU-Boot doesn't match "
+ "fdt value of %x. Using %x" % (text_base, name,
+ fdt_text_base, text_base))
+ fdt_text_base = text_base
+ return fdt_text_base
+
def _CreateBootStub(self, uboot, base_fdt, postload):
"""Create a boot stub and a signed boot stub.
@@ -292,7 +343,7 @@
CmdError if a command fails.
"""
bootstub = os.path.join(self._tools.outdir, 'u-boot-fdt.bin')
- text_base = self.fdt.GetInt('/chromeos-config/textbase');
+ text_base = self.CalcTextBase('', self.fdt, uboot)
uboot_data = self._tools.ReadFile(uboot)
# Make a copy of the fdt for the bootstub