]> nv-tegra.nvidia Code Review - linux-2.6.git/blobdiff - arch/x86/kernel/vmlinux_64.lds.S
x86: add brk allocation for very, very early allocations
[linux-2.6.git] / arch / x86 / kernel / vmlinux_64.lds.S
index d2a0baa87d1b737db2883b8964e2c190968e7943..ff373423138cd6a0ddb32eac33f0bd1b98d8325a 100644 (file)
@@ -6,7 +6,7 @@
 
 #include <asm-generic/vmlinux.lds.h>
 #include <asm/asm-offsets.h>
-#include <asm/page.h>
+#include <asm/page_types.h>
 
 #undef i386    /* in case the preprocessor is a 32bit one */
 
@@ -14,7 +14,6 @@ OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64", "elf64-x86-64")
 OUTPUT_ARCH(i386:x86-64)
 ENTRY(phys_startup_64)
 jiffies_64 = jiffies;
-_proxy_pda = 1;
 PHDRS {
        text PT_LOAD FLAGS(5);  /* R_E */
        data PT_LOAD FLAGS(7);  /* RWE */
@@ -23,14 +22,15 @@ PHDRS {
 #ifdef CONFIG_SMP
        percpu PT_LOAD FLAGS(7);        /* RWE */
 #endif
+       data.init2 PT_LOAD FLAGS(7);    /* RWE */
        note PT_NOTE FLAGS(0);  /* ___ */
 }
 SECTIONS
 {
   . = __START_KERNEL;
   phys_startup_64 = startup_64 - LOAD_OFFSET;
-  _text = .;                   /* Text and read-only data */
   .text :  AT(ADDR(.text) - LOAD_OFFSET) {
+       _text = .;                      /* Text and read-only data */
        /* First the code that has to be first for bootstrapping */
        *(.text.head)
        _stext = .;
@@ -61,13 +61,13 @@ SECTIONS
   .data : AT(ADDR(.data) - LOAD_OFFSET) {
        DATA_DATA
        CONSTRUCTORS
+       _edata = .;                     /* End of data section */
        } :data
 
-  _edata = .;                  /* End of data section */
 
-  . = ALIGN(PAGE_SIZE);
-  . = ALIGN(CONFIG_X86_L1_CACHE_BYTES);
   .data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) - LOAD_OFFSET) {
+       . = ALIGN(PAGE_SIZE);
+       . = ALIGN(CONFIG_X86_L1_CACHE_BYTES);
        *(.data.cacheline_aligned)
   }
   . = ALIGN(CONFIG_X86_INTERNODE_CACHE_BYTES);
@@ -125,29 +125,29 @@ SECTIONS
 #undef VVIRT_OFFSET
 #undef VVIRT
 
-  . = ALIGN(THREAD_SIZE);      /* init_task */
   .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) {
+       . = ALIGN(THREAD_SIZE); /* init_task */
        *(.data.init_task)
   }:data.init
 
-  . = ALIGN(PAGE_SIZE);
   .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) {
+       . = ALIGN(PAGE_SIZE);
        *(.data.page_aligned)
   }
 
-  /* might get freed after init */
-  . = ALIGN(PAGE_SIZE);
-  __smp_alt_begin = .;
-  __smp_locks = .;
   .smp_locks : AT(ADDR(.smp_locks) - LOAD_OFFSET) {
+       /* might get freed after init */
+       . = ALIGN(PAGE_SIZE);
+       __smp_alt_begin = .;
+       __smp_locks = .;
        *(.smp_locks)
+       __smp_locks_end = .;
+       . = ALIGN(PAGE_SIZE);
+       __smp_alt_end = .;
   }
-  __smp_locks_end = .;
-  . = ALIGN(PAGE_SIZE);
-  __smp_alt_end = .;
 
   . = ALIGN(PAGE_SIZE);                /* Init code and data */
-  __init_begin = .;
+  __init_begin = .;    /* paired with __init_end */
   .init.text : AT(ADDR(.init.text) - LOAD_OFFSET) {
        _sinittext = .;
        INIT_TEXT
@@ -159,40 +159,42 @@ SECTIONS
        __initdata_end = .;
    }
 
-  . = ALIGN(16);
-  __setup_start = .;
-  .init.setup : AT(ADDR(.init.setup) - LOAD_OFFSET) { *(.init.setup) }
-  __setup_end = .;
-  __initcall_start = .;
+  .init.setup : AT(ADDR(.init.setup) - LOAD_OFFSET) {
+       . = ALIGN(16);
+       __setup_start = .;
+       *(.init.setup)
+       __setup_end = .;
+  }
   .initcall.init : AT(ADDR(.initcall.init) - LOAD_OFFSET) {
+       __initcall_start = .;
        INITCALLS
+       __initcall_end = .;
   }
-  __initcall_end = .;
-  __con_initcall_start = .;
   .con_initcall.init : AT(ADDR(.con_initcall.init) - LOAD_OFFSET) {
+       __con_initcall_start = .;
        *(.con_initcall.init)
+       __con_initcall_end = .;
   }
