1# SPDX-License-Identifier: GPL-2.0+ 2# Copyright (c) 2018 Google, Inc 3# Written by Simon Glass <sjg@chromium.org> 4# 5 6# Support for a Chromium OS Google Binary Block, used to record read-only 7# information mostly used by firmware. 8 9from collections import OrderedDict 10 11import command 12from entry import Entry, EntryArg 13 14import fdt_util 15import tools 16 17# Build GBB flags. 18# (src/platform/vboot_reference/firmware/include/gbb_header.h) 19gbb_flag_properties = { 20 'dev-screen-short-delay': 0x1, 21 'load-option-roms': 0x2, 22 'enable-alternate-os': 0x4, 23 'force-dev-switch-on': 0x8, 24 'force-dev-boot-usb': 0x10, 25 'disable-fw-rollback-check': 0x20, 26 'enter-triggers-tonorm': 0x40, 27 'force-dev-boot-legacy': 0x80, 28 'faft-key-override': 0x100, 29 'disable-ec-software-sync': 0x200, 30 'default-dev-boot-legacy': 0x400, 31 'disable-pd-software-sync': 0x800, 32 'disable-lid-shutdown': 0x1000, 33 'force-dev-boot-fastboot-full-cap': 0x2000, 34 'enable-serial': 0x4000, 35 'disable-dwmp': 0x8000, 36} 37 38 39class Entry_gbb(Entry): 40 """An entry which contains a Chromium OS Google Binary Block 41 42 Properties / Entry arguments: 43 - hardware-id: Hardware ID to use for this build (a string) 44 - keydir: Directory containing the public keys to use 45 - bmpblk: Filename containing images used by recovery 46 47 Chromium OS uses a GBB to store various pieces of information, in particular 48 the root and recovery keys that are used to verify the boot process. Some 49 more details are here: 50 51 https://www.chromium.org/chromium-os/firmware-porting-guide/2-concepts 52 53 but note that the page dates from 2013 so is quite out of date. See 54 README.chromium for how to obtain the required keys and tools. 55 """ 56 def __init__(self, section, etype, node): 57 Entry.__init__(self, section, etype, node) 58 self.hardware_id, self.keydir, self.bmpblk = self.GetEntryArgsOrProps( 59 [EntryArg('hardware-id', str), 60 EntryArg('keydir', str), 61 EntryArg('bmpblk', str)]) 62 63 # Read in the GBB flags from the config 64 self.gbb_flags = 0 65 flags_node = node.FindNode('flags') 66 if flags_node: 67 for flag, value in gbb_flag_properties.iteritems(): 68 if fdt_util.GetBool(flags_node, flag): 69 self.gbb_flags |= value 70 71 def ObtainContents(self): 72 gbb = 'gbb.bin' 73 fname = tools.GetOutputFilename(gbb) 74 if not self.size: 75 self.Raise('GBB must have a fixed size') 76 gbb_size = self.size 77 bmpfv_size = gbb_size - 0x2180 78 if bmpfv_size < 0: 79 self.Raise('GBB is too small (minimum 0x2180 bytes)') 80 sizes = [0x100, 0x1000, bmpfv_size, 0x1000] 81 sizes = ['%#x' % size for size in sizes] 82 keydir = tools.GetInputFilename(self.keydir) 83 gbb_set_command = [ 84 'gbb_utility', '-s', 85 '--hwid=%s' % self.hardware_id, 86 '--rootkey=%s/root_key.vbpubk' % keydir, 87 '--recoverykey=%s/recovery_key.vbpubk' % keydir, 88 '--flags=%d' % self.gbb_flags, 89 '--bmpfv=%s' % tools.GetInputFilename(self.bmpblk), 90 fname] 91 92 tools.Run('futility', 'gbb_utility', '-c', ','.join(sizes), fname) 93 tools.Run('futility', *gbb_set_command) 94 95 self.SetContents(tools.ReadFile(fname)) 96 return True 97