code:
.. SPDX-License-Identifier: GPL-2.0

TAA - TSX Asynchronous Abort
======================================

TAA is a hardware vulnerability that allows unprivileged speculative access to
data which is available in various CPU internal buffers by using asynchronous
aborts within an Intel TSX transactional region.

Affected processors
-------------------

This vulnerability only affects Intel processors that support Intel
Transactional Synchronization Extensions (TSX) when the TAA_NO bit (bit 8)
is 0 in the IA32_ARCH_CAPABILITIES MSR.  On processors where the MDS_NO bit
(bit 5) is 0 in the IA32_ARCH_CAPABILITIES MSR, the existing MDS mitigations
also mitigate against TAA.

Whether a processor is affected or not can be read out from the TAA
vulnerability file in sysfs. See :ref:`tsx_async_abort_sys_info`.

Related CVEs
------------

The following CVE entry is related to this TAA issue:

   ==============  =====  ===================================================
   CVE-2019-11135  TAA    TSX Asynchronous Abort (TAA) condition on some
                          microprocessors utilizing speculative execution may
                          allow an authenticated user to potentially enable
                          information disclosure via a side channel with
                          local access.
   ==============  =====  ===================================================

Problem
-------

When performing store, load or L1 refill operations, processors write
data into temporary microarchitectural structures (buffers). The data in
those buffers can be forwarded to load operations as an optimization.

Intel TSX is an extension to the x86 instruction set architecture that adds
hardware transactional memory support to improve performance of multi-threaded
software. TSX lets the processor expose and exploit concurrency hidden in an
application due to dynamically avoiding unnecessary synchronization.

TSX supports atomic memory transactions that are either committed (success) or
aborted. During an abort, operations that happened within the transactional region
are rolled back. An asynchronous abort takes place, among other options, when a
different thread accesses a cache line that is also used within the transactional
region when that access might lead to a data race.

Immediately after an uncompleted asynchronous abort, certain speculatively
executed loads may read data from those internal buffers and pass it to dependent
operations. This can be then used to infer the value via a cache side channel
attack.

Because the buffers are potentially shared between Hyper-Threads cross
Hyper-Thread attacks are possible.

The victim of a malicious actor does not need to make use of TSX. Only the
attacker needs to begin a TSX transaction and raise an asynchronous abort
which in turn potentially leaks data stored in the buffers.

More detailed technical information is available in the TAA specific x86
architecture section: :ref:`Documentation/x86/tsx_async_abort.rst <tsx_async_abort>`.

Attack scenarios
----------------

Attacks against the TAA vulnerability can be implemented from unprivileged
applications running on hosts or guests.

As for MDS, the attacker has no control over the memory addresses that can
be leaked. Only the victim is responsible for bringing data to the CPU. As
a result, the malicious actor has to sample as much data as possible and
then postprocess it to try to infer any useful information from it.

A potential attacker only has read access to the data. Also, there is no direct
privilege escalation by using this technique.

.. _tsx_async_abort_sys_info:

TAA system information
-----------------------

The Linux kernel provides a sysfs interface to enumerate the current TAA status
of mitigated systems. The relevant sysfs file is:

/sys/devices/system/cpu/vulnerabilities/tsx_async_abort

The possible values in this file are:

.. list-table::

   * - 'Vulnerable'
     - The CPU is affected by this vulnerability and the microcode and kernel mitigation are not applied.
   * - 'Vulnerable: Clear CPU buffers attempted, no microcode'
     - The system tries to clear the buffers but the microcode might not support the operation.
   * - 'Mitigation: Clear CPU buffers'
     - The microcode has been updated to clear the buffers. TSX is still enabled.
   * - 'Mitigation: TSX disabled'
     - TSX is disabled.
   * - 'Not affected'
     - The CPU is not affected by this issue.

.. _ucode_needed:

Best effort mitigation mode
^^^^^^^^^^^^^^^^^^^^^^^^^^^

If the processor is vulnerable, but the availability of the microcode-based
mitigation mechanism is not advertised via CPUID the kernel selects a best
effort mitigation mode.  This mode invokes the mitigation instructions
without a guarantee that they clear the CPU buffers.

This is done to address virtualization scenarios where the host has the
microcode update applied, but the hypervisor is not yet updated to expose the
CPUID to the guest. If the host has updated microcode the protection takes
effect; otherwise a few CPU cycles are wasted pointlessly.

The state in the tsx_async_abort sysfs file reflects this situation
accordingly.

Mitigation mechanism
--------------------

The kernel detects the affected CPUs and the presence of the microcode which is
required. If a CPU is affected and the microcode is available, then the kernel
enables the mitigation by default.

The mitigation can be controlled at boot time via a kernel command line option.
See :ref:`taa_mitigation_control_command_line`.

Virtualization mitigation
^^^^^^^^^^^^^^^^^^^^^^^^^

Affected systems where the host has TAA microcode and TAA is mitigated by
having disabled TSX previously, are not vulnerable regardless of the status
of the VMs.

In all other cases, if the host either does not have the TAA microcode or
the kernel is not mitigated, the system might be vulnerable.

.. _taa_mitigation_control_command_line:

Mitigation control on the kernel command line
---------------------------------------------

The kernel command line allows to control the TAA mitigations at boot time with
the option "tsx_async_abort=". The valid arguments for this option are:

  ============  =============================================================
  off		This option disables the TAA mitigation on affected platforms.
                If the system has TSX enabled (see next parameter) and the CPU
                is affected, the system is vulnerable.

  full	        TAA mitigation is enabled. If TSX is enabled, on an affected
                system it will clear CPU buffers on ring transitions. On
                systems which are MDS-affected and deploy MDS mitigation,
                TAA is also mitigated. Specifying this option on those
                systems will have no effect.

  full,nosmt    The same as tsx_async_abort=full, with SMT disabled on
                vulnerable CPUs that have TSX enabled. This is the complete
                mitigation. When TSX is disabled, SMT is not disabled because
                CPU is not vulnerable to cross-thread TAA attacks.
  ============  =============================================================

Not specifying this option is equivalent to "tsx_async_abort=full". For
processors that are affected by both TAA and MDS, specifying just
"tsx_async_abort=off" without an accompanying "mds=off" will have no
effect as the same mitigation is used for both vulnerabilities.

The kernel command line also allows to control the TSX feature using the
parameter "tsx=" on CPUs which support TSX control. MSR_IA32_TSX_CTRL is used
to control the TSX feature and the enumeration of the TSX feature bits (RTM
and HLE) in CPUID.

The valid options are:

  ============  =============================================================
  off		Disables TSX on the system.

                Note that this option takes effect only on newer CPUs which are
                not vulnerable to MDS, i.e., have MSR_IA32_ARCH_CAPABILITIES.MDS_NO=1
                and which get the new IA32_TSX_CTRL MSR through a microcode
                update. This new MSR allows for the reliable deactivation of
                the TSX functionality.

  on		Enables TSX.

                Although there are mitigations for all known security
                vulnerabilities, TSX has been known to be an accelerator for
                several previous speculation-related CVEs, and so there may be
                unknown security risks associated with leaving it enabled.

  auto		Disables TSX if X86_BUG_TAA is present, otherwise enables TSX
                on the system.
  ============  =============================================================

Not specifying this option is equivalent to "tsx=off".

The following combinations of the "tsx_async_abort" and "tsx" are possible. For
affected platforms tsx=auto is equivalent to tsx=off and the result will be:

  =========  ==========================   =========================================
  tsx=on     tsx_async_abort=full         The system will use VERW to clear CPU
                                          buffers. Cross-thread attacks are still
					  possible on SMT machines.
  tsx=on     tsx_async_abort=full,nosmt   As above, cross-thread attacks on SMT
                                          mitigated.
  tsx=on     tsx_async_abort=off          The system is vulnerable.
  tsx=off    tsx_async_abort=full         TSX might be disabled if microcode
                                          provides a TSX control MSR. If so,
					  system is not vulnerable.
  tsx=off    tsx_async_abort=full,nosmt   Ditto
  tsx=off    tsx_async_abort=off          ditto
  =========  ==========================   =========================================

For unaffected platforms "tsx=on" and "tsx_async_abort=full" does not clear CPU
buffers.  For platforms without TSX control (MSR_IA32_ARCH_CAPABILITIES.MDS_NO=0)
"tsx" command line argument has no effect.

For the affected platforms below table indicates the mitigation status for the
combinations of CPUID bit MD_CLEAR and IA32_ARCH_CAPABILITIES MSR bits MDS_NO
and TSX_CTRL_MSR.

  =======  =========  =============  ========================================
  MDS_NO   MD_CLEAR   TSX_CTRL_MSR   Status
  =======  =========  =============  ========================================
    0          0            0        Vulnerable (needs microcode)
    0          1            0        MDS and TAA mitigated via VERW
    1          1            0        MDS fixed, TAA vulnerable if TSX enabled
                                     because MD_CLEAR has no meaning and
                                     VERW is not guaranteed to clear buffers
    1          X            1        MDS fixed, TAA can be mitigated by
                                     VERW or TSX_CTRL_MSR
  =======  =========  =============  ========================================

Mitigation selection guide
--------------------------

1. Trusted userspace and guests
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

If all user space applications are from a trusted source and do not execute
untrusted code which is supplied externally, then the mitigation can be
disabled. The same applies to virtualized environments with trusted guests.

2. Untrusted userspace and guests
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

If there are untrusted applications or guests on the system, enabling TSX
might allow a malicious actor to leak data from the host or from other
processes running on the same physical core.

If the microcode is available and the TSX is disabled on the host, attacks
are prevented in a virtualized environment as well, even if the VMs do not
explicitly enable the mitigation.

.. _taa_default_mitigations:

Default mitigations
-------------------

The kernel's default action for vulnerable processors is:

  - Deploy TSX disable mitigation (tsx_async_abort=full tsx=off).


code:
=================================
Hardware random number generators
=================================

Introduction
============

The hw_random framework is software that makes use of a
special hardware feature on your CPU or motherboard,
a Random Number Generator (RNG).  The software has two parts:
a core providing the /dev/hwrng character device and its
sysfs support, plus a hardware-specific driver that plugs
into that core.

To make the most effective use of these mechanisms, you
should download the support software as well.  Download the
latest version of the "rng-tools" package from the
hw_random driver's official Web site:

	http://sourceforge.net/projects/gkernel/

Those tools use /dev/hwrng to fill the kernel entropy pool,
which is used internally and exported by the /dev/urandom and
/dev/random special files.

Theory of operation
===================