-  __con_initcall_end = .;
-  __x86_cpu_dev_start = .;
   .x86_cpu_dev.init : AT(ADDR(.x86_cpu_dev.init) - LOAD_OFFSET) {
+       __x86_cpu_dev_start = .;
        *(.x86_cpu_dev.init)
+       __x86_cpu_dev_end = .;
   }
-  __x86_cpu_dev_end = .;
   SECURITY_INIT
 
   . = ALIGN(8);
   .parainstructions : AT(ADDR(.parainstructions) - LOAD_OFFSET) {
-  __parainstructions = .;
+       __parainstructions = .;
        *(.parainstructions)
-  __parainstructions_end = .;
+       __parainstructions_end = .;
   }
 
-  . = ALIGN(8);
-  __alt_instructions = .;
   .altinstructions : AT(ADDR(.altinstructions) - LOAD_OFFSET) {
+       . = ALIGN(8);
+       __alt_instructions = .;
        *(.altinstructions)
+       __alt_instructions_end = .;
   }
-  __alt_instructions_end = .;
   .altinstr_replacement : AT(ADDR(.altinstr_replacement) - LOAD_OFFSET) {
        *(.altinstr_replacement)
   }
@@ -207,22 +209,23 @@ SECTIONS
 
 #ifdef CONFIG_BLK_DEV_INITRD
   . = ALIGN(PAGE_SIZE);
-  __initramfs_start = .;
-  .init.ramfs : AT(ADDR(.init.ramfs) - LOAD_OFFSET) { *(.init.ramfs) }
-  __initramfs_end = .;
+  .init.ramfs : AT(ADDR(.init.ramfs) - LOAD_OFFSET) {
+       __initramfs_start = .;
+       *(.init.ramfs)
+       __initramfs_end = .;
+  }
 #endif
 
 #ifdef CONFIG_SMP
   /*
    * percpu offsets are zero-based on SMP.  PERCPU_VADDR() changes the
    * output PHDR, so the next output section - __data_nosave - should
-   * switch it back to data.init.  Also, pda should be at the head of
+   * start another section data.init2.  Also, pda should be at the head of
    * percpu area.  Preallocate it and define the percpu offset symbol
    * so that it can be accessed as a percpu variable.
    */
   . = ALIGN(PAGE_SIZE);
-  PERCPU_VADDR_PREALLOC(0, :percpu, pda_size)
-  per_cpu____pda = __per_cpu_start;
+  PERCPU_VADDR(0, :percpu)
 #else
   PERCPU(PAGE_SIZE)
 #endif
@@ -230,20 +233,26 @@ SECTIONS
   . = ALIGN(PAGE_SIZE);
   __init_end = .;
 
-  . = ALIGN(PAGE_SIZE);
-  __nosave_begin = .;
   .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) {
-      *(.data.nosave)
-  } :data.init /* switch back to data.init, see PERCPU_VADDR() above */
-  . = ALIGN(PAGE_SIZE);
-  __nosave_end = .;
+       . = ALIGN(PAGE_SIZE);
+       __nosave_begin = .;
+       *(.data.nosave)
+       . = ALIGN(PAGE_SIZE);
+       __nosave_end = .;
+  } :data.init2 /* use another section data.init2, see PERCPU_VADDR() above */
 
-  __bss_start = .;             /* BSS */
   .bss : AT(ADDR(.bss) - LOAD_OFFSET) {
+       . = ALIGN(PAGE_SIZE);
+       __bss_start = .;                /* BSS */
        *(.bss.page_aligned)
        *(.bss)
-       }
-  __bss_stop = .;
+       __bss_stop = .;
+
+       . = ALIGN(PAGE_SIZE);
+       __brk_base = . ;
+       . += 1024 * 1024 ;
+       __brk_limit = . ;
+  }
 
   _end = . ;
 
@@ -258,8 +267,28 @@ SECTIONS
   DWARF_DEBUG
 }
 
+ /*
+  * Per-cpu symbols which need to be offset from __per_cpu_load
+  * for the boot processor.
+  */
+#define INIT_PER_CPU(x) init_per_cpu__##x = per_cpu__##x + __per_cpu_load
+INIT_PER_CPU(gdt_page);
+INIT_PER_CPU(irq_stack_union);
+
 /*
  * Build-time check on the image size:
  */
 ASSERT((_end - _text <= KERNEL_IMAGE_SIZE),
        "kernel image bigger than KERNEL_IMAGE_SIZE")
+
+#ifdef CONFIG_SMP
+ASSERT((per_cpu__irq_stack_union == 0),
+        "irq_stack_union is not at start of per-cpu area");
+#endif
+
+#ifdef CONFIG_KEXEC
+#include <asm/kexec.h>
+
+ASSERT(kexec_control_code_size <= KEXEC_CONTROL_CODE_MAX_SIZE,
+       "kexec control code size is too big")
+#endif