浏览代码

[PATCH] kexec: x86: vmlinux: fix physical addresses

The vmlinux on i386 does not report the correct physical address of
the kernel.  Instead in the physical address field it currently
reports the virtual address of the kernel.

This is patch is a bug fix that corrects vmlinux to report the
proper physical addresses.

This is potentially a help for crash dump analysis tools.

This definitiely allows bootloaders that load vmlinux as a standard
ELF executable.  Bootloaders directly loading vmlinux become of
practical importance when we consider the kexec on panic case.

Signed-off-by: Eric Biederman <ebiederm@xmission.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Eric W. Biederman 20 年之前
父节点
当前提交
ad0d75ebac
共有 1 个文件被更改,包括 38 次插入21 次删除
  1. 38 21
      arch/i386/kernel/vmlinux.lds.S

+ 38 - 21
arch/i386/kernel/vmlinux.lds.S

@@ -2,20 +2,23 @@
  * Written by Martin Mares <mj@atrey.karlin.mff.cuni.cz>;
  * Written by Martin Mares <mj@atrey.karlin.mff.cuni.cz>;
  */
  */
 
 
+#define LOAD_OFFSET __PAGE_OFFSET
+
 #include <asm-generic/vmlinux.lds.h>
 #include <asm-generic/vmlinux.lds.h>
 #include <asm/thread_info.h>
 #include <asm/thread_info.h>
 #include <asm/page.h>
 #include <asm/page.h>
 
 
 OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
 OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
 OUTPUT_ARCH(i386)
 OUTPUT_ARCH(i386)
-ENTRY(startup_32)
+ENTRY(phys_startup_32)
 jiffies = jiffies_64;
 jiffies = jiffies_64;
 SECTIONS
 SECTIONS
 {
 {
-  . = __PAGE_OFFSET + 0x100000;
+  . = LOAD_OFFSET + 0x100000;
+  phys_startup_32 = startup_32 - LOAD_OFFSET;
   /* read-only */
   /* read-only */
   _text = .;			/* Text and read-only data */
   _text = .;			/* Text and read-only data */
-  .text : {
+  .text : AT(ADDR(.text) - LOAD_OFFSET) {
 	*(.text)
 	*(.text)
 	SCHED_TEXT
 	SCHED_TEXT
 	LOCK_TEXT
 	LOCK_TEXT
@@ -27,49 +30,55 @@ SECTIONS
 
 
   . = ALIGN(16);		/* Exception table */
   . = ALIGN(16);		/* Exception table */
   __start___ex_table = .;
   __start___ex_table = .;
-  __ex_table : { *(__ex_table) }
+  __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) { *(__ex_table) }
   __stop___ex_table = .;
   __stop___ex_table = .;
 
 
   RODATA
   RODATA
 
 
   /* writeable */
   /* writeable */
-  .data : {			/* Data */
+  .data : AT(ADDR(.data) - LOAD_OFFSET) {	/* Data */
 	*(.data)
 	*(.data)
 	CONSTRUCTORS
 	CONSTRUCTORS
 	}
 	}
 
 
   . = ALIGN(4096);
   . = ALIGN(4096);
   __nosave_begin = .;
   __nosave_begin = .;
-  .data_nosave : { *(.data.nosave) }
+  .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) { *(.data.nosave) }
   . = ALIGN(4096);
   . = ALIGN(4096);
   __nosave_end = .;
   __nosave_end = .;
 
 
   . = ALIGN(4096);
   . = ALIGN(4096);
-  .data.page_aligned : { *(.data.idt) }
+  .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) {
+	*(.data.idt)
+  }
 
 
   . = ALIGN(32);
   . = ALIGN(32);
-  .data.cacheline_aligned : { *(.data.cacheline_aligned) }
+  .data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) - LOAD_OFFSET) {
+	*(.data.cacheline_aligned)
+  }
 
 
   _edata = .;			/* End of data section */
   _edata = .;			/* End of data section */
 
 
   . = ALIGN(THREAD_SIZE);	/* init_task */
   . = ALIGN(THREAD_SIZE);	/* init_task */
-  .data.init_task : { *(.data.init_task) }
+  .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) {
+	*(.data.init_task)
+  }
 
 
   /* will be freed after init */
   /* will be freed after init */
   . = ALIGN(4096);		/* Init code and data */
   . = ALIGN(4096);		/* Init code and data */
   __init_begin = .;
   __init_begin = .;
