linux.c32: fix initrd alignment
authorH. Peter Anvin <hpa@zytor.com>
Thu, 12 Mar 2009 20:50:03 +0000 (13:50 -0700)
committerH. Peter Anvin <hpa@zytor.com>
Thu, 12 Mar 2009 20:54:08 +0000 (13:54 -0700)
Impact: fix boot failure on Dell E6500 and possibly other platforms

Linux may not be able to access a part of an initrd which resides in a
page that is part RAM, part non-RAM.  Make sure we round the end of
the memory range we want to use down to a page boundary (as well as
round the start up.)

Reported-by: Pierre-Alexandre Meyer <pierre@mouraf.org>
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
com32/lib/syslinux/load_linux.c

index b772056..cca2efd 100644 (file)
@@ -1,6 +1,6 @@
 /* ----------------------------------------------------------------------- *
  *
- *   Copyright 2007-2008 H. Peter Anvin - All Rights Reserved
+ *   Copyright 2007-2009 H. Peter Anvin - All Rights Reserved
  *
  *   Permission is hereby granted, free of charge, to any person
  *   obtaining a copy of this software and associated documentation
@@ -290,9 +290,9 @@ int syslinux_boot_linux(void *kernel_buf, size_t kernel_size,
     if (irf_size) {
       for (ml = amap; ml->type != SMT_END; ml = ml->next) {
        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) & ~align_mask;
+       addr_t adj_end   = ml->next->start & ~align_mask;
+       if (ml->type == SMT_FREE && adj_end-adj_start >= irf_size)
+         best_addr = (adj_end - irf_size) & ~align_mask;
       }
 
       if (!best_addr)