cros_bundle_firmware: Search a LZO magic when u-boot is LZO compressed

We look for a 'B reset' instruction which is at the start of u-boot to
locate the offset of u-boot. When u-boot is LZO compressed, this method
doesn't work. We should look for a LZO magic instead.

This CL tries to search both patterns and picks the minimal offsets.

BUG=chromium-os:37724
TEST=manual
Use a FDT in which RO u-boot flashmap has the property: compress = "lzo".
Run cros_bundle_firmware -w -p and check the resulted u-boot-from-image.bin
contains a correct compressed u-boot image.

Change-Id: Id6a4b3a50825b35850b70fae2b42f8889e6b1590
Reviewed-on: https://gerrit.chromium.org/gerrit/42693
Commit-Queue: Tom Wai-Hong Tam <waihong@chromium.org>
Reviewed-by: Tom Wai-Hong Tam <waihong@chromium.org>
Tested-by: Tom Wai-Hong Tam <waihong@chromium.org>
diff --git a/host/lib/write_firmware.py b/host/lib/write_firmware.py
index 391266a..8952dcc 100644
--- a/host/lib/write_firmware.py
+++ b/host/lib/write_firmware.py
@@ -400,9 +400,15 @@
     self._tools.WriteFile(bl1, data[:bl1_size])
 
     # Try to detect the BL2 size. We look for 0xea000014 which is the
-    # 'B reset' instruction at the start of U-Boot.
+    # 'B reset' instruction at the start of U-Boot. When U-Boot is LZO
+    # compressed, we look for a LZO magic instead.
     first_instr = struct.pack('<L', 0xea000014)
-    uboot_offset = data.find(first_instr, bl1_size + 0x3800)
+    lzo_magic = struct.pack('>B3s', 0x89, 'LZO')
+    first_instr_offset = data.find(first_instr, bl1_size + 0x3800)
+    lzo_magic_offset = data.find(lzo_magic, bl1_size + 0x3800)
+    uboot_offset = min(first_instr_offset, lzo_magic_offset)
+    if uboot_offset == -1:
+      uboot_offset = max(first_instr_offset, lzo_magic_offset)
     if uboot_offset == -1:
       raise ValueError('Could not locate start of U-Boot')
     bl2_size = uboot_offset - bl1_size - 0x800  # 2KB gap after BL2