CHARACTER DEVICE.  Using the standard open()
and read() system calls, you can read random data from
the hardware RNG device.  This data is NOT CHECKED by any
fitness tests, and could potentially be bogus (if the
hardware is faulty or has been tampered with).  Data is only
output if the hardware "has-data" flag is set, but nevertheless
a security-conscious person would run fitness tests on the
data before assuming it is truly random.

The rng-tools package uses such tests in "rngd", and lets you
run them by hand with a "rngtest" utility.

/dev/hwrng is char device major 10, minor 183.

CLASS DEVICE.  There is a /sys/class/misc/hw_random node with
two unique attributes, "rng_available" and "rng_current".  The
"rng_available" attribute lists the hardware-specific drivers
available, while "rng_current" lists the one which is currently
connected to /dev/hwrng.  If your system has more than one
RNG available, you may change the one used by writing a name from
the list in "rng_available" into "rng_current".

==========================================================================

Hardware driver for Intel/AMD/VIA Random Number Generators (RNG)
	- Copyright 2000,2001 Jeff Garzik <jgarzik@pobox.com>
	- Copyright 2000,2001 Philipp Rumpf <prumpf@mandrakesoft.com>

About the Intel RNG hardware, from the firmware hub datasheet
=============================================================

The Firmware Hub integrates a Random Number Generator (RNG)
using thermal noise generated from inherently random quantum
mechanical properties of silicon. When not generating new random
bits the RNG circuitry will enter a low power state. Intel will
provide a binary software driver to give third party software
access to our RNG for use as a security feature. At this time,
the RNG is only to be used with a system in an OS-present state.

Intel RNG Driver notes
======================

FIXME: support poll(2)

.. note::

	request_mem_region was removed, for three reasons:

	1) Only one RNG is supported by this driver;
	2) The location used by the RNG is a fixed location in
	   MMIO-addressable memory;
	3) users with properly working BIOS e820 handling will always
	   have the region in which the RNG is located reserved, so
	   request_mem_region calls always fail for proper setups.
	   However, for people who use mem=XX, BIOS e820 information is
	   **not** in /proc/iomem, and request_mem_region(RNG_ADDR) can
	   succeed.

Driver details
==============

Based on:
	Intel 82802AB/82802AC Firmware Hub (FWH) Datasheet
	May 1999 Order Number: 290658-002 R

Intel 82802 Firmware Hub:
	Random Number Generator
	Programmer's Reference Manual
	December 1999 Order Number: 298029-001 R

Intel 82802 Firmware HUB Random Number Generator Driver
	Copyright (c) 2000 Matt Sottek <msottek@quiknet.com>

Special thanks to Matt Sottek.  I did the "guts", he
did the "brains" and all the testing.

repo_name: angery/linux


code:
The Linux kernel user's and administrator's guide
=================================================

The following is a collection of user-oriented documents that have been
added to the kernel over time.  There is, as yet, little overall order or
organization here — this material was not written to be a single, coherent
document!  With luck things will improve quickly over time.

This initial section contains overall information, including the README
file describing the kernel as a whole, documentation on kernel parameters,
etc.

.. toctree::
   :maxdepth: 1

   README
   kernel-parameters
   devices
   sysctl/index

   abi
   features

This section describes CPU vulnerabilities and their mitigations.

.. toctree::
   :maxdepth: 1

   hw-vuln/index

Here is a set of documents aimed at users who are trying to track down
problems and bugs in particular.

.. toctree::
   :maxdepth: 1

   reporting-issues
   reporting-regressions
   security-bugs
   bug-hunting
   bug-bisect
   tainted-kernels
   ramoops
   dynamic-debug-howto
   init
   kdump/index
   perf/index
   pstore-blk

This is the beginning of a section with information of interest to
application developers.  Documents covering various aspects of the kernel
ABI will be found here.

.. toctree::
   :maxdepth: 1

   sysfs-rules

The rest of this manual consists of various unordered guides on how to
configure specific aspects of kernel behavior to your liking.

.. toctree::
   :maxdepth: 1

   acpi/index
   aoe/index
   auxdisplay/index
   bcache
   binderfs
   binfmt-misc
   blockdev/index
   bootconfig
   braille-console
   btmrvl
   cgroup-v1/index
   cgroup-v2
   cifs/index
   clearing-warn-once
   cpu-load
   cputopology
   dell_rbu
   device-mapper/index
   edid
   efi-stub
   ext4
   filesystem-monitoring
   nfs/index
   gpio/index
   highuid
   hw_random
   initrd
   iostats
   java
   jfs
   kernel-per-CPU-kthreads
   laptops/index
   lcd-panel-cgram
   ldm
   lockup-watchdogs
   LSM/index
   md
   media/index
   mm/index
   module-signing
   mono
   namespaces/index
   numastat
   parport
   perf-security
   pm/index
   pnp
   rapidio
   ras
   rtc
   serial-console
   svga
   syscall-user-dispatch
   sysrq
   thunderbolt
   ufs
   unicode
   vga-softcursor
   video-output
   xfs

.. only::  subproject and html

   Indices
   =======

   * :ref:`genindex`


code:
Explaining the "No working init found." boot hang message
=========================================================
:Authors: Andreas Mohr <andi at lisas period de>
          Cristian Souza <cristianmsbr at gmail period com>

This document provides some high-level reasons for failure
(listed roughly in order of execution) to load the init binary.

1) **Unable to mount root FS**: Set "debug" kernel parameter (in bootloader
   config file or CONFIG_CMDLINE) to get more detailed kernel messages.

2) **init binary doesn't exist on rootfs**: Make sure you have the correct
   root FS type (and ``root=`` kernel parameter points to the correct
   partition), required drivers such as storage hardware (such as SCSI or
   USB!) and filesystem (ext3, jffs2, etc.) are builtin (alternatively as
   modules, to be pre-loaded by an initrd).

3) **Broken console device**: Possibly a conflict in ``console= setup``
   --> initial console unavailable. E.g. some serial consoles are unreliable
   due to serial IRQ issues (e.g. missing interrupt-based configuration).
   Try using a different ``console= device`` or e.g. ``netconsole=``.

4) **Binary exists but dependencies not available**: E.g. required library
   dependencies of the init binary such as ``/lib/ld-linux.so.2`` missing or
   broken. Use ``readelf -d <INIT>|grep NEEDED`` to find out which libraries
   are required.

5) **Binary cannot be loaded**: Make sure the binary's architecture matches
   your hardware. E.g. i386 vs. x86_64 mismatch, or trying to load x86 on ARM
   hardware. In case you tried loading a non-binary file here (shell script?),
   you should make sure that the script specifies an interpreter in its
   shebang header line (``#!/...``) that is fully working (including its
   library dependencies). And before tackling scripts, better first test a
   simple non-script binary such as ``/bin/sh`` and confirm its successful
   execution. To find out more, add code ``to init/main.c`` to display
   kernel_execve()s return values.

Please extend this explanation whenever you find new failure causes
(after all loading the init binary is a CRITICAL and hard transition step
which needs to be made as painless as possible), then submit a patch to LKML.
Further TODOs:

- Implement the various ``run_init_process()`` invocations via a struct array
  which can then store the ``kernel_execve()`` result value and on failure
  log it all by iterating over **all** results (very important usability fix).
- Try to make the implementation itself more helpful in general, e.g. by
  providing additional error messages at affected places.


code:
Using the initial RAM disk (initrd)
===================================

Written 1996,2000 by Werner Almesberger <werner.almesberger@epfl.ch> and
Hans Lermen <lermen@fgan.de>

initrd provides the capability to load a RAM disk by the boot loader.
This RAM disk can then be mounted as the root file system and programs
can be run from it. Afterwards, a new root file system can be mounted
from a different device. The previous root (from initrd) is then moved
to a directory and can be subsequently unmounted.

initrd is mainly designed to allow system startup to occur in two phases,
where the kernel comes up with a minimum set of compiled-in drivers, and
where additional modules are loaded from initrd.

This document gives a brief overview of the use of initrd. A more detailed
discussion of the boot process can be found in [#f1]_.

Operation
---------

When using initrd, the system typically boots as follows:

  1) the boot loader loads the kernel and the initial RAM disk
  2) the kernel converts initrd into a "normal" RAM disk and
     frees the memory used by initrd
  3) if the root device is not ``/dev/ram0``, the old (deprecated)
     change_root procedure is followed. see the "Obsolete root change
     mechanism" section below.
  4) root device is mounted. if it is ``/dev/ram0``, the initrd image is
     then mounted as root
  5) /sbin/init is executed (this can be any valid executable, including
     shell scripts; it is run with uid 0 and can do basically everything
     init can do).
  6) init mounts the "real" root file system
  7) init places the root file system at the root directory using the
     pivot_root system call
  8) init execs the ``/sbin/init`` on the new root filesystem, performing
     the usual boot sequence
  9) the initrd file system is removed

Note that changing the root directory does not involve unmounting it.
It is therefore possible to leave processes running on initrd during that
procedure. Also note that file systems mounted under initrd continue to
be accessible.

Boot command-line options
-------------------------

initrd adds the following new options::

  initrd=<path>    (e.g. LOADLIN)

    Loads the specified file as the initial RAM disk. When using LILO, you
    have to specify the RAM disk image file in /etc/lilo.conf, using the
    INITRD configuration variable.

  noinitrd

    initrd data is preserved but it is not converted to a RAM disk and
    the "normal" root file system is mounted. initrd data can be read
    from /dev/initrd. Note that the data in initrd can have any structure
    in this case and doesn't necessarily have to be a file system image.
    This option is used mainly for debugging.

    Note: /dev/initrd is read-only and it can only be used once. As soon
    as the last process has closed it, all data is freed and /dev/initrd
    can't be opened anymore.

  root=/dev/ram0

    initrd is mounted as root, and the normal boot procedure is followed,
    with the RAM disk mounted as root.

Compressed cpio images
----------------------

Recent kernels have support for populating a ramdisk from a compressed cpio
archive. On such systems, the creation of a ramdisk image doesn't need to
involve special block devices or loopbacks; you merely create a directory on
disk with the desired initrd content, cd to that directory, and run (as an
example)::

	find . | cpio --quiet -H newc -o | gzip -9 -n > /boot/imagefile.img

Examining the contents of an existing image file is just as simple::

	mkdir /tmp/imagefile
	cd /tmp/imagefile
	gzip -cd /boot/imagefile.img | cpio -imd --quiet

Installation
------------

First, a directory for the initrd file system has to be created on the
"normal" root file system, e.g.::

	# mkdir /initrd

