|
/** * memparse - parse a string with mem suffixes into a number * @ptr: Where parse begins * @retptr: (output) Optional pointer to next char after parse completes * * Parses a string into a number. The number stored at @ptr is * potentially suffixed with %K (for kilobytes, or 1024 bytes), * %M (for megabytes, or 1048576 bytes), or %G (for gigabytes, or * 1073741824). If the number is suffixed with K, M, or G, then * the return value is the number multiplied by one kilobyte, one * megabyte, or one gigabyte, respectively. */ unsigned long long memparse(const char *ptr, char **retptr) { char *endptr; /* local pointer to end of parsed string */ unsigned long long ret = simple_strtoull(ptr, &endptr, 0); switch (*endptr) { case 'G': case 'g': ret <<= 10; case 'M': case 'm': ret <<= 10; case 'K': case 'k': ret <<= 10; endptr++; default: break; } if (retptr) *retptr = endptr; return ret; } static int __init parse_memmap_opt(char *p) { char *oldp; u64 start_at, mem_size; if (!p) return -EINVAL; if (!strncmp(p, "exactmap", 8)) { #ifdef CONFIG_CRASH_DUMP /* * If we are doing a crash dump, we still need to know * the real mem size before original memory map is * reset. */ saved_max_pfn = e820_end_of_ram_pfn(); #endif e820.nr_map = 0; userdef = 1; return 0; } oldp = p; mem_size = memparse(p, &p); if (p == oldp) return -EINVAL; userdef = 1; if (*p == '@') { start_at = memparse(p+1, &p); e820_add_region(start_at, mem_size, E820_RAM); } else if (*p == '#') { start_at = memparse(p+1, &p); e820_add_region(start_at, mem_size, E820_ACPI); } else if (*p == '$') { start_at = memparse(p+1, &p); e820_add_region(start_at, mem_size, E820_RESERVED); } else e820_remove_range(mem_size, ULLONG_MAX - mem_size, E820_RAM, 1); return *p == '\0' ? 0 : -EINVAL; } early_param("memmap", parse_memmap_opt); /* "mem=nopentium" disables the 4MB page tables. */ static int __init parse_memopt(char *p) { u64 mem_size; if (!p) return -EINVAL; #ifdef CONFIG_X86_32 if (!strcmp(p, "nopentium")) { setup_clear_cpu_cap(X86_FEATURE_PSE); return 0; } #endif userdef = 1; mem_size = memparse(p, &p); e820_remove_range(mem_size, ULLONG_MAX - mem_size, E820_RAM, 1); return 0; } early_param("mem", parse_memopt); |
