diff options
-rw-r--r-- | Documentation/kernel-parameters.txt | 2 | ||||
-rw-r--r-- | arch/x86_64/kernel/e820.c | 21 | ||||
-rw-r--r-- | arch/x86_64/kernel/setup.c | 27 | ||||
-rw-r--r-- | include/asm-x86_64/e820.h | 1 |
4 files changed, 50 insertions, 1 deletions
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 0dc848bf0b56..12b7d938a897 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt | |||
@@ -832,7 +832,7 @@ running once the system is up. | |||
832 | mem=nopentium [BUGS=IA-32] Disable usage of 4MB pages for kernel | 832 | mem=nopentium [BUGS=IA-32] Disable usage of 4MB pages for kernel |
833 | memory. | 833 | memory. |
834 | 834 | ||
835 | memmap=exactmap [KNL,IA-32] Enable setting of an exact | 835 | memmap=exactmap [KNL,IA-32,X86_64] Enable setting of an exact |
836 | E820 memory map, as specified by the user. | 836 | E820 memory map, as specified by the user. |
837 | Such memmap=exactmap lines can be constructed based on | 837 | Such memmap=exactmap lines can be constructed based on |
838 | BIOS output or other requirements. See the memmap=nn@ss | 838 | BIOS output or other requirements. See the memmap=nn@ss |
diff --git a/arch/x86_64/kernel/e820.c b/arch/x86_64/kernel/e820.c index 17579a1a174b..293cd71a266a 100644 --- a/arch/x86_64/kernel/e820.c +++ b/arch/x86_64/kernel/e820.c | |||
@@ -559,6 +559,27 @@ void __init parse_memopt(char *p, char **from) | |||
559 | end_user_pfn >>= PAGE_SHIFT; | 559 | end_user_pfn >>= PAGE_SHIFT; |
560 | } | 560 | } |
561 | 561 | ||
562 | void __init parse_memmapopt(char *p, char **from) | ||
563 | { | ||
564 | unsigned long long start_at, mem_size; | ||
565 | |||
566 | mem_size = memparse(p, from); | ||
567 | p = *from; | ||
568 | if (*p == '@') { | ||
569 | start_at = memparse(p+1, from); | ||
570 | add_memory_region(start_at, mem_size, E820_RAM); | ||
571 | } else if (*p == '#') { | ||
572 | start_at = memparse(p+1, from); | ||
573 | add_memory_region(start_at, mem_size, E820_ACPI); | ||
574 | } else if (*p == '$') { | ||
575 | start_at = memparse(p+1, from); | ||
576 | add_memory_region(start_at, mem_size, E820_RESERVED); | ||
577 | } else { | ||
578 | end_user_pfn = (mem_size >> PAGE_SHIFT); | ||
579 | } | ||
580 | p = *from; | ||
581 | } | ||
582 | |||
562 | unsigned long pci_mem_start = 0xaeedbabe; | 583 | unsigned long pci_mem_start = 0xaeedbabe; |
563 | 584 | ||
564 | /* | 585 | /* |
diff --git a/arch/x86_64/kernel/setup.c b/arch/x86_64/kernel/setup.c index 64c4534b930c..ff9620b800c0 100644 --- a/arch/x86_64/kernel/setup.c +++ b/arch/x86_64/kernel/setup.c | |||
@@ -275,6 +275,7 @@ static __init void parse_cmdline_early (char ** cmdline_p) | |||
275 | { | 275 | { |
276 | char c = ' ', *to = command_line, *from = COMMAND_LINE; | 276 | char c = ' ', *to = command_line, *from = COMMAND_LINE; |
277 | int len = 0; | 277 | int len = 0; |
278 | int userdef = 0; | ||
278 | 279 | ||
279 | /* Save unparsed command line copy for /proc/cmdline */ | 280 | /* Save unparsed command line copy for /proc/cmdline */ |
280 | memcpy(saved_command_line, COMMAND_LINE, COMMAND_LINE_SIZE); | 281 | memcpy(saved_command_line, COMMAND_LINE, COMMAND_LINE_SIZE); |
@@ -357,6 +358,28 @@ static __init void parse_cmdline_early (char ** cmdline_p) | |||
357 | if (!memcmp(from, "mem=", 4)) | 358 | if (!memcmp(from, "mem=", 4)) |
358 | parse_memopt(from+4, &from); | 359 | parse_memopt(from+4, &from); |
359 | 360 | ||
361 | if (!memcmp(from, "memmap=", 7)) { | ||
362 | /* exactmap option is for used defined memory */ | ||
363 | if (!memcmp(from+7, "exactmap", 8)) { | ||
364 | #ifdef CONFIG_CRASH_DUMP | ||
365 | /* If we are doing a crash dump, we | ||
366 | * still need to know the real mem | ||
367 | * size before original memory map is | ||
368 | * reset. | ||
369 | */ | ||
370 | saved_max_pfn = e820_end_of_ram(); | ||
371 | #endif | ||
372 | from += 8+7; | ||
373 | end_pfn_map = 0; | ||
374 | e820.nr_map = 0; | ||
375 | userdef = 1; | ||
376 | } | ||
377 | else { | ||
378 | parse_memmapopt(from+7, &from); | ||
379 | userdef = 1; | ||
380 | } | ||
381 | } | ||
382 | |||
360 | #ifdef CONFIG_NUMA | 383 | #ifdef CONFIG_NUMA |
361 | if (!memcmp(from, "numa=", 5)) | 384 | if (!memcmp(from, "numa=", 5)) |
362 | numa_setup(from+5); | 385 | numa_setup(from+5); |
@@ -403,6 +426,10 @@ static __init void parse_cmdline_early (char ** cmdline_p) | |||
403 | break; | 426 | break; |
404 | *(to++) = c; | 427 | *(to++) = c; |
405 | } | 428 | } |
429 | if (userdef) { | ||
430 | printk(KERN_INFO "user-defined physical RAM map:\n"); | ||
431 | e820_print_map("user"); | ||
432 | } | ||
406 | *to = '\0'; | 433 | *to = '\0'; |
407 | *cmdline_p = command_line; | 434 | *cmdline_p = command_line; |
408 | } | 435 | } |
diff --git a/include/asm-x86_64/e820.h b/include/asm-x86_64/e820.h index e682edc24a68..8dcc32665240 100644 --- a/include/asm-x86_64/e820.h +++ b/include/asm-x86_64/e820.h | |||
@@ -55,6 +55,7 @@ extern unsigned long e820_hole_size(unsigned long start_pfn, | |||
55 | unsigned long end_pfn); | 55 | unsigned long end_pfn); |
56 | 56 | ||
57 | extern void __init parse_memopt(char *p, char **end); | 57 | extern void __init parse_memopt(char *p, char **end); |
58 | extern void __init parse_memmapopt(char *p, char **end); | ||
58 | 59 | ||
59 | extern struct e820map e820; | 60 | extern struct e820map e820; |
60 | #endif/*!__ASSEMBLY__*/ | 61 | #endif/*!__ASSEMBLY__*/ |