Use leftovers
This commit is contained in:
parent
91b58e6b74
commit
6d6f55c557
3 changed files with 237 additions and 96 deletions
|
@ -66,8 +66,10 @@ struct grub_relocator_mmap_event
|
||||||
/* To track the regions already in heap. */
|
/* To track the regions already in heap. */
|
||||||
FIRMWARE_BLOCK_START = 6,
|
FIRMWARE_BLOCK_START = 6,
|
||||||
FIRMWARE_BLOCK_END = FIRMWARE_BLOCK_START | 1,
|
FIRMWARE_BLOCK_END = FIRMWARE_BLOCK_START | 1,
|
||||||
|
REG_LEFTOVER_START = 8,
|
||||||
|
REG_LEFTOVER_END = REG_LEFTOVER_START | 1,
|
||||||
#endif
|
#endif
|
||||||
COLLISION_START = 8,
|
COLLISION_START = 10,
|
||||||
COLLISION_END = COLLISION_START | 1
|
COLLISION_END = COLLISION_START | 1
|
||||||
} type;
|
} type;
|
||||||
grub_addr_t pos;
|
grub_addr_t pos;
|
||||||
|
@ -80,6 +82,9 @@ struct grub_relocator_mmap_event
|
||||||
grub_mm_region_t *regancestor;
|
grub_mm_region_t *regancestor;
|
||||||
grub_mm_header_t head;
|
grub_mm_header_t head;
|
||||||
};
|
};
|
||||||
|
#if GRUB_RELOCATOR_HAVE_FIRMWARE_REQUESTS
|
||||||
|
struct grub_relocator_fw_leftover *leftover;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
119
lib/relocator.c
119
lib/relocator.c
|
@ -35,7 +35,7 @@ struct grub_relocator_subchunk
|
||||||
{
|
{
|
||||||
enum {CHUNK_TYPE_IN_REGION, CHUNK_TYPE_REGION_START,
|
enum {CHUNK_TYPE_IN_REGION, CHUNK_TYPE_REGION_START,
|
||||||
#if GRUB_RELOCATOR_HAVE_FIRMWARE_REQUESTS
|
#if GRUB_RELOCATOR_HAVE_FIRMWARE_REQUESTS
|
||||||
CHUNK_TYPE_FIRMWARE
|
CHUNK_TYPE_FIRMWARE, CHUNK_TYPE_LEFTOVER
|
||||||
#endif
|
#endif
|
||||||
} type;
|
} type;
|
||||||
grub_addr_t host_start;
|
grub_addr_t host_start;
|
||||||
|
@ -334,6 +334,7 @@ free_subchunk (const struct grub_relocator_subchunk *subchu)
|
||||||
}
|
}
|
||||||
#if GRUB_RELOCATOR_HAVE_FIRMWARE_REQUESTS
|
#if GRUB_RELOCATOR_HAVE_FIRMWARE_REQUESTS
|
||||||
case CHUNK_TYPE_FIRMWARE:
|
case CHUNK_TYPE_FIRMWARE:
|
||||||
|
case CHUNK_TYPE_LEFTOVER:
|
||||||
{
|
{
|
||||||
grub_addr_t fstart, fend;
|
grub_addr_t fstart, fend;
|
||||||
fstart = ALIGN_UP (subchu->start,
|
fstart = ALIGN_UP (subchu->start,
|
||||||
|
@ -375,11 +376,12 @@ malloc_in_range (struct grub_relocator *rel,
|
||||||
{
|
{
|
||||||
grub_mm_region_t r, *ra, base_saved;
|
grub_mm_region_t r, *ra, base_saved;
|
||||||
struct grub_relocator_mmap_event *events = NULL, *eventt = NULL, *t;
|
struct grub_relocator_mmap_event *events = NULL, *eventt = NULL, *t;
|
||||||
unsigned maxevents = 2;
|
/* 128 is just in case of additional malloc (shouldn't happen). */
|
||||||
|
unsigned maxevents = 2 + 128;
|
||||||
grub_mm_header_t p, pa;
|
grub_mm_header_t p, pa;
|
||||||
unsigned *counter;
|
unsigned *counter;
|
||||||
int nallocs = 0;
|
int nallocs = 0;
|
||||||
unsigned i, j, N = 0;
|
unsigned j, N = 0;
|
||||||
grub_addr_t target = 0;
|
grub_addr_t target = 0;
|
||||||
|
|
||||||
grub_dprintf ("relocator",
|
grub_dprintf ("relocator",
|
||||||
|
@ -422,6 +424,23 @@ malloc_in_range (struct grub_relocator *rel,
|
||||||
}
|
}
|
||||||
|
|
||||||
maxevents += grub_relocator_firmware_get_max_events ();
|
maxevents += grub_relocator_firmware_get_max_events ();
|
||||||
|
|
||||||
|
{
|
||||||
|
struct grub_relocator_fw_leftover *cur;
|
||||||
|
for (cur = leftovers; cur; cur = cur->next)
|
||||||
|
{
|
||||||
|
int l = 0;
|
||||||
|
unsigned i;
|
||||||
|
for (i = 0; i < GRUB_RELOCATOR_FIRMWARE_REQUESTS_QUANT; i++)
|
||||||
|
{
|
||||||
|
if (l != ((cur->freebytes[i / 8] >> (i % 8)) & 1))
|
||||||
|
maxevents++;
|
||||||
|
l = ((cur->freebytes[i / 8] >> (i % 8)) & 1);
|
||||||
|
}
|
||||||
|
if (l)
|
||||||
|
maxevents++;
|
||||||
|
}
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
events = grub_malloc (maxevents * sizeof (events[0]));
|
events = grub_malloc (maxevents * sizeof (events[0]));
|
||||||
|
@ -478,10 +497,35 @@ malloc_in_range (struct grub_relocator *rel,
|
||||||
N++;
|
N++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
#if GRUB_RELOCATOR_HAVE_FIRMWARE_REQUESTS
|
|
||||||
N += grub_relocator_firmware_fill_events (events + N);
|
N += grub_relocator_firmware_fill_events (events + N);
|
||||||
|
|
||||||
|
{
|
||||||
|
struct grub_relocator_fw_leftover *cur;
|
||||||
|
for (cur = leftovers; cur; cur = cur->next)
|
||||||
|
{
|
||||||
|
unsigned i;
|
||||||
|
int l = 0;
|
||||||
|
for (i = 0; i < GRUB_RELOCATOR_FIRMWARE_REQUESTS_QUANT; i++)
|
||||||
|
{
|
||||||
|
if (l != ((cur->freebytes[i / 8] >> (i % 8)) & 1))
|
||||||
|
{
|
||||||
|
events[N].type = l ? REG_LEFTOVER_END : REG_LEFTOVER_START;
|
||||||
|
events[N].pos = cur->quantstart + i;
|
||||||
|
events[N].leftover = cur;
|
||||||
|
N++;
|
||||||
|
}
|
||||||
|
l = ((cur->freebytes[i / 8] >> (i % 8)) & 1);
|
||||||
|
}
|
||||||
|
if (l)
|
||||||
|
{
|
||||||
|
events[N].type = REG_LEFTOVER_END;
|
||||||
|
events[N].pos = cur->quantstart + i;
|
||||||
|
events[N].leftover = cur;
|
||||||
|
N++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* No malloc from this point. */
|
/* No malloc from this point. */
|
||||||
|
@ -539,6 +583,8 @@ malloc_in_range (struct grub_relocator *rel,
|
||||||
eventt = events;
|
eventt = events;
|
||||||
events = t;
|
events = t;
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
unsigned i;
|
||||||
for (i = 0; i < (BITS_IN_BYTE * sizeof (grub_addr_t) / DIGITSORT_BITS);
|
for (i = 0; i < (BITS_IN_BYTE * sizeof (grub_addr_t) / DIGITSORT_BITS);
|
||||||
i++)
|
i++)
|
||||||
{
|
{
|
||||||
|
@ -555,6 +601,7 @@ malloc_in_range (struct grub_relocator *rel,
|
||||||
eventt = events;
|
eventt = events;
|
||||||
events = t;
|
events = t;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#if GRUB_RELOCATOR_HAVE_FIRMWARE_REQUESTS
|
#if GRUB_RELOCATOR_HAVE_FIRMWARE_REQUESTS
|
||||||
retry:
|
retry:
|
||||||
|
@ -563,14 +610,15 @@ malloc_in_range (struct grub_relocator *rel,
|
||||||
/* Now events are nicely sorted. */
|
/* Now events are nicely sorted. */
|
||||||
{
|
{
|
||||||
int nstarted = 0, ncollisions = 0, nstartedfw = 0, nblockfw = 0;
|
int nstarted = 0, ncollisions = 0, nstartedfw = 0, nblockfw = 0;
|
||||||
|
int nlefto = 0;
|
||||||
grub_addr_t starta = 0;
|
grub_addr_t starta = 0;
|
||||||
int numstarted;
|
int numstarted;
|
||||||
for (j = from_low_priv ? 0 : N - 1; from_low_priv ? j < N : (j + 1);
|
for (j = from_low_priv ? 0 : N - 1; from_low_priv ? j < N : (j + 1);
|
||||||
from_low_priv ? j++ : j--)
|
from_low_priv ? j++ : j--)
|
||||||
{
|
{
|
||||||
int isinsidebefore, isinsideafter;
|
int isinsidebefore, isinsideafter;
|
||||||
isinsidebefore = (!ncollisions
|
isinsidebefore = (!ncollisions && (nstarted || (((nlefto || nstartedfw)
|
||||||
&& (nstarted || (nstartedfw && !nblockfw)));
|
&& !nblockfw))));
|
||||||
switch (events[j].type)
|
switch (events[j].type)
|
||||||
{
|
{
|
||||||
#if GRUB_RELOCATOR_HAVE_FIRMWARE_REQUESTS
|
#if GRUB_RELOCATOR_HAVE_FIRMWARE_REQUESTS
|
||||||
|
@ -589,6 +637,13 @@ malloc_in_range (struct grub_relocator *rel,
|
||||||
case FIRMWARE_BLOCK_END:
|
case FIRMWARE_BLOCK_END:
|
||||||
nblockfw--;
|
nblockfw--;
|
||||||
break;
|
break;
|
||||||
|
case REG_LEFTOVER_START:
|
||||||
|
nlefto++;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case REG_LEFTOVER_END:
|
||||||
|
nlefto--;
|
||||||
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
case COLLISION_START:
|
case COLLISION_START:
|
||||||
|
@ -609,8 +664,8 @@ malloc_in_range (struct grub_relocator *rel,
|
||||||
nstarted--;
|
nstarted--;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
isinsideafter = (!ncollisions
|
isinsideafter = (!ncollisions && (nstarted || ((nlefto || nstartedfw)
|
||||||
&& (nstarted || (nstartedfw && !nblockfw)));
|
&& !nblockfw)));
|
||||||
if (!isinsidebefore && isinsideafter)
|
if (!isinsidebefore && isinsideafter)
|
||||||
{
|
{
|
||||||
starta = from_low_priv ? ALIGN_UP (events[j].pos, align)
|
starta = from_low_priv ? ALIGN_UP (events[j].pos, align)
|
||||||
|
@ -647,7 +702,7 @@ malloc_in_range (struct grub_relocator *rel,
|
||||||
{
|
{
|
||||||
int inreg = 0, regbeg = 0, ncol = 0;
|
int inreg = 0, regbeg = 0, ncol = 0;
|
||||||
#if GRUB_RELOCATOR_HAVE_FIRMWARE_REQUESTS
|
#if GRUB_RELOCATOR_HAVE_FIRMWARE_REQUESTS
|
||||||
int fwin = 0, fwb = 0;
|
int fwin = 0, fwb = 0, fwlefto = 0;
|
||||||
#endif
|
#endif
|
||||||
int last_start = 0;
|
int last_start = 0;
|
||||||
for (j = 0; j < N; j++)
|
for (j = 0; j < N; j++)
|
||||||
|
@ -662,6 +717,8 @@ malloc_in_range (struct grub_relocator *rel,
|
||||||
#if GRUB_RELOCATOR_HAVE_FIRMWARE_REQUESTS
|
#if GRUB_RELOCATOR_HAVE_FIRMWARE_REQUESTS
|
||||||
else if (fwin && !fwb)
|
else if (fwin && !fwb)
|
||||||
typepre = CHUNK_TYPE_FIRMWARE;
|
typepre = CHUNK_TYPE_FIRMWARE;
|
||||||
|
else if (fwlefto && !fwb)
|
||||||
|
typepre = CHUNK_TYPE_LEFTOVER;
|
||||||
#endif
|
#endif
|
||||||
else
|
else
|
||||||
typepre = -1;
|
typepre = -1;
|
||||||
|
@ -722,6 +779,21 @@ malloc_in_range (struct grub_relocator *rel,
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case CHUNK_TYPE_LEFTOVER:
|
||||||
|
{
|
||||||
|
unsigned offstart = alloc_start
|
||||||
|
% GRUB_RELOCATOR_FIRMWARE_REQUESTS_QUANT;
|
||||||
|
unsigned offend = alloc_end
|
||||||
|
% GRUB_RELOCATOR_FIRMWARE_REQUESTS_QUANT;
|
||||||
|
struct grub_relocator_fw_leftover *lo
|
||||||
|
= events[last_start].leftover;
|
||||||
|
lo->freebytes[offstart / 8]
|
||||||
|
&= ((1 << (8 - (start % 8))) - 1);
|
||||||
|
grub_memset (lo->freebytes + (offstart + 7) / 8, 0,
|
||||||
|
offend / 8 - (offstart + 7) / 8);
|
||||||
|
lo->freebytes[offend / 8] &= ~((1 << (offend % 8)) - 1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
nallocs++;
|
nallocs++;
|
||||||
|
@ -757,6 +829,14 @@ malloc_in_range (struct grub_relocator *rel,
|
||||||
fwin--;
|
fwin--;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case REG_LEFTOVER_START:
|
||||||
|
fwlefto++;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case REG_LEFTOVER_END:
|
||||||
|
fwlefto--;
|
||||||
|
break;
|
||||||
|
|
||||||
case FIRMWARE_BLOCK_START:
|
case FIRMWARE_BLOCK_START:
|
||||||
fwb++;
|
fwb++;
|
||||||
break;
|
break;
|
||||||
|
@ -797,7 +877,7 @@ malloc_in_range (struct grub_relocator *rel,
|
||||||
int last_start = 0;
|
int last_start = 0;
|
||||||
int inreg = 0, regbeg = 0, ncol = 0;
|
int inreg = 0, regbeg = 0, ncol = 0;
|
||||||
#if GRUB_RELOCATOR_HAVE_FIRMWARE_REQUESTS
|
#if GRUB_RELOCATOR_HAVE_FIRMWARE_REQUESTS
|
||||||
int fwin = 0, fwb = 0;
|
int fwin = 0, fwlefto = 0, fwb = 0;
|
||||||
#endif
|
#endif
|
||||||
unsigned cural = 0;
|
unsigned cural = 0;
|
||||||
int oom = 0;
|
int oom = 0;
|
||||||
|
@ -818,6 +898,8 @@ malloc_in_range (struct grub_relocator *rel,
|
||||||
#if GRUB_RELOCATOR_HAVE_FIRMWARE_REQUESTS
|
#if GRUB_RELOCATOR_HAVE_FIRMWARE_REQUESTS
|
||||||
else if (fwin && !fwb)
|
else if (fwin && !fwb)
|
||||||
typepre = CHUNK_TYPE_FIRMWARE;
|
typepre = CHUNK_TYPE_FIRMWARE;
|
||||||
|
else if (fwlefto && !fwb)
|
||||||
|
typepre = CHUNK_TYPE_LEFTOVER;
|
||||||
#endif
|
#endif
|
||||||
else
|
else
|
||||||
typepre = -1;
|
typepre = -1;
|
||||||
|
@ -931,6 +1013,12 @@ malloc_in_range (struct grub_relocator *rel,
|
||||||
curschu->pre = lo1;
|
curschu->pre = lo1;
|
||||||
curschu->post = lo2;
|
curschu->post = lo2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (typepre == CHUNK_TYPE_LEFTOVER)
|
||||||
|
{
|
||||||
|
curschu->pre = events[last_start].leftover;
|
||||||
|
curschu->post = events[last_start].leftover;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
if (!oom)
|
if (!oom)
|
||||||
cural++;
|
cural++;
|
||||||
|
@ -965,6 +1053,14 @@ malloc_in_range (struct grub_relocator *rel,
|
||||||
fwin--;
|
fwin--;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case REG_LEFTOVER_START:
|
||||||
|
fwlefto++;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case REG_LEFTOVER_END:
|
||||||
|
fwlefto--;
|
||||||
|
break;
|
||||||
|
|
||||||
case FIRMWARE_BLOCK_START:
|
case FIRMWARE_BLOCK_START:
|
||||||
fwb++;
|
fwb++;
|
||||||
break;
|
break;
|
||||||
|
@ -983,6 +1079,7 @@ malloc_in_range (struct grub_relocator *rel,
|
||||||
}
|
}
|
||||||
if (oom)
|
if (oom)
|
||||||
{
|
{
|
||||||
|
unsigned i;
|
||||||
for (i = 0; i < cural; i++)
|
for (i = 0; i < cural; i++)
|
||||||
free_subchunk (&res->subchunks[i]);
|
free_subchunk (&res->subchunks[i]);
|
||||||
grub_free (res->subchunks);
|
grub_free (res->subchunks);
|
||||||
|
|
|
@ -32,6 +32,8 @@ pkglib_DATA="@pkglib_DATA@"
|
||||||
|
|
||||||
coreboot_dir=${libdir}/$(echo ${PACKAGE_TARNAME} | sed ${transform})/${target_cpu}-coreboot
|
coreboot_dir=${libdir}/$(echo ${PACKAGE_TARNAME} | sed ${transform})/${target_cpu}-coreboot
|
||||||
pc_dir=${libdir}/$(echo ${PACKAGE_TARNAME} | sed ${transform})/${target_cpu}-pc
|
pc_dir=${libdir}/$(echo ${PACKAGE_TARNAME} | sed ${transform})/${target_cpu}-pc
|
||||||
|
efi32_dir=${libdir}/$(echo ${PACKAGE_TARNAME} | sed ${transform})/i386-efi
|
||||||
|
efi64_dir=${libdir}/$(echo ${PACKAGE_TARNAME} | sed ${transform})/x86_64-efi
|
||||||
|
|
||||||
# Usage: usage
|
# Usage: usage
|
||||||
# Print the usage.
|
# Print the usage.
|
||||||
|
@ -128,13 +130,23 @@ if [ "${override_dir}" = "" ] ; then
|
||||||
if test -e "${pc_dir}" ; then
|
if test -e "${pc_dir}" ; then
|
||||||
process_input_dir ${pc_dir} pc
|
process_input_dir ${pc_dir} pc
|
||||||
fi
|
fi
|
||||||
|
if test -e "${efi32_dir}" ; then
|
||||||
|
process_input_dir ${efi32_dir} efi32
|
||||||
|
fi
|
||||||
|
if test -e "${efi64_dir}" ; then
|
||||||
|
process_input_dir ${efi64_dir} efi64
|
||||||
|
fi
|
||||||
else
|
else
|
||||||
process_input_dir ${override_dir} ${native_platform}
|
process_input_dir ${override_dir} ${native_platform}
|
||||||
coreboot_dir=
|
coreboot_dir=
|
||||||
pc_dir=
|
pc_dir=
|
||||||
case "${native_platform}" in
|
efi32_dir=
|
||||||
coreboot) coreboot_dir=${override_dir} ;;
|
efi64_dir=
|
||||||
pc) pc_dir=${override_dir} ;;
|
case "${target_cpu}-${native_platform}" in
|
||||||
|
i386-coreboot) coreboot_dir=${override_dir} ;;
|
||||||
|
i386-pc) pc_dir=${override_dir} ;;
|
||||||
|
i386-efi) efi32_dir=${override_dir} ;;
|
||||||
|
x86_64-efi) efi64_dir=${override_dir} ;;
|
||||||
esac
|
esac
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
@ -191,6 +203,33 @@ if test -e "${pc_dir}" ; then
|
||||||
--embedded-boot ${embed_img}"
|
--embedded-boot ${embed_img}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if test -e "${efi64_dir}" || test -e "${efi32_dir}"; then
|
||||||
|
efi_dir=`mktemp -d "$MKTEMP_TEMPLATE"`
|
||||||
|
mkdir -p "${efi_dir}/efi/boot"
|
||||||
|
else
|
||||||
|
efi_dir=
|
||||||
|
fi
|
||||||
|
|
||||||
|
# build bootx64.efi
|
||||||
|
if test -e "${efi64_dir}" ; then
|
||||||
|
echo "Generates bootx64.efi"
|
||||||
|
grub-mkimage -d "${efi64_dir}" -o "${efi_dir}"/efi/boot/bootx64.efi --prefix=/boot/grub/x86_64-efi \
|
||||||
|
search iso9660 configfile sh
|
||||||
|
|
||||||
|
modules="$(cat "${efi64_dir}"/partmap.lst) ${modules}"
|
||||||
|
(for i in ${modules} ; do
|
||||||
|
echo "insmod $i"
|
||||||
|
done ; \
|
||||||
|
echo "source /boot/grub/grub.cfg") \
|
||||||
|
> "${iso9660_dir}"/boot/grub/x86_64-efi/grub.cfg
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test x"${efi_dir}" != x; then
|
||||||
|
mformat -C -f 2880 -L 16 -i "${iso9660_dir}"/efi.img ::
|
||||||
|
mcopy -s -i "${iso9660_dir}"/efi.img ${efi_dir}/efi ::/
|
||||||
|
grub_mkisofs_arguments="${grub_mkisofs_arguments} --efi-boot efi.img"
|
||||||
|
fi
|
||||||
|
|
||||||
# build iso image
|
# build iso image
|
||||||
grub-mkisofs ${grub_mkisofs_arguments} --protective-msdos-label -o ${output_image} -r ${iso9660_dir} ${source}
|
grub-mkisofs ${grub_mkisofs_arguments} --protective-msdos-label -o ${output_image} -r ${iso9660_dir} ${source}
|
||||||
rm -rf ${iso9660_dir}
|
rm -rf ${iso9660_dir}
|
||||||
|
|
Loading…
Reference in a new issue