The patch titled i386: Distinguish absolute symbols has been added to the -mm tree. Its filename is i386-distinguish-absolute-symbols.patch See http://www.zip.com.au/~akpm/linux/patches/stuff/added-to-mm.txt to find out what to do about this ------------------------------------------------------ Subject: i386: Distinguish absolute symbols From: Vivek Goyal <vgoyal@xxxxxxxxxx> Eric Biederman implemented the relocatable kernel support for x86 and x86_64 and posted the patches for comments almost two months back. http://marc.theaimsgroup.com/?l=linux-kernel&m=115443019026302&w=2 We have been testing the patches in RHEL kernels since then and things are looking up. I think this is the time that patches can be included in -mm and get more testing done and get rest of the issues sorted out. Eric is currently held up with other things, so I have taken his patches and forward ported to 2.6.18-git19. Did some minor cleanups and fixed a couple of bugs as faced in our testing. I have also accomodated the review comments received last time. Currently this patch series is only for i386. I will be posting the patches for x86_64 later. Following is a brief account of changes I have done since last time. o Forward ported the patches to 2.6.18-git19 o Replaced CONFIG_PHYSICAL_START with CONFIG_PHYSICAL_ALIGN o Added a patch to prevent section relative symbols becoming absolute for sections with zero size. o Dropped support for serial output debugging in decompressor code for the time being as per the discussion last time. o Added symbol _text to few architectures so that compilation does not break o Fix a typo in config option (CONFIG_RELOCTABLE). It was causing wrong pice of code to be executed and second kernel was stomping over first kernel's data. o Modified __pa_symbol() definition as per Andi's comment. o Put --emit-relocs undef #ifdef, so that relocation sections are not retained of CONFIG_RELOCATABLE is not set. o Made symbol _end_rodata also section relative. o Align .data section to 4K address otherwise data segment is loaded at a non-4K aligned boundary and kexec-tools do the check. Following is the text from Eric's last post to refresh memory that why do we need a relocatable kernel. The problem: We can't always run the kernel at 1MB or 2MB, and so people who need different addresses must build multiple kernels. The bzImage format can't even represent loading a kernel at other than it's default address. With kexec on panic now starting to be used by distros having a kernel not running at the default load address is starting to become common. The goal of this patch series is to build kernels that are relocatable at run time, and to extend the bzImage format to make it capable of expressing a relocatable kernel. In extending the bzImage format I am replacing the existing unused bootsector with an ELF header. To express what is going on the ELF header will have type ET_DYN. Just like the kernel loading an ET_DYN executable bootloaders are not expected to process relocations. But the executable may be shifted in the address space so long as it's alignment requirements are met. The i386 kernel is built to process relocations generated with --emit-relocs (after vmlinux.lds.S) has been fixed up to sort out static and dynamic relocations. This patch: Ld knows about 2 kinds of symbols, absolute and section relative. Section relative symbols symbols change value when a section is moved and absolute symbols do not. Currently in the linker script we have several labels marking the beginning and ending of sections that are outside of sections, making them absolute symbols. Having a mixture of absolute and section relative symbols refereing to the same data is currently harmless but it is confusing. This must be done carefully as newer revs of ld do not place symbols that appear in sections without data and instead ld makes those symbols global :( My ultimate goal is to build a relocatable kernel. The safest and least intrusive technique is to generate relocation entries so the kernel can be relocated at load time. The only penalty would be an increase in the size of the kernel binary. The problem is that if absolute and relocatable symbols are not properly specified absolute symbols will be relocated or section relative symbols won't be, which is fatal. The practical motivation is that when generating kernels that will run from a reserved area for analyzing what caused a kernel panic, it is simpler if you don't need to hard code the physical memory location they will run at, especially for the distributions. Signed-off-by: Eric W. Biederman <ebiederm@xxxxxxxxxxxx> Signed-off-by: Vivek Goyal <vgoyal@xxxxxxxxxx> Cc: Andi Kleen <ak@xxxxxx> Cc: "H. Peter Anvin" <hpa@xxxxxxxxx> Signed-off-by: Andrew Morton <akpm@xxxxxxxx> --- arch/i386/kernel/vmlinux.lds.S | 107 +++++++++++++++------------- include/asm-generic/vmlinux.lds.h | 4 - 2 files changed, 60 insertions(+), 51 deletions(-) diff -puN arch/i386/kernel/vmlinux.lds.S~i386-distinguish-absolute-symbols arch/i386/kernel/vmlinux.lds.S --- a/arch/i386/kernel/vmlinux.lds.S~i386-distinguish-absolute-symbols +++ a/arch/i386/kernel/vmlinux.lds.S @@ -24,33 +24,36 @@ SECTIONS . = __KERNEL_START; phys_startup_32 = startup_32 - LOAD_OFFSET; /* read-only */ - _text = .; /* Text and read-only data */ .text : AT(ADDR(.text) - LOAD_OFFSET) { + _text = .; /* Text and read-only data */ *(.text) SCHED_TEXT LOCK_TEXT KPROBES_TEXT *(.fixup) *(.gnu.warning) - } :text = 0x9090 + _etext = .; /* End of text section */ + } :text = 0x9090 _etext = .; /* End of text section */ . = ALIGN(16); /* Exception table */ - __start___ex_table = .; - __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) { *(__ex_table) } - __stop___ex_table = .; + __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) { + __start___ex_table = .; + *(__ex_table) + __stop___ex_table = .; + } _sdata = .; /* End of text section */ RODATA . = ALIGN(4); - __tracedata_start = .; .tracedata : AT(ADDR(.tracedata) - LOAD_OFFSET) { + __tracedata_start = .; *(.tracedata) + __tracedata_end = .; } - __tracedata_end = .; /* writeable */ .data : AT(ADDR(.data) - LOAD_OFFSET) { /* Data */ @@ -59,10 +62,12 @@ SECTIONS } :data . = ALIGN(4096); - __nosave_begin = .; - .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) { *(.data.nosave) } - . = ALIGN(4096); - __nosave_end = .; + .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) { + __nosave_begin = .; + *(.data.nosave) + . = ALIGN(4096); + __nosave_end = .; + } . = ALIGN(4096); .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) { @@ -76,8 +81,10 @@ SECTIONS /* rarely changed data like cpu maps */ . = ALIGN(32); - .data.read_mostly : AT(ADDR(.data.read_mostly) - LOAD_OFFSET) { *(.data.read_mostly) } - _edata = .; /* End of data section */ + .data.read_mostly : AT(ADDR(.data.read_mostly) - LOAD_OFFSET) { + *(.data.read_mostly) + _edata = .; /* End of data section */ + } #ifdef CONFIG_STACK_UNWIND . = ALIGN(4); @@ -95,39 +102,41 @@ SECTIONS /* might get freed after init */ . = ALIGN(4096); - __smp_alt_begin = .; - __smp_alt_instructions = .; .smp_altinstructions : AT(ADDR(.smp_altinstructions) - LOAD_OFFSET) { + __smp_alt_begin = .; + __smp_alt_instructions = .; *(.smp_altinstructions) + __smp_alt_instructions_end = .; } - __smp_alt_instructions_end = .; . = ALIGN(4); - __smp_locks = .; .smp_locks : AT(ADDR(.smp_locks) - LOAD_OFFSET) { + __smp_locks = .; *(.smp_locks) + __smp_locks_end = .; } - __smp_locks_end = .; .smp_altinstr_replacement : AT(ADDR(.smp_altinstr_replacement) - LOAD_OFFSET) { *(.smp_altinstr_replacement) + . = ALIGN(4096); + __smp_alt_end = .; } - . = ALIGN(4096); - __smp_alt_end = .; /* will be freed after init */ . = ALIGN(4096); /* Init code and data */ - __init_begin = .; .init.text : AT(ADDR(.init.text) - LOAD_OFFSET) { + __init_begin = .; _sinittext = .; *(.init.text) _einittext = .; } .init.data : AT(ADDR(.init.data) - LOAD_OFFSET) { *(.init.data) } . = 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) { + __setup_start = .; + *(.init.setup) + __setup_end = .; + } .initcall.init : AT(ADDR(.initcall.init) - LOAD_OFFSET) { + __initcall_start = .; *(.initcall1.init) *(.initcall2.init) *(.initcall3.init) @@ -135,20 +144,20 @@ SECTIONS *(.initcall5.init) *(.initcall6.init) *(.initcall7.init) + __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 = .; SECURITY_INIT . = ALIGN(4); - __alt_instructions = .; .altinstructions : AT(ADDR(.altinstructions) - LOAD_OFFSET) { + __alt_instructions = .; *(.altinstructions) + __alt_instructions_end = .; } - __alt_instructions_end = .; .altinstr_replacement : AT(ADDR(.altinstr_replacement) - LOAD_OFFSET) { *(.altinstr_replacement) } @@ -157,32 +166,32 @@ SECTIONS .exit.text : AT(ADDR(.exit.text) - LOAD_OFFSET) { *(.exit.text) } .exit.data : AT(ADDR(.exit.data) - LOAD_OFFSET) { *(.exit.data) } . = ALIGN(4096); - __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 = .; + } . = ALIGN(L1_CACHE_BYTES); - __per_cpu_start = .; - .data.percpu : AT(ADDR(.data.percpu) - LOAD_OFFSET) { *(.data.percpu) } - __per_cpu_end = .; + .data.percpu : AT(ADDR(.data.percpu) - LOAD_OFFSET) { + __per_cpu_start = .; + *(.data.percpu) + __per_cpu_end = .; + } . = ALIGN(4096); - __init_end = .; /* freed after init ends here */ - __bss_start = .; /* BSS */ - .bss.page_aligned : AT(ADDR(.bss.page_aligned) - LOAD_OFFSET) { - *(.bss.page_aligned) - } .bss : AT(ADDR(.bss) - LOAD_OFFSET) { + __init_end = .; + __bss_start = .; /* BSS */ + *(.bss.page_aligned) *(.bss) + . = ALIGN(4); + __bss_stop = .; + _end = . ; + /* This is where the kernel creates the early boot page tables */ + . = ALIGN(4096); + pg0 = . ; } - . = ALIGN(4); - __bss_stop = .; - - _end = . ; - - /* This is where the kernel creates the early boot page tables */ - . = ALIGN(4096); - pg0 = .; /* Sections to be discarded */ /DISCARD/ : { diff -puN include/asm-generic/vmlinux.lds.h~i386-distinguish-absolute-symbols include/asm-generic/vmlinux.lds.h --- a/include/asm-generic/vmlinux.lds.h~i386-distinguish-absolute-symbols +++ a/include/asm-generic/vmlinux.lds.h @@ -11,8 +11,8 @@ #define RODATA \ . = ALIGN(4096); \ - __start_rodata = .; \ .rodata : AT(ADDR(.rodata) - LOAD_OFFSET) { \ + VMLINUX_SYMBOL(__start_rodata) = .; \ *(.rodata) *(.rodata.*) \ *(__vermagic) /* Kernel version magic */ \ } \ @@ -124,8 +124,8 @@ VMLINUX_SYMBOL(__start___param) = .; \ *(__param) \ VMLINUX_SYMBOL(__stop___param) = .; \ + VMLINUX_SYMBOL(__end_rodata) = .; \ } \ - __end_rodata = .; \ . = ALIGN(4096); #define SECURITY_INIT \ _ Patches currently in -mm which might be from vgoyal@xxxxxxxxxx are origin.patch i386-distinguish-absolute-symbols.patch i386-align-data-section-to-4k-boundary.patch i386-force-section-size-to-be-non-zero-to-prevent-a-symbol-becoming-absolute.patch i386-define-__pa_symbol.patch i386-setupc-reserve-kernel-memory-starting-from-_text.patch i386-config_physical_start-cleanup.patch make-linux-elfh-safe-to-be-included-in-assembly-files.patch elf-add-elfosabi_standalone-to-elfh.patch kallsyms-generate-relocatable-symbols.patch i386-relocatable-kernel-support.patch i386-implement-config_physical_align.patch i386-boot-add-an-elf-header-to-bzimage.patch - To unsubscribe from this list: send the line "unsubscribe mm-commits" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html