The name is not relevant. More details can be found on the
:manpage:`pivot_root(2)` man page.

If the root file system is created during the boot procedure (i.e. if
you're building an install floppy), the root file system creation
procedure should create the ``/initrd`` directory.

If initrd will not be mounted in some cases, its content is still
accessible if the following device has been created::

	# mknod /dev/initrd b 1 250
	# chmod 400 /dev/initrd

Second, the kernel has to be compiled with RAM disk support and with
support for the initial RAM disk enabled. Also, at least all components
needed to execute programs from initrd (e.g. executable format and file
system) must be compiled into the kernel.

Third, you have to create the RAM disk image. This is done by creating a
file system on a block device, copying files to it as needed, and then
copying the content of the block device to the initrd file. With recent
kernels, at least three types of devices are suitable for that:

 - a floppy disk (works everywhere but it's painfully slow)
 - a RAM disk (fast, but allocates physical memory)
 - a loopback device (the most elegant solution)

We'll describe the loopback device method:

 1) make sure loopback block devices are configured into the kernel
 2) create an empty file system of the appropriate size, e.g.::

	# dd if=/dev/zero of=initrd bs=300k count=1
	# mke2fs -F -m0 initrd

    (if space is critical, you may want to use the Minix FS instead of Ext2)
 3) mount the file system, e.g.::

	# mount -t ext2 -o loop initrd /mnt

 4) create the console device::

    # mkdir /mnt/dev
    # mknod /mnt/dev/console c 5 1

 5) copy all the files that are needed to properly use the initrd
    environment. Don't forget the most important file, ``/sbin/init``

    .. note:: ``/sbin/init`` permissions must include "x" (execute).

 6) correct operation the initrd environment can frequently be tested
    even without rebooting with the command::

	# chroot /mnt /sbin/init

    This is of course limited to initrds that do not interfere with the
    general system state (e.g. by reconfiguring network interfaces,
    overwriting mounted devices, trying to start already running demons,
    etc. Note however that it is usually possible to use pivot_root in
    such a chroot'ed initrd environment.)
 7) unmount the file system::

	# umount /mnt

 8) the initrd is now in the file "initrd". Optionally, it can now be
    compressed::

	# gzip -9 initrd

For experimenting with initrd, you may want to take a rescue floppy and
only add a symbolic link from ``/sbin/init`` to ``/bin/sh``. Alternatively, you
can try the experimental newlib environment [#f2]_ to create a small
initrd.

Finally, you have to boot the kernel and load initrd. Almost all Linux
boot loaders support initrd. Since the boot process is still compatible
with an older mechanism, the following boot command line parameters
have to be given::

  root=/dev/ram0 rw

(rw is only necessary if writing to the initrd file system.)

With LOADLIN, you simply execute::

     LOADLIN <kernel> initrd=<disk_image>

e.g.::

	LOADLIN C:\LINUX\BZIMAGE initrd=C:\LINUX\INITRD.GZ root=/dev/ram0 rw

With LILO, you add the option ``INITRD=<path>`` to either the global section
or to the section of the respective kernel in ``/etc/lilo.conf``, and pass
the options using APPEND, e.g.::

  image = /bzImage
    initrd = /boot/initrd.gz
    append = "root=/dev/ram0 rw"

and run ``/sbin/lilo``

For other boot loaders, please refer to the respective documentation.

Now you can boot and enjoy using initrd.

Changing the root device
------------------------

When finished with its duties, init typically changes the root device
and proceeds with starting the Linux system on the "real" root device.

The procedure involves the following steps:
 - mounting the new root file system
 - turning it into the root file system
 - removing all accesses to the old (initrd) root file system
 - unmounting the initrd file system and de-allocating the RAM disk

Mounting the new root file system is easy: it just needs to be mounted on
a directory under the current root. Example::

	# mkdir /new-root
	# mount -o ro /dev/hda1 /new-root

The root change is accomplished with the pivot_root system call, which
is also available via the ``pivot_root`` utility (see :manpage:`pivot_root(8)`
man page; ``pivot_root`` is distributed with util-linux version 2.10h or higher
[#f3]_). ``pivot_root`` moves the current root to a directory under the new
root, and puts the new root at its place. The directory for the old root
must exist before calling ``pivot_root``. Example::

	# cd /new-root
	# mkdir initrd
	# pivot_root . initrd

Now, the init process may still access the old root via its
executable, shared libraries, standard input/output/error, and its
current root directory. All these references are dropped by the
following command::

	# exec chroot . what-follows <dev/console >dev/console 2>&1

Where what-follows is a program under the new root, e.g. ``/sbin/init``
If the new root file system will be used with udev and has no valid
``/dev`` directory, udev must be initialized before invoking chroot in order
to provide ``/dev/console``.

Note: implementation details of pivot_root may change with time. In order
to ensure compatibility, the following points should be observed:

 - before calling pivot_root, the current directory of the invoking
   process should point to the new root directory
 - use . as the first argument, and the _relative_ path of the directory
   for the old root as the second argument
 - a chroot program must be available under the old and the new root
 - chroot to the new root afterwards
 - use relative paths for dev/console in the exec command

Now, the initrd can be unmounted and the memory allocated by the RAM
disk can be freed::

	# umount /initrd
	# blockdev --flushbufs /dev/ram0

It is also possible to use initrd with an NFS-mounted root, see the
:manpage:`pivot_root(8)` man page for details.

Usage scenarios
---------------

The main motivation for implementing initrd was to allow for modular
kernel configuration at system installation. The procedure would work
as follows:

  1) system boots from floppy or other media with a minimal kernel
     (e.g. support for RAM disks, initrd, a.out, and the Ext2 FS) and
     loads initrd
  2) ``/sbin/init`` determines what is needed to (1) mount the "real" root FS
     (i.e. device type, device drivers, file system) and (2) the
     distribution media (e.g. CD-ROM, network, tape, ...). This can be
     done by asking the user, by auto-probing, or by using a hybrid
     approach.
  3) ``/sbin/init`` loads the necessary kernel modules
  4) ``/sbin/init`` creates and populates the root file system (this doesn't
     have to be a very usable system yet)
  5) ``/sbin/init`` invokes ``pivot_root`` to change the root file system and
     execs - via chroot - a program that continues the installation
  6) the boot loader is installed
  7) the boot loader is configured to load an initrd with the set of
     modules that was used to bring up the system (e.g. ``/initrd`` can be
     modified, then unmounted, and finally, the image is written from
     ``/dev/ram0`` or ``/dev/rd/0`` to a file)
  8) now the system is bootable and additional installation tasks can be
     performed

The key role of initrd here is to re-use the configuration data during
normal system operation without requiring the use of a bloated "generic"
kernel or re-compiling or re-linking the kernel.

A second scenario is for installations where Linux runs on systems with
different hardware configurations in a single administrative domain. In
such cases, it is desirable to generate only a small set of kernels
(ideally only one) and to keep the system-specific part of configuration
information as small as possible. In this case, a common initrd could be
generated with all the necessary modules. Then, only ``/sbin/init`` or a file
read by it would have to be different.

A third scenario is more convenient recovery disks, because information
like the location of the root FS partition doesn't have to be provided at
boot time, but the system loaded from initrd can invoke a user-friendly
dialog and it can also perform some sanity checks (or even some form of
auto-detection).

Last not least, CD-ROM distributors may use it for better installation
from CD, e.g. by using a boot floppy and bootstrapping a bigger RAM disk
via initrd from CD; or by booting via a loader like ``LOADLIN`` or directly
from the CD-ROM, and loading the RAM disk from CD without need of
floppies.

Obsolete root change mechanism
------------------------------

The following mechanism was used before the introduction of pivot_root.
Current kernels still support it, but you should _not_ rely on its
continued availability.

It works by mounting the "real" root device (i.e. the one set with rdev
in the kernel image or with root=... at the boot command line) as the
root file system when linuxrc exits. The initrd file system is then
unmounted, or, if it is still busy, moved to a directory ``/initrd``, if
such a directory exists on the new root file system.

In order to use this mechanism, you do not have to specify the boot
command options root, init, or rw. (If specified, they will affect
the real root file system, not the initrd environment.)

If /proc is mounted, the "real" root device can be changed from within
linuxrc by writing the number of the new root FS device to the special
file /proc/sys/kernel/real-root-dev, e.g.::

  # echo 0x301 >/proc/sys/kernel/real-root-dev

Note that the mechanism is incompatible with NFS and similar file
systems.

This old, deprecated mechanism is commonly called ``change_root``, while
the new, supported mechanism is called ``pivot_root``.

Mixed change_root and pivot_root mechanism
------------------------------------------

In case you did not want to use ``root=/dev/ram0`` to trigger the pivot_root
mechanism, you may create both ``/linuxrc`` and ``/sbin/init`` in your initrd
image.

``/linuxrc`` would contain only the following::

	#! /bin/sh
	mount -n -t proc proc /proc
	echo 0x0100 >/proc/sys/kernel/real-root-dev
	umount -n /proc

Once linuxrc exited, the kernel would mount again your initrd as root,
this time executing ``/sbin/init``. Again, it would be the duty of this init
to build the right environment (maybe using the ``root= device`` passed on
the cmdline) before the final execution of the real ``/sbin/init``.

Resources
---------

