aboutsummaryrefslogtreecommitdiffstats
path: root/src/arch/i386/image
diff options
context:
space:
mode:
authorMichael Brown <mcb30@ipxe.org>2013-06-05 14:01:40 +0100
committerMichael Brown <mcb30@ipxe.org>2013-06-05 14:11:43 +0100
commitc825a9b39dddcdc8e403435f9984ef8be11967bc (patch)
tree999d31291a0b16b4035e4f930b0c9d7709997ef1 /src/arch/i386/image
parent0036fdd5c5a232662d07c6d1310241f4c5b6ab83 (diff)
downloadipxe-c825a9b39dddcdc8e403435f9984ef8be11967bc.tar.gz
[bzimage] Align initrd images to page boundary
Some versions of Linux apparently complain if initrds are not aligned to a page boundary. Fix by changing INITRD_ALIGN from 4 bytes to 4096 bytes. The amount of padding at the end of each initrd will now often be sufficient to allow the cpio header to be prepended without crossing an alignment boundary. The final location of the initrd may therefore end up being slightly higher than the post-shuffle location. bzimage_load_initrd() must therefore now copy the initrd body prior to copying the cpio header, otherwise the start of the initrd body may be overwritten by the cpio header. (Note that the guarantee that an initrd will never need to overwrite an initrd at a higher location still holds, since the overall length of each initrd cannot decrease as a result of adding a cpio header.) Reported-by: Dave Hansen <dave@sr71.net> Signed-off-by: Michael Brown <mcb30@ipxe.org>
Diffstat (limited to 'src/arch/i386/image')
-rw-r--r--src/arch/i386/image/bzimage.c30
1 files changed, 13 insertions, 17 deletions
diff --git a/src/arch/i386/image/bzimage.c b/src/arch/i386/image/bzimage.c
index 12be1779..3b484b17 100644
--- a/src/arch/i386/image/bzimage.c
+++ b/src/arch/i386/image/bzimage.c
@@ -360,7 +360,7 @@ static size_t bzimage_load_initrd ( struct image *image,
char *filename = initrd->cmdline;
char *cmdline;
struct cpio_header cpio;
- size_t offset = 0;
+ size_t offset;
size_t name_len;
size_t pad_len;
@@ -368,7 +368,7 @@ static size_t bzimage_load_initrd ( struct image *image,
if ( initrd == image )
return 0;
- /* Create cpio header before non-prebuilt images */
+ /* Create cpio header for non-prebuilt images */
if ( filename && filename[0] ) {
cmdline = strchr ( filename, ' ' );
name_len = ( ( cmdline ? ( ( size_t ) ( cmdline - filename ) )
@@ -383,24 +383,20 @@ static size_t bzimage_load_initrd ( struct image *image,
bzimage_parse_cpio_cmdline ( image, &cpio,
( cmdline + 1 /* ' ' */ ));
}
- if ( address ) {
- copy_to_user ( address, offset, &cpio,
- sizeof ( cpio ) );
- }
- offset += sizeof ( cpio );
- if ( address ) {
- memset_user ( address, offset, 0, name_len );
- copy_to_user ( address, offset, filename,
- ( name_len - 1 /* NUL (or space) */ ) );
- }
- offset += name_len;
- offset = ( ( offset + 0x03 ) & ~0x03 );
+ offset = ( ( sizeof ( cpio ) + name_len + 0x03 ) & ~0x03 );
+ } else {
+ offset = 0;
}
- /* Copy in initrd image body */
- if ( address )
- memmove_user ( address, offset, initrd->data, 0, initrd->len );
+ /* Copy in initrd image body (and cpio header if applicable) */
if ( address ) {
+ memmove_user ( address, offset, initrd->data, 0, initrd->len );
+ if ( offset ) {
+ memset_user ( address, 0, 0, offset );
+ copy_to_user ( address, 0, &cpio, sizeof ( cpio ) );
+ copy_to_user ( address, sizeof ( cpio ), filename,
+ ( name_len - 1 /* NUL (or space) */ ) );
+ }
DBGC ( image, "bzImage %p initrd %p [%#08lx,%#08lx,%#08lx)"
"%s%s\n", image, initrd, user_to_phys ( address, 0 ),
user_to_phys ( address, offset ),