提交 9e1f0860 编写于 作者: J Jonathan Corbet

Merge branch 'mauro-books' into docs-next

Merge Mauro's massive patch series creating the process and admin-guide
books.  I think there's a lot of stuff to clean up here, but there's no
point in holding things up for that.

Mauro sez:

This patch series continues the efforts of converting the Linux Kernel
documentation to Sphinx.

It contains text to ReST conversion of several files under Documentation,
and a few ones under the main dir (README, REPORTING-BUGS).

All patches on this series can be found on my development tree:
	https://git.linuxtv.org/mchehab/experimental.git/log/?h=lkml-books-v2

The Kernel docs html output after this series can be seen at:
	https://mchehab.fedorapeople.org/kernel_docs/
......@@ -15,11 +15,11 @@ Following translations are available on the WWW:
ABI/
- info on kernel <-> userspace ABI and relative interface stability.
BUG-HUNTING
admin-guide/bug-hunting.rst
- brute force method of doing binary search of patches to find bug.
Changes
process/changes.rst
- list of changes that break older software packages.
CodingStyle
process/coding-style.rst
- how the maintainers expect the C code in the kernel to look.
DMA-API.txt
- DMA API, pci_ API & extensions for non-consistent memory machines.
......@@ -33,7 +33,7 @@ DocBook/
- directory with DocBook templates etc. for kernel documentation.
EDID/
- directory with info on customizing EDID for broken gfx/displays.
HOWTO
process/howto.rst
- the process and procedures of how to do Linux kernel development.
IPMI.txt
- info on Linux Intelligent Platform Management Interface (IPMI) Driver.
......@@ -48,7 +48,7 @@ Intel-IOMMU.txt
Makefile
- This file does nothing. Removing it breaks make htmldocs and
make distclean.
ManagementStyle
process/management-style.rst
- how to (attempt to) manage kernel hackers.
RCU/
- directory with info on RCU (read-copy update).
......@@ -56,13 +56,13 @@ SAK.txt
- info on Secure Attention Keys.
SM501.txt
- Silicon Motion SM501 multimedia companion chip
SecurityBugs
admin-guide/security-bugs.rst
- procedure for reporting security bugs found in the kernel.
SubmitChecklist
process/submit-checklist.rst
- Linux kernel patch submission checklist.
SubmittingDrivers
process/submitting-drivers.rst
- procedure to get a new driver source included into the kernel tree.
SubmittingPatches
process/submitting-patches.rst
- procedure to get a source patch included into the kernel tree.
VGA-softcursor.txt
- how to change your VGA cursor from a blinking underscore.
......@@ -72,7 +72,7 @@ acpi/
- info on ACPI-specific hooks in the kernel.
aoe/
- description of AoE (ATA over Ethernet) along with config examples.
applying-patches.txt
process/applying-patches.rst
- description of various trees and how to apply their patches.
arm/
- directory with info about Linux on the ARM architecture.
......@@ -86,7 +86,7 @@ auxdisplay/
- misc. LCD driver documentation (cfag12864b, ks0108).
backlight/
- directory with info on controlling backlights in flat panel displays
bad_memory.txt
admin-guide/bad-memory.rst
- how to use kernel parameters to exclude bad RAM regions.
basic_profiling.txt
- basic instructions for those who wants to profile Linux kernel.
......@@ -150,11 +150,11 @@ debugging-via-ohci1394.txt
- how to use firewire like a hardware debugger memory reader.
dell_rbu.txt
- document demonstrating the use of the Dell Remote BIOS Update driver.
development-process/
process/
- how to work with the mainline kernel development process.
device-mapper/
- directory with info on Device Mapper.
devices.txt
admin-guide/devices.rst
- plain ASCII listing of all the nodes in /dev/ with major minor #'s.
devicetree/
- directory with info on device tree files used by OF/PowerPC/ARM
......@@ -166,8 +166,6 @@ dontdiff
- file containing a list of files that should never be diff'ed.
driver-model/
- directory with info about Linux driver model.
dvb/
- info on Linux Digital Video Broadcast (DVB) subsystem.
dynamic-debug-howto.txt
- how to use the dynamic debug (dyndbg) feature.
early-userspace/
......@@ -178,7 +176,7 @@ efi-stub.txt
- How to use the EFI boot stub to bypass GRUB or elilo on EFI systems.
eisa.txt
- info on EISA bus support.
email-clients.txt
process/email-clients.rst
- info on how to use e-mail to send un-mangled (git) patches.
extcon/
- directory with porting guide for Android kernel switch driver.
......@@ -226,9 +224,9 @@ ia64/
- directory with info about Linux on Intel 64 bit architecture.
infiniband/
- directory with documents concerning Linux InfiniBand support.
init.txt
admin-guide/init.rst
- what to do when the kernel can't find the 1st process to run.
initrd.txt
admin-guide/initrd.rst
- how to use the RAM disk as an initial/temporary root filesystem.
input/
- info on Linux input device support.
......@@ -248,7 +246,7 @@ isapnp.txt
- info on Linux ISA Plug & Play support.
isdn/
- directory with info on the Linux ISDN support, and supported cards.
java.txt
admin-guide/java.rst
- info on the in-kernel binary support for Java(tm).
ja_JP/
- directory with Japanese translations of various documents
......@@ -256,11 +254,11 @@ kbuild/
- directory with info about the kernel build process.
kdump/
- directory with mini HowTo on getting the crash dump code to work.
kernel-docs.txt
process/kernel-docs.rst
- listing of various WWW + books that document kernel internals.
kernel-documentation.rst
- how to write and format reStructuredText kernel documentation
kernel-parameters.txt
admin-guide/kernel-parameters.rst
- summary listing of command line / boot prompt args for the kernel.
kernel-per-CPU-kthreads.txt
- List of all per-CPU kthreads and how they introduce jitter.
......@@ -302,7 +300,7 @@ magic-number.txt
- list of magic numbers used to mark/protect kernel data structures.
mailbox.txt
- How to write drivers for the common mailbox framework (IPC).
md.txt
admin-guide/md.rst
- info on boot arguments for the multiple devices driver.
media-framework.txt
- info on media framework, its data structures, functions and usage.
......@@ -326,7 +324,7 @@ module-signing.txt
- Kernel module signing for increased security when loading modules.
mtd/
- directory with info about memory technology devices (flash)
mono.txt
admin-guide/mono.rst
- how to execute Mono-based .NET binaries with the help of BINFMT_MISC.
namespaces/
- directory with various information about namespaces
......@@ -340,7 +338,7 @@ nommu-mmap.txt
- documentation about no-mmu memory mapping support.
numastat.txt
- info on how to read Numa policy hit/miss statistics in sysfs.
oops-tracing.txt
admin-guide/oops-tracing.rst
- how to decode those nasty internal kernel error dump messages.
padata.txt
- An introduction to the "padata" parallel execution API
......@@ -378,7 +376,7 @@ ptp/
- directory with info on support for IEEE 1588 PTP clocks in Linux.
pwm.txt
- info on the pulse width modulation driver subsystem
ramoops.txt
admin-guide/ramoops.rst
- documentation of the ramoops oops/panic logging module.
rapidio/
- directory with info on RapidIO packet-based fabric interconnect
......@@ -406,7 +404,7 @@ security/
- directory that contains security-related info
serial/
- directory with info on the low level serial API.
serial-console.txt
admin-guide/serial-console.rst
- how to set up Linux with a serial line console as the default.
sgi-ioc4.txt
- description of the SGI IOC4 PCI (multi function) device.
......@@ -420,9 +418,9 @@ sparse.txt
- info on how to obtain and use the sparse tool for typechecking.
spi/
- overview of Linux kernel Serial Peripheral Interface (SPI) support.
stable_api_nonsense.txt
process/stable-api-nonsense.rst
- info on why the kernel does not have a stable in-kernel api or abi.
stable_kernel_rules.txt
process/stable-kernel-rules.rst
- rules and procedures for the -stable kernel releases.
static-keys.txt
- info on how static keys allow debug code in hotpaths via patching
......@@ -444,7 +442,7 @@ trace/
- directory with info on tracing technologies within linux
unaligned-memory-access.txt
- info on how to avoid arch breaking unaligned memory access in code.
unicode.txt
admin-guide/unicode.rst
- info on the Unicode character/font mapping used in Linux.
unshare.txt
- description of the Linux unshare system call.
......@@ -458,15 +456,13 @@ vgaarbiter.txt
- info on enable/disable the legacy decoding on different VGA devices
video-output.txt
- sysfs class driver interface to enable/disable a video output device.
video4linux/
- directory with info regarding video/TV/radio cards and linux.
virtual/
- directory with information on the various linux virtualizations.
vm/
- directory with info on the Linux vm code.
vme_api.txt
- file relating info on the VME bus API in linux
volatile-considered-harmful.txt
process/volatile-considered-harmful.rst
- Why the "volatile" type class should not be used
w1/
- directory with documents regarding the 1-wire (w1) subsystem.
......
......@@ -84,4 +84,4 @@ stable:
- Kernel-internal symbols. Do not rely on the presence, absence, location, or
type of any kernel symbol, either in System.map files or the kernel binary
itself. See Documentation/stable_api_nonsense.txt.
itself. See Documentation/process/stable-api-nonsense.rst.
......@@ -347,7 +347,7 @@ Description:
because of fragmentation, SLUB will retry with the minimum order
possible depending on its characteristics.
When debug_guardpage_minorder=N (N > 0) parameter is specified
(see Documentation/kernel-parameters.txt), the minimum possible
(see Documentation/admin-guide/kernel-parameters.rst), the minimum possible
order is used and this sysfs entry can not be used to change
the order at run time.
......
此差异已折叠。
......@@ -1208,8 +1208,8 @@ static struct block_device_operations opt_fops = {
<listitem>
<para>
Finally, don't forget to read <filename>Documentation/SubmittingPatches</filename>
and possibly <filename>Documentation/SubmittingDrivers</filename>.
Finally, don't forget to read <filename>Documentation/process/submitting-patches.rst</filename>
and possibly <filename>Documentation/process/submitting-drivers.rst</filename>.
</para>
</listitem>
</itemizedlist>
......
此差异已折叠。
Software cursor for VGA by Pavel Machek <pavel@atrey.karlin.mff.cuni.cz>
======================= and Martin Mares <mj@atrey.karlin.mff.cuni.cz>
Linux now has some ability to manipulate cursor appearance. Normally, you
can set the size of hardware cursor (and also work around some ugly bugs in
those miserable Trident cards--see #define TRIDENT_GLITCH in drivers/video/
vgacon.c). You can now play a few new tricks: you can make your cursor look
like a non-blinking red block, make it inverse background of the character it's
over or to highlight that character and still choose whether the original
hardware cursor should remain visible or not. There may be other things I have
never thought of.
The cursor appearance is controlled by a "<ESC>[?1;2;3c" escape sequence
where 1, 2 and 3 are parameters described below. If you omit any of them,
they will default to zeroes.
Parameter 1 specifies cursor size (0=default, 1=invisible, 2=underline, ...,
8=full block) + 16 if you want the software cursor to be applied + 32 if you
want to always change the background color + 64 if you dislike having the
background the same as the foreground. Highlights are ignored for the last two
flags.
The second parameter selects character attribute bits you want to change
(by simply XORing them with the value of this parameter). On standard VGA,
the high four bits specify background and the low four the foreground. In both
groups, low three bits set color (as in normal color codes used by the console)
and the most significant one turns on highlight (or sometimes blinking--it
depends on the configuration of your VGA).
The third parameter consists of character attribute bits you want to set.
Bit setting takes place before bit toggling, so you can simply clear a bit by
including it in both the set mask and the toggle mask.
Examples:
=========
To get normal blinking underline, use: echo -e '\033[?2c'
To get blinking block, use: echo -e '\033[?6c'
To get red non-blinking block, use: echo -e '\033[?17;0;64c'
......@@ -101,6 +101,6 @@ received a notification, it will set the backlight level accordingly. This does
not affect the sending of event to user space, they are always sent to user
space regardless of whether or not the video module controls the backlight level
directly. This behaviour can be controlled through the brightness_switch_enabled
module parameter as documented in kernel-parameters.txt. It is recommended to
module parameter as documented in admin-guide/kernel-parameters.rst. It is recommended to
disable this behaviour once a GUI environment starts up and wants to have full
control of the backlight level.
Linux kernel release 4.x <http://kernel.org/>
=============================================
These are the release notes for Linux version 4. Read them carefully,
as they tell you what this is all about, explain how to install the
kernel, and what to do if something goes wrong.
What is Linux?
--------------
Linux is a clone of the operating system Unix, written from scratch by
Linus Torvalds with assistance from a loosely-knit team of hackers across
the Net. It aims towards POSIX and Single UNIX Specification compliance.
It has all the features you would expect in a modern fully-fledged Unix,
including true multitasking, virtual memory, shared libraries, demand
loading, shared copy-on-write executables, proper memory management,
and multistack networking including IPv4 and IPv6.
It is distributed under the GNU General Public License - see the
accompanying COPYING file for more details.
On what hardware does it run?
-----------------------------
Although originally developed first for 32-bit x86-based PCs (386 or higher),
today Linux also runs on (at least) the Compaq Alpha AXP, Sun SPARC and
UltraSPARC, Motorola 68000, PowerPC, PowerPC64, ARM, Hitachi SuperH, Cell,
IBM S/390, MIPS, HP PA-RISC, Intel IA-64, DEC VAX, AMD x86-64, AXIS CRIS,
Xtensa, Tilera TILE, AVR32, ARC and Renesas M32R architectures.
Linux is easily portable to most general-purpose 32- or 64-bit architectures
as long as they have a paged memory management unit (PMMU) and a port of the
GNU C compiler (gcc) (part of The GNU Compiler Collection, GCC). Linux has
also been ported to a number of architectures without a PMMU, although
functionality is then obviously somewhat limited.
Linux has also been ported to itself. You can now run the kernel as a
userspace application - this is called UserMode Linux (UML).
Documentation
-------------
- There is a lot of documentation available both in electronic form on
the Internet and in books, both Linux-specific and pertaining to
general UNIX questions. I'd recommend looking into the documentation
subdirectories on any Linux FTP site for the LDP (Linux Documentation
Project) books. This README is not meant to be documentation on the
system: there are much better sources available.
- There are various README files in the Documentation/ subdirectory:
these typically contain kernel-specific installation notes for some
drivers for example. See Documentation/00-INDEX for a list of what
is contained in each file. Please read the
:ref:`Documentation/process/changes.rst <changes>` file, as it
contains information about the problems, which may result by upgrading
your kernel.
- The Documentation/DocBook/ subdirectory contains several guides for
kernel developers and users. These guides can be rendered in a
number of formats: PostScript (.ps), PDF, HTML, & man-pages, among others.
After installation, ``make psdocs``, ``make pdfdocs``, ``make htmldocs``,
or ``make mandocs`` will render the documentation in the requested format.
Installing the kernel source
----------------------------
- If you install the full sources, put the kernel tarball in a
directory where you have permissions (e.g. your home directory) and
unpack it::
xz -cd linux-4.X.tar.xz | tar xvf -
Replace "X" with the version number of the latest kernel.
Do NOT use the /usr/src/linux area! This area has a (usually
incomplete) set of kernel headers that are used by the library header
files. They should match the library, and not get messed up by
whatever the kernel-du-jour happens to be.
- You can also upgrade between 4.x releases by patching. Patches are
distributed in the xz format. To install by patching, get all the
newer patch files, enter the top level directory of the kernel source
(linux-4.X) and execute::
xz -cd ../patch-4.x.xz | patch -p1
Replace "x" for all versions bigger than the version "X" of your current
source tree, **in_order**, and you should be ok. You may want to remove
the backup files (some-file-name~ or some-file-name.orig), and make sure
that there are no failed patches (some-file-name# or some-file-name.rej).
If there are, either you or I have made a mistake.
Unlike patches for the 4.x kernels, patches for the 4.x.y kernels
(also known as the -stable kernels) are not incremental but instead apply
directly to the base 4.x kernel. For example, if your base kernel is 4.0
and you want to apply the 4.0.3 patch, you must not first apply the 4.0.1
and 4.0.2 patches. Similarly, if you are running kernel version 4.0.2 and
want to jump to 4.0.3, you must first reverse the 4.0.2 patch (that is,
patch -R) **before** applying the 4.0.3 patch. You can read more on this in
:ref:`Documentation/process/applying-patches.rst <applying_patches>`.
Alternatively, the script patch-kernel can be used to automate this
process. It determines the current kernel version and applies any
patches found::
linux/scripts/patch-kernel linux
The first argument in the command above is the location of the
kernel source. Patches are applied from the current directory, but
an alternative directory can be specified as the second argument.
- Make sure you have no stale .o files and dependencies lying around::
cd linux
make mrproper
You should now have the sources correctly installed.
Software requirements
---------------------
Compiling and running the 4.x kernels requires up-to-date
versions of various software packages. Consult
:ref:`Documentation/process/changes.rst <changes>` for the minimum version numbers
required and how to get updates for these packages. Beware that using
excessively old versions of these packages can cause indirect
errors that are very difficult to track down, so don't assume that
you can just update packages when obvious problems arise during
build or operation.
Build directory for the kernel
------------------------------
When compiling the kernel, all output files will per default be
stored together with the kernel source code.
Using the option ``make O=output/dir`` allows you to specify an alternate
place for the output files (including .config).
Example::
kernel source code: /usr/src/linux-4.X
build directory: /home/name/build/kernel
To configure and build the kernel, use::
cd /usr/src/linux-4.X
make O=/home/name/build/kernel menuconfig
make O=/home/name/build/kernel
sudo make O=/home/name/build/kernel modules_install install
Please note: If the ``O=output/dir`` option is used, then it must be
used for all invocations of make.
Configuring the kernel
----------------------
Do not skip this step even if you are only upgrading one minor
version. New configuration options are added in each release, and
odd problems will turn up if the configuration files are not set up
as expected. If you want to carry your existing configuration to a
new version with minimal work, use ``make oldconfig``, which will
only ask you for the answers to new questions.
- Alternative configuration commands are::
"make config" Plain text interface.
"make menuconfig" Text based color menus, radiolists & dialogs.
"make nconfig" Enhanced text based color menus.
"make xconfig" Qt based configuration tool.
"make gconfig" GTK+ based configuration tool.
"make oldconfig" Default all questions based on the contents of
your existing ./.config file and asking about
new config symbols.
"make silentoldconfig"
Like above, but avoids cluttering the screen
with questions already answered.
Additionally updates the dependencies.
"make olddefconfig"
Like above, but sets new symbols to their default
values without prompting.
"make defconfig" Create a ./.config file by using the default
symbol values from either arch/$ARCH/defconfig
or arch/$ARCH/configs/${PLATFORM}_defconfig,
depending on the architecture.
"make ${PLATFORM}_defconfig"
Create a ./.config file by using the default
symbol values from
arch/$ARCH/configs/${PLATFORM}_defconfig.
Use "make help" to get a list of all available
platforms of your architecture.
"make allyesconfig"
Create a ./.config file by setting symbol
values to 'y' as much as possible.
"make allmodconfig"
Create a ./.config file by setting symbol
values to 'm' as much as possible.
"make allnoconfig" Create a ./.config file by setting symbol
values to 'n' as much as possible.
"make randconfig" Create a ./.config file by setting symbol
values to random values.
"make localmodconfig" Create a config based on current config and
loaded modules (lsmod). Disables any module
option that is not needed for the loaded modules.
To create a localmodconfig for another machine,
store the lsmod of that machine into a file
and pass it in as a LSMOD parameter.
target$ lsmod > /tmp/mylsmod
target$ scp /tmp/mylsmod host:/tmp
host$ make LSMOD=/tmp/mylsmod localmodconfig
The above also works when cross compiling.
"make localyesconfig" Similar to localmodconfig, except it will convert
all module options to built in (=y) options.
You can find more information on using the Linux kernel config tools
in Documentation/kbuild/kconfig.txt.
- NOTES on ``make config``:
- Having unnecessary drivers will make the kernel bigger, and can
under some circumstances lead to problems: probing for a
nonexistent controller card may confuse your other controllers
- A kernel with math-emulation compiled in will still use the
coprocessor if one is present: the math emulation will just
never get used in that case. The kernel will be slightly larger,
but will work on different machines regardless of whether they
have a math coprocessor or not.
- The "kernel hacking" configuration details usually result in a
bigger or slower kernel (or both), and can even make the kernel
less stable by configuring some routines to actively try to
break bad code to find kernel problems (kmalloc()). Thus you
should probably answer 'n' to the questions for "development",
"experimental", or "debugging" features.
Compiling the kernel
--------------------
- Make sure you have at least gcc 3.2 available.
For more information, refer to :ref:`Documentation/process/changes.rst <changes>`.
Please note that you can still run a.out user programs with this kernel.
- Do a ``make`` to create a compressed kernel image. It is also
possible to do ``make install`` if you have lilo installed to suit the
kernel makefiles, but you may want to check your particular lilo setup first.
To do the actual install, you have to be root, but none of the normal
build should require that. Don't take the name of root in vain.
- If you configured any of the parts of the kernel as ``modules``, you
will also have to do ``make modules_install``.
- Verbose kernel compile/build output:
Normally, the kernel build system runs in a fairly quiet mode (but not
totally silent). However, sometimes you or other kernel developers need
to see compile, link, or other commands exactly as they are executed.
For this, use "verbose" build mode. This is done by passing
``V=1`` to the ``make`` command, e.g.::
make V=1 all
To have the build system also tell the reason for the rebuild of each
target, use ``V=2``. The default is ``V=0``.
- Keep a backup kernel handy in case something goes wrong. This is
especially true for the development releases, since each new release
contains new code which has not been debugged. Make sure you keep a
backup of the modules corresponding to that kernel, as well. If you
are installing a new kernel with the same version number as your
working kernel, make a backup of your modules directory before you
do a ``make modules_install``.
Alternatively, before compiling, use the kernel config option
"LOCALVERSION" to append a unique suffix to the regular kernel version.
LOCALVERSION can be set in the "General Setup" menu.
- In order to boot your new kernel, you'll need to copy the kernel
image (e.g. .../linux/arch/x86/boot/bzImage after compilation)
to the place where your regular bootable kernel is found.
- Booting a kernel directly from a floppy without the assistance of a
bootloader such as LILO, is no longer supported.
If you boot Linux from the hard drive, chances are you use LILO, which
uses the kernel image as specified in the file /etc/lilo.conf. The
kernel image file is usually /vmlinuz, /boot/vmlinuz, /bzImage or
/boot/bzImage. To use the new kernel, save a copy of the old image
and copy the new image over the old one. Then, you MUST RERUN LILO
to update the loading map! If you don't, you won't be able to boot
the new kernel image.
Reinstalling LILO is usually a matter of running /sbin/lilo.
You may wish to edit /etc/lilo.conf to specify an entry for your
old kernel image (say, /vmlinux.old) in case the new one does not
work. See the LILO docs for more information.
After reinstalling LILO, you should be all set. Shutdown the system,
reboot, and enjoy!
If you ever need to change the default root device, video mode,
ramdisk size, etc. in the kernel image, use the ``rdev`` program (or
alternatively the LILO boot options when appropriate). No need to
recompile the kernel to change these parameters.
- Reboot with the new kernel and enjoy.
If something goes wrong
-----------------------
- If you have problems that seem to be due to kernel bugs, please check
the file MAINTAINERS to see if there is a particular person associated
with the part of the kernel that you are having trouble with. If there
isn't anyone listed there, then the second best thing is to mail
them to me (torvalds@linux-foundation.org), and possibly to any other
relevant mailing-list or to the newsgroup.
- In all bug-reports, *please* tell what kernel you are talking about,
how to duplicate the problem, and what your setup is (use your common
sense). If the problem is new, tell me so, and if the problem is
old, please try to tell me when you first noticed it.
- If the bug results in a message like::
unable to handle kernel paging request at address C0000010
Oops: 0002
EIP: 0010:XXXXXXXX
eax: xxxxxxxx ebx: xxxxxxxx ecx: xxxxxxxx edx: xxxxxxxx
esi: xxxxxxxx edi: xxxxxxxx ebp: xxxxxxxx
ds: xxxx es: xxxx fs: xxxx gs: xxxx
Pid: xx, process nr: xx
xx xx xx xx xx xx xx xx xx xx
or similar kernel debugging information on your screen or in your
system log, please duplicate it *exactly*. The dump may look
incomprehensible to you, but it does contain information that may
help debugging the problem. The text above the dump is also
important: it tells something about why the kernel dumped code (in
the above example, it's due to a bad kernel pointer). More information
on making sense of the dump is in Documentation/admin-guide/oops-tracing.rst
- If you compiled the kernel with CONFIG_KALLSYMS you can send the dump
as is, otherwise you will have to use the ``ksymoops`` program to make
sense of the dump (but compiling with CONFIG_KALLSYMS is usually preferred).
This utility can be downloaded from
ftp://ftp.<country>.kernel.org/pub/linux/utils/kernel/ksymoops/ .
Alternatively, you can do the dump lookup by hand:
- In debugging dumps like the above, it helps enormously if you can
look up what the EIP value means. The hex value as such doesn't help
me or anybody else very much: it will depend on your particular
kernel setup. What you should do is take the hex value from the EIP
line (ignore the ``0010:``), and look it up in the kernel namelist to
see which kernel function contains the offending address.
To find out the kernel function name, you'll need to find the system
binary associated with the kernel that exhibited the symptom. This is
the file 'linux/vmlinux'. To extract the namelist and match it against
the EIP from the kernel crash, do::
nm vmlinux | sort | less
This will give you a list of kernel addresses sorted in ascending
order, from which it is simple to find the function that contains the
offending address. Note that the address given by the kernel
debugging messages will not necessarily match exactly with the
function addresses (in fact, that is very unlikely), so you can't
just 'grep' the list: the list will, however, give you the starting
point of each kernel function, so by looking for the function that
has a starting address lower than the one you are searching for but
is followed by a function with a higher address you will find the one
you want. In fact, it may be a good idea to include a bit of
"context" in your problem report, giving a few lines around the
interesting one.
If you for some reason cannot do the above (you have a pre-compiled
kernel image or similar), telling me as much about your setup as
possible will help. Please read the :ref:`admin-guide/reporting-bugs.rst <reportingbugs>`
document for details.
- Alternatively, you can use gdb on a running kernel. (read-only; i.e. you
cannot change values or set break points.) To do this, first compile the
kernel with -g; edit arch/x86/Makefile appropriately, then do a ``make
clean``. You'll also need to enable CONFIG_PROC_FS (via ``make config``).
After you've rebooted with the new kernel, do ``gdb vmlinux /proc/kcore``.
You can now use all the usual gdb commands. The command to look up the
point where your system crashed is ``l *0xXXXXXXXX``. (Replace the XXXes
with the EIP value.)
gdb'ing a non-running kernel currently fails because ``gdb`` (wrongly)
disregards the starting offset for which the kernel is compiled.
How to deal with bad memory e.g. reported by memtest86+ ?
=========================================================
March 2008
Jan-Simon Moeller, dl9pf@gmx.de
How to deal with bad memory e.g. reported by memtest86+ ?
#########################################################
There are three possibilities I know of:
......@@ -19,6 +20,7 @@ This Howto is about number 3) .
BadRAM
######
BadRAM is the actively developed and available as kernel-patch
here: http://rick.vanrein.org/linux/badram/
......@@ -31,15 +33,18 @@ memmap is already in the kernel and usable as kernel-parameter at
boot-time. Its syntax is slightly strange and you may need to
calculate the values by yourself!
Syntax to exclude a memory area (see kernel-parameters.txt for details):
memmap=<size>$<address>
Syntax to exclude a memory area (see admin-guide/kernel-parameters.rst for details)::
memmap=<size>$<address>
Example: memtest86+ reported here errors at address 0x18691458, 0x18698424 and
some others. All had 0x1869xxxx in common, so I chose a pattern of
0x18690000,0xffff0000.
some others. All had 0x1869xxxx in common, so I chose a pattern of
0x18690000,0xffff0000.
With the numbers of the example above::
memmap=64K$0x18690000
With the numbers of the example above:
memmap=64K$0x18690000
or
memmap=0x10000$0x18690000
or::
memmap=0x10000$0x18690000
Basic kernel profiling
======================
These instructions are deliberately very basic. If you want something clever,
go read the real docs ;-) Please don't add more stuff, but feel free to
go read the real docs ;-)
Please don't add more stuff, but feel free to
correct my mistakes ;-) (mbligh@aracnet.com)
Thanks to John Levon, Dave Hansen, et al. for help writing this.
<test> is the thing you're trying to measure.
Make sure you have the correct System.map / vmlinux referenced!
``<test>`` is the thing you're trying to measure.
Make sure you have the correct ``System.map`` / ``vmlinux`` referenced!
It is probably easiest to use "make install" for linux and hack
/sbin/installkernel to copy vmlinux to /boot, in addition to vmlinuz,
config, System.map, which are usually installed by default.
It is probably easiest to use ``make install`` for linux and hack
``/sbin/installkernel`` to copy ``vmlinux`` to ``/boot``, in addition to
``vmlinuz``, ``config``, ``System.map``, which are usually installed by default.
Readprofile
-----------
A recent readprofile command is needed for 2.6, such as found in util-linux
A recent ``readprofile`` command is needed for 2.6, such as found in util-linux
2.12a, which can be downloaded from:
http://www.kernel.org/pub/linux/utils/util-linux/
http://www.kernel.org/pub/linux/utils/util-linux/
Most distributions will ship it already.
Add "profile=2" to the kernel command line.
Add ``profile=2`` to the kernel command line.
clear readprofile -r
<test>
dump output readprofile -m /boot/System.map > captured_profile
Some ``readprofile`` commands::
clear readprofile -r
<test>
dump output readprofile -m /boot/System.map > captured_profile
Oprofile
--------
Get the source (see Changes for required version) from
http://oprofile.sourceforge.net/ and add "idle=poll" to the kernel command
http://oprofile.sourceforge.net/ and add ``idle=poll`` to the kernel command
line.
Configure with CONFIG_PROFILING=y and CONFIG_OPROFILE=y & reboot on new kernel
Configure with ``CONFIG_PROFILING=y`` and ``CONFIG_OPROFILE=y`` & reboot on new kernel::
./configure --with-kernel-support
make install
./configure --with-kernel-support
make install
For superior results, be sure to enable the local APIC. If opreport sees
a 0Hz CPU, APIC was not on. Be aware that idle=poll may mean a performance
penalty.
One time setup:
opcontrol --setup --vmlinux=/boot/vmlinux
One time setup::
opcontrol --setup --vmlinux=/boot/vmlinux
clear opcontrol --reset
start opcontrol --start
Some ``opcontrol`` commands::
clear opcontrol --reset
start opcontrol --start
<test>
stop opcontrol --stop
dump output opreport > output_file
stop opcontrol --stop
dump output opreport > output_file
To only report on the kernel, run opreport -l /boot/vmlinux > output_file
To only report on the kernel, run ``opreport -l /boot/vmlinux > output_file``
A reset is needed to clear old statistics, which survive a reboot.
Kernel Support for miscellaneous (your favourite) Binary Formats v1.1
=====================================================================
Kernel Support for miscellaneous (your favourite) Binary Formats v1.1
=====================================================================
This Kernel feature allows you to invoke almost (for restrictions see below)
every program by simply typing its name in the shell.
......@@ -9,122 +9,142 @@ To achieve this you must tell binfmt_misc which interpreter has to be invoked
with which binary. Binfmt_misc recognises the binary-type by matching some bytes
at the beginning of the file with a magic byte sequence (masking out specified
bits) you have supplied. Binfmt_misc can also recognise a filename extension
aka '.com' or '.exe'.
aka ``.com`` or ``.exe``.
First you must mount binfmt_misc:
mount binfmt_misc -t binfmt_misc /proc/sys/fs/binfmt_misc
First you must mount binfmt_misc::
mount binfmt_misc -t binfmt_misc /proc/sys/fs/binfmt_misc
To actually register a new binary type, you have to set up a string looking like
:name:type:offset:magic:mask:interpreter:flags (where you can choose the ':'
upon your needs) and echo it to /proc/sys/fs/binfmt_misc/register.
``:name:type:offset:magic:mask:interpreter:flags`` (where you can choose the
``:`` upon your needs) and echo it to ``/proc/sys/fs/binfmt_misc/register``.
Here is what the fields mean:
- 'name' is an identifier string. A new /proc file will be created with this
name below /proc/sys/fs/binfmt_misc; cannot contain slashes '/' for obvious
reasons.
- 'type' is the type of recognition. Give 'M' for magic and 'E' for extension.
- 'offset' is the offset of the magic/mask in the file, counted in bytes. This
defaults to 0 if you omit it (i.e. you write ':name:type::magic...'). Ignored
when using filename extension matching.
- 'magic' is the byte sequence binfmt_misc is matching for. The magic string
may contain hex-encoded characters like \x0a or \xA4. Note that you must
escape any NUL bytes; parsing halts at the first one. In a shell environment
you might have to write \\x0a to prevent the shell from eating your \.
- ``name``
is an identifier string. A new /proc file will be created with this
``name below /proc/sys/fs/binfmt_misc``; cannot contain slashes ``/`` for
obvious reasons.
- ``type``
is the type of recognition. Give ``M`` for magic and ``E`` for extension.
- ``offset``
is the offset of the magic/mask in the file, counted in bytes. This
defaults to 0 if you omit it (i.e. you write ``:name:type::magic...``).
Ignored when using filename extension matching.
- ``magic``
is the byte sequence binfmt_misc is matching for. The magic string
may contain hex-encoded characters like ``\x0a`` or ``\xA4``. Note that you
must escape any NUL bytes; parsing halts at the first one. In a shell
environment you might have to write ``\\x0a`` to prevent the shell from
eating your ``\``.
If you chose filename extension matching, this is the extension to be
recognised (without the '.', the \x0a specials are not allowed). Extension
matching is case sensitive, and slashes '/' are not allowed!
- 'mask' is an (optional, defaults to all 0xff) mask. You can mask out some
recognised (without the ``.``, the ``\x0a`` specials are not allowed).
Extension matching is case sensitive, and slashes ``/`` are not allowed!
- ``mask``
is an (optional, defaults to all 0xff) mask. You can mask out some
bits from matching by supplying a string like magic and as long as magic.
The mask is anded with the byte sequence of the file. Note that you must
escape any NUL bytes; parsing halts at the first one. Ignored when using
filename extension matching.
- 'interpreter' is the program that should be invoked with the binary as first
- ``interpreter``
is the program that should be invoked with the binary as first
argument (specify the full path)
- 'flags' is an optional field that controls several aspects of the invocation
- ``flags``
is an optional field that controls several aspects of the invocation
of the interpreter. It is a string of capital letters, each controls a
certain aspect. The following flags are supported -
'P' - preserve-argv[0]. Legacy behavior of binfmt_misc is to overwrite
certain aspect. The following flags are supported:
``P`` - preserve-argv[0]
Legacy behavior of binfmt_misc is to overwrite
the original argv[0] with the full path to the binary. When this
flag is included, binfmt_misc will add an argument to the argument
vector for this purpose, thus preserving the original argv[0].
e.g. If your interp is set to /bin/foo and you run `blah` (which is
in /usr/local/bin), then the kernel will execute /bin/foo with
argv[] set to ["/bin/foo", "/usr/local/bin/blah", "blah"]. The
interp has to be aware of this so it can execute /usr/local/bin/blah
with argv[] set to ["blah"].
'O' - open-binary. Legacy behavior of binfmt_misc is to pass the full path
vector for this purpose, thus preserving the original ``argv[0]``.
e.g. If your interp is set to ``/bin/foo`` and you run ``blah``
(which is in ``/usr/local/bin``), then the kernel will execute
``/bin/foo`` with ``argv[]`` set to ``["/bin/foo", "/usr/local/bin/blah", "blah"]``. The interp has to be aware of this so it can
execute ``/usr/local/bin/blah``
with ``argv[]`` set to ``["blah"]``.
``O`` - open-binary
Legacy behavior of binfmt_misc is to pass the full path
of the binary to the interpreter as an argument. When this flag is
included, binfmt_misc will open the file for reading and pass its
descriptor as an argument, instead of the full path, thus allowing
the interpreter to execute non-readable binaries. This feature
should be used with care - the interpreter has to be trusted not to
emit the contents of the non-readable binary.
'C' - credentials. Currently, the behavior of binfmt_misc is to calculate
``C`` - credentials
Currently, the behavior of binfmt_misc is to calculate
the credentials and security token of the new process according to
the interpreter. When this flag is included, these attributes are
calculated according to the binary. It also implies the 'O' flag.
calculated according to the binary. It also implies the ``O`` flag.
This feature should be used with care as the interpreter
will run with root permissions when a setuid binary owned by root
is run with binfmt_misc.
'F' - fix binary. The usual behaviour of binfmt_misc is to spawn the
binary lazily when the misc format file is invoked. However,
this doesn't work very well in the face of mount namespaces and
changeroots, so the F mode opens the binary as soon as the
``F`` - fix binary
The usual behaviour of binfmt_misc is to spawn the
binary lazily when the misc format file is invoked. However,
this doesn``t work very well in the face of mount namespaces and
changeroots, so the ``F`` mode opens the binary as soon as the
emulation is installed and uses the opened image to spawn the
emulator, meaning it is always available once installed,
regardless of how the environment changes.
There are some restrictions:
- the whole register string may not exceed 1920 characters
- the magic must reside in the first 128 bytes of the file, i.e.
offset+size(magic) has to be less than 128
- the interpreter string may not exceed 127 characters
To use binfmt_misc you have to mount it first. You can mount it with
"mount -t binfmt_misc none /proc/sys/fs/binfmt_misc" command, or you can add
a line "none /proc/sys/fs/binfmt_misc binfmt_misc defaults 0 0" to your
/etc/fstab so it auto mounts on boot.
``mount -t binfmt_misc none /proc/sys/fs/binfmt_misc`` command, or you can add
a line ``none /proc/sys/fs/binfmt_misc binfmt_misc defaults 0 0`` to your
``/etc/fstab`` so it auto mounts on boot.
You may want to add the binary formats in one of your /etc/rc scripts during
You may want to add the binary formats in one of your ``/etc/rc`` scripts during
boot-up. Read the manual of your init program to figure out how to do this
right.
Think about the order of adding entries! Later added entries are matched first!
A few examples (assumed you are in /proc/sys/fs/binfmt_misc):
A few examples (assumed you are in ``/proc/sys/fs/binfmt_misc``):
- enable support for em86 (like binfmt_em86, for Alpha AXP only)::
echo ':i386:M::\x7fELF\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x03:\xff\xff\xff\xff\xff\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfb\xff\xff:/bin/em86:' > register
echo ':i486:M::\x7fELF\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x06:\xff\xff\xff\xff\xff\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfb\xff\xff:/bin/em86:' > register
- enable support for packed DOS applications (pre-configured dosemu hdimages)::
- enable support for em86 (like binfmt_em86, for Alpha AXP only):
echo ':i386:M::\x7fELF\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x03:\xff\xff\xff\xff\xff\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfb\xff\xff:/bin/em86:' > register
echo ':i486:M::\x7fELF\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x06:\xff\xff\xff\xff\xff\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfb\xff\xff:/bin/em86:' > register
echo ':DEXE:M::\x0eDEX::/usr/bin/dosexec:' > register
- enable support for packed DOS applications (pre-configured dosemu hdimages):
echo ':DEXE:M::\x0eDEX::/usr/bin/dosexec:' > register
- enable support for Windows executables using wine::
- enable support for Windows executables using wine:
echo ':DOSWin:M::MZ::/usr/local/bin/wine:' > register
echo ':DOSWin:M::MZ::/usr/local/bin/wine:' > register
For java support see Documentation/java.txt
For java support see Documentation/admin-guide/java.rst
You can enable/disable binfmt_misc or one binary type by echoing 0 (to disable)
or 1 (to enable) to /proc/sys/fs/binfmt_misc/status or /proc/.../the_name.
Catting the file tells you the current status of binfmt_misc/the entry.
or 1 (to enable) to ``/proc/sys/fs/binfmt_misc/status`` or
``/proc/.../the_name``.
Catting the file tells you the current status of ``binfmt_misc/the_entry``.
You can remove one entry or all entries by echoing -1 to /proc/.../the_name
or /proc/sys/fs/binfmt_misc/status.
You can remove one entry or all entries by echoing -1 to ``/proc/.../the_name``
or ``/proc/sys/fs/binfmt_misc/status``.
HINTS:
======
Hints
-----
If you want to pass special arguments to your interpreter, you can
write a wrapper script for it. See Documentation/java.txt for an
write a wrapper script for it. See Documentation/admin-guide/java.rst for an
example.
Your interpreter should NOT look in the PATH for the filename; the kernel
passes it the full filename (or the file descriptor) to use. Using $PATH can
passes it the full filename (or the file descriptor) to use. Using ``$PATH`` can
cause unexpected behaviour and can be a security hazard.
......
Linux Braille Console
Linux Braille Console
=====================
To get early boot messages on a braille device (before userspace screen
readers can start), you first need to compile the support for the usual serial
console (see serial-console.txt), and for braille device (in Device Drivers -
Accessibility).
console (see :ref:`Documentation/admin-guide/serial-console.rst <serial_console>`), and
for braille device
(in :menuselection:`Device Drivers --> Accessibility support --> Console on braille device`).
Then you need to specify a console=brl, option on the kernel command line, the
format is:
Then you need to specify a ``console=brl``, option on the kernel command line, the
format is::
console=brl,serial_options...
where serial_options... are the same as described in serial-console.txt
where ``serial_options...`` are the same as described in
:ref:`Documentation/admin-guide/serial-console.rst <serial_console>`.
So for instance you can use console=brl,ttyS0 if the braille device is connected
to the first serial port, and console=brl,ttyS0,115200 to override the baud rate
to 115200, etc.
So for instance you can use ``console=brl,ttyS0`` if the braille device is connected to the first serial port, and ``console=brl,ttyS0,115200`` to
override the baud rate to 115200, etc.
By default, the braille device will just show the last kernel message (console
mode). To review previous messages, press the Insert key to switch to the VT
review mode. In review mode, the arrow keys permit to browse in the VT content,
page up/down keys go at the top/bottom of the screen, and the home key goes back
:kbd:`PAGE-UP`/:kbd:`PAGE-DOWN` keys go at the top/bottom of the screen, and
the :kbd:`HOME` key goes back
to the cursor, hence providing very basic screen reviewing facility.
Sound feedback can be obtained by adding the braille_console.sound=1 kernel
Sound feedback can be obtained by adding the ``braille_console.sound=1`` kernel
parameter.
For simplicity, only one braille console can be enabled, other uses of
console=brl,... will be discarded. Also note that it does not interfere with
the console selection mechanism described in serial-console.txt
``console=brl,...`` will be discarded. Also note that it does not interfere with
the console selection mechanism described in
:ref:`Documentation/admin-guide/serial-console.rst <serial_console>`.
For now, only the VisioBraille device is supported.
......
Table of contents
=================
Bug hunting
+++++++++++
Last updated: 20 December 2005
Contents
========
- Introduction
- Devices not appearing
- Finding patch that caused a bug
-- Finding using git-bisect
-- Finding it the old way
- Fixing the bug
Introduction
============
......@@ -24,7 +14,8 @@ Finding bugs is not always easy. Have a go though. If you can't find it don't
give up. Report as much as you have found to the relevant maintainer. See
MAINTAINERS for who that is for the subsystem you have worked on.
Before you submit a bug report read REPORTING-BUGS.
Before you submit a bug report read
:ref:`Documentation/admin-guide/reporting-bugs.rst <reportingbugs>`.
Devices not appearing
=====================
......@@ -37,15 +28,16 @@ Finding patch that caused a bug
Finding using git-bisect
------------------------
Finding using ``git-bisect``
----------------------------
Using the provided tools with git makes finding bugs easy provided the bug is
reproducible.
Using the provided tools with ``git`` makes finding bugs easy provided the bug
is reproducible.
Steps to do it:
- start using git for the kernel source
- read the man page for git-bisect
- read the man page for ``git-bisect``
- have fun
Finding it the old way
......@@ -58,22 +50,22 @@ It's a brute force approach but it works pretty well.
You need:
. A reproducible bug - it has to happen predictably (sorry)
. All the kernel tar files from a revision that worked to the
- A reproducible bug - it has to happen predictably (sorry)
- All the kernel tar files from a revision that worked to the
revision that doesn't
You will then do:
. Rebuild a revision that you believe works, install, and verify that.
. Do a binary search over the kernels to figure out which one
- Rebuild a revision that you believe works, install, and verify that.
- Do a binary search over the kernels to figure out which one
introduced the bug. I.e., suppose 1.3.28 didn't have the bug, but
you know that 1.3.69 does. Pick a kernel in the middle and build
that, like 1.3.50. Build & test; if it works, pick the mid point
between .50 and .69, else the mid point between .28 and .50.
. You'll narrow it down to the kernel that introduced the bug. You
- You'll narrow it down to the kernel that introduced the bug. You
can probably do better than this but it gets tricky.
. Narrow it down to a subdirectory
- Narrow it down to a subdirectory
- Copy kernel that works into "test". Let's say that 3.62 works,
but 3.63 doesn't. So you diff -r those two kernels and come
......@@ -83,7 +75,7 @@ You will then do:
Copy the non-working directory next to the working directory
as "dir.63".
One directory at time, try moving the working directory to
"dir.62" and mv dir.63 dir"time, try
"dir.62" and mv dir.63 dir"time, try::
mv dir dir.62
mv dir.63 dir
......@@ -97,15 +89,15 @@ You will then do:
found in my case that they were self explanatory - you may
or may not want to give up when that happens.
. Narrow it down to a file
- Narrow it down to a file
- You can apply the same technique to each file in the directory,
hoping that the changes in that file are self contained.
. Narrow it down to a routine
- Narrow it down to a routine
- You can take the old file and the new file and manually create
a merged file that has
a merged file that has::
#ifdef VER62
routine()
......@@ -120,7 +112,7 @@ You will then do:
#endif
And then walk through that file, one routine at a time and
prefix it with
prefix it with::
#define VER62
/* both routines here */
......@@ -153,94 +145,105 @@ To debug a kernel, use objdump and look for the hex offset from the crash
output to find the valid line of code/assembler. Without debug symbols, you
will see the assembler code for the routine shown, but if your kernel has
debug symbols the C code will also be available. (Debug symbols can be enabled
in the kernel hacking menu of the menu configuration.) For example:
in the kernel hacking menu of the menu configuration.) For example::
objdump -r -S -l --disassemble net/dccp/ipv4.o
NB.: you need to be at the top level of the kernel tree for this to pick up
your C files.
.. note::
You need to be at the top level of the kernel tree for this to pick up
your C files.
If you don't have access to the code you can also debug on some crash dumps
e.g. crash dump output as shown by Dave Miller.
> EIP is at ip_queue_xmit+0x14/0x4c0
> ...
> Code: 44 24 04 e8 6f 05 00 00 e9 e8 fe ff ff 8d 76 00 8d bc 27 00 00
> 00 00 55 57 56 53 81 ec bc 00 00 00 8b ac 24 d0 00 00 00 8b 5d 08
> <8b> 83 3c 01 00 00 89 44 24 14 8b 45 28 85 c0 89 44 24 18 0f 85
>
> Put the bytes into a "foo.s" file like this:
>
> .text
> .globl foo
> foo:
> .byte .... /* bytes from Code: part of OOPS dump */
>
> Compile it with "gcc -c -o foo.o foo.s" then look at the output of
> "objdump --disassemble foo.o".
>
> Output:
>
> ip_queue_xmit:
> push %ebp
> push %edi
> push %esi
> push %ebx
> sub $0xbc, %esp
> mov 0xd0(%esp), %ebp ! %ebp = arg0 (skb)
> mov 0x8(%ebp), %ebx ! %ebx = skb->sk
> mov 0x13c(%ebx), %eax ! %eax = inet_sk(sk)->opt
e.g. crash dump output as shown by Dave Miller::
EIP is at ip_queue_xmit+0x14/0x4c0
...
Code: 44 24 04 e8 6f 05 00 00 e9 e8 fe ff ff 8d 76 00 8d bc 27 00 00
00 00 55 57 56 53 81 ec bc 00 00 00 8b ac 24 d0 00 00 00 8b 5d 08
<8b> 83 3c 01 00 00 89 44 24 14 8b 45 28 85 c0 89 44 24 18 0f 85
Put the bytes into a "foo.s" file like this:
.text
.globl foo
foo:
.byte .... /* bytes from Code: part of OOPS dump */
Compile it with "gcc -c -o foo.o foo.s" then look at the output of
"objdump --disassemble foo.o".
Output:
ip_queue_xmit:
push %ebp
push %edi
push %esi
push %ebx
sub $0xbc, %esp
mov 0xd0(%esp), %ebp ! %ebp = arg0 (skb)
mov 0x8(%ebp), %ebx ! %ebx = skb->sk
mov 0x13c(%ebx), %eax ! %eax = inet_sk(sk)->opt
In addition, you can use GDB to figure out the exact file and line
number of the OOPS from the vmlinux file. If you have
CONFIG_DEBUG_INFO enabled, you can simply copy the EIP value from the
OOPS:
number of the OOPS from the ``vmlinux`` file. If you have
``CONFIG_DEBUG_INFO`` enabled, you can simply copy the EIP value from the
OOPS::
EIP: 0060:[<c021e50e>] Not tainted VLI
And use GDB to translate that to human-readable form:
And use GDB to translate that to human-readable form::
gdb vmlinux
(gdb) l *0xc021e50e
If you don't have CONFIG_DEBUG_INFO enabled, you use the function
offset from the OOPS:
If you don't have ``CONFIG_DEBUG_INFO`` enabled, you use the function
offset from the OOPS::
EIP is at vt_ioctl+0xda8/0x1482
And recompile the kernel with CONFIG_DEBUG_INFO enabled:
And recompile the kernel with ``CONFIG_DEBUG_INFO`` enabled::
make vmlinux
gdb vmlinux
(gdb) p vt_ioctl
(gdb) l *(0x<address of vt_ioctl> + 0xda8)
or, as one command
or, as one command::
(gdb) l *(vt_ioctl + 0xda8)
If you have a call trace, such as :-
>Call Trace:
> [<ffffffff8802c8e9>] :jbd:log_wait_commit+0xa3/0xf5
> [<ffffffff810482d9>] autoremove_wake_function+0x0/0x2e
> [<ffffffff8802770b>] :jbd:journal_stop+0x1be/0x1ee
> ...
If you have a call trace, such as::
Call Trace:
[<ffffffff8802c8e9>] :jbd:log_wait_commit+0xa3/0xf5
[<ffffffff810482d9>] autoremove_wake_function+0x0/0x2e
[<ffffffff8802770b>] :jbd:journal_stop+0x1be/0x1ee
...
this shows the problem in the :jbd: module. You can load that module in gdb
and list the relevant code.
and list the relevant code::
gdb fs/jbd/jbd.ko
(gdb) p log_wait_commit
(gdb) l *(0x<address> + 0xa3)
or
or::
(gdb) l *(log_wait_commit + 0xa3)
Another very useful option of the Kernel Hacking section in menuconfig is
Debug memory allocations. This will help you see whether data has been
initialised and not set before use etc. To see the values that get assigned
with this look at mm/slab.c and search for POISON_INUSE. When using this an
Oops will often show the poisoned data instead of zero which is the default.
with this look at ``mm/slab.c`` and search for ``POISON_INUSE``. When using
this an Oops will often show the poisoned data instead of zero which is the
default.
Once you have worked out a fix please submit it upstream. After all open
source is about sharing what you do and don't you want to be recognised for
your genius?
Please do read Documentation/SubmittingPatches though to help your code get
accepted.
Please do read
ref:`Documentation/process/submitting-patches.rst <submittingpatches>` though
to help your code get accepted.
# -*- coding: utf-8; mode: python -*-
project = 'Linux Kernel User Documentation'
tags.add("subproject")
latex_documents = [
('index', 'linux-user.tex', 'Linux Kernel User Documentation',
'The kernel development community', 'manual'),
]
Linux Kernel User's Documentation
=================================
Contents:
.. toctree::
:maxdepth: 2
:numbered:
README
reporting-bugs
bug-hunting
oops-tracing
ramoops
initrd
init
dynamic-debug-howto
security-bugs
kernel-parameters
serial-console
braille-console
parport
md
module-signing
sysrq
unicode
vga-softcursor
sysfs-rules
devices
binfmt-misc
mono
java
bad-memory
basic-profiling
......@@ -5,6 +5,7 @@ OK, so you've got this pretty unintuitive message (currently located
in init/main.c) and are wondering what the H*** went wrong.
Some high-level reasons for failure (listed roughly in order of execution)
to load the init binary are:
A) Unable to mount root FS
B) init binary doesn't exist on rootfs
C) broken console device
......@@ -12,37 +13,39 @@ D) binary exists but dependencies not available
E) binary cannot be loaded
Detailed explanations:
0) Set "debug" kernel parameter (in bootloader config file or CONFIG_CMDLINE)
A) Set "debug" kernel parameter (in bootloader config file or CONFIG_CMDLINE)
to get more detailed kernel messages.
A) make sure you have the correct root FS type
(and root= kernel parameter points to the correct partition),
B) 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)
C) Possibly a conflict in console= setup --> initial console unavailable.
C) 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= .
Try using a different ``console= device`` or e.g. ``netconsole=``.
D) 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.
``/lib/ld-linux.so.2`` missing or broken. Use
``readelf -d <INIT>|grep NEEDED`` to find out which libraries are required.
E) 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
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
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 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).
- 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.
......
......@@ -2,7 +2,7 @@ Using the initial RAM disk (initrd)
===================================
Written 1996,2000 by Werner Almesberger <werner.almesberger@epfl.ch> and
Hans Lermen <lermen@fgan.de>
Hans Lermen <lermen@fgan.de>
initrd provides the capability to load a RAM disk by the boot loader.
......@@ -16,7 +16,7 @@ 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 [1].
discussion of the boot process can be found in [#f1]_.
Operation
......@@ -27,10 +27,10 @@ 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)
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
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
......@@ -38,7 +38,7 @@ When using initrd, the system typically boots as follows:
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
8) init execs the ``/sbin/init`` on the new root filesystem, performing
the usual boot sequence
9) the initrd file system is removed
......@@ -51,7 +51,7 @@ be accessible.
Boot command-line options
-------------------------
initrd adds the following new options:
initrd adds the following new options::
initrd=<path> (e.g. LOADLIN)
......@@ -83,36 +83,36 @@ 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):
example)::
find . | cpio --quiet -H newc -o | gzip -9 -n > /boot/imagefile.img
find . | cpio --quiet -H newc -o | gzip -9 -n > /boot/imagefile.img
Examining the contents of an existing image file is just as simple:
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
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.
"normal" root file system, e.g.::
# mkdir /initrd
# mkdir /initrd
The name is not relevant. More details can be found on the pivot_root(2)
man page.
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.
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:
accessible if the following device has been created::
# mknod /dev/initrd b 1 250
# chmod 400 /dev/initrd
# 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
......@@ -131,60 +131,76 @@ kernels, at least three types of devices are suitable for that:
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
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:
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 that /sbin/init's permissions must include "x" (execute).
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
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
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
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 [2] to create a small
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:
have to be given::
root=/dev/ram0 rw
(rw is only necessary if writing to the initrd file system.)
With LOADLIN, you simply execute
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.
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
and run ``/sbin/lilo``
For other boot loaders, please refer to the respective documentation.
......@@ -204,33 +220,33 @@ The procedure involves the following steps:
- 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:
a directory under the current root. Example::
# mkdir /new-root
# mount -o ro /dev/hda1 /new-root
# 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 pivot_root(8) man
page; pivot_root is distributed with util-linux version 2.10h or higher
[3]). pivot_root moves the current root to a directory under the new
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:
must exist before calling ``pivot_root``. Example::
# cd /new-root
# mkdir initrd
# pivot_root . initrd
# 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:
following command::
# exec chroot . what-follows <dev/console >dev/console 2>&1
# exec chroot . what-follows <dev/console >dev/console 2>&1
Where what-follows is a program under the new root, e.g. /sbin/init
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.
``/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:
......@@ -244,13 +260,13 @@ to ensure compatibility, the following points should be observed:
- 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:
disk can be freed::
# umount /initrd
# blockdev --flushbufs /dev/ram0
# umount /initrd
# blockdev --flushbufs /dev/ram0
It is also possible to use initrd with an NFS-mounted root, see the
pivot_root(8) man page for details.
:manpage:`pivot_root(8)` man page for details.
Usage scenarios
......@@ -263,21 +279,21 @@ 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
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
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
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
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)
``/dev/ram0`` or ``/dev/rd/0`` to a file)
8) now the system is bootable and additional installation tasks can be
performed
......@@ -290,7 +306,7 @@ 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
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
......@@ -301,9 +317,9 @@ 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
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.
floppies.
Obsolete root change mechanism
......@@ -316,51 +332,52 @@ 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
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.
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".
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.
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:
``/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
#! /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.
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
---------
[1] Almesberger, Werner; "Booting Linux: The History and the Future"
.. [#f1] Almesberger, Werner; "Booting Linux: The History and the Future"
http://www.almesberger.net/cv/papers/ols2k-9.ps.gz
[2] newlib package (experimental), with initrd example
http://sources.redhat.com/newlib/
[3] util-linux: Miscellaneous utilities for Linux
http://www.kernel.org/pub/linux/utils/util-linux/
.. [#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/
Java(tm) Binary Kernel Support for Linux v1.03
----------------------------------------------
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!
......@@ -19,70 +19,80 @@ other program after you have done the following:
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.
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.
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:
(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:
support for executable Jar files::
':ExecutableJAR:E::jar::/usr/local/bin/jarwrapper:'
support for Java Applets:
support for Java Applets::
':Applet:E::html::/usr/bin/appletviewer:'
or the following, if you want to be more selective:
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)
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!
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.
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>.
====================== Cut here ===================
#!/bin/bash
# /usr/local/bin/javawrapper - the wrapper for binfmt_misc/java
Javawrapper shell script::
if [ -z "$1" ]; then
#!/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
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-/[^/]*$--'`
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
# for example:
# CLASS=Test.class
# FQCLASS=foo.bar.Test
# FQCLASSN=Test
# FQCLASSP=foo/bar
unset CLASSBASE
unset CLASSBASE
declare -i LINKLEVEL=0
declare -i LINKLEVEL=0
while :; do
while :; do
if [ "`basename $CLASS .class`" == "$FQCLASSN" ]; then
# See if this directory works straight off
cd -L `dirname $CLASS`
......@@ -119,9 +129,9 @@ while :; do
exit 1
fi
CLASS=`ls --color=no -l $CLASS | sed -e 's/^.* \([^ ]*\)$/\1/'`
done
done
if [ -z "$CLASSBASE" ]; then
if [ -z "$CLASSBASE" ]; then
if [ -z "$FQCLASSP" ]; then
GOODNAME=$FQCLASSN.class
else
......@@ -131,24 +141,23 @@ if [ -z "$CLASSBASE" ]; then
echo $0:
echo " $FQCLASS should be in a file called $GOODNAME"
exit 1
fi
fi
if ! echo $CLASSPATH | grep -q "^\(.*:\)*$CLASSBASE\(:.*\)*"; then
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
fi
shift
/usr/bin/java $FQCLASS "$@"
====================== Cut here ===================
shift
/usr/bin/java $FQCLASS "$@"
javaclassname.c::
====================== Cut here ===================
/* javaclassname.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.
......@@ -170,57 +179,57 @@ shift
* 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)
{
#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)
{
/* Reads in an unsigned 16-bit integer. */
u_int16_t read_16(FILE *classfile)
{
int b1, b2;
b1 = fgetc(classfile);
if(b1 == EOF)
......@@ -229,11 +238,11 @@ u_int16_t read_16(FILE *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)
{
/* 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);
......@@ -270,19 +279,19 @@ void skip_constant(FILE *classfile, u_int16_t *cur)
}
if(seekerr)
seek_error();
}
}
void error(const char *format, ...)
{
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)
{
int main(int argc, char **argv)
{
FILE *classfile;
u_int16_t cp_count, i, this_class, classinfo_ptr;
u_int8_t length;
......@@ -349,19 +358,19 @@ int main(int argc, char **argv)
free(pool);
fclose(classfile);
return 0;
}
====================== Cut here ===================
}
jarwrapper::
#!/bin/bash
# /usr/local/java/bin/jarwrapper - the wrapper for binfmt_misc/jar
====================== Cut here ===================
#!/bin/bash
# /usr/local/java/bin/jarwrapper - the wrapper for binfmt_misc/jar
java -jar $1
java -jar $1
====================== Cut here ===================
Now simply ``chmod +x`` the ``.class``, ``.jar`` and/or ``.html`` files you
want to execute.
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
......@@ -369,7 +378,7 @@ added to your CLASSPATH during execution.
To test your new setup, enter in the following simple Java app, and name
it "HelloWorld.java":
it "HelloWorld.java"::
class HelloWorld {
public static void main(String args[]) {
......@@ -377,23 +386,28 @@ it "HelloWorld.java":
}
}
Now compile the application with:
Now compile the application with::
javac HelloWorld.java
Set the executable permissions of the binary file, with:
Set the executable permissions of the binary file, with::
chmod 755 HelloWorld.class
And then execute it:
And then execute it::
./HelloWorld.class
To execute Java Jar files, simple chmod the *.jar files to include
the execution bit, then just do
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
To execute Java Applets, simple chmod the ``*.html`` files to include
the execution bit, then just do::
./Applet.html
......@@ -401,4 +415,3 @@ 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>
Kernel Parameters
~~~~~~~~~~~~~~~~~
Kernel Parameters
~~~~~~~~~~~~~~~~~
The following is a consolidated list of the kernel parameters as
implemented by the __setup(), core_param() and module_param() macros
......@@ -14,7 +14,7 @@ environment, others are passed as command line arguments to init.
Everything after "--" is passed as an argument to init.
Module parameters can be specified in two ways: via the kernel command
line with a module name prefix, or via modprobe, e.g.:
line with a module name prefix, or via modprobe, e.g.::
(kernel command line) usbcore.blinkenlights=1
(modprobe command line) modprobe usbcore blinkenlights=1
......@@ -25,12 +25,16 @@ kernel command line (/proc/cmdline) and collects module parameters
when it loads a module, so the kernel command line can be used for
loadable modules too.
Hyphens (dashes) and underscores are equivalent in parameter names, so
Hyphens (dashes) and underscores are equivalent in parameter names, so::
log_buf_len=1M print-fatal-signals=1
can also be entered as
can also be entered as::
log-buf-len=1M print_fatal_signals=1
Double-quotes can be used to protect spaces in values, e.g.:
Double-quotes can be used to protect spaces in values, e.g.::
param="spaces in here"
cpu lists:
......@@ -69,12 +73,12 @@ This document may not be entirely up to date and comprehensive. The command
module. Loadable modules, after being loaded into the running kernel, also
reveal their parameters in /sys/module/${modulename}/parameters/. Some of these
parameters may be changed at runtime by the command
"echo -n ${value} > /sys/module/${modulename}/parameters/${parm}".
``echo -n ${value} > /sys/module/${modulename}/parameters/${parm}``.
The parameters listed below are only valid if certain kernel build options were
enabled and if respective hardware is present. The text in square brackets at
the beginning of each description states the restrictions within which a
parameter is applicable:
parameter is applicable::
ACPI ACPI support is enabled.
AGP AGP (Accelerated Graphics Port) is enabled.
......@@ -165,7 +169,7 @@ parameter is applicable:
X86_UV SGI UV support is enabled.
XEN Xen support is enabled
In addition, the following text indicates that the option:
In addition, the following text indicates that the option::
BUGS= Relates to possible processor bugs on the said processor.
KNL Is a kernel start-up parameter.
......@@ -194,7 +198,7 @@ and is between 256 and 4096 characters. It is defined in the file
Finally, the [KMG] suffix is commonly described after a number of kernel
parameter values. These 'K', 'M', and 'G' letters represent the _binary_
multipliers 'Kilo', 'Mega', and 'Giga', equalling 2^10, 2^20, and 2^30
bytes respectively. Such letter suffixes can also be entirely omitted.
bytes respectively. Such letter suffixes can also be entirely omitted::
acpi= [HW,ACPI,X86,ARM64]
......@@ -811,7 +815,7 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
bits, and "f" is flow control ("r" for RTS or
omit it). Default is "9600n8".
See Documentation/serial-console.txt for more
See Documentation/admin-guide/serial-console.rst for more
information. See
Documentation/networking/netconsole.txt for an
alternative.
......@@ -2235,7 +2239,7 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
mce=option [X86-64] See Documentation/x86/x86_64/boot-options.txt
md= [HW] RAID subsystems devices and level
See Documentation/md.txt.
See Documentation/admin-guide/md.rst.
mdacon= [MDA]
Format: <first>,<last>
......@@ -2545,7 +2549,7 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
will be sent.
The default is to send the implementation identification
information.
nfs.recover_lost_locks =
[NFSv4] Attempt to recover locks that were lost due
to a lease timeout on the server. Please note that
......@@ -3318,7 +3322,7 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
r128= [HW,DRM]
raid= [HW,RAID]
See Documentation/md.txt.
See Documentation/admin-guide/md.rst.
ramdisk_size= [RAM] Sizes of RAM disks in kilobytes
See Documentation/blockdev/ramdisk.txt.
......@@ -4197,7 +4201,7 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
See also Documentation/input/joystick-parport.txt
udbg-immortal [PPC] When debugging early kernel crashes that
happen after console_init() and before a proper
happen after console_init() and before a proper
console driver takes over, this boot options might
help "seeing" what's going on.
......@@ -4565,8 +4569,9 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
Format:
<irq>,<irq_mask>,<io>,<full_duplex>,<do_sound>,<lockup_hack>[,<irq2>[,<irq3>[,<irq4>]]]
______________________________________________________________________
------------------------
TODO:
Todo
----
Add more DRM drivers.
==============================
KERNEL MODULE SIGNING FACILITY
==============================
CONTENTS
- Overview.
- Configuring module signing.
- Generating signing keys.
- Public keys in the kernel.
- Manually signing modules.
- Signed modules and stripping.
- Loading signed modules.
- Non-valid signatures and unsigned modules.
- Administering/protecting the private key.
Kernel module signing facility
------------------------------
.. CONTENTS
..
.. - Overview.
.. - Configuring module signing.
.. - Generating signing keys.
.. - Public keys in the kernel.
.. - Manually signing modules.
.. - Signed modules and stripping.
.. - Loading signed modules.
.. - Non-valid signatures and unsigned modules.
.. - Administering/protecting the private key.
========
OVERVIEW
Overview
========
The kernel module signing facility cryptographically signs modules during
......@@ -36,17 +35,19 @@ SHA-512 (the algorithm is selected by data in the signature).
==========================
CONFIGURING MODULE SIGNING
Configuring module signing
==========================
The module signing facility is enabled by going to the "Enable Loadable Module
Support" section of the kernel configuration and turning on
The module signing facility is enabled by going to the
:menuselection:`Enable Loadable Module Support` section of
the kernel configuration and turning on::
CONFIG_MODULE_SIG "Module signature verification"
This has a number of options available:
(1) "Require modules to be validly signed" (CONFIG_MODULE_SIG_FORCE)
(1) :menuselection:`Require modules to be validly signed`
(``CONFIG_MODULE_SIG_FORCE``)
This specifies how the kernel should deal with a module that has a
signature for which the key is not known or a module that is unsigned.
......@@ -64,35 +65,39 @@ This has a number of options available:
cannot be parsed, it will be rejected out of hand.
(2) "Automatically sign all modules" (CONFIG_MODULE_SIG_ALL)
(2) :menuselection:`Automatically sign all modules`
(``CONFIG_MODULE_SIG_ALL``)
If this is on then modules will be automatically signed during the
modules_install phase of a build. If this is off, then the modules must
be signed manually using:
be signed manually using::
scripts/sign-file
(3) "Which hash algorithm should modules be signed with?"
(3) :menuselection:`Which hash algorithm should modules be signed with?`
This presents a choice of which hash algorithm the installation phase will
sign the modules with:
CONFIG_MODULE_SIG_SHA1 "Sign modules with SHA-1"
CONFIG_MODULE_SIG_SHA224 "Sign modules with SHA-224"
CONFIG_MODULE_SIG_SHA256 "Sign modules with SHA-256"
CONFIG_MODULE_SIG_SHA384 "Sign modules with SHA-384"
CONFIG_MODULE_SIG_SHA512 "Sign modules with SHA-512"
=============================== ==========================================
``CONFIG_MODULE_SIG_SHA1`` :menuselection:`Sign modules with SHA-1`
``CONFIG_MODULE_SIG_SHA224`` :menuselection:`Sign modules with SHA-224`
``CONFIG_MODULE_SIG_SHA256`` :menuselection:`Sign modules with SHA-256`
``CONFIG_MODULE_SIG_SHA384`` :menuselection:`Sign modules with SHA-384`
``CONFIG_MODULE_SIG_SHA512`` :menuselection:`Sign modules with SHA-512`
=============================== ==========================================
The algorithm selected here will also be built into the kernel (rather
than being a module) so that modules signed with that algorithm can have
their signatures checked without causing a dependency loop.
(4) "File name or PKCS#11 URI of module signing key" (CONFIG_MODULE_SIG_KEY)
(4) :menuselection:`File name or PKCS#11 URI of module signing key`
(``CONFIG_MODULE_SIG_KEY``)
Setting this option to something other than its default of
"certs/signing_key.pem" will disable the autogeneration of signing keys
``certs/signing_key.pem`` will disable the autogeneration of signing keys
and allow the kernel modules to be signed with a key of your choosing.
The string provided should identify a file containing both a private key
and its corresponding X.509 certificate in PEM form, or — on systems where
......@@ -102,10 +107,11 @@ This has a number of options available:
If the PEM file containing the private key is encrypted, or if the
PKCS#11 token requries a PIN, this can be provided at build time by
means of the KBUILD_SIGN_PIN variable.
means of the ``KBUILD_SIGN_PIN`` variable.
(5) "Additional X.509 keys for default system keyring" (CONFIG_SYSTEM_TRUSTED_KEYS)
(5) :menuselection:`Additional X.509 keys for default system keyring`
(``CONFIG_SYSTEM_TRUSTED_KEYS``)
This option can be set to the filename of a PEM-encoded file containing
additional certificates which will be included in the system keyring by
......@@ -116,7 +122,7 @@ packages to the kernel build processes for the tool that does the signing.
=======================
GENERATING SIGNING KEYS
Generating signing keys
=======================
Cryptographic keypairs are required to generate and check signatures. A
......@@ -126,14 +132,14 @@ it can be deleted or stored securely. The public key gets built into the
kernel so that it can be used to check the signatures as the modules are
loaded.
Under normal conditions, when CONFIG_MODULE_SIG_KEY is unchanged from its
Under normal conditions, when ``CONFIG_MODULE_SIG_KEY`` is unchanged from its
default, the kernel build will automatically generate a new keypair using
openssl if one does not exist in the file:
openssl if one does not exist in the file::
certs/signing_key.pem
during the building of vmlinux (the public part of the key needs to be built
into vmlinux) using parameters in the:
into vmlinux) using parameters in the::
certs/x509.genkey
......@@ -142,14 +148,14 @@ file (which is also generated if it does not already exist).
It is strongly recommended that you provide your own x509.genkey file.
Most notably, in the x509.genkey file, the req_distinguished_name section
should be altered from the default:
should be altered from the default::
[ req_distinguished_name ]
#O = Unspecified company
CN = Build time autogenerated kernel key
#emailAddress = unspecified.user@unspecified.company
The generated RSA key size can also be set with:
The generated RSA key size can also be set with::
[ req ]
default_bits = 4096
......@@ -158,23 +164,23 @@ The generated RSA key size can also be set with:
It is also possible to manually generate the key private/public files using the
x509.genkey key generation configuration file in the root node of the Linux
kernel sources tree and the openssl command. The following is an example to
generate the public/private key files:
generate the public/private key files::
openssl req -new -nodes -utf8 -sha256 -days 36500 -batch -x509 \
-config x509.genkey -outform PEM -out kernel_key.pem \
-keyout kernel_key.pem
The full pathname for the resulting kernel_key.pem file can then be specified
in the CONFIG_MODULE_SIG_KEY option, and the certificate and key therein will
in the ``CONFIG_MODULE_SIG_KEY`` option, and the certificate and key therein will
be used instead of an autogenerated keypair.
=========================
PUBLIC KEYS IN THE KERNEL
Public keys in the kernel
=========================
The kernel contains a ring of public keys that can be viewed by root. They're
in a keyring called ".system_keyring" that can be seen by:
in a keyring called ".system_keyring" that can be seen by::
[root@deneb ~]# cat /proc/keys
...
......@@ -184,27 +190,27 @@ in a keyring called ".system_keyring" that can be seen by:
Beyond the public key generated specifically for module signing, additional
trusted certificates can be provided in a PEM-encoded file referenced by the
CONFIG_SYSTEM_TRUSTED_KEYS configuration option.
``CONFIG_SYSTEM_TRUSTED_KEYS`` configuration option.
Further, the architecture code may take public keys from a hardware store and
add those in also (e.g. from the UEFI key database).
Finally, it is possible to add additional public keys by doing:
Finally, it is possible to add additional public keys by doing::
keyctl padd asymmetric "" [.system_keyring-ID] <[key-file]
e.g.:
e.g.::
keyctl padd asymmetric "" 0x223c7853 <my_public_key.x509
Note, however, that the kernel will only permit keys to be added to
.system_keyring _if_ the new key's X.509 wrapper is validly signed by a key
``.system_keyring _if_`` the new key's X.509 wrapper is validly signed by a key
that is already resident in the .system_keyring at the time the key was added.
=========================
MANUALLY SIGNING MODULES
=========================
========================
Manually signing modules
========================
To manually sign a module, use the scripts/sign-file tool available in
the Linux kernel source tree. The script requires 4 arguments:
......@@ -214,7 +220,7 @@ the Linux kernel source tree. The script requires 4 arguments:
3. The public key filename
4. The kernel module to be signed
The following is an example to sign a kernel module:
The following is an example to sign a kernel module::
scripts/sign-file sha512 kernel-signkey.priv \
kernel-signkey.x509 module.ko
......@@ -228,11 +234,11 @@ $KBUILD_SIGN_PIN environment variable.
============================
SIGNED MODULES AND STRIPPING
Signed modules and stripping
============================
A signed module has a digital signature simply appended at the end. The string
"~Module signature appended~." at the end of the module's file confirms that a
``~Module signature appended~.`` at the end of the module's file confirms that a
signature is present but it does not confirm that the signature is valid!
Signed modules are BRITTLE as the signature is outside of the defined ELF
......@@ -242,19 +248,19 @@ debug information present at the time of signing.
======================
LOADING SIGNED MODULES
Loading signed modules
======================
Modules are loaded with insmod, modprobe, init_module() or finit_module(),
exactly as for unsigned modules as no processing is done in userspace. The
signature checking is all done within the kernel.
Modules are loaded with insmod, modprobe, ``init_module()`` or
``finit_module()``, exactly as for unsigned modules as no processing is
done in userspace. The signature checking is all done within the kernel.
=========================================
NON-VALID SIGNATURES AND UNSIGNED MODULES
Non-valid signatures and unsigned modules
=========================================
If CONFIG_MODULE_SIG_FORCE is enabled or module.sig_enforce=1 is supplied on
If ``CONFIG_MODULE_SIG_FORCE`` is enabled or module.sig_enforce=1 is supplied on
the kernel command line, the kernel will only load validly signed modules
for which it has a public key. Otherwise, it will also load modules that are
unsigned. Any module for which the kernel has a key, but which proves to have
......@@ -264,7 +270,7 @@ Any module that has an unparseable signature will be rejected.
=========================================
ADMINISTERING/PROTECTING THE PRIVATE KEY
Administering/protecting the private key
=========================================
Since the private key is used to sign modules, viruses and malware could use
......@@ -275,5 +281,5 @@ in the root node of the kernel source tree.
If you use the same private key to sign modules for multiple kernel
configurations, you must ensure that the module version information is
sufficient to prevent loading a module into a different kernel. Either
set CONFIG_MODVERSIONS=y or ensure that each configuration has a different
kernel release string by changing EXTRAVERSION or CONFIG_LOCALVERSION.
set ``CONFIG_MODVERSIONS=y`` or ensure that each configuration has a different
kernel release string by changing ``EXTRAVERSION`` or ``CONFIG_LOCALVERSION``.
此差异已折叠。
......@@ -51,7 +51,7 @@ As an alternative, the boot loader can pass the relevant 'console='
option to the kernel via the tagged lists specifying the port, and
serial format options as described in
Documentation/kernel-parameters.txt.
Documentation/admin-guide/kernel-parameters.rst.
3. Detect the machine type
......
......@@ -16,7 +16,7 @@ will fail. Something like the following should suffice:
typedef struct { long counter; } atomic_long_t;
Historically, counter has been declared volatile. This is now discouraged.
See Documentation/volatile-considered-harmful.txt for the complete rationale.
See Documentation/process/volatile-considered-harmful.rst for the complete rationale.
local_t is very similar to atomic_t. If the counter is per CPU and only
updated by one CPU, local_t is probably more appropriate. Please see
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册