.. [#f1] Almesberger, Werner; "Booting Linux: The History and the Future"
    https://www.almesberger.net/cv/papers/ols2k-9.ps.gz
.. [#f2] newlib package (experimental), with initrd example
    https://www.sourceware.org/newlib/
.. [#f3] util-linux: Miscellaneous utilities for Linux
    https://www.kernel.org/pub/linux/utils/util-linux/


code:
=====================
I/O statistics fields
=====================

Since 2.4.20 (and some versions before, with patches), and 2.5.45,
more extensive disk statistics have been introduced to help measure disk
activity. Tools such as ``sar`` and ``iostat`` typically interpret these and do
the work for you, but in case you are interested in creating your own
tools, the fields are explained here.

In 2.4 now, the information is found as additional fields in
``/proc/partitions``.  In 2.6 and upper, the same information is found in two
places: one is in the file ``/proc/diskstats``, and the other is within
the sysfs file system, which must be mounted in order to obtain
the information. Throughout this document we'll assume that sysfs
is mounted on ``/sys``, although of course it may be mounted anywhere.
Both ``/proc/diskstats`` and sysfs use the same source for the information
and so should not differ.

Here are examples of these different formats::

   2.4:
      3     0   39082680 hda 446216 784926 9550688 4382310 424847 312726 5922052 19310380 0 3376340 23705160
      3     1    9221278 hda1 35486 0 35496 38030 0 0 0 0 0 38030 38030

   2.6+ sysfs:
      446216 784926 9550688 4382310 424847 312726 5922052 19310380 0 3376340 23705160
      35486    38030    38030    38030

   2.6+ diskstats:
      3    0   hda 446216 784926 9550688 4382310 424847 312726 5922052 19310380 0 3376340 23705160
      3    1   hda1 35486 38030 38030 38030

   4.18+ diskstats:
      3    0   hda 446216 784926 9550688 4382310 424847 312726 5922052 19310380 0 3376340 23705160 0 0 0 0

On 2.4 you might execute ``grep 'hda ' /proc/partitions``. On 2.6+, you have
a choice of ``cat /sys/block/hda/stat`` or ``grep 'hda ' /proc/diskstats``.

The advantage of one over the other is that the sysfs choice works well
if you are watching a known, small set of disks.  ``/proc/diskstats`` may
be a better choice if you are watching a large number of disks because
you'll avoid the overhead of 50, 100, or 500 or more opens/closes with
each snapshot of your disk statistics.

In 2.4, the statistics fields are those after the device name. In
the above example, the first field of statistics would be 446216.
By contrast, in 2.6+ if you look at ``/sys/block/hda/stat``, you'll
find just the 15 fields, beginning with 446216.  If you look at
``/proc/diskstats``, the 15 fields will be preceded by the major and
minor device numbers, and device name.  Each of these formats provides
15 fields of statistics, each meaning exactly the same things.
All fields except field 9 are cumulative since boot.  Field 9 should
go to zero as I/Os complete; all others only increase (unless they
overflow and wrap). Wrapping might eventually occur on a very busy
or long-lived system; so applications should be prepared to deal with
it. Regarding wrapping, the types of the fields are either unsigned
int (32 bit) or unsigned long (32-bit or 64-bit, depending on your
machine) as noted per-field below. Unless your observations are very
spread in time, these fields should not wrap twice before you notice it.

Each set of stats only applies to the indicated device; if you want
system-wide stats you'll have to find all the devices and sum them all up.

Field  1 -- # of reads completed (unsigned long)
    This is the total number of reads completed successfully.

Field  2 -- # of reads merged, field 6 -- # of writes merged (unsigned long)
    Reads and writes which are adjacent to each other may be merged for
    efficiency.  Thus two 4K reads may become one 8K read before it is
    ultimately handed to the disk, and so it will be counted (and queued)
    as only one I/O.  This field lets you know how often this was done.

Field  3 -- # of sectors read (unsigned long)
    This is the total number of sectors read successfully.

Field  4 -- # of milliseconds spent reading (unsigned int)
    This is the total number of milliseconds spent by all reads (as
    measured from blk_mq_alloc_request() to __blk_mq_end_request()).

Field  5 -- # of writes completed (unsigned long)
    This is the total number of writes completed successfully.

Field  6 -- # of writes merged  (unsigned long)
    See the description of field 2.

Field  7 -- # of sectors written (unsigned long)
    This is the total number of sectors written successfully.

Field  8 -- # of milliseconds spent writing (unsigned int)
    This is the total number of milliseconds spent by all writes (as
    measured from blk_mq_alloc_request() to __blk_mq_end_request()).

Field  9 -- # of I/Os currently in progress (unsigned int)
    The only field that should go to zero. Incremented as requests are
    given to appropriate struct request_queue and decremented as they finish.

Field 10 -- # of milliseconds spent doing I/Os (unsigned int)
    This field increases so long as field 9 is nonzero.

    Since 5.0 this field counts jiffies when at least one request was
    started or completed. If request runs more than 2 jiffies then some
    I/O time might be not accounted in case of concurrent requests.

Field 11 -- weighted # of milliseconds spent doing I/Os (unsigned int)
    This field is incremented at each I/O start, I/O completion, I/O
    merge, or read of these stats by the number of I/Os in progress
    (field 9) times the number of milliseconds spent doing I/O since the
    last update of this field.  This can provide an easy measure of both
    I/O completion time and the backlog that may be accumulating.

Field 12 -- # of discards completed (unsigned long)
    This is the total number of discards completed successfully.

Field 13 -- # of discards merged (unsigned long)
    See the description of field 2

Field 14 -- # of sectors discarded (unsigned long)
    This is the total number of sectors discarded successfully.

Field 15 -- # of milliseconds spent discarding (unsigned int)
    This is the total number of milliseconds spent by all discards (as
    measured from blk_mq_alloc_request() to __blk_mq_end_request()).

Field 16 -- # of flush requests completed
    This is the total number of flush requests completed successfully.

    Block layer combines flush requests and executes at most one at a time.
    This counts flush requests executed by disk. Not tracked for partitions.

Field 17 -- # of milliseconds spent flushing
    This is the total number of milliseconds spent by all flush requests.

To avoid introducing performance bottlenecks, no locks are held while
modifying these counters.  This implies that minor inaccuracies may be
introduced when changes collide, so (for instance) adding up all the
read I/Os issued per partition should equal those made to the disks ...
but due to the lack of locking it may only be very close.

In 2.6+, there are counters for each CPU, which make the lack of locking
almost a non-issue.  When the statistics are read, the per-CPU counters
are summed (possibly overflowing the unsigned long variable they are
summed to) and the result given to the user.  There is no convenient
user interface for accessing the per-CPU counters themselves.

Since 4.19 request times are measured with nanoseconds precision and
truncated to milliseconds before showing in this interface.

Disks vs Partitions
-------------------

There were significant changes between 2.4 and 2.6+ in the I/O subsystem.
As a result, some statistic information disappeared. The translation from
a disk address relative to a partition to the disk address relative to
the host disk happens much earlier.  All merges and timings now happen
at the disk level rather than at both the disk and partition level as
in 2.4.  Consequently, you'll see a different statistics output on 2.6+ for
partitions from that for disks.  There are only *four* fields available
for partitions on 2.6+ machines.  This is reflected in the examples above.

Field  1 -- # of reads issued
    This is the total number of reads issued to this partition.

Field  2 -- # of sectors read
    This is the total number of sectors requested to be read from this
    partition.

Field  3 -- # of writes issued
    This is the total number of writes issued to this partition.

Field  4 -- # of sectors written
    This is the total number of sectors requested to be written to
    this partition.

Note that since the address is translated to a disk-relative one, and no
record of the partition-relative address is kept, the subsequent success
or failure of the read cannot be attributed to the partition.  In other
words, the number of reads for partitions is counted slightly before time
of queuing for partitions, and at completion for whole disks.  This is
a subtle distinction that is probably uninteresting for most cases.

More significant is the error induced by counting the numbers of
reads/writes before merges for partitions and after for disks. Since a
typical workload usually contains a lot of successive and adjacent requests,
the number of reads/writes issued can be several times higher than the
number of reads/writes completed.

In 2.6.25, the full statistic set is again available for partitions and
disk and partition statistics are consistent again. Since we still don't
keep record of the partition-relative address, an operation is attributed to
the partition which contains the first sector of the request after the
eventual merges. As requests can be merged across partition, this could lead
to some (probably insignificant) inaccuracy.

Additional notes
----------------

In 2.6+, sysfs is not mounted by default.  If your distribution of
Linux hasn't added it already, here's the line you'll want to add to
your ``/etc/fstab``::

	none /sys sysfs defaults 0 0

In 2.6+, all disk statistics were removed from ``/proc/stat``.  In 2.4, they
appear in both ``/proc/partitions`` and ``/proc/stat``, although the ones in
``/proc/stat`` take a very different format from those in ``/proc/partitions``
(see proc(5), if your system has it.)

-- ricklind@us.ibm.com


code:
Java(tm) Binary Kernel Support for Linux v1.03
----------------------------------------------

Linux beats them ALL! While all other OS's are TALKING about direct
support of Java Binaries in the OS, Linux is doing it!

You can execute Java applications and Java Applets just like any
other program after you have done the following:

1) You MUST FIRST install the Java Developers Kit for Linux.
   The Java on Linux HOWTO gives the details on getting and
   installing this. This HOWTO can be found at:

	ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO/Java-HOWTO

   You should also set up a reasonable CLASSPATH environment
   variable to use Java applications that make use of any
   nonstandard classes (not included in the same directory
   as the application itself).

2) You have to compile BINFMT_MISC either as a module or into
   the kernel (``CONFIG_BINFMT_MISC``) and set it up properly.
   If you choose to compile it as a module, you will have
   to insert it manually with modprobe/insmod, as kmod
   cannot easily be supported with binfmt_misc.
   Read the file 'binfmt_misc.txt' in this directory to know
   more about the configuration process.

3) Add the following configuration items to binfmt_misc
   (you should really have read ``binfmt_misc.txt`` now):
   support for Java applications::

     ':Java:M::\xca\xfe\xba\xbe::/usr/local/bin/javawrapper:'

   support for executable Jar files::

     ':ExecutableJAR:E::jar::/usr/local/bin/jarwrapper:'

   support for Java Applets::

     ':Applet:E::html::/usr/bin/appletviewer:'

   or the following, if you want to be more selective::

     ':Applet:M::<!--applet::/usr/bin/appletviewer:'

   Of course you have to fix the path names. The path/file names given in this
   document match the Debian 2.1 system. (i.e. jdk installed in ``/usr``,
   custom wrappers from this document in ``/usr/local``)

   Note, that for the more selective applet support you have to modify
   existing html-files to contain ``<!--applet-->`` in the first line
   (``<`` has to be the first character!) to let this work!

   For the compiled Java programs you need a wrapper script like the
   following (this is because Java is broken in case of the filename
   handling), again fix the path names, both in the script and in the
   above given configuration string.

   You, too, need the little program after the script. Compile like::

	gcc -O2 -o javaclassname javaclassname.c

   and stick it to ``/usr/local/bin``.

   Both the javawrapper shellscript and the javaclassname program
   were supplied by Colin J. Watson <cjw44@cam.ac.uk>.

Javawrapper shell script:

