summary refs log tree commit diff
path: root/x86_64
diff options
context:
space:
mode:
authorDaniel Verkamp <dverkamp@chromium.org>2019-05-17 10:55:45 -0700
committerchrome-bot <chrome-bot@chromium.org>2019-05-20 15:47:23 -0700
commit3007ff3cf408f9e6a2e0731a4fa7d6f8f65dfa47 (patch)
tree339cc27c92c02bb818f4d30550ba090ddd020e19 /x86_64
parentbe1ad40a0e698a0b6c483d0162cd80df6ce78ed8 (diff)
downloadcrosvm-3007ff3cf408f9e6a2e0731a4fa7d6f8f65dfa47.tar
crosvm-3007ff3cf408f9e6a2e0731a4fa7d6f8f65dfa47.tar.gz
crosvm-3007ff3cf408f9e6a2e0731a4fa7d6f8f65dfa47.tar.bz2
crosvm-3007ff3cf408f9e6a2e0731a4fa7d6f8f65dfa47.tar.lz
crosvm-3007ff3cf408f9e6a2e0731a4fa7d6f8f65dfa47.tar.xz
crosvm-3007ff3cf408f9e6a2e0731a4fa7d6f8f65dfa47.tar.zst
crosvm-3007ff3cf408f9e6a2e0731a4fa7d6f8f65dfa47.zip
x86_64: load initrd at max address
This matches behavior of other bootloaders (grub2, iPXE), and the kernel
seems to be relying on this; decompression of the initrd fails if the
initrd is loaded right after the kernel as before, but succeeds if
loaded at the maximum address.

BUG=None
TEST=Boot Debian kernel + initrd on workstation

Change-Id: If7712efb05f55ef413a419dfe276ed3f68c335b7
Signed-off-by: Daniel Verkamp <dverkamp@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/1616989
Tested-by: kokoro <noreply+kokoro@google.com>
Legacy-Commit-Queue: Commit Bot <commit-bot@chromium.org>
Reviewed-by: Dylan Reid <dgreid@chromium.org>
Diffstat (limited to 'x86_64')
-rw-r--r--x86_64/src/lib.rs22
1 files changed, 16 insertions, 6 deletions
diff --git a/x86_64/src/lib.rs b/x86_64/src/lib.rs
index eafdc61..0a2185c 100644
--- a/x86_64/src/lib.rs
+++ b/x86_64/src/lib.rs
@@ -458,16 +458,26 @@ impl X8664arch {
 
         let initrd = match initrd_file {
             Some(mut initrd_file) => {
-                let initrd_start = free_addr;
-                let initrd_max_size = mem_size - initrd_start;
-                let initrd_size = arch::load_image(
+                let mut initrd_addr_max = u64::from(params.hdr.initrd_addr_max);
+                // Default initrd_addr_max for old kernels (see Documentation/x86/boot.txt).
+                if initrd_addr_max == 0 {
+                    initrd_addr_max = 0x37FFFFFF;
+                }
+
+                let mem_max = mem.end_addr().offset() - 1;
+                if initrd_addr_max > mem_max {
+                    initrd_addr_max = mem_max;
+                }
+
+                let (initrd_start, initrd_size) = arch::load_image_high(
                     mem,
                     &mut initrd_file,
-                    GuestAddress(initrd_start),
-                    initrd_max_size,
+                    GuestAddress(free_addr),
+                    GuestAddress(initrd_addr_max),
+                    sys_util::pagesize() as u64,
                 )
                 .map_err(Error::LoadInitrd)?;
-                Some((GuestAddress(initrd_start), initrd_size))
+                Some((initrd_start, initrd_size))
             }
             None => None,
         };