-  .init.text : { 
+  .init.text : AT(ADDR(.init.text) - LOAD_OFFSET) {
 	_sinittext = .;
 	_sinittext = .;
 	*(.init.text)
 	*(.init.text)
 	_einittext = .;
 	_einittext = .;
   }
   }
-  .init.data : { *(.init.data) }
+  .init.data : AT(ADDR(.init.data) - LOAD_OFFSET) { *(.init.data) }
   . = ALIGN(16);
   . = ALIGN(16);
   __setup_start = .;
   __setup_start = .;
-  .init.setup : { *(.init.setup) }
+  .init.setup : AT(ADDR(.init.setup) - LOAD_OFFSET) { *(.init.setup) }
   __setup_end = .;
   __setup_end = .;
   __initcall_start = .;
   __initcall_start = .;
-  .initcall.init : {
+  .initcall.init : AT(ADDR(.initcall.init) - LOAD_OFFSET) {
 	*(.initcall1.init) 
 	*(.initcall1.init) 
 	*(.initcall2.init) 
 	*(.initcall2.init) 
 	*(.initcall3.init) 
 	*(.initcall3.init) 
@@ -80,33 +89,41 @@ SECTIONS
   }
   }
   __initcall_end = .;
   __initcall_end = .;
   __con_initcall_start = .;
   __con_initcall_start = .;
-  .con_initcall.init : { *(.con_initcall.init) }
+  .con_initcall.init : AT(ADDR(.con_initcall.init) - LOAD_OFFSET) {
+	*(.con_initcall.init)
+  }
   __con_initcall_end = .;
   __con_initcall_end = .;
   SECURITY_INIT
   SECURITY_INIT
   . = ALIGN(4);
   . = ALIGN(4);
   __alt_instructions = .;
   __alt_instructions = .;
-  .altinstructions : { *(.altinstructions) } 
+  .altinstructions : AT(ADDR(.altinstructions) - LOAD_OFFSET) {
+	*(.altinstructions)
+  }
   __alt_instructions_end = .; 
   __alt_instructions_end = .; 
- .altinstr_replacement : { *(.altinstr_replacement) } 
+  .altinstr_replacement : AT(ADDR(.altinstr_replacement) - LOAD_OFFSET) {
+	*(.altinstr_replacement)
+  }
   /* .exit.text is discard at runtime, not link time, to deal with references
   /* .exit.text is discard at runtime, not link time, to deal with references
      from .altinstructions and .eh_frame */
      from .altinstructions and .eh_frame */
-  .exit.text : { *(.exit.text) }
-  .exit.data : { *(.exit.data) }
+  .exit.text : AT(ADDR(.exit.text) - LOAD_OFFSET) { *(.exit.text) }
+  .exit.data : AT(ADDR(.exit.data) - LOAD_OFFSET) { *(.exit.data) }
   . = ALIGN(4096);
   . = ALIGN(4096);
   __initramfs_start = .;
   __initramfs_start = .;
-  .init.ramfs : { *(.init.ramfs) }
+  .init.ramfs : AT(ADDR(.init.ramfs) - LOAD_OFFSET) { *(.init.ramfs) }
   __initramfs_end = .;
   __initramfs_end = .;
   . = ALIGN(32);
   . = ALIGN(32);
   __per_cpu_start = .;
   __per_cpu_start = .;
-  .data.percpu  : { *(.data.percpu) }
+  .data.percpu  : AT(ADDR(.data.percpu) - LOAD_OFFSET) { *(.data.percpu) }
   __per_cpu_end = .;
   __per_cpu_end = .;
   . = ALIGN(4096);
   . = ALIGN(4096);
   __init_end = .;
   __init_end = .;
   /* freed after init ends here */
   /* freed after init ends here */
 	
 	
   __bss_start = .;		/* BSS */
   __bss_start = .;		/* BSS */
-  .bss : {
+  .bss.page_aligned : AT(ADDR(.bss.page_aligned) - LOAD_OFFSET) {
 	*(.bss.page_aligned)
 	*(.bss.page_aligned)
+  }
+  .bss : AT(ADDR(.bss) - LOAD_OFFSET) {
 	*(.bss)
 	*(.bss)
   }
   }
   . = ALIGN(4);
   . = ALIGN(4);