.. code-block:: sh

  #!/bin/bash
  # /usr/local/bin/javawrapper - the wrapper for binfmt_misc/java

  if [ -z "$1" ]; then
	exec 1>&2
	echo Usage: $0 class-file
	exit 1
  fi

  CLASS=$1
  FQCLASS=`/usr/local/bin/javaclassname $1`
  FQCLASSN=`echo $FQCLASS | sed -e 's/^.*\.\([^.]*\)$/\1/'`
  FQCLASSP=`echo $FQCLASS | sed -e 's-\.-/-g' -e 's-^[^/]*$--' -e 's-/[^/]*$--'`

  # for example:
  # CLASS=Test.class
  # FQCLASS=foo.bar.Test
  # FQCLASSN=Test
  # FQCLASSP=foo/bar

  unset CLASSBASE

  declare -i LINKLEVEL=0

  while :; do
	if [ "`basename $CLASS .class`" == "$FQCLASSN" ]; then
		# See if this directory works straight off
		cd -L `dirname $CLASS`
		CLASSDIR=$PWD
		cd $OLDPWD
		if echo $CLASSDIR | grep -q "$FQCLASSP$"; then
			CLASSBASE=`echo $CLASSDIR | sed -e "s.$FQCLASSP$.."`
			break;
		fi
		# Try dereferencing the directory name
		cd -P `dirname $CLASS`
		CLASSDIR=$PWD
		cd $OLDPWD
		if echo $CLASSDIR | grep -q "$FQCLASSP$"; then
			CLASSBASE=`echo $CLASSDIR | sed -e "s.$FQCLASSP$.."`
			break;
		fi
		# If no other possible filename exists
		if [ ! -L $CLASS ]; then
			exec 1>&2
			echo $0:
			echo "  $CLASS should be in a" \
			     "directory tree called $FQCLASSP"
			exit 1
		fi
	fi
	if [ ! -L $CLASS ]; then break; fi
	# Go down one more level of symbolic links
	let LINKLEVEL+=1
	if [ $LINKLEVEL -gt 5 ]; then
		exec 1>&2
		echo $0:
		echo "  Too many symbolic links encountered"
		exit 1
	fi
	CLASS=`ls --color=no -l $CLASS | sed -e 's/^.* \([^ ]*\)$/\1/'`
  done

  if [ -z "$CLASSBASE" ]; then
	if [ -z "$FQCLASSP" ]; then
		GOODNAME=$FQCLASSN.class
	else
		GOODNAME=$FQCLASSP/$FQCLASSN.class
	fi
	exec 1>&2
	echo $0:
	echo "  $FQCLASS should be in a file called $GOODNAME"
	exit 1
  fi

  if ! echo $CLASSPATH | grep -q "^\(.*:\)*$CLASSBASE\(:.*\)*"; then
	# class is not in CLASSPATH, so prepend dir of class to CLASSPATH
	if [ -z "${CLASSPATH}" ] ; then
		export CLASSPATH=$CLASSBASE
	else
		export CLASSPATH=$CLASSBASE:$CLASSPATH
	fi
  fi

  shift
  /usr/bin/java $FQCLASS "$@"

javaclassname.c:

.. code-block:: c

  /* javaclassname.c
   *
   * Extracts the class name from a Java class file; intended for use in a Java
   * wrapper of the type supported by the binfmt_misc option in the Linux kernel.
   *
   * Copyright (C) 1999 Colin J. Watson <cjw44@cam.ac.uk>.
   *
   * This program is free software; you can redistribute it and/or modify
   * it under the terms of the GNU General Public License as published by
   * the Free Software Foundation; either version 2 of the License, or
   * (at your option) any later version.
   *
   * This program is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   * GNU General Public License for more details.
   *
   * You should have received a copy of the GNU General Public License
   * along with this program; if not, write to the Free Software
   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   */

  #include <stdlib.h>
  #include <stdio.h>
  #include <stdarg.h>
  #include <sys/types.h>

  /* From Sun's Java VM Specification, as tag entries in the constant pool. */

  #define CP_UTF8 1
  #define CP_INTEGER 3
  #define CP_FLOAT 4
  #define CP_LONG 5
  #define CP_DOUBLE 6
  #define CP_CLASS 7
  #define CP_STRING 8
  #define CP_FIELDREF 9
  #define CP_METHODREF 10
  #define CP_INTERFACEMETHODREF 11
  #define CP_NAMEANDTYPE 12
  #define CP_METHODHANDLE 15
  #define CP_METHODTYPE 16
  #define CP_INVOKEDYNAMIC 18

  /* Define some commonly used error messages */

  #define seek_error() error("%s: Cannot seek\n", program)
  #define corrupt_error() error("%s: Class file corrupt\n", program)
  #define eof_error() error("%s: Unexpected end of file\n", program)
  #define utf8_error() error("%s: Only ASCII 1-255 supported\n", program);

  char *program;

  long *pool;

  u_int8_t read_8(FILE *classfile);
  u_int16_t read_16(FILE *classfile);
  void skip_constant(FILE *classfile, u_int16_t *cur);
  void error(const char *format, ...);
  int main(int argc, char **argv);

  /* Reads in an unsigned 8-bit integer. */
  u_int8_t read_8(FILE *classfile)
  {
	int b = fgetc(classfile);
	if(b == EOF)
		eof_error();
	return (u_int8_t)b;
  }

  /* Reads in an unsigned 16-bit integer. */
  u_int16_t read_16(FILE *classfile)
  {
	int b1, b2;
	b1 = fgetc(classfile);
	if(b1 == EOF)
		eof_error();
	b2 = fgetc(classfile);
	if(b2 == EOF)
		eof_error();
	return (u_int16_t)((b1 << 8) | b2);
  }

  /* Reads in a value from the constant pool. */
  void skip_constant(FILE *classfile, u_int16_t *cur)
  {
	u_int16_t len;
	int seekerr = 1;
	pool[*cur] = ftell(classfile);
	switch(read_8(classfile))
	{
	case CP_UTF8:
		len = read_16(classfile);
		seekerr = fseek(classfile, len, SEEK_CUR);
		break;
	case CP_CLASS:
	case CP_STRING:
	case CP_METHODTYPE:
		seekerr = fseek(classfile, 2, SEEK_CUR);
		break;
	case CP_METHODHANDLE:
		seekerr = fseek(classfile, 3, SEEK_CUR);
		break;
	case CP_INTEGER:
	case CP_FLOAT:
	case CP_FIELDREF:
	case CP_METHODREF:
	case CP_INTERFACEMETHODREF:
	case CP_NAMEANDTYPE:
	case CP_INVOKEDYNAMIC:
		seekerr = fseek(classfile, 4, SEEK_CUR);
		break;
	case CP_LONG:
	case CP_DOUBLE:
		seekerr = fseek(classfile, 8, SEEK_CUR);
		++(*cur);
		break;
	default:
		corrupt_error();
	}
	if(seekerr)
		seek_error();
  }

  void error(const char *format, ...)
  {
	va_list ap;
	va_start(ap, format);
	vfprintf(stderr, format, ap);
	va_end(ap);
	exit(1);
  }

  int main(int argc, char **argv)
  {
	FILE *classfile;
	u_int16_t cp_count, i, this_class, classinfo_ptr;
	u_int8_t length;

	program = argv[0];

	if(!argv[1])
		error("%s: Missing input file\n", program);
	classfile = fopen(argv[1], "rb");
	if(!classfile)
		error("%s: Error opening %s\n", program, argv[1]);

	if(fseek(classfile, 8, SEEK_SET))  /* skip magic and version numbers */
		seek_error();
	cp_count = read_16(classfile);
	pool = calloc(cp_count, sizeof(long));
	if(!pool)
		error("%s: Out of memory for constant pool\n", program);

	for(i = 1; i < cp_count; ++i)
		skip_constant(classfile, &i);
	if(fseek(classfile, 2, SEEK_CUR))	/* skip access flags */
		seek_error();

	this_class = read_16(classfile);
	if(this_class < 1 || this_class >= cp_count)
		corrupt_error();
	if(!pool[this_class] || pool[this_class] == -1)
		corrupt_error();
	if(fseek(classfile, pool[this_class] + 1, SEEK_SET))
		seek_error();

	classinfo_ptr = read_16(classfile);
	if(classinfo_ptr < 1 || classinfo_ptr >= cp_count)
		corrupt_error();
	if(!pool[classinfo_ptr] || pool[classinfo_ptr] == -1)
		corrupt_error();
	if(fseek(classfile, pool[classinfo_ptr] + 1, SEEK_SET))
		seek_error();

	length = read_16(classfile);
	for(i = 0; i < length; ++i)
	{
		u_int8_t x = read_8(classfile);
		if((x & 0x80) || !x)
		{
			if((x & 0xE0) == 0xC0)
			{
				u_int8_t y = read_8(classfile);
				if((y & 0xC0) == 0x80)
				{
					int c = ((x & 0x1f) << 6) + (y & 0x3f);
					if(c) putchar(c);
					else utf8_error();
				}
				else utf8_error();
			}
			else utf8_error();
		}
		else if(x == '/') putchar('.');
		else putchar(x);
	}
	putchar('\n');
	free(pool);
	fclose(classfile);
	return 0;
  }

jarwrapper::

  #!/bin/bash
  # /usr/local/java/bin/jarwrapper - the wrapper for binfmt_misc/jar

  java -jar $1

Now simply ``chmod +x`` the ``.class``, ``.jar`` and/or ``.html`` files you
want to execute.

To add a Java program to your path best put a symbolic link to the main
.class file into /usr/bin (or another place you like) omitting the .class
extension. The directory containing the original .class file will be
added to your CLASSPATH during execution.

To test your new setup, enter in the following simple Java app, and name
it "HelloWorld.java":

.. code-block:: java

	class HelloWorld {
		public static void main(String args[]) {
			System.out.println("Hello World!");
		}
	}

Now compile the application with::

	javac HelloWorld.java

Set the executable permissions of the binary file, with::

	chmod 755 HelloWorld.class

And then execute it::

	./HelloWorld.class

To execute Java Jar files, simple chmod the ``*.jar`` files to include
the execution bit, then just do::

       ./Application.jar

To execute Java Applets, simple chmod the ``*.html`` files to include
the execution bit, then just do::

	./Applet.html

originally by Brian A. Lantz, brian@lantz.com
heavily edited for binfmt_misc by Richard Günther
new scripts by Colin J. Watson <cjw44@cam.ac.uk>
added executable Jar file support by Kurt Huwig <kurt@iku-netz.de>


code:
===========================================
IBM's Journaled File System (JFS) for Linux
===========================================

JFS Homepage:  http://jfs.sourceforge.net/

The following mount options are supported:

(*) == default

iocharset=name
                Character set to use for converting from Unicode to
		ASCII.  The default is to do no conversion.  Use
		iocharset=utf8 for UTF-8 translations.  This requires
		CONFIG_NLS_UTF8 to be set in the kernel .config file.
		iocharset=none specifies the default behavior explicitly.

resize=value
                Resize the volume to <value> blocks.  JFS only supports
		growing a volume, not shrinking it.  This option is only
		valid during a remount, when the volume is mounted
		read-write.  The resize keyword with no value will grow
		the volume to the full size of the partition.

