fmap_from_fmd.c
1 /* fmap_from_fmd.c, tool to distill flashmap descriptors into raw FMAP sections */ 2 /* SPDX-License-Identifier: GPL-2.0-only */ 3 4 #include "fmap_from_fmd.h" 5 6 #include "common.h" 7 8 #include <assert.h> 9 #include <string.h> 10 11 static bool fmap_append_fmd_node(struct fmap **flashmap, 12 const struct flashmap_descriptor *section, 13 unsigned absolute_watermark) { 14 uint16_t flags = 0; 15 if (strlen(section->name) >= FMAP_STRLEN) { 16 ERROR("Section name ('%s') exceeds %d character FMAP format limit\n", 17 section->name, FMAP_STRLEN - 1); 18 return false; 19 } 20 21 absolute_watermark += section->offset; 22 23 if (section->flags.f.preserve) 24 flags |= FMAP_AREA_PRESERVE; 25 26 if (fmap_append_area(flashmap, absolute_watermark, section->size, 27 (uint8_t *)section->name, flags) < 0) { 28 ERROR("Failed to insert section '%s' into FMAP\n", 29 section->name); 30 return false; 31 } 32 33 fmd_foreach_child(subsection, section) { 34 if (!fmap_append_fmd_node(flashmap, subsection, 35 absolute_watermark)) 36 return false; 37 } 38 39 return true; 40 } 41 42 struct fmap *fmap_from_fmd(const struct flashmap_descriptor *desc) 43 { 44 assert(desc); 45 assert(desc->size_known); 46 47 if (strlen(desc->name) >= FMAP_STRLEN) { 48 ERROR("Image name ('%s') exceeds %d character FMAP header limit\n", 49 desc->name, FMAP_STRLEN - 1); 50 return NULL; 51 } 52 53 struct fmap *fmap = fmap_create(desc->offset_known ? desc->offset : 0, 54 desc->size, (uint8_t *)desc->name); 55 if (!fmap) { 56 ERROR("Failed to allocate FMAP header\n"); 57 return fmap; 58 } 59 60 fmd_foreach_child(real_section, desc) { 61 if (!fmap_append_fmd_node(&fmap, real_section, 0)) { 62 fmap_destroy(fmap); 63 return NULL; 64 } 65 } 66 67 return fmap; 68 }