mec1322: Update pack script

This includes:
  - Reference to the boot ROM document
  - Update flags usage from the document
  - Command line argument support

BUG=chrome-os-partner:24107, chrome-os-partner:24188
TEST=Pack and boot
BRANCH=None

Change-Id: I6f79ca94fbc10448e3a1c884a2d52fdf4abf266d
Signed-off-by: Vic (Chun-Ju) Yang <victoryang@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/180180
Reviewed-by: Randall Spangler <rspangler@chromium.org>
Reviewed-by: Vincent Palatin <vpalatin@chromium.org>
This commit is contained in:
Vic (Chun-Ju) Yang
2013-12-14 23:51:03 +08:00
committed by chrome-internal-fetch
parent 96dbfda900
commit ae237cfabf

View File

@@ -5,30 +5,19 @@
# found in the LICENSE file.
# A script to pack EC binary into SPI flash image for MEC1322
# Based on MEC1322_ROM_Doc_Rev0.5.pdf.
# TODO(crosbug.com/p/24107): Add reference to document on image format.
import argparse
import hashlib
import os
import struct
import subprocess
import tempfile
# TODO(crosbug.com/p/24188): Make these options available as command line
# arguments.
SPI_SIZE = 4 * 1024 * 1024
HEADER_PEM_FILE = 'rsakey_sign_header.pem'
PAYLOAD_PEM_FILE = 'rsakey_sign_payload.pem'
PAYLOAD_FILE = 'ec.bin' # Set to 'ec.RO.flat' for RO-only image
HEADER_LOCATION = 0x170000
HEADER_FLAG1 = 0x00
HEADER_FLAG2 = 0x01
SPI_READ_CMD = 0x01
LOAD_ADDR = 0x100000
SPI_CHIP_SELECT = 0
HEADER_SIZE = 0x140
PAYLOAD_OFFSET = 0x240
OUTPUT_FILE = 'ec.4mb.bin'
SPI_CLOCK_LIST = [48, 24, 12, 8]
SPI_READ_CMD_LIST = [0x3, 0xb, 0x3b]
CRC_TABLE = [0x00, 0x07, 0x0e, 0x09, 0x1c, 0x1b, 0x12, 0x15,
0x38, 0x3f, 0x36, 0x31, 0x24, 0x23, 0x2a, 0x2d]
@@ -77,20 +66,35 @@ def GetPublicKey(pem_file):
modulus_raw[0:256])))
return struct.pack('<Q', exp), modulus
def GetSpiClockParameter(args):
assert args.spi_clock in SPI_CLOCK_LIST, \
"Unsupported SPI clock speed %d MHz" % args.spi_clock
return SPI_CLOCK_LIST.index(args.spi_clock)
def GetSpiReadCmdParameter(args):
assert args.spi_read_cmd in SPI_READ_CMD_LIST, \
"Unsupported SPI read command 0x%x" % args.spi_read_cmd
return SPI_READ_CMD_LIST.index(args.spi_read_cmd)
def PadZeroTo(data, size):
data.extend('\0' * (size - len(data)))
def BuildHeader(payload_len):
def BuildHeader(args, payload_len):
# Identifier and header version
header = bytearray(['C', 'S', 'M', 'S', '\0'])
header.extend([HEADER_FLAG1, HEADER_FLAG2, SPI_READ_CMD])
PadZeroTo(header, 0x6)
header.append(GetSpiClockParameter(args))
header.append(GetSpiReadCmdParameter(args))
header.extend(struct.pack('<I', LOAD_ADDR))
header.extend(struct.pack('<I', GetEntryPoint(PAYLOAD_FILE)))
header.extend(struct.pack('<I', GetEntryPoint(args.input)))
header.append((payload_len >> 6) & 0xff)
header.append((payload_len >> 14) & 0xff)
PadZeroTo(header, 0x14)
header.extend(struct.pack('<I', PAYLOAD_OFFSET))
header.extend(struct.pack('<I', args.payload_offset))
exp, modulus = GetPublicKey(PAYLOAD_PEM_FILE)
exp, modulus = GetPublicKey(args.payload_key)
PadZeroTo(header, 0x20)
header.extend(exp)
PadZeroTo(header, 0x30)
@@ -114,36 +118,70 @@ def SignByteArray(data, pem_file):
signed.reverse()
return bytearray(''.join(signed))
def BuildTag(header_loc):
tag = bytearray([(header_loc >> 8) & 0xff,
(header_loc >> 16) & 0xff,
(header_loc >> 24) & 0xff])
if SPI_CHIP_SELECT != 0:
def BuildTag(args):
tag = bytearray([(args.header_loc >> 8) & 0xff,
(args.header_loc >> 16) & 0xff,
(args.header_loc >> 24) & 0xff])
if args.chip_select != 0:
tag[2] |= 0x80
tag.append(Crc8(0, tag))
return tag
def main():
parser = argparse.ArgumentParser()
parser.add_argument("-i", "--input",
help="EC binary to pack, usually ec.bin or ec.RO.flat.",
metavar="EC_BIN", default="ec.bin")
parser.add_argument("-o", "--output",
help="Output flash binary file",
metavar="EC_SPI_FLASH", default="ec.packed.bin")
parser.add_argument("--header_key",
help="PEM key file for signing header",
default="rsakey_sign_header.pem")
parser.add_argument("--payload_key",
help="PEM key file for signing payload",
default="rsakey_sign_payload.pem")
parser.add_argument("-s", "--spi_size", type=int,
help="Size of the SPI flash in MB",
default=4)
parser.add_argument("-l", "--header_loc", type=int,
help="Location of header in SPI flash",
default=0x170000)
parser.add_argument("-p", "--payload_offset", type=int,
help="The offset of payload from the header",
default=0x240)
parser.add_argument("-c", "--chip_select", type=int,
help="Chip select signal to use, either 0 or 1.",
default=0)
parser.add_argument("--spi_clock", type=int,
help="SPI clock speed. 8, 12, 24, or 48 MHz.",
default=24)
parser.add_argument("--spi_read_cmd", type=int,
help="SPI read command. 0x3, 0xB, or 0x3B.",
default=0xb)
args = parser.parse_args()
spi_size = args.spi_size * 1024 * 1024
spi_list = []
payload = GetPayload(PAYLOAD_FILE)
payload = GetPayload(args.input)
payload_len = len(payload)
payload_signature = SignByteArray(payload, PAYLOAD_PEM_FILE)
header = BuildHeader(payload_len)
header_signature = SignByteArray(header, HEADER_PEM_FILE)
tag = BuildTag(HEADER_LOCATION)
payload_signature = SignByteArray(payload, args.payload_key)
header = BuildHeader(args, payload_len)
header_signature = SignByteArray(header, args.header_key)
tag = BuildTag(args)
spi_list.append((HEADER_LOCATION, header))
spi_list.append((HEADER_LOCATION + HEADER_SIZE, header_signature))
spi_list.append((HEADER_LOCATION + PAYLOAD_OFFSET, payload))
spi_list.append((HEADER_LOCATION + PAYLOAD_OFFSET + payload_len,
spi_list.append((args.header_loc, header))
spi_list.append((args.header_loc + HEADER_SIZE, header_signature))
spi_list.append((args.header_loc + args.payload_offset, payload))
spi_list.append((args.header_loc + args.payload_offset + payload_len,
payload_signature))
spi_list.append((SPI_SIZE - 256, tag))
spi_list.append((spi_size - 256, tag))
spi_list = sorted(spi_list)
with open(OUTPUT_FILE, 'wb') as f:
with open(args.output, 'wb') as f:
addr = 0
for s in spi_list:
assert addr <= s[0]
@@ -152,8 +190,8 @@ def main():
addr = s[0]
f.write(s[1])
addr += len(s[1])
if addr < SPI_SIZE:
f.write('\xff' * (SPI_SIZE - addr))
if addr < spi_size:
f.write('\xff' * (spi_size - addr))
if __name__ == '__main__':
main()