fmap.c 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. /*
  2. * Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
  3. * Use of this source code is governed by a BSD-style license that can be
  4. * found in the LICENSE file.
  5. */
  6. #include <stdio.h>
  7. #include <string.h>
  8. #include "fmap.h"
  9. static int is_fmap(uint8_t *ptr)
  10. {
  11. FmapHeader *fmap_header = (FmapHeader *)ptr;
  12. if (0 != memcmp(ptr, FMAP_SIGNATURE, FMAP_SIGNATURE_SIZE))
  13. return 0;
  14. if (fmap_header->fmap_ver_major == FMAP_VER_MAJOR)
  15. return 1;
  16. fprintf(stderr, "Found FMAP, but major version is %u instead of %u\n",
  17. fmap_header->fmap_ver_major, FMAP_VER_MAJOR);
  18. return 0;
  19. }
  20. /* Find and point to the FMAP header within the buffer */
  21. FmapHeader *fmap_find(uint8_t *ptr, size_t size)
  22. {
  23. ssize_t offset, align;
  24. ssize_t lim = size - sizeof(FmapHeader);
  25. if (lim >= 0 && is_fmap(ptr))
  26. return (FmapHeader *)ptr;
  27. /* Search large alignments before small ones to find "right" FMAP. */
  28. for (align = FMAP_SEARCH_STRIDE; align <= lim; align *= 2);
  29. for (; align >= FMAP_SEARCH_STRIDE; align /= 2)
  30. for (offset = align; offset <= lim; offset += align * 2)
  31. if (is_fmap(ptr + offset))
  32. return (FmapHeader *)(ptr + offset);
  33. return NULL;
  34. }
  35. /* Search for an area by name, return pointer to its beginning */
  36. uint8_t *fmap_find_by_name(uint8_t *ptr, size_t size, FmapHeader *fmap,
  37. const char *name, FmapAreaHeader **ah_ptr)
  38. {
  39. int i;
  40. FmapAreaHeader *ah;
  41. if (!fmap)
  42. fmap = fmap_find(ptr, size);
  43. if (!fmap)
  44. return NULL;
  45. ah = (FmapAreaHeader*)((void *)fmap + sizeof(FmapHeader));
  46. for (i = 0; i < fmap->fmap_nareas; i++)
  47. if (!strncmp(ah[i].area_name, name, FMAP_NAMELEN)) {
  48. if (ah_ptr)
  49. *ah_ptr = ah + i;
  50. return ptr + ah[i].area_offset;
  51. }
  52. return NULL;
  53. }