nointegrity
                Do not write to the journal.  The primary use of this option
		is to allow for higher performance when restoring a volume
		from backup media.  The integrity of the volume is not
		guaranteed if the system abnormally abends.

integrity(*)
                Commit metadata changes to the journal.  Use this option to
		remount a volume where the nointegrity option was
		previously specified in order to restore normal behavior.

errors=continue
                        Keep going on a filesystem error.
errors=remount-ro(*)
                        Remount the filesystem read-only on an error.
errors=panic
                        Panic and halt the machine if an error occurs.

uid=value
                Override on-disk uid with specified value
gid=value
                Override on-disk gid with specified value
umask=value
                Override on-disk umask with specified octal value. For
                directories, the execute bit will be set if the corresponding
		read bit is set.

discard=minlen, discard/nodiscard(*)
                This enables/disables the use of discard/TRIM commands.
		The discard/TRIM commands are sent to the underlying
                block device when blocks are freed. This is useful for SSD
                devices and sparse/thinly-provisioned LUNs.  The FITRIM ioctl
		command is also available together with the nodiscard option.
		The value of minlen specifies the minimum blockcount, when
		a TRIM command to the block device is considered useful.
		When no value is given to the discard option, it defaults to
		64 blocks, which means 256KiB in JFS.
		The minlen value of discard overrides the minlen value given
		on an FITRIM ioctl().

The JFS mailing list can be subscribed to by using the link labeled
"Mail list Subscribe" at our web page http://jfs.sourceforge.net/


code:
#
# This file contains a few gdb macros (user defined commands) to extract
# useful information from kernel crashdump (kdump) like stack traces of
# all the processes or a particular process and trapinfo.
#
# These macros can be used by copying this file in .gdbinit (put in home
# directory or current directory) or by invoking gdb command with
# --command=<command-file-name> option
#
# Credits:
# Alexander Nyberg <alexn@telia.com>
# V Srivatsa <vatsa@in.ibm.com>
# Maneesh Soni <maneesh@in.ibm.com>
#

define bttnobp
	set $tasks_off=((size_t)&((struct task_struct *)0)->tasks)
	set $pid_off=((size_t)&((struct task_struct *)0)->thread_group.next)
	set $init_t=&init_task
	set $next_t=(((char *)($init_t->tasks).next) - $tasks_off)
	set var $stacksize = sizeof(union thread_union)
	while ($next_t != $init_t)
		set $next_t=(struct task_struct *)$next_t
		printf "\npid %d; comm %s:\n", $next_t.pid, $next_t.comm
		printf "===================\n"
		set var $stackp = $next_t.thread.sp
		set var $stack_top = ($stackp & ~($stacksize - 1)) + $stacksize

		while ($stackp < $stack_top)
			if (*($stackp) > _stext && *($stackp) < _sinittext)
				info symbol *($stackp)
			end
			set $stackp += 4
		end
		set $next_th=(((char *)$next_t->thread_group.next) - $pid_off)
		while ($next_th != $next_t)
			set $next_th=(struct task_struct *)$next_th
			printf "\npid %d; comm %s:\n", $next_t.pid, $next_t.comm
			printf "===================\n"
			set var $stackp = $next_t.thread.sp
			set var $stack_top = ($stackp & ~($stacksize - 1)) + stacksize

			while ($stackp < $stack_top)
				if (*($stackp) > _stext && *($stackp) < _sinittext)
					info symbol *($stackp)
				end
				set $stackp += 4
			end
			set $next_th=(((char *)$next_th->thread_group.next) - $pid_off)
		end
		set $next_t=(char *)($next_t->tasks.next) - $tasks_off
	end
end
document bttnobp
	dump all thread stack traces on a kernel compiled with !CONFIG_FRAME_POINTER
end

define btthreadstack
	set var $pid_task = $arg0

	printf "\npid %d; comm %s:\n", $pid_task.pid, $pid_task.comm
	printf "task struct: "
	print $pid_task
	printf "===================\n"
	set var $stackp = $pid_task.thread.sp
	set var $stacksize = sizeof(union thread_union)
	set var $stack_top = ($stackp & ~($stacksize - 1)) + $stacksize
	set var $stack_bot = ($stackp & ~($stacksize - 1))

	set $stackp = *((unsigned long *) $stackp)
	while (($stackp < $stack_top) && ($stackp > $stack_bot))
		set var $addr = *(((unsigned long *) $stackp) + 1)
		info symbol $addr
		set $stackp = *((unsigned long *) $stackp)
	end
end
document btthreadstack
	 dump a thread stack using the given task structure pointer
end

define btt
	set $tasks_off=((size_t)&((struct task_struct *)0)->tasks)
	set $pid_off=((size_t)&((struct task_struct *)0)->thread_group.next)
	set $init_t=&init_task
	set $next_t=(((char *)($init_t->tasks).next) - $tasks_off)
	while ($next_t != $init_t)
		set $next_t=(struct task_struct *)$next_t
		btthreadstack $next_t

		set $next_th=(((char *)$next_t->thread_group.next) - $pid_off)
		while ($next_th != $next_t)
			set $next_th=(struct task_struct *)$next_th
			btthreadstack $next_th
			set $next_th=(((char *)$next_th->thread_group.next) - $pid_off)
		end
		set $next_t=(char *)($next_t->tasks.next) - $tasks_off
	end
end
document btt
	dump all thread stack traces on a kernel compiled with CONFIG_FRAME_POINTER
end

define btpid
	set var $pid = $arg0
	set $tasks_off=((size_t)&((struct task_struct *)0)->tasks)
	set $pid_off=((size_t)&((struct task_struct *)0)->thread_group.next)
	set $init_t=&init_task
	set $next_t=(((char *)($init_t->tasks).next) - $tasks_off)
	set var $pid_task = 0

	while ($next_t != $init_t)
		set $next_t=(struct task_struct *)$next_t

		if ($next_t.pid == $pid)
			set $pid_task = $next_t
		end

		set $next_th=(((char *)$next_t->thread_group.next) - $pid_off)
		while ($next_th != $next_t)
			set $next_th=(struct task_struct *)$next_th
			if ($next_th.pid == $pid)
				set $pid_task = $next_th
			end
			set $next_th=(((char *)$next_th->thread_group.next) - $pid_off)
		end
		set $next_t=(char *)($next_t->tasks.next) - $tasks_off
	end

	btthreadstack $pid_task
end
document btpid
	backtrace of pid
end

define trapinfo
	set var $pid = $arg0
	set $tasks_off=((size_t)&((struct task_struct *)0)->tasks)
	set $pid_off=((size_t)&((struct task_struct *)0)->thread_group.next)
	set $init_t=&init_task
	set $next_t=(((char *)($init_t->tasks).next) - $tasks_off)
	set var $pid_task = 0

	while ($next_t != $init_t)
		set $next_t=(struct task_struct *)$next_t

		if ($next_t.pid == $pid)
			set $pid_task = $next_t
		end

		set $next_th=(((char *)$next_t->thread_group.next) - $pid_off)
		while ($next_th != $next_t)
			set $next_th=(struct task_struct *)$next_th
			if ($next_th.pid == $pid)
				set $pid_task = $next_th
			end
			set $next_th=(((char *)$next_th->thread_group.next) - $pid_off)
		end
		set $next_t=(char *)($next_t->tasks.next) - $tasks_off
	end

	printf "Trapno %ld, cr2 0x%lx, error_code %ld\n", $pid_task.thread.trap_no, \
				$pid_task.thread.cr2, $pid_task.thread.error_code

end
document trapinfo
	Run info threads and lookup pid of thread #1
	'trapinfo <pid>' will tell you by which trap & possibly
	address the kernel panicked.
end

define dump_record
	set var $desc = $arg0
	set var $info = $arg1
	if ($argc > 2)
		set var $prev_flags = $arg2
	else
		set var $prev_flags = 0
	end

	set var $prefix = 1
	set var $newline = 1

	set var $begin = $desc->text_blk_lpos.begin % (1U << prb->text_data_ring.size_bits)
	set var $next = $desc->text_blk_lpos.next % (1U << prb->text_data_ring.size_bits)

	# handle data-less record
	if ($begin & 1)
		set var $text_len = 0
		set var $log = ""
	else
		# handle wrapping data block
		if ($begin > $next)
			set var $begin = 0
		end

		# skip over descriptor id
		set var $begin = $begin + sizeof(long)

		# handle truncated message
		if ($next - $begin < $info->text_len)
			set var $text_len = $next - $begin
		else
			set var $text_len = $info->text_len
		end

		set var $log = &prb->text_data_ring.data[$begin]
	end

	# prev & LOG_CONT && !(info->flags & LOG_PREIX)
	if (($prev_flags & 8) && !($info->flags & 4))
		set var $prefix = 0
	end

	# info->flags & LOG_CONT
	if ($info->flags & 8)
		# (prev & LOG_CONT && !(prev & LOG_NEWLINE))
		if (($prev_flags & 8) && !($prev_flags & 2))
			set var $prefix = 0
		end
		# (!(info->flags & LOG_NEWLINE))
		if (!($info->flags & 2))
			set var $newline = 0
		end
	end

	if ($prefix)
		printf "[%5lu.%06lu] ", $info->ts_nsec / 1000000000, $info->ts_nsec % 1000000000
	end
	if ($text_len)
		eval "printf \"%%%d.%ds\", $log", $text_len, $text_len
	end
	if ($newline)
		printf "\n"
	end

	# handle dictionary data

	set var $dict = &$info->dev_info.subsystem[0]
	set var $dict_len = sizeof($info->dev_info.subsystem)
	if ($dict[0] != '\0')
		printf " SUBSYSTEM="
		set var $idx = 0
		while ($idx < $dict_len)
			set var $c = $dict[$idx]
			if ($c == '\0')
				loop_break
			else
				if ($c < ' ' || $c >= 127 || $c == '\\')
					printf "\\x%02x", $c
				else
					printf "%c", $c
				end
			end
			set var $idx = $idx + 1
		end
		printf "\n"
	end

	set var $dict = &$info->dev_info.device[0]
	set var $dict_len = sizeof($info->dev_info.device)
	if ($dict[0] != '\0')
		printf " DEVICE="
		set var $idx = 0
		while ($idx < $dict_len)
			set var $c = $dict[$idx]
			if ($c == '\0')
				loop_break
			else
				if ($c < ' ' || $c >= 127 || $c == '\\')
					printf "\\x%02x", $c
				else
					printf "%c", $c
				end
			end
			set var $idx = $idx + 1
		end
		printf "\n"
	end
