|  | @@ -346,13 +346,24 @@ static void bzimage_parse_cpio_cmdline ( struct image *image,
 | 
		
	
		
			
			| 346 | 346 |  	}
 | 
		
	
		
			
			| 347 | 347 |  }
 | 
		
	
		
			
			| 348 | 348 |  
 | 
		
	
		
			
			|  | 349 | +/**
 | 
		
	
		
			
			|  | 350 | + * Align initrd length
 | 
		
	
		
			
			|  | 351 | + *
 | 
		
	
		
			
			|  | 352 | + * @v len		Length
 | 
		
	
		
			
			|  | 353 | + * @ret len		Length rounded up to INITRD_ALIGN
 | 
		
	
		
			
			|  | 354 | + */
 | 
		
	
		
			
			|  | 355 | +static inline size_t bzimage_align ( size_t len ) {
 | 
		
	
		
			
			|  | 356 | +
 | 
		
	
		
			
			|  | 357 | +	return ( ( len + INITRD_ALIGN - 1 ) & ~( INITRD_ALIGN - 1 ) );
 | 
		
	
		
			
			|  | 358 | +}
 | 
		
	
		
			
			|  | 359 | +
 | 
		
	
		
			
			| 349 | 360 |  /**
 | 
		
	
		
			
			| 350 | 361 |   * Load initrd
 | 
		
	
		
			
			| 351 | 362 |   *
 | 
		
	
		
			
			| 352 | 363 |   * @v image		bzImage image
 | 
		
	
		
			
			| 353 | 364 |   * @v initrd		initrd image
 | 
		
	
		
			
			| 354 | 365 |   * @v address		Address at which to load, or UNULL
 | 
		
	
		
			
			| 355 |  | - * @ret len		Length of loaded image, rounded up to INITRD_ALIGN
 | 
		
	
		
			
			|  | 366 | + * @ret len		Length of loaded image, excluding zero-padding
 | 
		
	
		
			
			| 356 | 367 |   */
 | 
		
	
		
			
			| 357 | 368 |  static size_t bzimage_load_initrd ( struct image *image,
 | 
		
	
		
			
			| 358 | 369 |  				    struct image *initrd,
 | 
		
	
	
		
			
			|  | @@ -408,11 +419,10 @@ static size_t bzimage_load_initrd ( struct image *image,
 | 
		
	
		
			
			| 408 | 419 |  	}
 | 
		
	
		
			
			| 409 | 420 |  	offset += initrd->len;
 | 
		
	
		
			
			| 410 | 421 |  
 | 
		
	
		
			
			| 411 |  | -	/* Round up to multiple of INITRD_ALIGN and zero-pad */
 | 
		
	
		
			
			|  | 422 | +	/* Zero-pad to next INITRD_ALIGN boundary */
 | 
		
	
		
			
			| 412 | 423 |  	pad_len = ( ( -offset ) & ( INITRD_ALIGN - 1 ) );
 | 
		
	
		
			
			| 413 | 424 |  	if ( address )
 | 
		
	
		
			
			| 414 | 425 |  		memset_user ( address, offset, 0, pad_len );
 | 
		
	
		
			
			| 415 |  | -	offset += pad_len;
 | 
		
	
		
			
			| 416 | 426 |  
 | 
		
	
		
			
			| 417 | 427 |  	return offset;
 | 
		
	
		
			
			| 418 | 428 |  }
 | 
		
	
	
		
			
			|  | @@ -440,6 +450,7 @@ static int bzimage_check_initrds ( struct image *image,
 | 
		
	
		
			
			| 440 | 450 |  
 | 
		
	
		
			
			| 441 | 451 |  		/* Calculate length */
 | 
		
	
		
			
			| 442 | 452 |  		len += bzimage_load_initrd ( image, initrd, UNULL );
 | 
		
	
		
			
			|  | 453 | +		len = bzimage_align ( len );
 | 
		
	
		
			
			| 443 | 454 |  
 | 
		
	
		
			
			| 444 | 455 |  		DBGC ( image, "bzImage %p initrd %p from [%#08lx,%#08lx)%s%s\n",
 | 
		
	
		
			
			| 445 | 456 |  		       image, initrd, user_to_phys ( initrd->data, 0 ),
 | 
		
	
	
		
			
			|  | @@ -487,6 +498,7 @@ static void bzimage_load_initrds ( struct image *image,
 | 
		
	
		
			
			| 487 | 498 |  	struct image *other;
 | 
		
	
		
			
			| 488 | 499 |  	userptr_t top;
 | 
		
	
		
			
			| 489 | 500 |  	userptr_t dest;
 | 
		
	
		
			
			|  | 501 | +	size_t offset;
 | 
		
	
		
			
			| 490 | 502 |  	size_t len;
 | 
		
	
		
			
			| 491 | 503 |  
 | 
		
	
		
			
			| 492 | 504 |  	/* Reshuffle initrds into desired order */
 | 
		
	
	
		
			
			|  | @@ -505,9 +517,7 @@ static void bzimage_load_initrds ( struct image *image,
 | 
		
	
		
			
			| 505 | 517 |  		return;
 | 
		
	
		
			
			| 506 | 518 |  
 | 
		
	
		
			
			| 507 | 519 |  	/* Find highest usable address */
 | 
		
	
		
			
			| 508 |  | -	top = userptr_add ( highest->data,
 | 
		
	
		
			
			| 509 |  | -			    ( ( highest->len + INITRD_ALIGN - 1 ) &
 | 
		
	
		
			
			| 510 |  | -			      ~( INITRD_ALIGN - 1 ) ) );
 | 
		
	
		
			
			|  | 520 | +	top = userptr_add ( highest->data, bzimage_align ( highest->len ) );
 | 
		
	
		
			
			| 511 | 521 |  	if ( user_to_phys ( top, 0 ) > bzimg->mem_limit )
 | 
		
	
		
			
			| 512 | 522 |  		top = phys_to_user ( bzimg->mem_limit );
 | 
		
	
		
			
			| 513 | 523 |  	DBGC ( image, "bzImage %p loading initrds from %#08lx downwards\n",
 | 
		
	
	
		
			
			|  | @@ -519,23 +529,27 @@ static void bzimage_load_initrds ( struct image *image,
 | 
		
	
		
			
			| 519 | 529 |  		/* Calculate cumulative length of following
 | 
		
	
		
			
			| 520 | 530 |  		 * initrds (including padding).
 | 
		
	
		
			
			| 521 | 531 |  		 */
 | 
		
	
		
			
			| 522 |  | -		len = 0;
 | 
		
	
		
			
			|  | 532 | +		offset = 0;
 | 
		
	
		
			
			| 523 | 533 |  		for_each_image ( other ) {
 | 
		
	
		
			
			| 524 | 534 |  			if ( other == initrd )
 | 
		
	
		
			
			| 525 |  | -				len = 0;
 | 
		
	
		
			
			| 526 |  | -			len += bzimage_load_initrd ( image, other, UNULL );
 | 
		
	
		
			
			|  | 535 | +				offset = 0;
 | 
		
	
		
			
			|  | 536 | +			offset += bzimage_load_initrd ( image, other, UNULL );
 | 
		
	
		
			
			|  | 537 | +			offset = bzimage_align ( offset );
 | 
		
	
		
			
			| 527 | 538 |  		}
 | 
		
	
		
			
			| 528 | 539 |  
 | 
		
	
		
			
			| 529 | 540 |  		/* Load initrd at this address */
 | 
		
	
		
			
			| 530 |  | -		dest = userptr_add ( top, -len );
 | 
		
	
		
			
			| 531 |  | -		bzimage_load_initrd ( image, initrd, dest );
 | 
		
	
		
			
			|  | 541 | +		dest = userptr_add ( top, -offset );
 | 
		
	
		
			
			|  | 542 | +		len = bzimage_load_initrd ( image, initrd, dest );
 | 
		
	
		
			
			| 532 | 543 |  
 | 
		
	
		
			
			| 533 | 544 |  		/* Record initrd location */
 | 
		
	
		
			
			| 534 |  | -		if ( ! bzimg->ramdisk_image ) {
 | 
		
	
		
			
			|  | 545 | +		if ( ! bzimg->ramdisk_image )
 | 
		
	
		
			
			| 535 | 546 |  			bzimg->ramdisk_image = user_to_phys ( dest, 0 );
 | 
		
	
		
			
			| 536 |  | -			bzimg->ramdisk_size = len;
 | 
		
	
		
			
			| 537 |  | -		}
 | 
		
	
		
			
			|  | 547 | +		bzimg->ramdisk_size = ( user_to_phys ( dest, len ) -
 | 
		
	
		
			
			|  | 548 | +					bzimg->ramdisk_image );
 | 
		
	
		
			
			| 538 | 549 |  	}
 | 
		
	
		
			
			|  | 550 | +	DBGC ( image, "bzImage %p initrds at [%#08lx,%#08lx)\n",
 | 
		
	
		
			
			|  | 551 | +	       image, bzimg->ramdisk_image,
 | 
		
	
		
			
			|  | 552 | +	       ( bzimg->ramdisk_image + bzimg->ramdisk_size ) );
 | 
		
	
		
			
			| 539 | 553 |  }
 | 
		
	
		
			
			| 540 | 554 |  
 | 
		
	
		
			
			| 541 | 555 |  /**
 |