size_t memmap_pool_amount(char* mmap_addr, char* mmap_end) { size_t size = 0; while (mmap_addr < mmap_end) { memmap_entry entry = parse_memmap_entry(mmap_addr); if (entry.type == 1) { auto length = entry.length; while (length > 4096) { size++; length >>= 2; } } mmap_addr += entry.size; }
/* documentation: firmware_memmap.h */ int get_firmware_memmap_ranges(struct memory_range *range, size_t *ranges) { DIR *firmware_memmap_dir = NULL; struct dirent *dirent; int i = 0; /* argument checking */ if (!range || !ranges) { fprintf(stderr, "%s: Invalid arguments.\n", __FUNCTION__); return -1; } /* open the directory */ firmware_memmap_dir = opendir(FIRMWARE_MEMMAP_DIR); if (!firmware_memmap_dir) { perror("Could not open \"" FIRMWARE_MEMMAP_DIR "\""); goto error; } /* parse the entries */ while ((dirent = readdir(firmware_memmap_dir)) != NULL) { int ret; char full_path[PATH_MAX]; /* array overflow check */ if ((size_t)i >= *ranges) { fprintf(stderr, "The firmware provides more entries " "allowed (%zd). Please report that as bug.\n", *ranges); goto error; } /* exclude '.' and '..' */ if (dirent->d_name[0] && dirent->d_name[0] == '.') { continue; } snprintf(full_path, PATH_MAX, "%s/%s", FIRMWARE_MEMMAP_DIR, dirent->d_name); full_path[PATH_MAX-1] = 0; ret = parse_memmap_entry(full_path, &range[i]); if (ret < 0) { goto error; } i++; } /* close the dir as we don't need it any more */ closedir(firmware_memmap_dir); /* update the number of ranges for the caller */ *ranges = i; /* and finally sort the entries with qsort */ qsort(range, *ranges, sizeof(struct memory_range), compare_ranges); return 0; error: if (firmware_memmap_dir) { closedir(firmware_memmap_dir); } return -1; }