Blob Lists - bloblist¶
Introduction¶
A bloblist provides a way to store collections of binary information (blobs) in a central structure. Each record of information is assigned a tag so that its owner can find it and update it. Each record is generally described by a C structure defined by the code that owns it.
For the design goals of bloblist, please see the comments at the top of the bloblist.h header file.
Passing state through the boot process¶
The bloblist is created when the first U-Boot component runs (often SPL, sometimes TPL). It is passed through to each successive part of the boot and can be accessed as needed. This provides a way to transfer state from one part to the next. For example, TPL may determine that a watchdog reset occurred by reading an SoC register. Reading the register may reset the value, so that it cannot be read a second time. So TPL can store that in a bloblist record which can be passed through to SPL and U-Boot proper, which can print a message indicating that something went wrong and the watchdog fired.
Blobs¶
While each blob in the bloblist can be of any length, bloblists are designed to hold small amounts of data, typically a few KB at most. It is not possible to change the length of a blob once it has been written. Each blob is normally created from a C structure which can be used to access its fields.
Blob tags¶
Each blob has a tag which is a 32-bit number. This uniquely identifies the owner of the blob. Blob tags are listed in enum blob_tag_t and are named with a BLOBT_ prefix.
Single structure¶
There is normally only one bloblist in U-Boot. Since a bloblist can store multiple blobs it does not seem useful to allow multiple bloblists. Of course there could be reasons for this, such as needing to spread the blobs around in different memory areas due to fragmented memory, but it is simpler to just have a single bloblist.
API¶
Bloblist provides a fairly simple API which allows blobs to be created and found. All access is via the blob’s tag. Blob records are zeroed when added.
Placing the bloblist¶
The bloblist is typically positioned at a fixed address by TPL, or SPL. This is controlled by CONFIG_BLOBLIST_ADDR. But in some cases it is preferable to allocate the bloblist in the malloc() space. Use the CONFIG_BLOBLIST_ALLOC option to enable this.
The bloblist is automatically relocated as part of U-Boot relocation. Sometimes it is useful to expand the bloblist in U-Boot proper, since it may want to add information for use by Linux. Note that this does not mean that Linux needs to know anything about the bloblist format, just that it is convenient to use bloblist to place things contiguously in memory. Set CONFIG_BLOBLIST_SIZE_RELOC to define the expanded size, if needed.
Finishing the bloblist¶
When a part of U-Boot is about to jump to the next part, it can ‘finish’ the bloblist in preparation for the next stage. This involves adding a checksum so that the next stage can make sure that the data arrived safely. While the bloblist is in use, changes can be made which will affect the checksum, so it is easier to calculate the checksum at the end after all changes are made.
Future work¶
Bootstage has a mechanism to ‘stash’ its records for passing to the next part. This should move to using bloblist, to avoid having its own mechanism for passing information between U-Boot parts.
API documentation¶
-
struct
bloblist_hdr
¶ header for the bloblist
Definition
struct bloblist_hdr {
u32 magic;
u32 version;
u32 hdr_size;
u32 flags;
u32 size;
u32 alloced;
u32 spare;
u32 chksum;
};
Members
magic
BLOBLIST_MAGIC
version
BLOBLIST_VERSION
hdr_size
Size of this header, normally sizeof(struct bloblist_hdr). The first bloblist_rec starts at this offset from the start of the header
flags
Space for BLOBLISTF… flags (none yet)
size
Total size of the bloblist (non-zero if valid) including this header. The bloblist extends for this many bytes from the start of this header. When adding new records, the bloblist can grow up to this size.
alloced
Total size allocated so far for this bloblist. This starts out as sizeof(bloblist_hdr) since we need at least that much space to store a valid bloblist
spare
Spare space (for future use)
chksum
CRC32 for the entire bloblist allocated area. Since any of the blobs can be altered after being created, this checksum is only valid when the bloblist is finalised before jumping to the next stage of boot. Note that chksum is last to make it easier to exclude it from the checksum calculation.
Description
This is stored at the start of the bloblist which is always on a 16-byte boundary. Records follow this header. The bloblist normally stays in the same place in memory as SPL and U-Boot execute, but it can be safely moved around.
None of the bloblist headers themselves contain pointers but it is possible to put pointers inside a bloblist record if desired. This is not encouraged, since it can make part of the bloblist inaccessible if the pointer is no-longer valid. It is better to just store all the data inside a bloblist record.
Each bloblist record is aligned to a 16-byte boundary and follows immediately from the last.
-
struct
bloblist_rec
¶ record for the bloblist
Definition
struct bloblist_rec {
u32 tag;
u32 hdr_size;
u32 size;
u32 spare;
};
Members
tag
Tag indicating what the record contains
hdr_size
Size of this header, normally sizeof(struct bloblist_rec). The record’s data starts at this offset from the start of the record
size
Size of record in bytes, excluding the header size. This does not need to be aligned (e.g. 3 is OK).
spare
Spare space for other things
Description
The bloblist contains a number of records each consisting of this record structure followed by the data contained. Each records is 16-byte aligned.
NOTE
Only exported for testing purposes. Do not use this struct.
-
void *
bloblist_check_magic
(ulong addr)¶ return a bloblist if the magic matches
Parameters
ulong addr
Address to check
Return
pointer to bloblist, if the magic matches, else NULL
-
void *
bloblist_find
(uint tag, int size)¶ Find a blob
Parameters
uint tag
Tag to search for (enum bloblist_tag_t)
int size
Expected size of the blob, or 0 for any size
Description
Searches the bloblist and returns the blob with the matching tag
Return
pointer to blob if found, or NULL if not found, or a blob was found but it is the wrong size
-
void *
bloblist_add
(uint tag, int size, int align)¶ Add a new blob
Parameters
uint tag
Tag to add (enum bloblist_tag_t)
int size
Size of the blob
int align
Alignment of the blob (in bytes), 0 for default
Description
Add a new blob to the bloblist
This should only be called if you konw there is no existing blob for a particular tag. It is typically safe to call in the first phase of U-Boot (e.g. TPL or SPL). After that, bloblist_ensure() should be used instead.
Return
pointer to the newly added block, or NULL if there is not enough space for the blob
-
int
bloblist_ensure_size
(uint tag, int size, int align, void **blobp)¶ Find or add a blob
Parameters
uint tag
Tag to add (enum bloblist_tag_t)
int size
Size of the blob
int align
Alignment of the blob (in bytes), 0 for default
void **blobp
Returns a pointer to blob on success
Description
Find an existing blob, or add a new one if not found
Return
0 if OK, -ENOSPC if it is missing and could not be added due to lack of space, or -ESPIPE it exists but has the wrong size
-
void *
bloblist_ensure
(uint tag, int size)¶ Find or add a blob
Parameters
uint tag
Tag to add (enum bloblist_tag_t)
int size
Size of the blob
Description
Find an existing blob, or add a new one if not found
Return
pointer to blob, or NULL if it is missing and could not be added due to lack of space, or it exists but has the wrong size
-
int
bloblist_ensure_size_ret
(uint tag, int *sizep, void **blobp)¶ Find or add a blob
Parameters
uint tag
Tag to add (enum bloblist_tag_t)
int *sizep
Size of the blob to create; returns size of actual blob
void **blobp
Returns a pointer to blob on success
Description
Find an existing blob, or add a new one if not found
Return
0 if OK, -ENOSPC if it is missing and could not be added due to lack of space
-
int
bloblist_resize
(uint tag, int new_size)¶ resize a blob
Parameters
uint tag
Tag to add (enum bloblist_tag_t)
int new_size
New size of the blob (>0 to expand, <0 to contract)
Description
Any blobs above this one are relocated up or down. The resized blob remains in the same place.
Return
0 if OK, -ENOSPC if the bloblist does not have enough space, -ENOENT if the tag is not found
-
int
bloblist_new
(ulong addr, uint size, uint flags)¶ Create a new, empty bloblist of a given size
Parameters
ulong addr
Address of bloblist
uint size
Initial size for bloblist
uint flags
Flags to use for bloblist
Return
0 if OK, -EFAULT if addr is not aligned correctly, -ENOSPC is the area is not large enough
-
int
bloblist_check
(ulong addr, uint size)¶ Check if a bloblist exists
Parameters
ulong addr
Address of bloblist
uint size
Expected size of blobsize, or 0 to detect the size
Return
0 if OK, -ENOENT if the magic number doesn’t match (indicating that there problem is no bloblist at the given address), -EPROTONOSUPPORT if the version does not match, -EIO if the checksum does not match, -EFBIG if the expected size does not match the detected size, -ENOSPC if the size is not large enough to hold the headers
-
int
bloblist_finish
(void)¶ Set up the bloblist for the next U-Boot part
Parameters
void
no arguments
Description
This sets the correct checksum for the bloblist. This ensures that the bloblist will be detected correctly by the next phase of U-Boot.
Return
0
-
void
bloblist_get_stats
(ulong *basep, ulong *sizep, ulong *allocedp)¶ Get information about the bloblist
Parameters
ulong *basep
Returns base address of bloblist
ulong *sizep
Returns the number of bytes used in the bloblist
ulong *allocedp
Returns the total space allocated to the bloblist
Description
This returns useful information about the bloblist
-
ulong
bloblist_get_base
(void)¶ Get the base address of the bloblist
Parameters
void
no arguments
Return
base address of bloblist
-
ulong
bloblist_get_size
(void)¶ Get the size of the bloblist
Parameters
void
no arguments
Return
the size in bytes
-
void
bloblist_show_stats
(void)¶ Show information about the bloblist
Parameters
void
no arguments
Description
This shows useful information about the bloblist on the console
-
void
bloblist_show_list
(void)¶ Show a list of blobs in the bloblist
Parameters
void
no arguments
Description
This shows a list of blobs, showing their address, size and tag.
-
const char *
bloblist_tag_name
(enum bloblist_tag_t tag)¶ Get the name for a tag
Parameters
enum bloblist_tag_t tag
Tag to check
Return
name of tag, or “invalid” if an invalid tag is provided
-
void
bloblist_reloc
(void *to, uint to_size, void *from, uint from_size)¶ Relocate the bloblist and optionally resize it
Parameters
void *to
Pointer to new bloblist location (must not overlap old location)
uint to_size
New size for bloblist (must be larger than from_size)
void *from
Pointer to bloblist to relocate
uint from_size
Size of bloblist to relocate
-
int
bloblist_init
(void)¶ Init the bloblist system with a single bloblist
Parameters
void
no arguments
Description
This locates and sets up the blocklist for use.
If CONFIG_BLOBLIST_FIXED is selected, it uses CONFIG_BLOBLIST_ADDR and CONFIG_BLOBLIST_SIZE to set up a bloblist for use by U-Boot.
If CONFIG_BLOBLIST_ALLOC is selected, it allocates memory for a bloblist of size CONFIG_BLOBLIST_SIZE.
If CONFIG_BLOBLIST_PASSAGE is selected, it uses the bloblist in the incoming standard passage. The size is detected automatically so CONFIG_BLOBLIST_SIZE can be 0.
Return
0 if OK, -ve on error
Simon Glass sjg@chromium.org 12-Aug-2018