- DBGC ( image, "bzImage %p loading initrd %p (%s)\n",
- image, initrd, initrd->name );
-
- /* Find a suitable start address */
- if ( ( start + initrd->len ) <= exec_ctx->mem_limit ) {
- /* Just use initrd in situ */
- DBGC ( image, "bzImage %p using initrd as [%lx,%lx)\n",
- image, start, ( start + initrd->len ) );
- } else {
- for ( ; ; start -= 0x100000 ) {
- /* Check that we're not going to overwrite the
- * kernel itself. This check isn't totally
- * accurate, but errs on the side of caution.
- */
- if ( start <= ( BZI_LOAD_HIGH_ADDR + image->len ) ) {
- DBGC ( image, "bzImage %p could not find a "
- "location for initrd\n", image );
- return -ENOBUFS;
- }
- /* Check that we are within the kernel's range */
- if ( ( start + initrd->len ) > exec_ctx->mem_limit )
- continue;
- /* Prepare and verify segment */
- if ( ( rc = prep_segment ( phys_to_user ( start ),
- initrd->len,
- initrd->len ) ) != 0 )
- continue;
- /* Copy to segment */
- DBGC ( image, "bzImage %p relocating initrd to "
- "[%lx,%lx)\n", image, start,
- ( start + initrd->len ) );
- memcpy_user ( phys_to_user ( start ), 0,
- initrd->data, 0, initrd->len );
- break;
+ /* Add up length of all initrd images */
+ for_each_image ( initrd ) {
+ if ( initrd->type != &initrd_image_type )
+ continue;
+ initrd_len = ( ( image->len + 0x0f ) & ~0x0f );
+ total_len += initrd_len;
+ }
+
+ if ( ! total_len )
+ return 0;
+
+ /* Find a suitable start address. Try 1MB boundaries,
+ * starting from the downloaded kernel image itself and
+ * working downwards until we hit an available region.
+ */
+ for ( start = ( user_to_phys ( image->data, 0 ) & ~0xfffff ) ; ;
+ start -= 0x100000 ) {
+ /* Check that we're not going to overwrite the
+ * kernel itself. This check isn't totally
+ * accurate, but errs on the side of caution.
+ */
+ if ( start <= ( BZI_LOAD_HIGH_ADDR + image->len ) ) {
+ DBGC ( image, "bzImage %p could not find a location "
+ "for initrd\n", image );
+ return -ENOBUFS;