aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/setup_32.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/kernel/setup_32.c')
-rw-r--r--arch/x86/kernel/setup_32.c109
1 files changed, 23 insertions, 86 deletions
diff --git a/arch/x86/kernel/setup_32.c b/arch/x86/kernel/setup_32.c
index 5faeab69edd9..fed482c62450 100644
--- a/arch/x86/kernel/setup_32.c
+++ b/arch/x86/kernel/setup_32.c
@@ -359,56 +359,6 @@ unsigned long __init find_max_low_pfn(void)
359 return max_low_pfn; 359 return max_low_pfn;
360} 360}
361 361
362#define BIOS_LOWMEM_KILOBYTES 0x413
363
364/*
365 * The BIOS places the EBDA/XBDA at the top of conventional
366 * memory, and usually decreases the reported amount of
367 * conventional memory (int 0x12) too. This also contains a
368 * workaround for Dell systems that neglect to reserve EBDA.
369 * The same workaround also avoids a problem with the AMD768MPX
370 * chipset: reserve a page before VGA to prevent PCI prefetch
371 * into it (errata #56). Usually the page is reserved anyways,
372 * unless you have no PS/2 mouse plugged in.
373 */
374static void __init reserve_ebda_region(void)
375{
376 unsigned int lowmem, ebda_addr;
377
378 /* To determine the position of the EBDA and the */
379 /* end of conventional memory, we need to look at */
380 /* the BIOS data area. In a paravirtual environment */
381 /* that area is absent. We'll just have to assume */
382 /* that the paravirt case can handle memory setup */
383 /* correctly, without our help. */
384 if (paravirt_enabled())
385 return;
386
387 /* end of low (conventional) memory */
388 lowmem = *(unsigned short *)__va(BIOS_LOWMEM_KILOBYTES);
389 lowmem <<= 10;
390
391 /* start of EBDA area */
392 ebda_addr = get_bios_ebda();
393
394 /* Fixup: bios puts an EBDA in the top 64K segment */
395 /* of conventional memory, but does not adjust lowmem. */
396 if ((lowmem - ebda_addr) <= 0x10000)
397 lowmem = ebda_addr;
398
399 /* Fixup: bios does not report an EBDA at all. */
400 /* Some old Dells seem to need 4k anyhow (bugzilla 2990) */
401 if ((ebda_addr == 0) && (lowmem >= 0x9f000))
402 lowmem = 0x9f000;
403
404 /* Paranoia: should never happen, but... */
405 if ((lowmem == 0) || (lowmem >= 0x100000))
406 lowmem = 0x9f000;
407
408 /* reserve all memory between lowmem and the 1MB mark */
409 reserve_bootmem(lowmem, 0x100000 - lowmem, BOOTMEM_DEFAULT);
410}
411
412#ifndef CONFIG_NEED_MULTIPLE_NODES 362#ifndef CONFIG_NEED_MULTIPLE_NODES
413static void __init setup_bootmem_allocator(void); 363static void __init setup_bootmem_allocator(void);
414static unsigned long __init setup_memory(void) 364static unsigned long __init setup_memory(void)
@@ -522,25 +472,32 @@ static void __init reserve_initrd(void)
522 unsigned long end_of_lowmem = max_low_pfn << PAGE_SHIFT; 472 unsigned long end_of_lowmem = max_low_pfn << PAGE_SHIFT;
523 unsigned long ramdisk_here; 473 unsigned long ramdisk_here;
524 474
525 initrd_start = 0;
526
527 if (!boot_params.hdr.type_of_loader || 475 if (!boot_params.hdr.type_of_loader ||
528 !ramdisk_image || !ramdisk_size) 476 !ramdisk_image || !ramdisk_size)
529 return; /* No initrd provided by bootloader */ 477 return; /* No initrd provided by bootloader */
530 478
479 initrd_start = 0;
480
531 if (ramdisk_end < ramdisk_image) { 481 if (ramdisk_end < ramdisk_image) {
482 free_bootmem(ramdisk_image, ramdisk_size);
532 printk(KERN_ERR "initrd wraps around end of memory, " 483 printk(KERN_ERR "initrd wraps around end of memory, "
533 "disabling initrd\n"); 484 "disabling initrd\n");
534 return; 485 return;
535 } 486 }
536 if (ramdisk_size >= end_of_lowmem/2) { 487 if (ramdisk_size >= end_of_lowmem/2) {
488 free_bootmem(ramdisk_image, ramdisk_size);
537 printk(KERN_ERR "initrd too large to handle, " 489 printk(KERN_ERR "initrd too large to handle, "
538 "disabling initrd\n"); 490 "disabling initrd\n");
539 return; 491 return;
540 } 492 }
493
541 if (ramdisk_end <= end_of_lowmem) { 494 if (ramdisk_end <= end_of_lowmem) {
542 /* All in lowmem, easy case */ 495 /* All in lowmem, easy case */
543 reserve_bootmem(ramdisk_image, ramdisk_size, BOOTMEM_DEFAULT); 496 /*
497 * don't need to reserve again, already reserved early
498 * in i386_start_kernel, and early_res_to_bootmem
499 * convert that to reserved in bootmem
500 */
544 initrd_start = ramdisk_image + PAGE_OFFSET; 501 initrd_start = ramdisk_image + PAGE_OFFSET;
545 initrd_end = initrd_start+ramdisk_size; 502 initrd_end = initrd_start+ramdisk_size;
546 return; 503 return;
@@ -582,6 +539,8 @@ static void __init relocate_initrd(void)
582 p = (char *)__va(ramdisk_image); 539 p = (char *)__va(ramdisk_image);
583 memcpy(q, p, clen); 540 memcpy(q, p, clen);
584 q += clen; 541 q += clen;
542 /* need to free these low pages...*/
543 free_bootmem(ramdisk_image, clen);
585 ramdisk_image += clen; 544 ramdisk_image += clen;
586 ramdisk_size -= clen; 545 ramdisk_size -= clen;
587 } 546 }
@@ -600,47 +559,28 @@ static void __init relocate_initrd(void)
600 ramdisk_image += clen; 559 ramdisk_image += clen;
601 ramdisk_size -= clen; 560 ramdisk_size -= clen;
602 } 561 }
562 /* high pages is not converted by early_res_to_bootmem */
603} 563}
604 564
605#endif /* CONFIG_BLK_DEV_INITRD */ 565#endif /* CONFIG_BLK_DEV_INITRD */
606 566
607void __init setup_bootmem_allocator(void) 567void __init setup_bootmem_allocator(void)
608{ 568{
609 unsigned long bootmap_size; 569 unsigned long bootmap_size, bootmap;
610 /* 570 /*
611 * Initialize the boot-time allocator (with low memory only): 571 * Initialize the boot-time allocator (with low memory only):
612 */ 572 */
613 bootmap_size = init_bootmem(min_low_pfn, max_low_pfn); 573 bootmap_size = bootmem_bootmap_pages(max_low_pfn)<<PAGE_SHIFT;
614 574 bootmap = find_e820_area(min_low_pfn<<PAGE_SHIFT,
575 max_low_pfn<<PAGE_SHIFT, bootmap_size,
576 PAGE_SIZE);
577 if (bootmap == -1L)
578 panic("Cannot find bootmem map of size %ld\n", bootmap_size);
579 bootmap_size = init_bootmem(bootmap >> PAGE_SHIFT, max_low_pfn);
615 register_bootmem_low_pages(max_low_pfn); 580 register_bootmem_low_pages(max_low_pfn);
581 early_res_to_bootmem(0, max_low_pfn<<PAGE_SHIFT);
582 reserve_bootmem(bootmap, bootmap_size, BOOTMEM_DEFAULT);
616 583
617 /*
618 * Reserve the bootmem bitmap itself as well. We do this in two
619 * steps (first step was init_bootmem()) because this catches
620 * the (very unlikely) case of us accidentally initializing the
621 * bootmem allocator with an invalid RAM area.
622 */
623 reserve_bootmem(__pa_symbol(_text), (PFN_PHYS(min_low_pfn) +
624 bootmap_size + PAGE_SIZE-1) - __pa_symbol(_text),
625 BOOTMEM_DEFAULT);
626
627 /*
628 * reserve physical page 0 - it's a special BIOS page on many boxes,
629 * enabling clean reboots, SMP operation, laptop functions.
630 */
631 reserve_bootmem(0, PAGE_SIZE, BOOTMEM_DEFAULT);
632
633 /* reserve EBDA region */
634 reserve_ebda_region();
635
636#ifdef CONFIG_SMP
637 /*
638 * But first pinch a few for the stack/trampoline stuff
639 * FIXME: Don't need the extra page at 4K, but need to fix
640 * trampoline before removing it. (see the GDT stuff)
641 */
642 reserve_bootmem(PAGE_SIZE, PAGE_SIZE, BOOTMEM_DEFAULT);
643#endif
644#ifdef CONFIG_ACPI_SLEEP 584#ifdef CONFIG_ACPI_SLEEP
645 /* 585 /*
646 * Reserve low memory region for sleep support. 586 * Reserve low memory region for sleep support.
@@ -803,9 +743,6 @@ void __init setup_arch(char **cmdline_p)
803 * not to exceed the 8Mb limit. 743 * not to exceed the 8Mb limit.
804 */ 744 */
805 745
806#ifdef CONFIG_SMP
807 smp_alloc_memory(); /* AP processor realmode stacks in low memory*/
808#endif
809 paging_init(); 746 paging_init();
810 747
811 /* 748 /*