diff options
Diffstat (limited to 'arch/x86/kernel/head64.c')
-rw-r--r-- | arch/x86/kernel/head64.c | 63 |
1 files changed, 58 insertions, 5 deletions
diff --git a/arch/x86/kernel/head64.c b/arch/x86/kernel/head64.c index 6b3469311e42..24dbf56928d7 100644 --- a/arch/x86/kernel/head64.c +++ b/arch/x86/kernel/head64.c | |||
@@ -10,6 +10,7 @@ | |||
10 | #include <linux/kernel.h> | 10 | #include <linux/kernel.h> |
11 | #include <linux/string.h> | 11 | #include <linux/string.h> |
12 | #include <linux/percpu.h> | 12 | #include <linux/percpu.h> |
13 | #include <linux/start_kernel.h> | ||
13 | 14 | ||
14 | #include <asm/processor.h> | 15 | #include <asm/processor.h> |
15 | #include <asm/proto.h> | 16 | #include <asm/proto.h> |
@@ -19,12 +20,14 @@ | |||
19 | #include <asm/pgtable.h> | 20 | #include <asm/pgtable.h> |
20 | #include <asm/tlbflush.h> | 21 | #include <asm/tlbflush.h> |
21 | #include <asm/sections.h> | 22 | #include <asm/sections.h> |
23 | #include <asm/kdebug.h> | ||
24 | #include <asm/e820.h> | ||
22 | 25 | ||
23 | static void __init zap_identity_mappings(void) | 26 | static void __init zap_identity_mappings(void) |
24 | { | 27 | { |
25 | pgd_t *pgd = pgd_offset_k(0UL); | 28 | pgd_t *pgd = pgd_offset_k(0UL); |
26 | pgd_clear(pgd); | 29 | pgd_clear(pgd); |
27 | __flush_tlb(); | 30 | __flush_tlb_all(); |
28 | } | 31 | } |
29 | 32 | ||
30 | /* Don't add a printk in there. printk relies on the PDA which is not initialized | 33 | /* Don't add a printk in there. printk relies on the PDA which is not initialized |
@@ -46,6 +49,35 @@ static void __init copy_bootdata(char *real_mode_data) | |||
46 | } | 49 | } |
47 | } | 50 | } |
48 | 51 | ||
52 | #define EBDA_ADDR_POINTER 0x40E | ||
53 | |||
54 | static __init void reserve_ebda(void) | ||
55 | { | ||
56 | unsigned ebda_addr, ebda_size; | ||
57 | |||
58 | /* | ||
59 | * there is a real-mode segmented pointer pointing to the | ||
60 | * 4K EBDA area at 0x40E | ||
61 | */ | ||
62 | ebda_addr = *(unsigned short *)__va(EBDA_ADDR_POINTER); | ||
63 | ebda_addr <<= 4; | ||
64 | |||
65 | if (!ebda_addr) | ||
66 | return; | ||
67 | |||
68 | ebda_size = *(unsigned short *)__va(ebda_addr); | ||
69 | |||
70 | /* Round EBDA up to pages */ | ||
71 | if (ebda_size == 0) | ||
72 | ebda_size = 1; | ||
73 | ebda_size <<= 10; | ||
74 | ebda_size = round_up(ebda_size + (ebda_addr & ~PAGE_MASK), PAGE_SIZE); | ||
75 | if (ebda_size > 64*1024) | ||
76 | ebda_size = 64*1024; | ||
77 | |||
78 | reserve_early(ebda_addr, ebda_addr + ebda_size, "EBDA"); | ||
79 | } | ||
80 | |||
49 | void __init x86_64_start_kernel(char * real_mode_data) | 81 | void __init x86_64_start_kernel(char * real_mode_data) |
50 | { | 82 | { |
51 | int i; | 83 | int i; |
@@ -56,8 +88,13 @@ void __init x86_64_start_kernel(char * real_mode_data) | |||
56 | /* Make NULL pointers segfault */ | 88 | /* Make NULL pointers segfault */ |
57 | zap_identity_mappings(); | 89 | zap_identity_mappings(); |
58 | 90 | ||
59 | for (i = 0; i < IDT_ENTRIES; i++) | 91 | for (i = 0; i < IDT_ENTRIES; i++) { |
92 | #ifdef CONFIG_EARLY_PRINTK | ||
93 | set_intr_gate(i, &early_idt_handlers[i]); | ||
94 | #else | ||
60 | set_intr_gate(i, early_idt_handler); | 95 | set_intr_gate(i, early_idt_handler); |
96 | #endif | ||
97 | } | ||
61 | load_idt((const struct desc_ptr *)&idt_descr); | 98 | load_idt((const struct desc_ptr *)&idt_descr); |
62 | 99 | ||
63 | early_printk("Kernel alive\n"); | 100 | early_printk("Kernel alive\n"); |
@@ -67,8 +104,24 @@ void __init x86_64_start_kernel(char * real_mode_data) | |||
67 | 104 | ||
68 | pda_init(0); | 105 | pda_init(0); |
69 | copy_bootdata(__va(real_mode_data)); | 106 | copy_bootdata(__va(real_mode_data)); |
70 | #ifdef CONFIG_SMP | 107 | |
71 | cpu_set(0, cpu_online_map); | 108 | reserve_early(__pa_symbol(&_text), __pa_symbol(&_end), "TEXT DATA BSS"); |
72 | #endif | 109 | |
110 | /* Reserve INITRD */ | ||
111 | if (boot_params.hdr.type_of_loader && boot_params.hdr.ramdisk_image) { | ||
112 | unsigned long ramdisk_image = boot_params.hdr.ramdisk_image; | ||
113 | unsigned long ramdisk_size = boot_params.hdr.ramdisk_size; | ||
114 | unsigned long ramdisk_end = ramdisk_image + ramdisk_size; | ||
115 | reserve_early(ramdisk_image, ramdisk_end, "RAMDISK"); | ||
116 | } | ||
117 | |||
118 | reserve_ebda(); | ||
119 | |||
120 | /* | ||
121 | * At this point everything still needed from the boot loader | ||
122 | * or BIOS or kernel text should be early reserved or marked not | ||
123 | * RAM in e820. All other memory is free game. | ||
124 | */ | ||
125 | |||
73 | start_kernel(); | 126 | start_kernel(); |
74 | } | 127 | } |