binman: Ensure attributes always come last in the metadata

cbfsutil changed to write zero bytes instead of 0xff when a small
padding must be added. Adjust the binman implementation to do the same.

Drop the code which looks for an unused attribute tag, since it is not
used. A future patch moves the attributes to the end of the header in
any case, so no data will follow the attributes.

This mirrors commit f0cc7adb2f in coreboot.

Signed-off-by: Simon Glass <sjg@chromium.org>
This commit is contained in:
Simon Glass
2023-10-14 14:40:27 -06:00
committed by Tom Rini
parent bd13255a91
commit e9199a74e0

View File

@@ -54,10 +54,6 @@ ATTR_COMPRESSION_FORMAT = '>IIII'
ATTR_COMPRESSION_LEN = 0x10 ATTR_COMPRESSION_LEN = 0x10
# Attribute tags # Attribute tags
# Depending on how the header was initialised, it may be backed with 0x00 or
# 0xff. Support both.
FILE_ATTR_TAG_UNUSED = 0
FILE_ATTR_TAG_UNUSED2 = 0xffffffff
FILE_ATTR_TAG_COMPRESSION = 0x42435a4c FILE_ATTR_TAG_COMPRESSION = 0x42435a4c
FILE_ATTR_TAG_HASH = 0x68736148 FILE_ATTR_TAG_HASH = 0x68736148
FILE_ATTR_TAG_POSITION = 0x42435350 # PSCB FILE_ATTR_TAG_POSITION = 0x42435350 # PSCB
@@ -394,6 +390,8 @@ class CbfsFile(object):
raise ValueError("Internal error: CBFS file '%s': Requested offset %#x but current output position is %#x" % raise ValueError("Internal error: CBFS file '%s': Requested offset %#x but current output position is %#x" %
(self.name, self.cbfs_offset, offset)) (self.name, self.cbfs_offset, offset))
pad = tools.get_bytes(pad_byte, pad_len) pad = tools.get_bytes(pad_byte, pad_len)
if attr_pos:
attr_pos += pad_len
hdr_len += pad_len hdr_len += pad_len
# This is the offset of the start of the file's data, # This is the offset of the start of the file's data,
@@ -410,7 +408,7 @@ class CbfsFile(object):
# happen. It probably indicates that get_header_len() is broken. # happen. It probably indicates that get_header_len() is broken.
raise ValueError("Internal error: CBFS file '%s': Expected headers of %#x bytes, got %#x" % raise ValueError("Internal error: CBFS file '%s': Expected headers of %#x bytes, got %#x" %
(self.name, expected_len, actual_len)) (self.name, expected_len, actual_len))
return hdr + name + attr + pad + content + data, hdr_len return hdr + name + pad + attr + content + data, hdr_len
class CbfsWriter(object): class CbfsWriter(object):
@@ -456,6 +454,9 @@ class CbfsWriter(object):
self._arch = arch self._arch = arch
self._bootblock_size = 0 self._bootblock_size = 0
self._erase_byte = 0xff self._erase_byte = 0xff
# Small padding to align a file uses 0
self._small_pad_byte = 0
self._align = ENTRY_ALIGN self._align = ENTRY_ALIGN
self._add_fileheader = False self._add_fileheader = False
if self._arch == ARCHITECTURE_X86: if self._arch == ARCHITECTURE_X86:
@@ -477,7 +478,7 @@ class CbfsWriter(object):
self._bootblock_size, self._align) self._bootblock_size, self._align)
self._hdr_at_start = True self._hdr_at_start = True
def _skip_to(self, fd, offset): def _skip_to(self, fd, offset, pad_byte):
"""Write out pad bytes until a given offset """Write out pad bytes until a given offset
Args: Args:
@@ -487,16 +488,16 @@ class CbfsWriter(object):
if fd.tell() > offset: if fd.tell() > offset:
raise ValueError('No space for data before offset %#x (current offset %#x)' % raise ValueError('No space for data before offset %#x (current offset %#x)' %
(offset, fd.tell())) (offset, fd.tell()))
fd.write(tools.get_bytes(self._erase_byte, offset - fd.tell())) fd.write(tools.get_bytes(pad_byte, offset - fd.tell()))
def _pad_to(self, fd, offset): def _pad_to(self, fd, offset, pad_byte):
"""Write out pad bytes and/or an empty file until a given offset """Write out pad bytes and/or an empty file until a given offset
Args: Args:
fd: File objext to write to fd: File objext to write to
offset: Offset to write to offset: Offset to write to
""" """
self._align_to(fd, self._align) self._align_to(fd, self._align, pad_byte)
upto = fd.tell() upto = fd.tell()
if upto > offset: if upto > offset:
raise ValueError('No space for data before pad offset %#x (current offset %#x)' % raise ValueError('No space for data before pad offset %#x (current offset %#x)' %
@@ -505,9 +506,9 @@ class CbfsWriter(object):
if todo: if todo:
cbf = CbfsFile.empty(todo, self._erase_byte) cbf = CbfsFile.empty(todo, self._erase_byte)
fd.write(cbf.get_data_and_offset()[0]) fd.write(cbf.get_data_and_offset()[0])
self._skip_to(fd, offset) self._skip_to(fd, offset, pad_byte)
def _align_to(self, fd, align): def _align_to(self, fd, align, pad_byte):
"""Write out pad bytes until a given alignment is reached """Write out pad bytes until a given alignment is reached
This only aligns if the resulting output would not reach the end of the This only aligns if the resulting output would not reach the end of the
@@ -521,7 +522,7 @@ class CbfsWriter(object):
""" """
offset = align_int(fd.tell(), align) offset = align_int(fd.tell(), align)
if offset < self._size: if offset < self._size:
self._skip_to(fd, offset) self._skip_to(fd, offset, pad_byte)
def add_file_stage(self, name, data, cbfs_offset=None): def add_file_stage(self, name, data, cbfs_offset=None):
"""Add a new stage file to the CBFS """Add a new stage file to the CBFS
@@ -571,7 +572,7 @@ class CbfsWriter(object):
raise ValueError('No space for header at offset %#x (current offset %#x)' % raise ValueError('No space for header at offset %#x (current offset %#x)' %
(self._header_offset, fd.tell())) (self._header_offset, fd.tell()))
if not add_fileheader: if not add_fileheader:
self._pad_to(fd, self._header_offset) self._pad_to(fd, self._header_offset, self._erase_byte)
hdr = struct.pack(HEADER_FORMAT, HEADER_MAGIC, HEADER_VERSION2, hdr = struct.pack(HEADER_FORMAT, HEADER_MAGIC, HEADER_VERSION2,
self._size, self._bootblock_size, self._align, self._size, self._bootblock_size, self._align,
self._contents_offset, self._arch, 0xffffffff) self._contents_offset, self._arch, 0xffffffff)
@@ -583,7 +584,7 @@ class CbfsWriter(object):
fd.write(name) fd.write(name)
self._header_offset = fd.tell() self._header_offset = fd.tell()
fd.write(hdr) fd.write(hdr)
self._align_to(fd, self._align) self._align_to(fd, self._align, self._erase_byte)
else: else:
fd.write(hdr) fd.write(hdr)
@@ -600,24 +601,26 @@ class CbfsWriter(object):
# THe header can go at the start in some cases # THe header can go at the start in some cases
if self._hdr_at_start: if self._hdr_at_start:
self._write_header(fd, add_fileheader=self._add_fileheader) self._write_header(fd, add_fileheader=self._add_fileheader)
self._skip_to(fd, self._contents_offset) self._skip_to(fd, self._contents_offset, self._erase_byte)
# Write out each file # Write out each file
for cbf in self._files.values(): for cbf in self._files.values():
# Place the file at its requested place, if any # Place the file at its requested place, if any
offset = cbf.calc_start_offset() offset = cbf.calc_start_offset()
if offset is not None: if offset is not None:
self._pad_to(fd, align_int_down(offset, self._align)) self._pad_to(fd, align_int_down(offset, self._align),
self._erase_byte)
pos = fd.tell() pos = fd.tell()
data, data_offset = cbf.get_data_and_offset(pos, self._erase_byte) data, data_offset = cbf.get_data_and_offset(pos,
self._small_pad_byte)
fd.write(data) fd.write(data)
self._align_to(fd, self._align) self._align_to(fd, self._align, self._erase_byte)
cbf.calced_cbfs_offset = pos + data_offset cbf.calced_cbfs_offset = pos + data_offset
if not self._hdr_at_start: if not self._hdr_at_start:
self._write_header(fd, add_fileheader=self._add_fileheader) self._write_header(fd, add_fileheader=self._add_fileheader)
# Pad to the end and write a pointer to the CBFS master header # Pad to the end and write a pointer to the CBFS master header
self._pad_to(fd, self._base_address or self._size - 4) self._pad_to(fd, self._base_address or self._size - 4, self._erase_byte)
rel_offset = self._header_offset - self._size rel_offset = self._header_offset - self._size
fd.write(struct.pack('<I', rel_offset & 0xffffffff)) fd.write(struct.pack('<I', rel_offset & 0xffffffff))
@@ -810,8 +813,6 @@ class CbfsReader(object):
# We don't currently use this information # We don't currently use this information
atag, alen, compress, _decomp_size = struct.unpack( atag, alen, compress, _decomp_size = struct.unpack(
ATTR_COMPRESSION_FORMAT, data) ATTR_COMPRESSION_FORMAT, data)
elif atag == FILE_ATTR_TAG_UNUSED2:
break
else: else:
print('Unknown attribute tag %x' % atag) print('Unknown attribute tag %x' % atag)
attr_size -= len(data) attr_size -= len(data)
@@ -846,7 +847,8 @@ class CbfsReader(object):
def _read_string(cls, fd): def _read_string(cls, fd):
"""Read a string from a file """Read a string from a file
This reads a string and aligns the data to the next alignment boundary This reads a string and aligns the data to the next alignment boundary.
The string must be nul-terminated
Args: Args:
fd: File to read from fd: File to read from