summaryrefslogtreecommitdiff
path: root/com32/lib/syslinux/load_linux.c
diff options
context:
space:
mode:
Diffstat (limited to 'com32/lib/syslinux/load_linux.c')
-rw-r--r--com32/lib/syslinux/load_linux.c29
1 files changed, 22 insertions, 7 deletions
diff --git a/com32/lib/syslinux/load_linux.c b/com32/lib/syslinux/load_linux.c
index 620ad081..b8d5a732 100644
--- a/com32/lib/syslinux/load_linux.c
+++ b/com32/lib/syslinux/load_linux.c
@@ -93,8 +93,10 @@ static addr_t initramfs_size(struct initramfs *initramfs)
if (!initramfs)
return 0;
- for (ip = initramfs->next; ip->len; ip = ip->next)
+ for (ip = initramfs->next; ip->len; ip = ip->next) {
+ size = (size+ip->align-1) & ~(ip->align-1); /* Alignment */
size += ip->len;
+ }
return size;
}
@@ -106,18 +108,30 @@ static int map_initramfs(struct syslinux_movelist **fraglist,
addr_t addr)
{
struct initramfs *ip;
+ addr_t next_addr, len, pad;
for (ip = initramfs->next; ip->len; ip = ip->next) {
+ len = ip->len;
+ next_addr = addr+len;
+
+ /* If this isn't the last entry, extend the zero-pad region
+ to enforce the alignment of the next chunk. */
+ if (ip->next->len) {
+ pad = -next_addr & (ip->next->align-1);
+ len += pad;
+ next_addr += pad;
+ }
+
if (ip->data_len) {
- if (syslinux_add_movelist(fraglist, addr, (addr_t)ip->data, ip->len))
+ if (syslinux_add_movelist(fraglist, addr, (addr_t)ip->data, len))
return -1;
}
- if (ip->len > ip->data_len) {
+ if (len > ip->data_len) {
if (syslinux_add_memmap(mmap, addr+ip->data_len,
- ip->len-ip->data_len, SMT_ZERO))
+ len-ip->data_len, SMT_ZERO))
return -1;
}
- addr += ip->len;
+ addr = next_addr;
}
return 0;
@@ -253,13 +267,14 @@ int syslinux_boot_linux(void *kernel_buf, size_t kernel_size,
if (irf_size) {
addr_t best_addr = 0;
struct syslinux_memmap *ml;
+ const addr_t align_mask = INITRAMFS_MAX_ALIGN-1;
if (irf_size) {
for (ml = amap; ml->type != SMT_END; ml = ml->next) {
- addr_t adj_start = (ml->start+0xfff) & ~0xfff; /* Page-aligned */
+ addr_t adj_start = (ml->start+align_mask) & ~align_mask;
if (ml->type == SMT_FREE &&
ml->next->start - adj_start >= irf_size)
- best_addr = (ml->next->start - irf_size) & ~0xfff;
+ best_addr = (ml->next->start - irf_size) & ~align_mask;
}
if (!best_addr)