- multiple regions may be used as free space. They may not be
contiguous.
+ - if existing regions are insufficient to satisfy an allocation, a new
+ region can be requested from firmware.
+
Regions are managed by a singly linked list, and the meta information is
stored in the beginning of each region. Space after the meta information
is used to allocate memory.
\f
grub_mm_region_t grub_mm_base;
+grub_mm_add_region_func_t grub_mm_add_region_fn;
/* Get a header from the pointer PTR, and set *P and *R to a pointer
to the header and a pointer to its region, respectively. PTR must
count++;
goto again;
+ case 1:
+ /* Request additional pages, contiguous */
+ count++;
+
+ if (grub_mm_add_region_fn != NULL &&
+ grub_mm_add_region_fn (size, GRUB_MM_ADD_REGION_CONSECUTIVE) == GRUB_ERR_NONE)
+ goto again;
+
+ /* fallthrough */
+
+ case 2:
+ /* Request additional pages, anything at all */
+ count++;
+
+ if (grub_mm_add_region_fn != NULL)
+ {
+ /*
+ * Try again even if this fails, in case it was able to partially
+ * satisfy the request
+ */
+ grub_mm_add_region_fn (size, GRUB_MM_ADD_REGION_NONE);
+ goto again;
+ }
+
+ /* fallthrough */
+
default:
break;
}
#ifndef GRUB_MM_H
#define GRUB_MM_H 1
+#include <grub/err.h>
#include <grub/types.h>
#include <grub/symbol.h>
#include <config.h>
# define NULL ((void *) 0)
#endif
+#define GRUB_MM_ADD_REGION_NONE 0
+#define GRUB_MM_ADD_REGION_CONSECUTIVE (1 << 0)
+
+/*
+ * Function used to request memory regions of `grub_size_t` bytes. The second
+ * parameter is a bitfield of `GRUB_MM_ADD_REGION` flags.
+ */
+typedef grub_err_t (*grub_mm_add_region_func_t) (grub_size_t, unsigned int);
+
+/*
+ * Set this function pointer to enable adding memory-regions at runtime in case
+ * a memory allocation cannot be satisfied with existing regions.
+ */
+#ifndef GRUB_MACHINE_EMU
+extern grub_mm_add_region_func_t EXPORT_VAR(grub_mm_add_region_fn);
+#endif
+
void grub_mm_init_region (void *addr, grub_size_t size);
void *EXPORT_FUNC(grub_calloc) (grub_size_t nmemb, grub_size_t size);
void *EXPORT_FUNC(grub_malloc) (grub_size_t size);