summaryrefslogtreecommitdiff
path: root/com32/lib/syslinux/shuffle.c
diff options
context:
space:
mode:
Diffstat (limited to 'com32/lib/syslinux/shuffle.c')
-rw-r--r--com32/lib/syslinux/shuffle.c32
1 files changed, 21 insertions, 11 deletions
diff --git a/com32/lib/syslinux/shuffle.c b/com32/lib/syslinux/shuffle.c
index ad6e7d06..22719544 100644
--- a/com32/lib/syslinux/shuffle.c
+++ b/com32/lib/syslinux/shuffle.c
@@ -42,23 +42,21 @@ struct shuffle_descriptor {
uint32_t dst, src, len;
};
-int syslinux_prepare_shuffle(struct syslinux_movelist *fraglist)
+int syslinux_prepare_shuffle(struct syslinux_movelist *fraglist,
+ struct syslinux_memmap *memmap)
{
- struct syslinux_movelist *moves = NULL, *freelist = NULL, *mp;
- int n;
+ struct syslinux_movelist *moves = NULL, *mp;
+ struct syslinux_memmap *ml;
struct shuffle_descriptor *dp;
int np, rv = -1;
- freelist = syslinux_memory_map();
- if (!freelist)
- goto bail;
-
- if (syslinux_compute_movelist(&moves, fraglist, freelist))
+ if (syslinux_compute_movelist(&moves, fraglist, memmap))
goto bail;
dp = __com32.cs_bounce;
np = 0;
+ /* Copy the move sequence into the bounce buffer */
for (mp = moves; mp; mp = mp->next) {
if (np >= 65536/12)
goto bail; /* Way too many descriptors... */
@@ -66,14 +64,26 @@ int syslinux_prepare_shuffle(struct syslinux_movelist *fraglist)
dp->dst = mp->dst;
dp->src = mp->src;
dp->len = mp->len;
- np++;
+ dp++; np++;
+ }
+
+ /* Copy any zeroing operations into the bounce buffer */
+ for (ml = memmap; ml->type != SMT_END; ml = ml->next) {
+ if (ml->type == SMT_ZERO) {
+ if (np >= 65536/12)
+ goto bail;
+
+ dp->dst = ml->start;
+ dp->src = (addr_t)-1; /* bzero this region */
+ dp->len = ml->next->start - ml->start;
+ dp++; np++;
+ }
}
rv = np;
bail:
- if (freelist)
- syslinux_free_movelist(freelist);
+ /* This is safe only because free() doesn't use the bounce buffer!!!! */
if (moves)
syslinux_free_movelist(moves);