end
document dump_record
	Dump a single record. The first parameter is the descriptor,
	the second parameter is the info, the third parameter is
	optional and specifies the previous record's flags, used for
	properly formatting continued lines.
end

define dmesg
	# definitions from kernel/printk/printk_ringbuffer.h
	set var $desc_committed = 1
	set var $desc_finalized = 2
	set var $desc_sv_bits = sizeof(long) * 8
	set var $desc_flags_shift = $desc_sv_bits - 2
	set var $desc_flags_mask = 3 << $desc_flags_shift
	set var $id_mask = ~$desc_flags_mask

	set var $desc_count = 1U << prb->desc_ring.count_bits
	set var $prev_flags = 0

	set var $id = prb->desc_ring.tail_id.counter
	set var $end_id = prb->desc_ring.head_id.counter

	while (1)
		set var $desc = &prb->desc_ring.descs[$id % $desc_count]
		set var $info = &prb->desc_ring.infos[$id % $desc_count]

		# skip non-committed record
		set var $state = 3 & ($desc->state_var.counter >> $desc_flags_shift)
		if ($state == $desc_committed || $state == $desc_finalized)
			dump_record $desc $info $prev_flags
			set var $prev_flags = $info->flags
		end

		set var $id = ($id + 1) & $id_mask
		if ($id == $end_id)
			loop_break
		end
	end
end
document dmesg
	print the kernel ring buffer
end


code:
================================================================
Documentation for Kdump - The kexec-based Crash Dumping Solution
================================================================

This document includes overview, setup and installation, and analysis
information.

.. toctree::
    :maxdepth: 1

    kdump
    vmcoreinfo

.. only::  subproject and html

   Indices
   =======

   * :ref:`genindex`


code:
================================================================
Documentation for Kdump - The kexec-based Crash Dumping Solution
================================================================

This document includes overview, setup, installation, and analysis
information.

Overview
========

Kdump uses kexec to quickly boot to a dump-capture kernel whenever a
dump of the system kernel's memory needs to be taken (for example, when
the system panics). The system kernel's memory image is preserved across
the reboot and is accessible to the dump-capture kernel.

You can use common commands, such as cp, scp or makedumpfile to copy
the memory image to a dump file on the local disk, or across the network
to a remote system.

Kdump and kexec are currently supported on the x86, x86_64, ppc64, ia64,
s390x, arm and arm64 architectures.

When the system kernel boots, it reserves a small section of memory for
the dump-capture kernel. This ensures that ongoing Direct Memory Access
(DMA) from the system kernel does not corrupt the dump-capture kernel.
The kexec -p command loads the dump-capture kernel into this reserved
memory.

On x86 machines, the first 640 KB of physical memory is needed for boot,
regardless of where the kernel loads. For simpler handling, the whole
low 1M is reserved to avoid any later kernel or device driver writing
data into this area. Like this, the low 1M can be reused as system RAM
by kdump kernel without extra handling.

On PPC64 machines first 32KB of physical memory is needed for booting
regardless of where the kernel is loaded and to support 64K page size
kexec backs up the first 64KB memory.

For s390x, when kdump is triggered, the crashkernel region is exchanged
with the region [0, crashkernel region size] and then the kdump kernel
runs in [0, crashkernel region size]. Therefore no relocatable kernel is
needed for s390x.

All of the necessary information about the system kernel's core image is
encoded in the ELF format, and stored in a reserved area of memory
before a crash. The physical address of the start of the ELF header is
passed to the dump-capture kernel through the elfcorehdr= boot
parameter. Optionally the size of the ELF header can also be passed
when using the elfcorehdr=[size[KMG]@]offset[KMG] syntax.

With the dump-capture kernel, you can access the memory image through
/proc/vmcore. This exports the dump as an ELF-format file that you can
write out using file copy commands such as cp or scp. You can also use
makedumpfile utility to analyze and write out filtered contents with
options, e.g with '-d 31' it will only write out kernel data. Further,
you can use analysis tools such as the GNU Debugger (GDB) and the Crash
tool to debug the dump file. This method ensures that the dump pages are
correctly ordered.

Setup and Installation
======================

Install kexec-tools
-------------------

1) Login as the root user.

2) Download the kexec-tools user-space package from the following URL:

http://kernel.org/pub/linux/utils/kernel/kexec/kexec-tools.tar.gz

This is a symlink to the latest version.

The latest kexec-tools git tree is available at:

- git://git.kernel.org/pub/scm/utils/kernel/kexec/kexec-tools.git
- http://www.kernel.org/pub/scm/utils/kernel/kexec/kexec-tools.git

There is also a gitweb interface available at
http://www.kernel.org/git/?p=utils/kernel/kexec/kexec-tools.git

More information about kexec-tools can be found at
http://horms.net/projects/kexec/

3) Unpack the tarball with the tar command, as follows::

	tar xvpzf kexec-tools.tar.gz

4) Change to the kexec-tools directory, as follows::

	cd kexec-tools-VERSION

5) Configure the package, as follows::

	./configure

6) Compile the package, as follows::

	make

7) Install the package, as follows::

	make install

Build the system and dump-capture kernels
-----------------------------------------
There are two possible methods of using Kdump.

1) Build a separate custom dump-capture kernel for capturing the
   kernel core dump.

2) Or use the system kernel binary itself as dump-capture kernel and there is
   no need to build a separate dump-capture kernel. This is possible
   only with the architectures which support a relocatable kernel. As
   of today, i386, x86_64, ppc64, ia64, arm and arm64 architectures support
   relocatable kernel.

Building a relocatable kernel is advantageous from the point of view that
one does not have to build a second kernel for capturing the dump. But
at the same time one might want to build a custom dump capture kernel
suitable to his needs.

Following are the configuration setting required for system and
dump-capture kernels for enabling kdump support.

System kernel config options
----------------------------

1) Enable "kexec system call" or "kexec file based system call" in
   "Processor type and features."::

	CONFIG_KEXEC=y or CONFIG_KEXEC_FILE=y

   And both of them will select KEXEC_CORE::

	CONFIG_KEXEC_CORE=y

   Subsequently, CRASH_CORE is selected by KEXEC_CORE::

	CONFIG_CRASH_CORE=y

2) Enable "sysfs file system support" in "Filesystem" -> "Pseudo
   filesystems." This is usually enabled by default::

	CONFIG_SYSFS=y

   Note that "sysfs file system support" might not appear in the "Pseudo
   filesystems" menu if "Configure standard kernel features (expert users)"
   is not enabled in "General Setup." In this case, check the .config file
   itself to ensure that sysfs is turned on, as follows::

	grep 'CONFIG_SYSFS' .config

3) Enable "Compile the kernel with debug info" in "Kernel hacking."::

	CONFIG_DEBUG_INFO=Y

   This causes the kernel to be built with debug symbols. The dump
   analysis tools require a vmlinux with debug symbols in order to read
   and analyze a dump file.

Dump-capture kernel config options (Arch Independent)
-----------------------------------------------------

1) Enable "kernel crash dumps" support under "Processor type and
   features"::

	CONFIG_CRASH_DUMP=y

2) Enable "/proc/vmcore support" under "Filesystems" -> "Pseudo filesystems"::

	CONFIG_PROC_VMCORE=y

   (CONFIG_PROC_VMCORE is set by default when CONFIG_CRASH_DUMP is selected.)

Dump-capture kernel config options (Arch Dependent, i386 and x86_64)
--------------------------------------------------------------------

1) On i386, enable high memory support under "Processor type and
   features"::

	CONFIG_HIGHMEM64G=y

   or::

	CONFIG_HIGHMEM4G

2) With CONFIG_SMP=y, usually nr_cpus=1 need specified on the kernel
   command line when loading the dump-capture kernel because one
   CPU is enough for kdump kernel to dump vmcore on most of systems.

   However, you can also specify nr_cpus=X to enable multiple processors
   in kdump kernel. In this case, "disable_cpu_apicid=" is needed to
   tell kdump kernel which cpu is 1st kernel's BSP. Please refer to
   admin-guide/kernel-parameters.txt for more details.

   With CONFIG_SMP=n, the above things are not related.

3) A relocatable kernel is suggested to be built by default. If not yet,
   enable "Build a relocatable kernel" support under "Processor type and
   features"::

	CONFIG_RELOCATABLE=y

4) Use a suitable value for "Physical address where the kernel is
   loaded" (under "Processor type and features"). This only appears when
   "kernel crash dumps" is enabled. A suitable value depends upon
   whether kernel is relocatable or not.

   If you are using a relocatable kernel use CONFIG_PHYSICAL_START=0x100000
   This will compile the kernel for physical address 1MB, but given the fact
   kernel is relocatable, it can be run from any physical address hence
   kexec boot loader will load it in memory region reserved for dump-capture
   kernel.

   Otherwise it should be the start of memory region reserved for
   second kernel using boot parameter "crashkernel=Y@X". Here X is
   start of memory region reserved for dump-capture kernel.
   Generally X is 16MB (0x1000000). So you can set
   CONFIG_PHYSICAL_START=0x1000000

5) Make and install the kernel and its modules. DO NOT add this kernel
   to the boot loader configuration files.

Dump-capture kernel config options (Arch Dependent, ppc64)
----------------------------------------------------------

1) Enable "Build a kdump crash kernel" support under "Kernel" options::

	CONFIG_CRASH_DUMP=y

2)   Enable "Build a relocatable kernel" support::

	CONFIG_RELOCATABLE=y

   Make and install the kernel and its modules.

Dump-capture kernel config options (Arch Dependent, ia64)
----------------------------------------------------------

- No specific options are required to create a dump-capture kernel
  for ia64, other than those specified in the arch independent section
  above. This means that it is possible to use the system kernel
  as a dump-capture kernel if desired.

  The crashkernel region can be automatically placed by the system
  kernel at runtime. This is done by specifying the base address as 0,
  or omitting it all together::

	crashkernel=256M@0

  or::

	crashkernel=256M

Dump-capture kernel config options (Arch Dependent, arm)
----------------------------------------------------------

-   To use a relocatable kernel,
    Enable "AUTO_ZRELADDR" support under "Boot" options::

	AUTO_ZRELADDR=y

Dump-capture kernel config options (Arch Dependent, arm64)
----------------------------------------------------------

- Please note that kvm of the dump-capture kernel will not be enabled
  on non-VHE systems even if it is configured. This is because the CPU
  will not be reset to EL2 on panic.

