Skip to content

Commit

Permalink
[PATCH] x86-64: Relocatable Kernel Support
Browse files Browse the repository at this point in the history
This patch modifies the x86_64 kernel so that it can be loaded and run
at any 2M aligned address, below 512G.  The technique used is to
compile the decompressor with -fPIC and modify it so the decompressor
is fully relocatable.  For the main kernel the page tables are
modified so the kernel remains at the same virtual address.  In
addition a variable phys_base is kept that holds the physical address
the kernel is loaded at.  __pa_symbol is modified to add that when
we take the address of a kernel symbol.

When loaded with a normal bootloader the decompressor will decompress
the kernel to 2M and it will run there.  This both ensures the
relocation code is always working, and makes it easier to use 2M
pages for the kernel and the cpu.

AK: changed to not make RELOCATABLE default in Kconfig

Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
Signed-off-by: Vivek Goyal <vgoyal@in.ibm.com>
Signed-off-by: Andi Kleen <ak@suse.de>
  • Loading branch information
Vivek Goyal authored and Andi Kleen committed May 2, 2007
1 parent 0dbf702 commit 1ab60e0
Show file tree
Hide file tree
Showing 9 changed files with 597 additions and 332 deletions.
49 changes: 41 additions & 8 deletions arch/x86_64/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -565,23 +565,56 @@ config CRASH_DUMP
PHYSICAL_START.
For more details see Documentation/kdump/kdump.txt

config RELOCATABLE
bool "Build a relocatable kernel(EXPERIMENTAL)"
depends on EXPERIMENTAL
help
Builds a relocatable kernel. This enables loading and running
a kernel binary from a different physical address than it has
been compiled for.

One use is for the kexec on panic case where the recovery kernel
must live at a different physical address than the primary
kernel.

Note: If CONFIG_RELOCATABLE=y, then kernel run from the address
it has been loaded at and compile time physical address
(CONFIG_PHYSICAL_START) is ignored.

config PHYSICAL_START
hex "Physical address where the kernel is loaded" if (EMBEDDED || CRASH_DUMP)
default "0x1000000" if CRASH_DUMP
default "0x200000"
help
This gives the physical address where the kernel is loaded. Normally
for regular kernels this value is 0x200000 (2MB). But in the case
of kexec on panic the fail safe kernel needs to run at a different
address than the panic-ed kernel. This option is used to set the load
address for kernels used to capture crash dump on being kexec'ed
after panic. The default value for crash dump kernels is
0x1000000 (16MB). This can also be set based on the "X" value as
This gives the physical address where the kernel is loaded. It
should be aligned to 2MB boundary.

If kernel is a not relocatable (CONFIG_RELOCATABLE=n) then
bzImage will decompress itself to above physical address and
run from there. Otherwise, bzImage will run from the address where
it has been loaded by the boot loader and will ignore above physical
address.

In normal kdump cases one does not have to set/change this option
as now bzImage can be compiled as a completely relocatable image
(CONFIG_RELOCATABLE=y) and be used to load and run from a different
address. This option is mainly useful for the folks who don't want
to use a bzImage for capturing the crash dump and want to use a
vmlinux instead.

So if you are using bzImage for capturing the crash dump, leave
the value here unchanged to 0x200000 and set CONFIG_RELOCATABLE=y.
Otherwise if you plan to use vmlinux for capturing the crash dump
change this value to start of the reserved region (Typically 16MB
0x1000000). In other words, it can be set based on the "X" value as
specified in the "crashkernel=YM@XM" command line boot parameter
passed to the panic-ed kernel. Typically this parameter is set as
crashkernel=64M@16M. Please take a look at
Documentation/kdump/kdump.txt for more details about crash dumps.

Usage of bzImage for capturing the crash dump is advantageous as
one does not have to build two kernels. Same kernel can be used
as production kernel and capture kernel.

Don't change this unless you know what you are doing.

config SECCOMP
Expand Down
12 changes: 5 additions & 7 deletions arch/x86_64/boot/compressed/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,14 @@

targets := vmlinux vmlinux.bin vmlinux.bin.gz head.o misc.o piggy.o
EXTRA_AFLAGS := -traditional
AFLAGS := $(subst -m64,-m32,$(AFLAGS))

# cannot use EXTRA_CFLAGS because base CFLAGS contains -mkernel which conflicts with
# -m32
CFLAGS := -m32 -D__KERNEL__ -Iinclude -O2 -fno-strict-aliasing
LDFLAGS := -m elf_i386
CFLAGS := -m64 -D__KERNEL__ -Iinclude -O2 -fno-strict-aliasing -fPIC -mcmodel=small -fno-builtin
LDFLAGS := -m elf_x86_64

LDFLAGS_vmlinux := -Ttext $(IMAGE_OFFSET) -e startup_32 -m elf_i386

$(obj)/vmlinux: $(obj)/head.o $(obj)/misc.o $(obj)/piggy.o FORCE
LDFLAGS_vmlinux := -T
$(obj)/vmlinux: $(src)/vmlinux.lds $(obj)/head.o $(obj)/misc.o $(obj)/piggy.o FORCE
$(call if_changed,ld)
@:

Expand All @@ -27,7 +25,7 @@ $(obj)/vmlinux.bin: vmlinux FORCE
$(obj)/vmlinux.bin.gz: $(obj)/vmlinux.bin FORCE
$(call if_changed,gzip)

LDFLAGS_piggy.o := -r --format binary --oformat elf32-i386 -T
LDFLAGS_piggy.o := -r --format binary --oformat elf64-x86-64 -T

$(obj)/piggy.o: $(obj)/vmlinux.scr $(obj)/vmlinux.bin.gz FORCE
$(call if_changed,ld)
Loading

0 comments on commit 1ab60e0

Please sign in to comment.