[1/5] README

R Sharada sharada at in.ibm.com
Thu Apr 14 00:12:39 EST 2005

This package contains files used to develop and test kexec on the
ppc64 platform.  Specifically, v2wrap, a minimal wrapper to call the
kernel entry point from the kexec entrypoint context, fs2dt, a program to
generate a boot-block and device tree structure (the structured arguments
the kernel expects to find on entry) from a file system representation,
and loadem, a minimalist program to call kexec with user specified
arguments ("load the contents of this file here").  

After the description are some examples, followed by some bulid and
design notes.



Stub assembly code for trampoline during kexec boot, converting the master
cpu thread's argument registers from those provided by kexec to those
expected by the 2.6.10 or later kernel.  The boot-block and device-tree
are assumed to immediately follow the code, and kernel is located by
reading the last word in this stub, which is patched by the kexec user
space tools.  Since some platforms do not allow cpus to be stopped and
restarted, they must always be running valid code, thus expanding the
trampoline from a simple store and a load.  Secondary cpus are expected
to start in a copy of this code located at address 0x60.  The secondary
cpus are told to move to the master copy of the code, the kernel code
is copied to address 0, and then the secondary are moved to the kernels
code block before transfering the master cpu thread to the new kernel.


fs2dt creates a flattened data block of the device-tree from a file system
representation, such as that provided by the kernel in /proc/device-tree.
This flatened data block is passed by reference to the new kernel (the
address is placed in a register).  Since this block itself must be placed
in the contained list of memory regions to reserve, the address to load
this block of data is passed as an argument with the -b flag.

The syntax for invoking the tool is
./fs2dt -b <load-address> <path-to-device_tree-tree>

./fs2dt -b 0x5000100 /proc/device-tree

The tool outputs to stdout, which can be redirected and stored in
a to file, or passed directly to another tool like loadem.


loadem is a small program that can invoke the either the reboot syscall
with kexec arg, or read files (and/or stdin) into memory and call the
kexec_load syscall without any interpretation of the loaded contents.
Although written to test the ppc64 kexec kernel code, it should work on
any architecture (the -c option should have a trival change for little

Arguments supported by loadem:

-a <load-address> 
	=> Start a new segment at the given address
-c <offset> 
	=> chain this segment -- place the current segments address
	anchored at at offset bytes into the previous segment 
	=> save the current address as the kexec entry point 
-f <filename> 
	=> load this file into the current segment
	=> perform a kexec reboot
	=> load the kernel for kexec reboot under panic case
-r <page-size> 
	=> round up the segment size to the given page-size boundary (the
	beginning of a segment must be page aligned by the user)
	=> read input from stdin and add to the current segment
-t <arch> 
	=> provide the native architecture (this is needed when we are
	running the loadem as a 32bit utility on a 64 bit kernel)
-z <size>
	=> zero extend the segment by increasing memsz


In the examples below, the trampoline v2wrap and the device-tree generated
by fs2dt are loaded into the first segment.  The second segment is the
actual the kernel to be loaded, which can be obtained by the objcopy
command from the vmlinux.  The word anchored (ending) at offset 100 in the
first segment is patched with the address of the beginning of the second
segment, providing v2wrap the lcoation of the kernel.  Optionally, a
ramdisk can be loaded into an additional segment which the kernel would
locate via properties placed in the device-tree.  On PPC64, the kernel
can be loaded at any word-aligned address that fits within the real mode
limit and the kernel will copy itself into its linked execution location.

Extract the kernel load image from the ELF file:
objcopy -O binary vmlinux vmlinux.kexec

Example for testing a simple kernel, without ramdisk (one line):
./fs2dt -b 0x5000100 /proc/device-tree/ | ./loadem -t 21 -a 0x5000000 -e -f 
v2wrap -s -a 0x6000000 -c 0x100 -f vmlinux.kexec -r 0x1000

Example loading two cpios into an initramfs at address 38000000 and
clearing 1MB at 768MB on PPC64 with 4k page size (one line):
/fs2dt -b 0x5000100 /proc/device-tree/ | /loadem -t 0x15 -r 0x1000
-a 0x5000000 -e -f /v2wrap -s -a 0x6000000 -c 0x100 -f vmlinux.kexec
-a 0x38000000 -f fs_large.cpio.gz -4 -f kexec.cpio.gz -a 0x30000000 -z 0x10000


The programs were developed with the following goals in mind:
	1) Do only what is necessary
	2) Simple, easy to port
	3) Provide explicit control to a power user
	3) Be of minimal size
	4) Easily ported to other libraries
These goals are reflected in choices such as minimalist error reporting
and making no calls to printf.  Goals 3 and 4 are intended to target the
tools to a limited initramfs environment.

While the utilities can be compiled as 32-bit or 64-bit programs,
the included Makefile creates 32-bit static executables.  When using
a 64-bit kernel, the compat wrapper requires the architecture to be
specified explicitly.  This can be achieved with the -t flag.

In additon to the files included, loadem.c includes kexec-syscall.h
which can be obtained from the kexec-tools package.   As of our testing
with version 1.99, the file was located in the kexec subdirectory.
Simply copy it into the directory you unpack these files.

The anchor point used for the -c flag is defined the address of the end
of the word that will not move as the word size changes.  Using this
scheme means the anchor point is independent of word size.  For big
endian machines, this is the address of the byte following the word,
or a word offset of -1.  For little endian machines, offset 0 should
be used and the chain point would be the first byte.  Note that the code
currently does not detect endian, but is hardcoded for big endian.

Passing an initramfs or initrd to a ppc64 kernel requires the addresses
to be placed as properties in the device tree.  While fs2dt will 
automatically reserve the memory for the initrd, changing the initrd
size or load address requires copying the device-tree and changing binary
files in the copied tree.

More information about the Linuxppc64-dev mailing list