We are going to expose ths tool to end users, and want to take care that the presented information can be consumed by them. The current code simply prints below warnings if we use release binary available for end-user to download: No firmware volume header present No valid firmware volume was found It will be concerning and not clear to end users, they might not understant why it happens, what are the implications, and whether it is something that they should worry about. This commit tries to explain what actually happens here. Change-Id: Iaa2678f5ae7c243811484c0567ced97ae0b3fc0a Signed-off-by: Maciej Pijanowski <maciej.pijanowski@3mdeb.com> Reviewed-on: https://review.coreboot.org/c/coreboot/+/82692 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Sergii Dmytruk <sergii.dmytruk@3mdeb.com>
102 lines
2.4 KiB
C
102 lines
2.4 KiB
C
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
|
|
|
#include "storage.h"
|
|
|
|
#include <assert.h>
|
|
#include <stdio.h>
|
|
|
|
#include "commonlib/bsd/compiler.h"
|
|
#include "fmap.h"
|
|
|
|
#include "fv.h"
|
|
#include "utils.h"
|
|
|
|
bool storage_open(const char store_file[], struct storage_t *storage, bool rw)
|
|
{
|
|
storage->rw = rw;
|
|
|
|
storage->file = map_file(store_file, rw);
|
|
if (storage->file.start == NULL) {
|
|
fprintf(stderr, "Failed to load smm-store-file \"%s\"\n",
|
|
store_file);
|
|
return false;
|
|
}
|
|
|
|
/* If we won't find FMAP with SMMSTORE, use the whole file, but fail if
|
|
* FMAP is there without SMMSTORE. */
|
|
storage->region = storage->file;
|
|
|
|
long fmap_offset = fmap_find(storage->file.start, storage->file.length);
|
|
if (fmap_offset >= 0) {
|
|
struct fmap *fmap = (void *)(storage->file.start + fmap_offset);
|
|
const struct fmap_area *area = fmap_find_area(fmap, "SMMSTORE");
|
|
if (area == NULL) {
|
|
fprintf(stderr,
|
|
"Found FMAP without SMMSTORE in \"%s\"\n",
|
|
store_file);
|
|
return false;
|
|
}
|
|
|
|
storage->region.start += area->offset;
|
|
storage->region.length = area->size;
|
|
}
|
|
|
|
bool auth_vars;
|
|
if (!fv_parse(storage->region, &storage->store_area, &auth_vars)) {
|
|
if (!rw) {
|
|
fprintf(stderr,
|
|
"Failed to find variable store in \"%s\"\n",
|
|
store_file);
|
|
goto error;
|
|
}
|
|
|
|
fprintf(stderr,
|
|
"\nThe variable store has not been found in the ROM image\n"
|
|
"and is about to be initialized. This situation is normal\n"
|
|
"for a release image, as the variable store is usually\n"
|
|
"initialized on the first boot of the platform.\n\n");
|
|
|
|
if (!fv_init(storage->region)) {
|
|
fprintf(stderr,
|
|
"Failed to create variable store in \"%s\"\n",
|
|
store_file);
|
|
goto error;
|
|
}
|
|
|
|
if (!fv_parse(storage->region, &storage->store_area, &auth_vars)) {
|
|
fprintf(stderr,
|
|
"Failed to parse newly formatted store in \"%s\"\n",
|
|
store_file);
|
|
goto error;
|
|
}
|
|
|
|
fprintf(stderr,
|
|
"Successfully created variable store in \"%s\"\n",
|
|
store_file);
|
|
}
|
|
|
|
storage->vs = vs_load(storage->store_area, auth_vars);
|
|
return true;
|
|
|
|
error:
|
|
unmap_file(storage->file);
|
|
return false;
|
|
}
|
|
|
|
bool storage_write_back(struct storage_t *storage)
|
|
{
|
|
assert(storage->rw && "Only RW storage can be updated.");
|
|
|
|
bool success = vs_store(&storage->vs, storage->store_area);
|
|
if (!success)
|
|
fprintf(stderr, "Failed to update variable store\n");
|
|
storage_drop(storage);
|
|
return success;
|
|
}
|
|
|
|
void storage_drop(struct storage_t *storage)
|
|
{
|
|
unmap_file(storage->file);
|
|
vs_free(&storage->vs);
|
|
}
|