From 475bf447ccab91e11ddfc3445606d7debb3c71ed Mon Sep 17 00:00:00 2001 From: Che-Liang Chiou Date: Mon, 23 Aug 2010 11:20:44 +0800 Subject: [PATCH] Add fake e820 memory map entries to zeropage BUG=chromium-os:4521 TEST=manual This patch set adds two e820 memory map entries to kernel's zeropage to trick kernel into booting; otherwise kernel will choke on missing e820 memory map. The added e820 memory map entries should let kernel boot and should not make the memory map differ from that without the added entries. Test Procedure: 1. Boot your test machine and save dmesg output, referred to as LOG1. 2. Apply the following one-line patch and then compile and install kernel. 3. Apply this patch set and re-build zeropage on kernel partition. 4. Boot the test machine and save dmesg output, referred to as LOG2. LOG1 would contain the following messages (the exactly addresses of memory map should differ slightly). ... [ 0.000000] BIOS-provided physical RAM map: [ 0.000000] bootconsole [earlyser0] enabled ... [ 0.000000] modified physical RAM map: [ 0.000000] modified: 0000000000000000 - 0000000000002000 (usable) [ 0.000000] modified: 0000000000002000 - 0000000000006000 (reserved) [ 0.000000] modified: 0000000000006000 - 000000000008f000 (usable) [ 0.000000] modified: 000000000008f000 - 0000000000090000 (ACPI NVS) [ 0.000000] modified: 0000000000090000 - 00000000000a0000 (usable) [ 0.000000] modified: 0000000000100000 - 0000000000f00000 (usable) [ 0.000000] modified: 0000000001000000 - 000000003f33f000 (usable) [ 0.000000] modified: 000000003f33f000 - 000000003f4bf000 (reserved) [ 0.000000] modified: 000000003f4bf000 - 000000003f5bf000 (ACPI NVS) [ 0.000000] modified: 000000003f5bf000 - 000000003f5f7000 (ACPI data) [ 0.000000] modified: 000000003f5f7000 - 000000003f600000 (usable) [ 0.000000] modified: 00000000fed1c000 - 00000000fed20000 (reserved) [ 0.000000] modified: 00000000ffc00000 - 0000000100000000 (reserved) LOG2 would contain the following messages (the exactly addresses of memory map should differ slightly). ... [ 0.000000] BIOS-provided physical RAM map: [ 0.000000] BIOS-e820: 0000000000000000 - 0000000000001000 (usable) [ 0.000000] BIOS-e820: 00000000fffff000 - 0000000100000000 (reserved) [ 0.000000] bootconsole [earlyser0] enabled ... [ 0.000000] modified physical RAM map: [ 0.000000] modified: 0000000000000000 - 0000000000002000 (usable) [ 0.000000] modified: 0000000000002000 - 0000000000006000 (reserved) [ 0.000000] modified: 0000000000006000 - 000000000008f000 (usable) [ 0.000000] modified: 000000000008f000 - 0000000000090000 (ACPI NVS) [ 0.000000] modified: 0000000000090000 - 00000000000a0000 (usable) [ 0.000000] modified: 0000000000100000 - 0000000000f00000 (usable) [ 0.000000] modified: 0000000001000000 - 000000003f33f000 (usable) [ 0.000000] modified: 000000003f33f000 - 000000003f4bf000 (reserved) [ 0.000000] modified: 000000003f4bf000 - 000000003f5bf000 (ACPI NVS) [ 0.000000] modified: 000000003f5bf000 - 000000003f5f7000 (ACPI data) [ 0.000000] modified: 000000003f5f7000 - 000000003f600000 (usable) [ 0.000000] modified: 00000000fed1c000 - 00000000fed20000 (reserved) [ 0.000000] modified: 00000000ffc00000 - 0000000100000000 (reserved) Test result: 1. Compare the first paragraph of excerpts from LOG1 and LOG2: This shows that the fake e820 memory map entries are successfully added. 2. Compare the second paragraphs of excerpts from LOG1 and LOG2: This shows that the added entries do not modify the memory map. diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c index 49706d0..c9075ee 100644 --- a/arch/x86/kernel/e820.c +++ b/arch/x86/kernel/e820.c @@ -425,7 +425,7 @@ static int __init append_e820_map(struct e820entry *biosmap, int nr_map) { /* Only one memory region (or negative)? Ignore it */ if (nr_map < 2) - return no_e820_map_return(); + return -1; return __append_e820_map(biosmap, nr_map); } Review URL: http://codereview.chromium.org/3176019 --- utility/include/kernel_blob.h | 27 ++++++++++++++++++++------- utility/vbutil_kernel.c | 8 ++++++++ 2 files changed, 28 insertions(+), 7 deletions(-) diff --git a/utility/include/kernel_blob.h b/utility/include/kernel_blob.h index d5256aa826..e8f813eb0c 100644 --- a/utility/include/kernel_blob.h +++ b/utility/include/kernel_blob.h @@ -28,22 +28,35 @@ struct linux_kernel_header uint8_t pad1[0x0230 - 0x1f2]; } __attribute__ ((packed)); +// Simplified version of x86 kernel e820 memory map entries +#define E820_ENTRY_MAX 128 +#define E820_TYPE_RAM 1 +#define E820_TYPE_RESERVED 2 + +struct linux_kernel_e820entry { + uint64_t start_addr; + uint64_t segment_size; + uint32_t segment_type; +} __attribute__((packed)); // Simplified version of the x86 kernel zeropage table struct linux_kernel_params { - uint8_t pad0[0x01f1 - 0x0]; + uint8_t pad0[0x1e8 - 0x0]; + uint8_t n_e820_entry; // 1e8 + uint8_t pad1[0x1f1 - 0x1e9]; uint8_t setup_sects; // 1f1 - uint8_t pad1[0x1fe - 0x1f2]; + uint8_t pad2[0x1fe - 0x1f2]; uint16_t boot_flag; // 1fe - uint8_t pad2[0x210 - 0x200]; + uint8_t pad3[0x210 - 0x200]; uint8_t type_of_loader; // 210 - uint8_t pad3[0x218 - 0x211]; + uint8_t pad4[0x218 - 0x211]; uint32_t ramdisk_image; // 218 - uint32_t ramdisk_size; // 21c - uint8_t pad4[0x228 - 0x220]; + uint32_t ramdisk_size; // 21c + uint8_t pad5[0x228 - 0x220]; uint32_t cmd_line_ptr; // 228 - uint8_t pad5[0x0cd0 - 0x22c]; + uint8_t pad6[0x2d0 - 0x22c]; + struct linux_kernel_e820entry e820_entries[E820_ENTRY_MAX]; // 2d0 - cd0 } __attribute__ ((packed)); diff --git a/utility/vbutil_kernel.c b/utility/vbutil_kernel.c index 763480e35f..80197194b8 100644 --- a/utility/vbutil_kernel.c +++ b/utility/vbutil_kernel.c @@ -335,6 +335,14 @@ static blob_t *NewBlob(uint64_t version, params->ramdisk_size = 0; params->type_of_loader = 0xff; params->cmd_line_ptr = cmdline_addr; + /* A fake e820 memory map with 2 entries */ + params->n_e820_entry = 2; + params->e820_entries[0].start_addr = 0x00000000; + params->e820_entries[0].segment_size = 0x00001000; + params->e820_entries[0].segment_type = E820_TYPE_RAM; + params->e820_entries[1].start_addr = 0xfffff000; + params->e820_entries[1].segment_size = 0x00001000; + params->e820_entries[1].segment_type = E820_TYPE_RESERVED; now += CROS_PARAMS_SIZE; /* Finally, append the bootloader. Remember where it will load in