x86: replace hard coded reservations in 64-bit early boot code with dynamic table
On x86-64 there are several memory allocations before bootmem. To avoid them stomping on each other they used to be all hard coded in bad_area(). Replace this with an array that is filled as needed. This cleans up the code considerably and allows to expand its use. Cc: peterz@infradead.org Signed-off-by: Andi Kleen <ak@suse.de> Signed-off-by: Ingo Molnar <mingo@elte.hu> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
This commit is contained in:
@@ -21,6 +21,7 @@
|
||||
#include <asm/tlbflush.h>
|
||||
#include <asm/sections.h>
|
||||
#include <asm/kdebug.h>
|
||||
#include <asm/e820.h>
|
||||
|
||||
static void __init zap_identity_mappings(void)
|
||||
{
|
||||
@@ -48,6 +49,35 @@ static void __init copy_bootdata(char *real_mode_data)
|
||||
}
|
||||
}
|
||||
|
||||
#define EBDA_ADDR_POINTER 0x40E
|
||||
|
||||
static __init void reserve_ebda(void)
|
||||
{
|
||||
unsigned ebda_addr, ebda_size;
|
||||
|
||||
/*
|
||||
* there is a real-mode segmented pointer pointing to the
|
||||
* 4K EBDA area at 0x40E
|
||||
*/
|
||||
ebda_addr = *(unsigned short *)__va(EBDA_ADDR_POINTER);
|
||||
ebda_addr <<= 4;
|
||||
|
||||
if (!ebda_addr)
|
||||
return;
|
||||
|
||||
ebda_size = *(unsigned short *)__va(ebda_addr);
|
||||
|
||||
/* Round EBDA up to pages */
|
||||
if (ebda_size == 0)
|
||||
ebda_size = 1;
|
||||
ebda_size <<= 10;
|
||||
ebda_size = round_up(ebda_size + (ebda_addr & ~PAGE_MASK), PAGE_SIZE);
|
||||
if (ebda_size > 64*1024)
|
||||
ebda_size = 64*1024;
|
||||
|
||||
reserve_early(ebda_addr, ebda_addr + ebda_size);
|
||||
}
|
||||
|
||||
void __init x86_64_start_kernel(char * real_mode_data)
|
||||
{
|
||||
int i;
|
||||
@@ -75,5 +105,23 @@ void __init x86_64_start_kernel(char * real_mode_data)
|
||||
pda_init(0);
|
||||
copy_bootdata(__va(real_mode_data));
|
||||
|
||||
reserve_early(__pa_symbol(&_text), __pa_symbol(&_end));
|
||||
|
||||
/* Reserve INITRD */
|
||||
if (boot_params.hdr.type_of_loader && boot_params.hdr.ramdisk_image) {
|
||||
unsigned long ramdisk_image = boot_params.hdr.ramdisk_image;
|
||||
unsigned long ramdisk_size = boot_params.hdr.ramdisk_size;
|
||||
unsigned long ramdisk_end = ramdisk_image + ramdisk_size;
|
||||
reserve_early(ramdisk_image, ramdisk_end);
|
||||
}
|
||||
|
||||
reserve_ebda();
|
||||
|
||||
/*
|
||||
* At this point everything still needed from the boot loader
|
||||
* or BIOS or kernel text should be early reserved or marked not
|
||||
* RAM in e820. All other memory is free game.
|
||||
*/
|
||||
|
||||
start_kernel();
|
||||
}
|
||||
|
Reference in New Issue
Block a user