crashkernel syntax
===========================
1) crashkernel=size@offset

   Here 'size' specifies how much memory to reserve for the dump-capture kernel
   and 'offset' specifies the beginning of this reserved memory. For example,
   "crashkernel=64M@16M" tells the system kernel to reserve 64 MB of memory
   starting at physical address 0x01000000 (16MB) for the dump-capture kernel.

   The crashkernel region can be automatically placed by the system
   kernel at run time. This is done by specifying the base address as 0,
   or omitting it all together::

         crashkernel=256M@0

   or::

         crashkernel=256M

   If the start address is specified, note that the start address of the
   kernel will be aligned to a value (which is Arch dependent), so if the
   start address is not then any space below the alignment point will be
   wasted.

2) range1:size1[,range2:size2,...][@offset]

   While the "crashkernel=size[@offset]" syntax is sufficient for most
   configurations, sometimes it's handy to have the reserved memory dependent
   on the value of System RAM -- that's mostly for distributors that pre-setup
   the kernel command line to avoid a unbootable system after some memory has
   been removed from the machine.

   The syntax is::

       crashkernel=<range1>:<size1>[,<range2>:<size2>,...][@offset]
       range=start-[end]

   For example::

       crashkernel=512M-2G:64M,2G-:128M

   This would mean:

       1) if the RAM is smaller than 512M, then don't reserve anything
          (this is the "rescue" case)
       2) if the RAM size is between 512M and 2G (exclusive), then reserve 64M
       3) if the RAM size is larger than 2G, then reserve 128M

3) crashkernel=size,high and crashkernel=size,low

   If memory above 4G is preferred, crashkernel=size,high can be used to
   fulfill that. With it, physical memory is allowed to be allocated from top,
   so could be above 4G if system has more than 4G RAM installed. Otherwise,
   memory region will be allocated below 4G if available.

   When crashkernel=X,high is passed, kernel could allocate physical memory
   region above 4G, low memory under 4G is needed in this case. There are
   three ways to get low memory:

      1) Kernel will allocate at least 256M memory below 4G automatically
         if crashkernel=Y,low is not specified.
      2) Let user specify low memory size instead.
      3) Specified value 0 will disable low memory allocation::

            crashkernel=0,low

Boot into System Kernel
-----------------------
1) Update the boot loader (such as grub, yaboot, or lilo) configuration
   files as necessary.

2) Boot the system kernel with the boot parameter "crashkernel=Y@X".

   On x86 and x86_64, use "crashkernel=Y[@X]". Most of the time, the
   start address 'X' is not necessary, kernel will search a suitable
   area. Unless an explicit start address is expected.

   On ppc64, use "crashkernel=128M@32M".

   On ia64, 256M@256M is a generous value that typically works.
   The region may be automatically placed on ia64, see the
   dump-capture kernel config option notes above.
   If use sparse memory, the size should be rounded to GRANULE boundaries.

   On s390x, typically use "crashkernel=xxM". The value of xx is dependent
   on the memory consumption of the kdump system. In general this is not
   dependent on the memory size of the production system.

   On arm, the use of "crashkernel=Y@X" is no longer necessary; the
   kernel will automatically locate the crash kernel image within the
   first 512MB of RAM if X is not given.

   On arm64, use "crashkernel=Y[@X]".  Note that the start address of
   the kernel, X if explicitly specified, must be aligned to 2MiB (0x200000).

Load the Dump-capture Kernel
============================

After booting to the system kernel, dump-capture kernel needs to be
loaded.

Based on the architecture and type of image (relocatable or not), one
can choose to load the uncompressed vmlinux or compressed bzImage/vmlinuz
of dump-capture kernel. Following is the summary.

For i386 and x86_64:

	- Use bzImage/vmlinuz if kernel is relocatable.
	- Use vmlinux if kernel is not relocatable.

For ppc64:

	- Use vmlinux

For ia64:

	- Use vmlinux or vmlinuz.gz

For s390x:

	- Use image or bzImage

For arm:

	- Use zImage

For arm64:

	- Use vmlinux or Image

If you are using an uncompressed vmlinux image then use following command
to load dump-capture kernel::

   kexec -p <dump-capture-kernel-vmlinux-image> \
   --initrd=<initrd-for-dump-capture-kernel> --args-linux \
   --append="root=<root-dev> <arch-specific-options>"

If you are using a compressed bzImage/vmlinuz, then use following command
to load dump-capture kernel::

   kexec -p <dump-capture-kernel-bzImage> \
   --initrd=<initrd-for-dump-capture-kernel> \
   --append="root=<root-dev> <arch-specific-options>"

If you are using a compressed zImage, then use following command
to load dump-capture kernel::

   kexec --type zImage -p <dump-capture-kernel-bzImage> \
   --initrd=<initrd-for-dump-capture-kernel> \
   --dtb=<dtb-for-dump-capture-kernel> \
   --append="root=<root-dev> <arch-specific-options>"

If you are using an uncompressed Image, then use following command
to load dump-capture kernel::

   kexec -p <dump-capture-kernel-Image> \
   --initrd=<initrd-for-dump-capture-kernel> \
   --append="root=<root-dev> <arch-specific-options>"

Please note, that --args-linux does not need to be specified for ia64.
It is planned to make this a no-op on that architecture, but for now
it should be omitted

Following are the arch specific command line options to be used while
loading dump-capture kernel.

For i386, x86_64 and ia64:

	"1 irqpoll nr_cpus=1 reset_devices"

For ppc64:

	"1 maxcpus=1 noirqdistrib reset_devices"

For s390x:

	"1 nr_cpus=1 cgroup_disable=memory"

For arm:

	"1 maxcpus=1 reset_devices"

For arm64:

	"1 nr_cpus=1 reset_devices"

Notes on loading the dump-capture kernel:

* By default, the ELF headers are stored in ELF64 format to support
  systems with more than 4GB memory. On i386, kexec automatically checks if
  the physical RAM size exceeds the 4 GB limit and if not, uses ELF32.
  So, on non-PAE systems, ELF32 is always used.

  The --elf32-core-headers option can be used to force the generation of ELF32
  headers. This is necessary because GDB currently cannot open vmcore files
  with ELF64 headers on 32-bit systems.

* The "irqpoll" boot parameter reduces driver initialization failures
  due to shared interrupts in the dump-capture kernel.

* You must specify <root-dev> in the format corresponding to the root
  device name in the output of mount command.

* Boot parameter "1" boots the dump-capture kernel into single-user
  mode without networking. If you want networking, use "3".

* We generally don't have to bring up a SMP kernel just to capture the
  dump. Hence generally it is useful either to build a UP dump-capture
  kernel or specify maxcpus=1 option while loading dump-capture kernel.
  Note, though maxcpus always works, you had better replace it with
  nr_cpus to save memory if supported by the current ARCH, such as x86.

* You should enable multi-cpu support in dump-capture kernel if you intend
  to use multi-thread programs with it, such as parallel dump feature of
  makedumpfile. Otherwise, the multi-thread program may have a great
  performance degradation. To enable multi-cpu support, you should bring up an
  SMP dump-capture kernel and specify maxcpus/nr_cpus, disable_cpu_apicid=[X]
  options while loading it.

* For s390x there are two kdump modes: If a ELF header is specified with
  the elfcorehdr= kernel parameter, it is used by the kdump kernel as it
  is done on all other architectures. If no elfcorehdr= kernel parameter is
  specified, the s390x kdump kernel dynamically creates the header. The
  second mode has the advantage that for CPU and memory hotplug, kdump has
  not to be reloaded with kexec_load().

* For s390x systems with many attached devices the "cio_ignore" kernel
  parameter should be used for the kdump kernel in order to prevent allocation
  of kernel memory for devices that are not relevant for kdump. The same
  applies to systems that use SCSI/FCP devices. In that case the
  "allow_lun_scan" zfcp module parameter should be set to zero before
  setting FCP devices online.

Kernel Panic
============

After successfully loading the dump-capture kernel as previously
described, the system will reboot into the dump-capture kernel if a
system crash is triggered.  Trigger points are located in panic(),
die(), die_nmi() and in the sysrq handler (ALT-SysRq-c).

The following conditions will execute a crash trigger point:

If a hard lockup is detected and "NMI watchdog" is configured, the system
will boot into the dump-capture kernel ( die_nmi() ).

If die() is called, and it happens to be a thread with pid 0 or 1, or die()
is called inside interrupt context or die() is called and panic_on_oops is set,
the system will boot into the dump-capture kernel.

On powerpc systems when a soft-reset is generated, die() is called by all cpus
and the system will boot into the dump-capture kernel.

For testing purposes, you can trigger a crash by using "ALT-SysRq-c",
"echo c > /proc/sysrq-trigger" or write a module to force the panic.

Write Out the Dump File
=======================

After the dump-capture kernel is booted, write out the dump file with
the following command::

   cp /proc/vmcore <dump-file>

or use scp to write out the dump file between hosts on a network, e.g::

   scp /proc/vmcore remote_username@remote_ip:<dump-file>

You can also use makedumpfile utility to write out the dump file
with specified options to filter out unwanted contents, e.g::

   makedumpfile -l --message-level 1 -d 31 /proc/vmcore <dump-file>

Analysis
========

Before analyzing the dump image, you should reboot into a stable kernel.

You can do limited analysis using GDB on the dump file copied out of
/proc/vmcore. Use the debug vmlinux built with -g and run the following
command::

   gdb vmlinux <dump-file>

Stack trace for the task on processor 0, register display, and memory
display work fine.

Note: GDB cannot analyze core files generated in ELF64 format for x86.
On systems with a maximum of 4GB of memory, you can generate
ELF32-format headers using the --elf32-core-headers kernel option on the
dump kernel.

You can also use the Crash utility to analyze dump files in Kdump
format. Crash is available at the following URL:

   https://github.com/crash-utility/crash

Crash document can be found at:
   https://crash-utility.github.io/

Trigger Kdump on WARN()
=======================

The kernel parameter, panic_on_warn, calls panic() in all WARN() paths.  This
will cause a kdump to occur at the panic() call.  In cases where a user wants
to specify this during runtime, /proc/sys/kernel/panic_on_warn can be set to 1
to achieve the same behaviour.

Trigger Kdump on add_taint()
============================

The kernel parameter panic_on_taint facilitates a conditional call to panic()
from within add_taint() whenever the value set in this bitmask matches with the
bit flag being set by add_taint().
This will cause a kdump to occur at the add_taint()->panic() call.

Contact
=======

- kexec@lists.infradead.org

GDB macros
==========

.. include:: gdbmacros.txt
   :literal: