mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2026-01-10 17:41:54 +00:00
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:
committed by
chrome-internal-fetch
parent
96dbfda900
commit
ae237cfabf
@@ -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()
|
||||
|
||||
Reference in New Issue
Block a user