This is the documentation update pull for the 4.9 merge window.
The Sphinx transition is still creating a fair amount of work. Here we have a number of fixes and, importantly, a proper PDF output solution, thanks to Jani Nikula, Mauro Carvalho Chehab and Markus Heiser. I've started a couple of new books: a driver API book (based on the old device-drivers.tmpl) and a development tools book. Both are meant to show how we can integrate together our existing documentation into a more coherent and accessible whole. It involves moving some stuff around and formatting changes, but, I think, the results are worth it. The good news is that most of our existing Documentation/*.txt files are *almost* in RST format already; the amount of messing around required is minimal. And, of course, there's the usual set of updates, typo fixes, and more. -----BEGIN PGP SIGNATURE----- iQIcBAABAgAGBQJX8st8AAoJEI3ONVYwIuV6d10P/0Zsnx3hSSx22aHxP4kVb4s/ NTttFAienYzc2fYYD3K/wMQbSbprW8Pp7uSP1suzAbU5FGgfLyDFQHnE0AVqFNiT MHVc5oBWp4ZlvNcyQUeXOsKtb5Rin00XHjer2mm/T9HfgmCYR4i+C9HQuv+J94Jf sgeI4IimvLjlp7dDbhcIfdqCpZ+UwBSpSm9w5f7astYDjocJHrkBqyk/46Ir4qz9 +2joNZRWMUatrQYJWMJnnvlnx8lHhkDjaL/Egy+f7ucpddEkbGvWvabGCSMtCyzS CKlA53Y4wS59cNFkAuxsHjun4TcQhbZn/iBIM+8aOdameO0ksC4jSoND2P6N6vKF dHkAkayP9ChW3k/J8D+3cGIJNFiaYevEXcgxLyShjCuh4t4yfOC9aIGUl3Ye9/mR tiKpMsvzmwJ+yO+kzJsxWTmRAX5wdI1Z062ltiS1dmSbl3c3NgQFpfP7V7AJSQ7c DzkuoUnGEqJOHm64dAZQuxL4jj6StzejjxlhH0bIjbNn1a9VlX9afwsdJaXA+kmr jQHJtR0wD1mLMYYdvNEiqvcCbumG+kaXmH6eUQadRxruRdZyhi1Z6Ql1CtwQGtbR SetC/MVxIN3fGPbZYhJ162xVjQ8OeX0ndRmRjy6SBDMoRGSKqi2IME8JAGOshxE0 0uYAJJFZOeiR6KaPnci/ =kGKl -----END PGP SIGNATURE----- Merge tag 'docs-4.9' of git://git.lwn.net/linux Pull documentation updates from Jonathan Corbet: "This is the documentation update pull for the 4.9 merge window. The Sphinx transition is still creating a fair amount of work. Here we have a number of fixes and, importantly, a proper PDF output solution, thanks to Jani Nikula, Mauro Carvalho Chehab and Markus Heiser. I've started a couple of new books: a driver API book (based on the old device-drivers.tmpl) and a development tools book. Both are meant to show how we can integrate together our existing documentation into a more coherent and accessible whole. It involves moving some stuff around and formatting changes, but, I think, the results are worth it. The good news is that most of our existing Documentation/*.txt files are *almost* in RST format already; the amount of messing around required is minimal. And, of course, there's the usual set of updates, typo fixes, and more" * tag 'docs-4.9' of git://git.lwn.net/linux: (120 commits) URL changed for Linux Foundation TAB dax : Fix documentation with respect to struct pages iio: Documentation: Correct the path used to create triggers. docs: Remove space-before-label guidance from CodingStyle docs-rst: add inter-document cross references Documentation/email-clients.txt: convert it to ReST markup Documentation/kernel-docs.txt: reorder based on timestamp Documentation/kernel-docs.txt: Add dates for online docs Documentation/kernel-docs.txt: get rid of broken docs Documentation/kernel-docs.txt: move in-kernel docs Documentation/kernel-docs.txt: remove more legacy references Documentation/kernel-docs.txt: add two published books Documentation/kernel-docs.txt: sort books per publication date Documentation/kernel-docs.txt: adjust LDD references Documentation/kernel-docs.txt: some improvements on the ReST output Documentation/kernel-docs.txt: Consistent indenting: 4 spaces Documentation/kernel-docs.txt: Add 4 paper/book references Documentation/kernel-docs.txt: Improve layouting of book list Documentation/kernel-docs.txt: Remove offline or outdated entries docs: Clean up bare :: lines ...
This commit is contained in:
Коммит
02bafd96f3
|
@ -1,8 +1,13 @@
|
|||
.. _changes:
|
||||
|
||||
Minimal requerements to compile the Kernel
|
||||
++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
Intro
|
||||
=====
|
||||
|
||||
This document is designed to provide a list of the minimum levels of
|
||||
software necessary to run the 3.0 kernels.
|
||||
software necessary to run the 4.x kernels.
|
||||
|
||||
This document is originally based on my "Changes" file for 2.0.x kernels
|
||||
and therefore owes credit to the same people as that file (Jared Mauch,
|
||||
|
@ -10,9 +15,9 @@ Axel Boldt, Alessandro Sigala, and countless other users all over the
|
|||
'net).
|
||||
|
||||
Current Minimal Requirements
|
||||
============================
|
||||
****************************
|
||||
|
||||
Upgrade to at *least* these software revisions before thinking you've
|
||||
Upgrade to at **least** these software revisions before thinking you've
|
||||
encountered a bug! If you're unsure what version you're currently
|
||||
running, the suggested command should tell you.
|
||||
|
||||
|
@ -21,34 +26,40 @@ running a Linux kernel. Also, not all tools are necessary on all
|
|||
systems; obviously, if you don't have any ISDN hardware, for example,
|
||||
you probably needn't concern yourself with isdn4k-utils.
|
||||
|
||||
o GNU C 3.2 # gcc --version
|
||||
o GNU make 3.80 # make --version
|
||||
o binutils 2.12 # ld -v
|
||||
o util-linux 2.10o # fdformat --version
|
||||
o module-init-tools 0.9.10 # depmod -V
|
||||
o e2fsprogs 1.41.4 # e2fsck -V
|
||||
o jfsutils 1.1.3 # fsck.jfs -V
|
||||
o reiserfsprogs 3.6.3 # reiserfsck -V
|
||||
o xfsprogs 2.6.0 # xfs_db -V
|
||||
o squashfs-tools 4.0 # mksquashfs -version
|
||||
o btrfs-progs 0.18 # btrfsck
|
||||
o pcmciautils 004 # pccardctl -V
|
||||
o quota-tools 3.09 # quota -V
|
||||
o PPP 2.4.0 # pppd --version
|
||||
o isdn4k-utils 3.1pre1 # isdnctrl 2>&1|grep version
|
||||
o nfs-utils 1.0.5 # showmount --version
|
||||
o procps 3.2.0 # ps --version
|
||||
o oprofile 0.9 # oprofiled --version
|
||||
o udev 081 # udevd --version
|
||||
o grub 0.93 # grub --version || grub-install --version
|
||||
o mcelog 0.6 # mcelog --version
|
||||
o iptables 1.4.2 # iptables -V
|
||||
o openssl & libcrypto 1.0.0 # openssl version
|
||||
o bc 1.06.95 # bc --version
|
||||
====================== =============== ========================================
|
||||
Program Minimal version Command to check the version
|
||||
====================== =============== ========================================
|
||||
GNU C 3.2 gcc --version
|
||||
GNU make 3.80 make --version
|
||||
binutils 2.12 ld -v
|
||||
util-linux 2.10o fdformat --version
|
||||
module-init-tools 0.9.10 depmod -V
|
||||
e2fsprogs 1.41.4 e2fsck -V
|
||||
jfsutils 1.1.3 fsck.jfs -V
|
||||
reiserfsprogs 3.6.3 reiserfsck -V
|
||||
xfsprogs 2.6.0 xfs_db -V
|
||||
squashfs-tools 4.0 mksquashfs -version
|
||||
btrfs-progs 0.18 btrfsck
|
||||
pcmciautils 004 pccardctl -V
|
||||
quota-tools 3.09 quota -V
|
||||
PPP 2.4.0 pppd --version
|
||||
isdn4k-utils 3.1pre1 isdnctrl 2>&1|grep version
|
||||
nfs-utils 1.0.5 showmount --version
|
||||
procps 3.2.0 ps --version
|
||||
oprofile 0.9 oprofiled --version
|
||||
udev 081 udevd --version
|
||||
grub 0.93 grub --version || grub-install --version
|
||||
mcelog 0.6 mcelog --version
|
||||
iptables 1.4.2 iptables -V
|
||||
openssl & libcrypto 1.0.0 openssl version
|
||||
bc 1.06.95 bc --version
|
||||
Sphinx\ [#f1]_ 1.2 sphinx-build --version
|
||||
====================== =============== ========================================
|
||||
|
||||
.. [#f1] Sphinx is needed only to build the Kernel documentation
|
||||
|
||||
Kernel compilation
|
||||
==================
|
||||
******************
|
||||
|
||||
GCC
|
||||
---
|
||||
|
@ -64,16 +75,16 @@ You will need GNU make 3.80 or later to build the kernel.
|
|||
Binutils
|
||||
--------
|
||||
|
||||
Linux on IA-32 has recently switched from using as86 to using gas for
|
||||
assembling the 16-bit boot code, removing the need for as86 to compile
|
||||
Linux on IA-32 has recently switched from using ``as86`` to using ``gas`` for
|
||||
assembling the 16-bit boot code, removing the need for ``as86`` to compile
|
||||
your kernel. This change does, however, mean that you need a recent
|
||||
release of binutils.
|
||||
|
||||
Perl
|
||||
----
|
||||
|
||||
You will need perl 5 and the following modules: Getopt::Long, Getopt::Std,
|
||||
File::Basename, and File::Find to build the kernel.
|
||||
You will need perl 5 and the following modules: ``Getopt::Long``,
|
||||
``Getopt::Std``, ``File::Basename``, and ``File::Find`` to build the kernel.
|
||||
|
||||
BC
|
||||
--
|
||||
|
@ -93,7 +104,7 @@ and higher.
|
|||
|
||||
|
||||
System utilities
|
||||
================
|
||||
****************
|
||||
|
||||
Architectural changes
|
||||
---------------------
|
||||
|
@ -115,7 +126,7 @@ well as the desired DocBook stylesheets.
|
|||
Util-linux
|
||||
----------
|
||||
|
||||
New versions of util-linux provide *fdisk support for larger disks,
|
||||
New versions of util-linux provide ``fdisk`` support for larger disks,
|
||||
support new options to mount, recognize more supported partition
|
||||
types, have a fdformat which works with 2.4 kernels, and similar goodies.
|
||||
You'll probably want to upgrade.
|
||||
|
@ -125,54 +136,57 @@ Ksymoops
|
|||
|
||||
If the unthinkable happens and your kernel oopses, you may need the
|
||||
ksymoops tool to decode it, but in most cases you don't.
|
||||
It is generally preferred to build the kernel with CONFIG_KALLSYMS so
|
||||
It is generally preferred to build the kernel with ``CONFIG_KALLSYMS`` so
|
||||
that it produces readable dumps that can be used as-is (this also
|
||||
produces better output than ksymoops). If for some reason your kernel
|
||||
is not build with CONFIG_KALLSYMS and you have no way to rebuild and
|
||||
is not build with ``CONFIG_KALLSYMS`` and you have no way to rebuild and
|
||||
reproduce the Oops with that option, then you can still decode that Oops
|
||||
with ksymoops.
|
||||
|
||||
Module-Init-Tools
|
||||
-----------------
|
||||
|
||||
A new module loader is now in the kernel that requires module-init-tools
|
||||
A new module loader is now in the kernel that requires ``module-init-tools``
|
||||
to use. It is backward compatible with the 2.4.x series kernels.
|
||||
|
||||
Mkinitrd
|
||||
--------
|
||||
|
||||
These changes to the /lib/modules file tree layout also require that
|
||||
These changes to the ``/lib/modules`` file tree layout also require that
|
||||
mkinitrd be upgraded.
|
||||
|
||||
E2fsprogs
|
||||
---------
|
||||
|
||||
The latest version of e2fsprogs fixes several bugs in fsck and
|
||||
The latest version of ``e2fsprogs`` fixes several bugs in fsck and
|
||||
debugfs. Obviously, it's a good idea to upgrade.
|
||||
|
||||
JFSutils
|
||||
--------
|
||||
|
||||
The jfsutils package contains the utilities for the file system.
|
||||
The ``jfsutils`` package contains the utilities for the file system.
|
||||
The following utilities are available:
|
||||
o fsck.jfs - initiate replay of the transaction log, and check
|
||||
|
||||
- ``fsck.jfs`` - initiate replay of the transaction log, and check
|
||||
and repair a JFS formatted partition.
|
||||
o mkfs.jfs - create a JFS formatted partition.
|
||||
o other file system utilities are also available in this package.
|
||||
|
||||
- ``mkfs.jfs`` - create a JFS formatted partition.
|
||||
|
||||
- other file system utilities are also available in this package.
|
||||
|
||||
Reiserfsprogs
|
||||
-------------
|
||||
|
||||
The reiserfsprogs package should be used for reiserfs-3.6.x
|
||||
(Linux kernels 2.4.x). It is a combined package and contains working
|
||||
versions of mkreiserfs, resize_reiserfs, debugreiserfs and
|
||||
reiserfsck. These utils work on both i386 and alpha platforms.
|
||||
versions of ``mkreiserfs``, ``resize_reiserfs``, ``debugreiserfs`` and
|
||||
``reiserfsck``. These utils work on both i386 and alpha platforms.
|
||||
|
||||
Xfsprogs
|
||||
--------
|
||||
|
||||
The latest version of xfsprogs contains mkfs.xfs, xfs_db, and the
|
||||
xfs_repair utilities, among others, for the XFS filesystem. It is
|
||||
The latest version of ``xfsprogs`` contains ``mkfs.xfs``, ``xfs_db``, and the
|
||||
``xfs_repair`` utilities, among others, for the XFS filesystem. It is
|
||||
architecture independent and any version from 2.0.0 onward should
|
||||
work correctly with this version of the XFS kernel code (2.6.0 or
|
||||
later is recommended, due to some significant improvements).
|
||||
|
@ -180,7 +194,7 @@ later is recommended, due to some significant improvements).
|
|||
PCMCIAutils
|
||||
-----------
|
||||
|
||||
PCMCIAutils replaces pcmcia-cs. It properly sets up
|
||||
PCMCIAutils replaces ``pcmcia-cs``. It properly sets up
|
||||
PCMCIA sockets at system startup and loads the appropriate modules
|
||||
for 16-bit PCMCIA devices if the kernel is modularized and the hotplug
|
||||
subsystem is used.
|
||||
|
@ -198,19 +212,20 @@ Intel IA32 microcode
|
|||
|
||||
A driver has been added to allow updating of Intel IA32 microcode,
|
||||
accessible as a normal (misc) character device. If you are not using
|
||||
udev you may need to:
|
||||
udev you may need to::
|
||||
|
||||
mkdir /dev/cpu
|
||||
mknod /dev/cpu/microcode c 10 184
|
||||
chmod 0644 /dev/cpu/microcode
|
||||
mkdir /dev/cpu
|
||||
mknod /dev/cpu/microcode c 10 184
|
||||
chmod 0644 /dev/cpu/microcode
|
||||
|
||||
as root before you can use this. You'll probably also want to
|
||||
get the user-space microcode_ctl utility to use with this.
|
||||
|
||||
udev
|
||||
----
|
||||
udev is a userspace application for populating /dev dynamically with
|
||||
only entries for devices actually present. udev replaces the basic
|
||||
|
||||
``udev`` is a userspace application for populating ``/dev`` dynamically with
|
||||
only entries for devices actually present. ``udev`` replaces the basic
|
||||
functionality of devfs, while allowing persistent device naming for
|
||||
devices.
|
||||
|
||||
|
@ -218,10 +233,10 @@ FUSE
|
|||
----
|
||||
|
||||
Needs libfuse 2.4.0 or later. Absolute minimum is 2.3.0 but mount
|
||||
options 'direct_io' and 'kernel_cache' won't work.
|
||||
options ``direct_io`` and ``kernel_cache`` won't work.
|
||||
|
||||
Networking
|
||||
==========
|
||||
**********
|
||||
|
||||
General changes
|
||||
---------------
|
||||
|
@ -243,9 +258,9 @@ enable it to operate over diverse media layers. If you use PPP,
|
|||
upgrade pppd to at least 2.4.0.
|
||||
|
||||
If you are not using udev, you must have the device file /dev/ppp
|
||||
which can be made by:
|
||||
which can be made by::
|
||||
|
||||
mknod /dev/ppp c 108 0
|
||||
mknod /dev/ppp c 108 0
|
||||
|
||||
as root.
|
||||
|
||||
|
@ -260,22 +275,22 @@ NFS-utils
|
|||
|
||||
In ancient (2.4 and earlier) kernels, the nfs server needed to know
|
||||
about any client that expected to be able to access files via NFS. This
|
||||
information would be given to the kernel by "mountd" when the client
|
||||
mounted the filesystem, or by "exportfs" at system startup. exportfs
|
||||
would take information about active clients from /var/lib/nfs/rmtab.
|
||||
information would be given to the kernel by ``mountd`` when the client
|
||||
mounted the filesystem, or by ``exportfs`` at system startup. exportfs
|
||||
would take information about active clients from ``/var/lib/nfs/rmtab``.
|
||||
|
||||
This approach is quite fragile as it depends on rmtab being correct
|
||||
which is not always easy, particularly when trying to implement
|
||||
fail-over. Even when the system is working well, rmtab suffers from
|
||||
fail-over. Even when the system is working well, ``rmtab`` suffers from
|
||||
getting lots of old entries that never get removed.
|
||||
|
||||
With modern kernels we have the option of having the kernel tell mountd
|
||||
when it gets a request from an unknown host, and mountd can give
|
||||
appropriate export information to the kernel. This removes the
|
||||
dependency on rmtab and means that the kernel only needs to know about
|
||||
dependency on ``rmtab`` and means that the kernel only needs to know about
|
||||
currently active clients.
|
||||
|
||||
To enable this new functionality, you need to:
|
||||
To enable this new functionality, you need to::
|
||||
|
||||
mount -t nfsd nfsd /proc/fs/nfsd
|
||||
|
||||
|
@ -287,8 +302,32 @@ mcelog
|
|||
------
|
||||
|
||||
On x86 kernels the mcelog utility is needed to process and log machine check
|
||||
events when CONFIG_X86_MCE is enabled. Machine check events are errors reported
|
||||
by the CPU. Processing them is strongly encouraged.
|
||||
events when ``CONFIG_X86_MCE`` is enabled. Machine check events are errors
|
||||
reported by the CPU. Processing them is strongly encouraged.
|
||||
|
||||
Kernel documentation
|
||||
********************
|
||||
|
||||
Sphinx
|
||||
------
|
||||
|
||||
The ReST markups currently used by the Documentation/ files are meant to be
|
||||
built with ``Sphinx`` version 1.2 or upper. If you're desiring to build
|
||||
PDF outputs, it is recommended to use version 1.4.6.
|
||||
|
||||
.. note::
|
||||
|
||||
Please notice that, for PDF and LaTeX output, you'll also need ``XeLaTeX``
|
||||
version 3.14159265. Depending on the distribution, you may also need
|
||||
to install a series of ``texlive`` packages that provide the minimal
|
||||
set of functionalities required for ``XeLaTex`` to work.
|
||||
|
||||
Other tools
|
||||
-----------
|
||||
|
||||
In order to produce documentation from DocBook, you'll also need ``xmlto``.
|
||||
Please notice, however, that we're currently migrating all documents to use
|
||||
``Sphinx``.
|
||||
|
||||
Getting updated software
|
||||
========================
|
||||
|
@ -298,114 +337,149 @@ Kernel compilation
|
|||
|
||||
gcc
|
||||
---
|
||||
o <ftp://ftp.gnu.org/gnu/gcc/>
|
||||
|
||||
- <ftp://ftp.gnu.org/gnu/gcc/>
|
||||
|
||||
Make
|
||||
----
|
||||
o <ftp://ftp.gnu.org/gnu/make/>
|
||||
|
||||
- <ftp://ftp.gnu.org/gnu/make/>
|
||||
|
||||
Binutils
|
||||
--------
|
||||
o <ftp://ftp.kernel.org/pub/linux/devel/binutils/>
|
||||
|
||||
- <ftp://ftp.kernel.org/pub/linux/devel/binutils/>
|
||||
|
||||
OpenSSL
|
||||
-------
|
||||
o <https://www.openssl.org/>
|
||||
|
||||
- <https://www.openssl.org/>
|
||||
|
||||
System utilities
|
||||
****************
|
||||
|
||||
Util-linux
|
||||
----------
|
||||
o <ftp://ftp.kernel.org/pub/linux/utils/util-linux/>
|
||||
|
||||
- <ftp://ftp.kernel.org/pub/linux/utils/util-linux/>
|
||||
|
||||
Ksymoops
|
||||
--------
|
||||
o <ftp://ftp.kernel.org/pub/linux/utils/kernel/ksymoops/v2.4/>
|
||||
|
||||
- <ftp://ftp.kernel.org/pub/linux/utils/kernel/ksymoops/v2.4/>
|
||||
|
||||
Module-Init-Tools
|
||||
-----------------
|
||||
o <ftp://ftp.kernel.org/pub/linux/kernel/people/rusty/modules/>
|
||||
|
||||
- <ftp://ftp.kernel.org/pub/linux/kernel/people/rusty/modules/>
|
||||
|
||||
Mkinitrd
|
||||
--------
|
||||
o <https://code.launchpad.net/initrd-tools/main>
|
||||
|
||||
- <https://code.launchpad.net/initrd-tools/main>
|
||||
|
||||
E2fsprogs
|
||||
---------
|
||||
o <http://prdownloads.sourceforge.net/e2fsprogs/e2fsprogs-1.29.tar.gz>
|
||||
|
||||
- <http://prdownloads.sourceforge.net/e2fsprogs/e2fsprogs-1.29.tar.gz>
|
||||
|
||||
JFSutils
|
||||
--------
|
||||
o <http://jfs.sourceforge.net/>
|
||||
|
||||
- <http://jfs.sourceforge.net/>
|
||||
|
||||
Reiserfsprogs
|
||||
-------------
|
||||
o <http://www.kernel.org/pub/linux/utils/fs/reiserfs/>
|
||||
|
||||
- <http://www.kernel.org/pub/linux/utils/fs/reiserfs/>
|
||||
|
||||
Xfsprogs
|
||||
--------
|
||||
o <ftp://oss.sgi.com/projects/xfs/>
|
||||
|
||||
- <ftp://oss.sgi.com/projects/xfs/>
|
||||
|
||||
Pcmciautils
|
||||
-----------
|
||||
o <ftp://ftp.kernel.org/pub/linux/utils/kernel/pcmcia/>
|
||||
|
||||
- <ftp://ftp.kernel.org/pub/linux/utils/kernel/pcmcia/>
|
||||
|
||||
Quota-tools
|
||||
----------
|
||||
o <http://sourceforge.net/projects/linuxquota/>
|
||||
-----------
|
||||
|
||||
- <http://sourceforge.net/projects/linuxquota/>
|
||||
|
||||
DocBook Stylesheets
|
||||
-------------------
|
||||
o <http://sourceforge.net/projects/docbook/files/docbook-dsssl/>
|
||||
|
||||
- <http://sourceforge.net/projects/docbook/files/docbook-dsssl/>
|
||||
|
||||
XMLTO XSLT Frontend
|
||||
-------------------
|
||||
o <http://cyberelk.net/tim/xmlto/>
|
||||
|
||||
- <http://cyberelk.net/tim/xmlto/>
|
||||
|
||||
Intel P6 microcode
|
||||
------------------
|
||||
o <https://downloadcenter.intel.com/>
|
||||
|
||||
- <https://downloadcenter.intel.com/>
|
||||
|
||||
udev
|
||||
----
|
||||
o <http://www.freedesktop.org/software/systemd/man/udev.html>
|
||||
|
||||
- <http://www.freedesktop.org/software/systemd/man/udev.html>
|
||||
|
||||
FUSE
|
||||
----
|
||||
o <http://sourceforge.net/projects/fuse>
|
||||
|
||||
- <http://sourceforge.net/projects/fuse>
|
||||
|
||||
mcelog
|
||||
------
|
||||
o <http://www.mcelog.org/>
|
||||
|
||||
- <http://www.mcelog.org/>
|
||||
|
||||
Networking
|
||||
**********
|
||||
|
||||
PPP
|
||||
---
|
||||
o <ftp://ftp.samba.org/pub/ppp/>
|
||||
|
||||
- <ftp://ftp.samba.org/pub/ppp/>
|
||||
|
||||
Isdn4k-utils
|
||||
------------
|
||||
o <ftp://ftp.isdn4linux.de/pub/isdn4linux/utils/>
|
||||
|
||||
- <ftp://ftp.isdn4linux.de/pub/isdn4linux/utils/>
|
||||
|
||||
NFS-utils
|
||||
---------
|
||||
o <http://sourceforge.net/project/showfiles.php?group_id=14>
|
||||
|
||||
- <http://sourceforge.net/project/showfiles.php?group_id=14>
|
||||
|
||||
Iptables
|
||||
--------
|
||||
o <http://www.iptables.org/downloads.html>
|
||||
|
||||
- <http://www.iptables.org/downloads.html>
|
||||
|
||||
Ip-route2
|
||||
---------
|
||||
o <https://www.kernel.org/pub/linux/utils/net/iproute2/>
|
||||
|
||||
- <https://www.kernel.org/pub/linux/utils/net/iproute2/>
|
||||
|
||||
OProfile
|
||||
--------
|
||||
o <http://oprofile.sf.net/download/>
|
||||
|
||||
- <http://oprofile.sf.net/download/>
|
||||
|
||||
NFS-Utils
|
||||
---------
|
||||
o <http://nfs.sourceforge.net/>
|
||||
|
||||
- <http://nfs.sourceforge.net/>
|
||||
|
||||
Kernel documentation
|
||||
********************
|
||||
|
||||
Sphinx
|
||||
------
|
||||
|
||||
- <http://www.sphinx-doc.org/>
|
||||
|
|
|
@ -19,7 +19,7 @@ please contact the Linux Foundation's Technical Advisory Board at
|
|||
will work to resolve the issue to the best of their ability. For more
|
||||
information on who is on the Technical Advisory Board and what their
|
||||
role is, please see:
|
||||
http://www.linuxfoundation.org/programs/advisory-councils/tab
|
||||
http://www.linuxfoundation.org/projects/linux/tab
|
||||
|
||||
As a reviewer of code, please strive to keep things civil and focused on
|
||||
the technical issues involved. We are all humans, and frustrations can
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
.. _codingstyle:
|
||||
|
||||
Linux kernel coding style
|
||||
Linux kernel coding style
|
||||
=========================
|
||||
|
||||
This is a short document describing the preferred coding style for the
|
||||
linux kernel. Coding style is very personal, and I won't _force_ my
|
||||
linux kernel. Coding style is very personal, and I won't **force** my
|
||||
views on anybody, but this is what goes for anything that I have to be
|
||||
able to maintain, and I'd prefer it for most other things too. Please
|
||||
at least consider the points made here.
|
||||
|
@ -13,7 +15,8 @@ and NOT read it. Burn them, it's a great symbolic gesture.
|
|||
Anyway, here goes:
|
||||
|
||||
|
||||
Chapter 1: Indentation
|
||||
1) Indentation
|
||||
--------------
|
||||
|
||||
Tabs are 8 characters, and thus indentations are also 8 characters.
|
||||
There are heretic movements that try to make indentations 4 (or even 2!)
|
||||
|
@ -36,8 +39,10 @@ benefit of warning you when you're nesting your functions too deep.
|
|||
Heed that warning.
|
||||
|
||||
The preferred way to ease multiple indentation levels in a switch statement is
|
||||
to align the "switch" and its subordinate "case" labels in the same column
|
||||
instead of "double-indenting" the "case" labels. E.g.:
|
||||
to align the ``switch`` and its subordinate ``case`` labels in the same column
|
||||
instead of ``double-indenting`` the ``case`` labels. E.g.:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
switch (suffix) {
|
||||
case 'G':
|
||||
|
@ -59,6 +64,8 @@ instead of "double-indenting" the "case" labels. E.g.:
|
|||
Don't put multiple statements on a single line unless you have
|
||||
something to hide:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
if (condition) do_this;
|
||||
do_something_everytime;
|
||||
|
||||
|
@ -71,7 +78,8 @@ used for indentation, and the above example is deliberately broken.
|
|||
Get a decent editor and don't leave whitespace at the end of lines.
|
||||
|
||||
|
||||
Chapter 2: Breaking long lines and strings
|
||||
2) Breaking long lines and strings
|
||||
----------------------------------
|
||||
|
||||
Coding style is all about readability and maintainability using commonly
|
||||
available tools.
|
||||
|
@ -87,7 +95,8 @@ with a long argument list. However, never break user-visible strings such as
|
|||
printk messages, because that breaks the ability to grep for them.
|
||||
|
||||
|
||||
Chapter 3: Placing Braces and Spaces
|
||||
3) Placing Braces and Spaces
|
||||
----------------------------
|
||||
|
||||
The other issue that always comes up in C styling is the placement of
|
||||
braces. Unlike the indent size, there are few technical reasons to
|
||||
|
@ -95,6 +104,8 @@ choose one placement strategy over the other, but the preferred way, as
|
|||
shown to us by the prophets Kernighan and Ritchie, is to put the opening
|
||||
brace last on the line, and put the closing brace first, thusly:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
if (x is true) {
|
||||
we do y
|
||||
}
|
||||
|
@ -102,6 +113,8 @@ brace last on the line, and put the closing brace first, thusly:
|
|||
This applies to all non-function statement blocks (if, switch, for,
|
||||
while, do). E.g.:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
switch (action) {
|
||||
case KOBJ_ADD:
|
||||
return "add";
|
||||
|
@ -116,6 +129,8 @@ while, do). E.g.:
|
|||
However, there is one special case, namely functions: they have the
|
||||
opening brace at the beginning of the next line, thus:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
int function(int x)
|
||||
{
|
||||
body of function
|
||||
|
@ -123,20 +138,24 @@ opening brace at the beginning of the next line, thus:
|
|||
|
||||
Heretic people all over the world have claimed that this inconsistency
|
||||
is ... well ... inconsistent, but all right-thinking people know that
|
||||
(a) K&R are _right_ and (b) K&R are right. Besides, functions are
|
||||
(a) K&R are **right** and (b) K&R are right. Besides, functions are
|
||||
special anyway (you can't nest them in C).
|
||||
|
||||
Note that the closing brace is empty on a line of its own, _except_ in
|
||||
Note that the closing brace is empty on a line of its own, **except** in
|
||||
the cases where it is followed by a continuation of the same statement,
|
||||
ie a "while" in a do-statement or an "else" in an if-statement, like
|
||||
ie a ``while`` in a do-statement or an ``else`` in an if-statement, like
|
||||
this:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
do {
|
||||
body of do-loop
|
||||
} while (condition);
|
||||
|
||||
and
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
if (x == y) {
|
||||
..
|
||||
} else if (x > y) {
|
||||
|
@ -155,11 +174,15 @@ comments on.
|
|||
|
||||
Do not unnecessarily use braces where a single statement will do.
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
if (condition)
|
||||
action();
|
||||
|
||||
and
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
if (condition)
|
||||
do_this();
|
||||
else
|
||||
|
@ -168,6 +191,8 @@ and
|
|||
This does not apply if only one branch of a conditional statement is a single
|
||||
statement; in the latter case use braces in both branches:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
if (condition) {
|
||||
do_this();
|
||||
do_that();
|
||||
|
@ -175,57 +200,67 @@ statement; in the latter case use braces in both branches:
|
|||
otherwise();
|
||||
}
|
||||
|
||||
3.1: Spaces
|
||||
3.1) Spaces
|
||||
***********
|
||||
|
||||
Linux kernel style for use of spaces depends (mostly) on
|
||||
function-versus-keyword usage. Use a space after (most) keywords. The
|
||||
notable exceptions are sizeof, typeof, alignof, and __attribute__, which look
|
||||
somewhat like functions (and are usually used with parentheses in Linux,
|
||||
although they are not required in the language, as in: "sizeof info" after
|
||||
"struct fileinfo info;" is declared).
|
||||
although they are not required in the language, as in: ``sizeof info`` after
|
||||
``struct fileinfo info;`` is declared).
|
||||
|
||||
So use a space after these keywords:
|
||||
So use a space after these keywords::
|
||||
|
||||
if, switch, case, for, do, while
|
||||
|
||||
but not with sizeof, typeof, alignof, or __attribute__. E.g.,
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
|
||||
s = sizeof(struct file);
|
||||
|
||||
Do not add spaces around (inside) parenthesized expressions. This example is
|
||||
*bad*:
|
||||
**bad**:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
|
||||
s = sizeof( struct file );
|
||||
|
||||
When declaring pointer data or a function that returns a pointer type, the
|
||||
preferred use of '*' is adjacent to the data name or function name and not
|
||||
preferred use of ``*`` is adjacent to the data name or function name and not
|
||||
adjacent to the type name. Examples:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
|
||||
char *linux_banner;
|
||||
unsigned long long memparse(char *ptr, char **retptr);
|
||||
char *match_strdup(substring_t *s);
|
||||
|
||||
Use one space around (on each side of) most binary and ternary operators,
|
||||
such as any of these:
|
||||
such as any of these::
|
||||
|
||||
= + - < > * / % | & ^ <= >= == != ? :
|
||||
|
||||
but no space after unary operators:
|
||||
but no space after unary operators::
|
||||
|
||||
& * + - ~ ! sizeof typeof alignof __attribute__ defined
|
||||
|
||||
no space before the postfix increment & decrement unary operators:
|
||||
no space before the postfix increment & decrement unary operators::
|
||||
|
||||
++ --
|
||||
|
||||
no space after the prefix increment & decrement unary operators:
|
||||
no space after the prefix increment & decrement unary operators::
|
||||
|
||||
++ --
|
||||
|
||||
and no space around the '.' and "->" structure member operators.
|
||||
and no space around the ``.`` and ``->`` structure member operators.
|
||||
|
||||
Do not leave trailing whitespace at the ends of lines. Some editors with
|
||||
"smart" indentation will insert whitespace at the beginning of new lines as
|
||||
``smart`` indentation will insert whitespace at the beginning of new lines as
|
||||
appropriate, so you can start typing the next line of code right away.
|
||||
However, some such editors do not remove the whitespace if you end up not
|
||||
putting a line of code there, such as if you leave a blank line. As a result,
|
||||
|
@ -237,22 +272,23 @@ of patches, this may make later patches in the series fail by changing their
|
|||
context lines.
|
||||
|
||||
|
||||
Chapter 4: Naming
|
||||
4) Naming
|
||||
---------
|
||||
|
||||
C is a Spartan language, and so should your naming be. Unlike Modula-2
|
||||
and Pascal programmers, C programmers do not use cute names like
|
||||
ThisVariableIsATemporaryCounter. A C programmer would call that
|
||||
variable "tmp", which is much easier to write, and not the least more
|
||||
variable ``tmp``, which is much easier to write, and not the least more
|
||||
difficult to understand.
|
||||
|
||||
HOWEVER, while mixed-case names are frowned upon, descriptive names for
|
||||
global variables are a must. To call a global function "foo" is a
|
||||
global variables are a must. To call a global function ``foo`` is a
|
||||
shooting offense.
|
||||
|
||||
GLOBAL variables (to be used only if you _really_ need them) need to
|
||||
GLOBAL variables (to be used only if you **really** need them) need to
|
||||
have descriptive names, as do global functions. If you have a function
|
||||
that counts the number of active users, you should call that
|
||||
"count_active_users()" or similar, you should _not_ call it "cntusr()".
|
||||
``count_active_users()`` or similar, you should **not** call it ``cntusr()``.
|
||||
|
||||
Encoding the type of a function into the name (so-called Hungarian
|
||||
notation) is brain damaged - the compiler knows the types anyway and can
|
||||
|
@ -260,9 +296,9 @@ check those, and it only confuses the programmer. No wonder MicroSoft
|
|||
makes buggy programs.
|
||||
|
||||
LOCAL variable names should be short, and to the point. If you have
|
||||
some random integer loop counter, it should probably be called "i".
|
||||
Calling it "loop_counter" is non-productive, if there is no chance of it
|
||||
being mis-understood. Similarly, "tmp" can be just about any type of
|
||||
some random integer loop counter, it should probably be called ``i``.
|
||||
Calling it ``loop_counter`` is non-productive, if there is no chance of it
|
||||
being mis-understood. Similarly, ``tmp`` can be just about any type of
|
||||
variable that is used to hold a temporary value.
|
||||
|
||||
If you are afraid to mix up your local variable names, you have another
|
||||
|
@ -270,59 +306,69 @@ problem, which is called the function-growth-hormone-imbalance syndrome.
|
|||
See chapter 6 (Functions).
|
||||
|
||||
|
||||
Chapter 5: Typedefs
|
||||
5) Typedefs
|
||||
-----------
|
||||
|
||||
Please don't use things like ``vps_t``.
|
||||
It's a **mistake** to use typedef for structures and pointers. When you see a
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
Please don't use things like "vps_t".
|
||||
It's a _mistake_ to use typedef for structures and pointers. When you see a
|
||||
|
||||
vps_t a;
|
||||
|
||||
in the source, what does it mean?
|
||||
In contrast, if it says
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
struct virtual_container *a;
|
||||
|
||||
you can actually tell what "a" is.
|
||||
you can actually tell what ``a`` is.
|
||||
|
||||
Lots of people think that typedefs "help readability". Not so. They are
|
||||
Lots of people think that typedefs ``help readability``. Not so. They are
|
||||
useful only for:
|
||||
|
||||
(a) totally opaque objects (where the typedef is actively used to _hide_
|
||||
(a) totally opaque objects (where the typedef is actively used to **hide**
|
||||
what the object is).
|
||||
|
||||
Example: "pte_t" etc. opaque objects that you can only access using
|
||||
Example: ``pte_t`` etc. opaque objects that you can only access using
|
||||
the proper accessor functions.
|
||||
|
||||
NOTE! Opaqueness and "accessor functions" are not good in themselves.
|
||||
The reason we have them for things like pte_t etc. is that there
|
||||
really is absolutely _zero_ portably accessible information there.
|
||||
.. note::
|
||||
|
||||
(b) Clear integer types, where the abstraction _helps_ avoid confusion
|
||||
whether it is "int" or "long".
|
||||
Opaqueness and ``accessor functions`` are not good in themselves.
|
||||
The reason we have them for things like pte_t etc. is that there
|
||||
really is absolutely **zero** portably accessible information there.
|
||||
|
||||
(b) Clear integer types, where the abstraction **helps** avoid confusion
|
||||
whether it is ``int`` or ``long``.
|
||||
|
||||
u8/u16/u32 are perfectly fine typedefs, although they fit into
|
||||
category (d) better than here.
|
||||
|
||||
NOTE! Again - there needs to be a _reason_ for this. If something is
|
||||
"unsigned long", then there's no reason to do
|
||||
.. note::
|
||||
|
||||
Again - there needs to be a **reason** for this. If something is
|
||||
``unsigned long``, then there's no reason to do
|
||||
|
||||
typedef unsigned long myflags_t;
|
||||
|
||||
but if there is a clear reason for why it under certain circumstances
|
||||
might be an "unsigned int" and under other configurations might be
|
||||
"unsigned long", then by all means go ahead and use a typedef.
|
||||
might be an ``unsigned int`` and under other configurations might be
|
||||
``unsigned long``, then by all means go ahead and use a typedef.
|
||||
|
||||
(c) when you use sparse to literally create a _new_ type for
|
||||
(c) when you use sparse to literally create a **new** type for
|
||||
type-checking.
|
||||
|
||||
(d) New types which are identical to standard C99 types, in certain
|
||||
exceptional circumstances.
|
||||
|
||||
Although it would only take a short amount of time for the eyes and
|
||||
brain to become accustomed to the standard types like 'uint32_t',
|
||||
brain to become accustomed to the standard types like ``uint32_t``,
|
||||
some people object to their use anyway.
|
||||
|
||||
Therefore, the Linux-specific 'u8/u16/u32/u64' types and their
|
||||
Therefore, the Linux-specific ``u8/u16/u32/u64`` types and their
|
||||
signed equivalents which are identical to standard types are
|
||||
permitted -- although they are not mandatory in new code of your
|
||||
own.
|
||||
|
@ -333,7 +379,7 @@ useful only for:
|
|||
(e) Types safe for use in userspace.
|
||||
|
||||
In certain structures which are visible to userspace, we cannot
|
||||
require C99 types and cannot use the 'u32' form above. Thus, we
|
||||
require C99 types and cannot use the ``u32`` form above. Thus, we
|
||||
use __u32 and similar types in all structures which are shared
|
||||
with userspace.
|
||||
|
||||
|
@ -341,10 +387,11 @@ Maybe there are other cases too, but the rule should basically be to NEVER
|
|||
EVER use a typedef unless you can clearly match one of those rules.
|
||||
|
||||
In general, a pointer, or a struct that has elements that can reasonably
|
||||
be directly accessed should _never_ be a typedef.
|
||||
be directly accessed should **never** be a typedef.
|
||||
|
||||
|
||||
Chapter 6: Functions
|
||||
6) Functions
|
||||
------------
|
||||
|
||||
Functions should be short and sweet, and do just one thing. They should
|
||||
fit on one or two screenfuls of text (the ISO/ANSI screen size is 80x24,
|
||||
|
@ -372,8 +419,10 @@ and it gets confused. You know you're brilliant, but maybe you'd like
|
|||
to understand what you did 2 weeks from now.
|
||||
|
||||
In source files, separate functions with one blank line. If the function is
|
||||
exported, the EXPORT* macro for it should follow immediately after the closing
|
||||
function brace line. E.g.:
|
||||
exported, the **EXPORT** macro for it should follow immediately after the
|
||||
closing function brace line. E.g.:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
int system_is_up(void)
|
||||
{
|
||||
|
@ -386,7 +435,8 @@ Although this is not required by the C language, it is preferred in Linux
|
|||
because it is a simple way to add valuable information for the reader.
|
||||
|
||||
|
||||
Chapter 7: Centralized exiting of functions
|
||||
7) Centralized exiting of functions
|
||||
-----------------------------------
|
||||
|
||||
Albeit deprecated by some people, the equivalent of the goto statement is
|
||||
used frequently by compilers in form of the unconditional jump instruction.
|
||||
|
@ -396,18 +446,21 @@ locations and some common work such as cleanup has to be done. If there is no
|
|||
cleanup needed then just return directly.
|
||||
|
||||
Choose label names which say what the goto does or why the goto exists. An
|
||||
example of a good name could be "out_buffer:" if the goto frees "buffer". Avoid
|
||||
using GW-BASIC names like "err1:" and "err2:". Also don't name them after the
|
||||
goto location like "err_kmalloc_failed:"
|
||||
example of a good name could be ``out_free_buffer:`` if the goto frees ``buffer``.
|
||||
Avoid using GW-BASIC names like ``err1:`` and ``err2:``, as you would have to
|
||||
renumber them if you ever add or remove exit paths, and they make correctness
|
||||
difficult to verify anyway.
|
||||
|
||||
The rationale for using gotos is:
|
||||
|
||||
- unconditional statements are easier to understand and follow
|
||||
- nesting is reduced
|
||||
- errors by not updating individual exit points when making
|
||||
modifications are prevented
|
||||
modifications are prevented
|
||||
- saves the compiler work to optimize redundant code away ;)
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
int fun(int a)
|
||||
{
|
||||
int result = 0;
|
||||
|
@ -425,27 +478,41 @@ The rationale for using gotos is:
|
|||
goto out_buffer;
|
||||
}
|
||||
...
|
||||
out_buffer:
|
||||
out_free_buffer:
|
||||
kfree(buffer);
|
||||
return result;
|
||||
}
|
||||
|
||||
A common type of bug to be aware of is "one err bugs" which look like this:
|
||||
A common type of bug to be aware of is ``one err bugs`` which look like this:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
err:
|
||||
kfree(foo->bar);
|
||||
kfree(foo);
|
||||
return ret;
|
||||
|
||||
The bug in this code is that on some exit paths "foo" is NULL. Normally the
|
||||
fix for this is to split it up into two error labels "err_bar:" and "err_foo:".
|
||||
The bug in this code is that on some exit paths ``foo`` is NULL. Normally the
|
||||
fix for this is to split it up into two error labels ``err_free_bar:`` and
|
||||
``err_free_foo:``:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
err_free_bar:
|
||||
kfree(foo->bar);
|
||||
err_free_foo:
|
||||
kfree(foo);
|
||||
return ret;
|
||||
|
||||
Ideally you should simulate errors to test all exit paths.
|
||||
|
||||
|
||||
Chapter 8: Commenting
|
||||
8) Commenting
|
||||
-------------
|
||||
|
||||
Comments are good, but there is also a danger of over-commenting. NEVER
|
||||
try to explain HOW your code works in a comment: it's much better to
|
||||
write the code so that the _working_ is obvious, and it's a waste of
|
||||
write the code so that the **working** is obvious, and it's a waste of
|
||||
time to explain badly written code.
|
||||
|
||||
Generally, you want your comments to tell WHAT your code does, not HOW.
|
||||
|
@ -461,11 +528,10 @@ When commenting the kernel API functions, please use the kernel-doc format.
|
|||
See the files Documentation/kernel-documentation.rst and scripts/kernel-doc
|
||||
for details.
|
||||
|
||||
Linux style for comments is the C89 "/* ... */" style.
|
||||
Don't use C99-style "// ..." comments.
|
||||
|
||||
The preferred style for long (multi-line) comments is:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
/*
|
||||
* This is the preferred style for multi-line
|
||||
* comments in the Linux kernel source code.
|
||||
|
@ -478,6 +544,8 @@ The preferred style for long (multi-line) comments is:
|
|||
For files in net/ and drivers/net/ the preferred style for long (multi-line)
|
||||
comments is a little different.
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
/* The preferred comment style for files in net/ and drivers/net
|
||||
* looks like this.
|
||||
*
|
||||
|
@ -491,10 +559,11 @@ multiple data declarations). This leaves you room for a small comment on each
|
|||
item, explaining its use.
|
||||
|
||||
|
||||
Chapter 9: You've made a mess of it
|
||||
9) You've made a mess of it
|
||||
---------------------------
|
||||
|
||||
That's OK, we all do. You've probably been told by your long-time Unix
|
||||
user helper that "GNU emacs" automatically formats the C sources for
|
||||
user helper that ``GNU emacs`` automatically formats the C sources for
|
||||
you, and you've noticed that yes, it does do that, but the defaults it
|
||||
uses are less than desirable (in fact, they are worse than random
|
||||
typing - an infinite number of monkeys typing into GNU emacs would never
|
||||
|
@ -503,63 +572,66 @@ make a good program).
|
|||
So, you can either get rid of GNU emacs, or change it to use saner
|
||||
values. To do the latter, you can stick the following in your .emacs file:
|
||||
|
||||
(defun c-lineup-arglist-tabs-only (ignored)
|
||||
"Line up argument lists by tabs, not spaces"
|
||||
(let* ((anchor (c-langelem-pos c-syntactic-element))
|
||||
(column (c-langelem-2nd-pos c-syntactic-element))
|
||||
(offset (- (1+ column) anchor))
|
||||
(steps (floor offset c-basic-offset)))
|
||||
(* (max steps 1)
|
||||
c-basic-offset)))
|
||||
.. code-block:: none
|
||||
|
||||
(add-hook 'c-mode-common-hook
|
||||
(lambda ()
|
||||
;; Add kernel style
|
||||
(c-add-style
|
||||
"linux-tabs-only"
|
||||
'("linux" (c-offsets-alist
|
||||
(arglist-cont-nonempty
|
||||
c-lineup-gcc-asm-reg
|
||||
c-lineup-arglist-tabs-only))))))
|
||||
(defun c-lineup-arglist-tabs-only (ignored)
|
||||
"Line up argument lists by tabs, not spaces"
|
||||
(let* ((anchor (c-langelem-pos c-syntactic-element))
|
||||
(column (c-langelem-2nd-pos c-syntactic-element))
|
||||
(offset (- (1+ column) anchor))
|
||||
(steps (floor offset c-basic-offset)))
|
||||
(* (max steps 1)
|
||||
c-basic-offset)))
|
||||
|
||||
(add-hook 'c-mode-hook
|
||||
(lambda ()
|
||||
(let ((filename (buffer-file-name)))
|
||||
;; Enable kernel mode for the appropriate files
|
||||
(when (and filename
|
||||
(string-match (expand-file-name "~/src/linux-trees")
|
||||
filename))
|
||||
(setq indent-tabs-mode t)
|
||||
(setq show-trailing-whitespace t)
|
||||
(c-set-style "linux-tabs-only")))))
|
||||
(add-hook 'c-mode-common-hook
|
||||
(lambda ()
|
||||
;; Add kernel style
|
||||
(c-add-style
|
||||
"linux-tabs-only"
|
||||
'("linux" (c-offsets-alist
|
||||
(arglist-cont-nonempty
|
||||
c-lineup-gcc-asm-reg
|
||||
c-lineup-arglist-tabs-only))))))
|
||||
|
||||
(add-hook 'c-mode-hook
|
||||
(lambda ()
|
||||
(let ((filename (buffer-file-name)))
|
||||
;; Enable kernel mode for the appropriate files
|
||||
(when (and filename
|
||||
(string-match (expand-file-name "~/src/linux-trees")
|
||||
filename))
|
||||
(setq indent-tabs-mode t)
|
||||
(setq show-trailing-whitespace t)
|
||||
(c-set-style "linux-tabs-only")))))
|
||||
|
||||
This will make emacs go better with the kernel coding style for C
|
||||
files below ~/src/linux-trees.
|
||||
files below ``~/src/linux-trees``.
|
||||
|
||||
But even if you fail in getting emacs to do sane formatting, not
|
||||
everything is lost: use "indent".
|
||||
everything is lost: use ``indent``.
|
||||
|
||||
Now, again, GNU indent has the same brain-dead settings that GNU emacs
|
||||
has, which is why you need to give it a few command line options.
|
||||
However, that's not too bad, because even the makers of GNU indent
|
||||
recognize the authority of K&R (the GNU people aren't evil, they are
|
||||
just severely misguided in this matter), so you just give indent the
|
||||
options "-kr -i8" (stands for "K&R, 8 character indents"), or use
|
||||
"scripts/Lindent", which indents in the latest style.
|
||||
options ``-kr -i8`` (stands for ``K&R, 8 character indents``), or use
|
||||
``scripts/Lindent``, which indents in the latest style.
|
||||
|
||||
"indent" has a lot of options, and especially when it comes to comment
|
||||
``indent`` has a lot of options, and especially when it comes to comment
|
||||
re-formatting you may want to take a look at the man page. But
|
||||
remember: "indent" is not a fix for bad programming.
|
||||
remember: ``indent`` is not a fix for bad programming.
|
||||
|
||||
|
||||
Chapter 10: Kconfig configuration files
|
||||
10) Kconfig configuration files
|
||||
-------------------------------
|
||||
|
||||
For all of the Kconfig* configuration files throughout the source tree,
|
||||
the indentation is somewhat different. Lines under a "config" definition
|
||||
the indentation is somewhat different. Lines under a ``config`` definition
|
||||
are indented with one tab, while help text is indented an additional two
|
||||
spaces. Example:
|
||||
spaces. Example::
|
||||
|
||||
config AUDIT
|
||||
config AUDIT
|
||||
bool "Auditing support"
|
||||
depends on NET
|
||||
help
|
||||
|
@ -569,9 +641,9 @@ config AUDIT
|
|||
auditing without CONFIG_AUDITSYSCALL.
|
||||
|
||||
Seriously dangerous features (such as write support for certain
|
||||
filesystems) should advertise this prominently in their prompt string:
|
||||
filesystems) should advertise this prominently in their prompt string::
|
||||
|
||||
config ADFS_FS_RW
|
||||
config ADFS_FS_RW
|
||||
bool "ADFS write support (DANGEROUS)"
|
||||
depends on ADFS_FS
|
||||
...
|
||||
|
@ -580,41 +652,45 @@ For full documentation on the configuration files, see the file
|
|||
Documentation/kbuild/kconfig-language.txt.
|
||||
|
||||
|
||||
Chapter 11: Data structures
|
||||
11) Data structures
|
||||
-------------------
|
||||
|
||||
Data structures that have visibility outside the single-threaded
|
||||
environment they are created and destroyed in should always have
|
||||
reference counts. In the kernel, garbage collection doesn't exist (and
|
||||
outside the kernel garbage collection is slow and inefficient), which
|
||||
means that you absolutely _have_ to reference count all your uses.
|
||||
means that you absolutely **have** to reference count all your uses.
|
||||
|
||||
Reference counting means that you can avoid locking, and allows multiple
|
||||
users to have access to the data structure in parallel - and not having
|
||||
to worry about the structure suddenly going away from under them just
|
||||
because they slept or did something else for a while.
|
||||
|
||||
Note that locking is _not_ a replacement for reference counting.
|
||||
Note that locking is **not** a replacement for reference counting.
|
||||
Locking is used to keep data structures coherent, while reference
|
||||
counting is a memory management technique. Usually both are needed, and
|
||||
they are not to be confused with each other.
|
||||
|
||||
Many data structures can indeed have two levels of reference counting,
|
||||
when there are users of different "classes". The subclass count counts
|
||||
when there are users of different ``classes``. The subclass count counts
|
||||
the number of subclass users, and decrements the global count just once
|
||||
when the subclass count goes to zero.
|
||||
|
||||
Examples of this kind of "multi-level-reference-counting" can be found in
|
||||
memory management ("struct mm_struct": mm_users and mm_count), and in
|
||||
filesystem code ("struct super_block": s_count and s_active).
|
||||
Examples of this kind of ``multi-level-reference-counting`` can be found in
|
||||
memory management (``struct mm_struct``: mm_users and mm_count), and in
|
||||
filesystem code (``struct super_block``: s_count and s_active).
|
||||
|
||||
Remember: if another thread can find your data structure, and you don't
|
||||
have a reference count on it, you almost certainly have a bug.
|
||||
|
||||
|
||||
Chapter 12: Macros, Enums and RTL
|
||||
12) Macros, Enums and RTL
|
||||
-------------------------
|
||||
|
||||
Names of macros defining constants and labels in enums are capitalized.
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
#define CONSTANT 0x12345
|
||||
|
||||
Enums are preferred when defining several related constants.
|
||||
|
@ -626,7 +702,9 @@ Generally, inline functions are preferable to macros resembling functions.
|
|||
|
||||
Macros with multiple statements should be enclosed in a do - while block:
|
||||
|
||||
#define macrofun(a, b, c) \
|
||||
.. code-block:: c
|
||||
|
||||
#define macrofun(a, b, c) \
|
||||
do { \
|
||||
if (a == 5) \
|
||||
do_this(b, c); \
|
||||
|
@ -636,17 +714,21 @@ Things to avoid when using macros:
|
|||
|
||||
1) macros that affect control flow:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
#define FOO(x) \
|
||||
do { \
|
||||
if (blah(x) < 0) \
|
||||
return -EBUGGERED; \
|
||||
} while (0)
|
||||
|
||||
is a _very_ bad idea. It looks like a function call but exits the "calling"
|
||||
is a **very** bad idea. It looks like a function call but exits the ``calling``
|
||||
function; don't break the internal parsers of those who will read the code.
|
||||
|
||||
2) macros that depend on having a local variable with a magic name:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
#define FOO(val) bar(index, val)
|
||||
|
||||
might look like a good thing, but it's confusing as hell when one reads the
|
||||
|
@ -659,18 +741,22 @@ bite you if somebody e.g. turns FOO into an inline function.
|
|||
must enclose the expression in parentheses. Beware of similar issues with
|
||||
macros using parameters.
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
#define CONSTANT 0x4000
|
||||
#define CONSTEXP (CONSTANT | 3)
|
||||
|
||||
5) namespace collisions when defining local variables in macros resembling
|
||||
functions:
|
||||
|
||||
#define FOO(x) \
|
||||
({ \
|
||||
typeof(x) ret; \
|
||||
ret = calc_ret(x); \
|
||||
(ret); \
|
||||
})
|
||||
.. code-block:: c
|
||||
|
||||
#define FOO(x) \
|
||||
({ \
|
||||
typeof(x) ret; \
|
||||
ret = calc_ret(x); \
|
||||
(ret); \
|
||||
})
|
||||
|
||||
ret is a common name for a local variable - __foo_ret is less likely
|
||||
to collide with an existing variable.
|
||||
|
@ -679,11 +765,12 @@ The cpp manual deals with macros exhaustively. The gcc internals manual also
|
|||
covers RTL which is used frequently with assembly language in the kernel.
|
||||
|
||||
|
||||
Chapter 13: Printing kernel messages
|
||||
13) Printing kernel messages
|
||||
----------------------------
|
||||
|
||||
Kernel developers like to be seen as literate. Do mind the spelling
|
||||
of kernel messages to make a good impression. Do not use crippled
|
||||
words like "dont"; use "do not" or "don't" instead. Make the messages
|
||||
words like ``dont``; use ``do not`` or ``don't`` instead. Make the messages
|
||||
concise, clear, and unambiguous.
|
||||
|
||||
Kernel messages do not have to be terminated with a period.
|
||||
|
@ -713,7 +800,8 @@ already inside a debug-related #ifdef section, printk(KERN_DEBUG ...) can be
|
|||
used.
|
||||
|
||||
|
||||
Chapter 14: Allocating memory
|
||||
14) Allocating memory
|
||||
---------------------
|
||||
|
||||
The kernel provides the following general purpose memory allocators:
|
||||
kmalloc(), kzalloc(), kmalloc_array(), kcalloc(), vmalloc(), and
|
||||
|
@ -722,6 +810,8 @@ about them.
|
|||
|
||||
The preferred form for passing a size of a struct is the following:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
p = kmalloc(sizeof(*p), ...);
|
||||
|
||||
The alternative form where struct name is spelled out hurts readability and
|
||||
|
@ -734,20 +824,25 @@ language.
|
|||
|
||||
The preferred form for allocating an array is the following:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
p = kmalloc_array(n, sizeof(...), ...);
|
||||
|
||||
The preferred form for allocating a zeroed array is the following:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
p = kcalloc(n, sizeof(...), ...);
|
||||
|
||||
Both forms check for overflow on the allocation size n * sizeof(...),
|
||||
and return NULL if that occurred.
|
||||
|
||||
|
||||
Chapter 15: The inline disease
|
||||
15) The inline disease
|
||||
----------------------
|
||||
|
||||
There appears to be a common misperception that gcc has a magic "make me
|
||||
faster" speedup option called "inline". While the use of inlines can be
|
||||
faster" speedup option called ``inline``. While the use of inlines can be
|
||||
appropriate (for example as a means of replacing macros, see Chapter 12), it
|
||||
very often is not. Abundant use of the inline keyword leads to a much bigger
|
||||
kernel, which in turn slows the system as a whole down, due to a bigger
|
||||
|
@ -771,26 +866,27 @@ appears outweighs the potential value of the hint that tells gcc to do
|
|||
something it would have done anyway.
|
||||
|
||||
|
||||
Chapter 16: Function return values and names
|
||||
16) Function return values and names
|
||||
------------------------------------
|
||||
|
||||
Functions can return values of many different kinds, and one of the
|
||||
most common is a value indicating whether the function succeeded or
|
||||
failed. Such a value can be represented as an error-code integer
|
||||
(-Exxx = failure, 0 = success) or a "succeeded" boolean (0 = failure,
|
||||
(-Exxx = failure, 0 = success) or a ``succeeded`` boolean (0 = failure,
|
||||
non-zero = success).
|
||||
|
||||
Mixing up these two sorts of representations is a fertile source of
|
||||
difficult-to-find bugs. If the C language included a strong distinction
|
||||
between integers and booleans then the compiler would find these mistakes
|
||||
for us... but it doesn't. To help prevent such bugs, always follow this
|
||||
convention:
|
||||
convention::
|
||||
|
||||
If the name of a function is an action or an imperative command,
|
||||
the function should return an error-code integer. If the name
|
||||
is a predicate, the function should return a "succeeded" boolean.
|
||||
|
||||
For example, "add work" is a command, and the add_work() function returns 0
|
||||
for success or -EBUSY for failure. In the same way, "PCI device present" is
|
||||
For example, ``add work`` is a command, and the add_work() function returns 0
|
||||
for success or -EBUSY for failure. In the same way, ``PCI device present`` is
|
||||
a predicate, and the pci_dev_present() function returns 1 if it succeeds in
|
||||
finding a matching device or 0 if it doesn't.
|
||||
|
||||
|
@ -805,17 +901,22 @@ result. Typical examples would be functions that return pointers; they use
|
|||
NULL or the ERR_PTR mechanism to report failure.
|
||||
|
||||
|
||||
Chapter 17: Don't re-invent the kernel macros
|
||||
17) Don't re-invent the kernel macros
|
||||
-------------------------------------
|
||||
|
||||
The header file include/linux/kernel.h contains a number of macros that
|
||||
you should use, rather than explicitly coding some variant of them yourself.
|
||||
For example, if you need to calculate the length of an array, take advantage
|
||||
of the macro
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
|
||||
|
||||
Similarly, if you need to calculate the size of some structure member, use
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
#define FIELD_SIZEOF(t, f) (sizeof(((t*)0)->f))
|
||||
|
||||
There are also min() and max() macros that do strict type checking if you
|
||||
|
@ -823,16 +924,21 @@ need them. Feel free to peruse that header file to see what else is already
|
|||
defined that you shouldn't reproduce in your code.
|
||||
|
||||
|
||||
Chapter 18: Editor modelines and other cruft
|
||||
18) Editor modelines and other cruft
|
||||
------------------------------------
|
||||
|
||||
Some editors can interpret configuration information embedded in source files,
|
||||
indicated with special markers. For example, emacs interprets lines marked
|
||||
like this:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
-*- mode: c -*-
|
||||
|
||||
Or like this:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
/*
|
||||
Local Variables:
|
||||
compile-command: "gcc -DMAGIC_DEBUG_FLAG foo.c"
|
||||
|
@ -841,6 +947,8 @@ Or like this:
|
|||
|
||||
Vim interprets markers that look like this:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
/* vim:set sw=8 noet */
|
||||
|
||||
Do not include any of these in source files. People have their own personal
|
||||
|
@ -850,7 +958,8 @@ own custom mode, or may have some other magic method for making indentation
|
|||
work correctly.
|
||||
|
||||
|
||||
Chapter 19: Inline assembly
|
||||
19) Inline assembly
|
||||
-------------------
|
||||
|
||||
In architecture-specific code, you may need to use inline assembly to interface
|
||||
with CPU or platform functionality. Don't hesitate to do so when necessary.
|
||||
|
@ -863,7 +972,7 @@ that inline assembly can use C parameters.
|
|||
|
||||
Large, non-trivial assembly functions should go in .S files, with corresponding
|
||||
C prototypes defined in C header files. The C prototypes for assembly
|
||||
functions should use "asmlinkage".
|
||||
functions should use ``asmlinkage``.
|
||||
|
||||
You may need to mark your asm statement as volatile, to prevent GCC from
|
||||
removing it if GCC doesn't notice any side effects. You don't always need to
|
||||
|
@ -874,12 +983,15 @@ instructions, put each instruction on a separate line in a separate quoted
|
|||
string, and end each string except the last with \n\t to properly indent the
|
||||
next instruction in the assembly output:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
asm ("magic %reg1, #42\n\t"
|
||||
"more_magic %reg2, %reg3"
|
||||
: /* outputs */ : /* inputs */ : /* clobbers */);
|
||||
|
||||
|
||||
Chapter 20: Conditional Compilation
|
||||
20) Conditional Compilation
|
||||
---------------------------
|
||||
|
||||
Wherever possible, don't use preprocessor conditionals (#if, #ifdef) in .c
|
||||
files; doing so makes code harder to read and logic harder to follow. Instead,
|
||||
|
@ -903,6 +1015,8 @@ unused, delete it.)
|
|||
Within code, where possible, use the IS_ENABLED macro to convert a Kconfig
|
||||
symbol into a C boolean expression, and use it in a normal C conditional:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
if (IS_ENABLED(CONFIG_SOMETHING)) {
|
||||
...
|
||||
}
|
||||
|
@ -918,12 +1032,15 @@ At the end of any non-trivial #if or #ifdef block (more than a few lines),
|
|||
place a comment after the #endif on the same line, noting the conditional
|
||||
expression used. For instance:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
#ifdef CONFIG_SOMETHING
|
||||
...
|
||||
#endif /* CONFIG_SOMETHING */
|
||||
|
||||
|
||||
Appendix I: References
|
||||
Appendix I) References
|
||||
----------------------
|
||||
|
||||
The C Programming Language, Second Edition
|
||||
by Brian W. Kernighan and Dennis M. Ritchie.
|
||||
|
@ -943,4 +1060,3 @@ language C, URL: http://www.open-std.org/JTC1/SC22/WG14/
|
|||
|
||||
Kernel CodingStyle, by greg@kroah.com at OLS 2002:
|
||||
http://www.kroah.com/linux/talks/ols_2002_kernel_codingstyle_talk/html/
|
||||
|
||||
|
|
|
@ -699,7 +699,7 @@ to use the dma_sync_*() interfaces.
|
|||
dma_addr_t mapping;
|
||||
|
||||
mapping = dma_map_single(cp->dev, buffer, len, DMA_FROM_DEVICE);
|
||||
if (dma_mapping_error(cp->dev, dma_handle)) {
|
||||
if (dma_mapping_error(cp->dev, mapping)) {
|
||||
/*
|
||||
* reduce current DMA mapping usage,
|
||||
* delay and try again later or
|
||||
|
@ -931,10 +931,8 @@ to "Closing".
|
|||
|
||||
1) Struct scatterlist requirements.
|
||||
|
||||
Don't invent the architecture specific struct scatterlist; just use
|
||||
<asm-generic/scatterlist.h>. You need to enable
|
||||
CONFIG_NEED_SG_DMA_LENGTH if the architecture supports IOMMUs
|
||||
(including software IOMMU).
|
||||
You need to enable CONFIG_NEED_SG_DMA_LENGTH if the architecture
|
||||
supports IOMMUs (including software IOMMU).
|
||||
|
||||
2) ARCH_DMA_MINALIGN
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
# To add a new book the only step required is to add the book to the
|
||||
# list of DOCBOOKS.
|
||||
|
||||
DOCBOOKS := z8530book.xml device-drivers.xml \
|
||||
DOCBOOKS := z8530book.xml \
|
||||
kernel-hacking.xml kernel-locking.xml deviceiobook.xml \
|
||||
writing_usb_driver.xml networking.xml \
|
||||
kernel-api.xml filesystems.xml lsm.xml usb.xml kgdb.xml \
|
||||
|
@ -22,8 +22,14 @@ ifeq ($(DOCBOOKS),)
|
|||
# Skip DocBook build if the user explicitly requested no DOCBOOKS.
|
||||
.DEFAULT:
|
||||
@echo " SKIP DocBook $@ target (DOCBOOKS=\"\" specified)."
|
||||
|
||||
else
|
||||
ifneq ($(SPHINXDIRS),)
|
||||
|
||||
# Skip DocBook build if the user explicitly requested a sphinx dir
|
||||
.DEFAULT:
|
||||
@echo " SKIP DocBook $@ target (SPHINXDIRS specified)."
|
||||
else
|
||||
|
||||
|
||||
###
|
||||
# The build process is as follows (targets):
|
||||
|
@ -66,6 +72,7 @@ installmandocs: mandocs
|
|||
|
||||
# no-op for the DocBook toolchain
|
||||
epubdocs:
|
||||
latexdocs:
|
||||
|
||||
###
|
||||
#External programs used
|
||||
|
@ -221,6 +228,7 @@ silent_gen_xml = :
|
|||
echo "</programlisting>") > $@
|
||||
|
||||
endif # DOCBOOKS=""
|
||||
endif # SPHINDIR=...
|
||||
|
||||
###
|
||||
# Help targets as used by the top-level makefile
|
||||
|
|
|
@ -1,521 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
|
||||
"http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" []>
|
||||
|
||||
<book id="LinuxDriversAPI">
|
||||
<bookinfo>
|
||||
<title>Linux Device Drivers</title>
|
||||
|
||||
<legalnotice>
|
||||
<para>
|
||||
This documentation is free software; you can redistribute
|
||||
it and/or modify it under the terms of the GNU General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later
|
||||
version.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
This program is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied
|
||||
warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the GNU General Public License for more details.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
You should have received a copy of the GNU General Public
|
||||
License along with this program; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
MA 02111-1307 USA
|
||||
</para>
|
||||
|
||||
<para>
|
||||
For more details see the file COPYING in the source
|
||||
distribution of Linux.
|
||||
</para>
|
||||
</legalnotice>
|
||||
</bookinfo>
|
||||
|
||||
<toc></toc>
|
||||
|
||||
<chapter id="Basics">
|
||||
<title>Driver Basics</title>
|
||||
<sect1><title>Driver Entry and Exit points</title>
|
||||
!Iinclude/linux/init.h
|
||||
</sect1>
|
||||
|
||||
<sect1><title>Atomic and pointer manipulation</title>
|
||||
!Iarch/x86/include/asm/atomic.h
|
||||
</sect1>
|
||||
|
||||
<sect1><title>Delaying, scheduling, and timer routines</title>
|
||||
!Iinclude/linux/sched.h
|
||||
!Ekernel/sched/core.c
|
||||
!Ikernel/sched/cpupri.c
|
||||
!Ikernel/sched/fair.c
|
||||
!Iinclude/linux/completion.h
|
||||
!Ekernel/time/timer.c
|
||||
</sect1>
|
||||
<sect1><title>Wait queues and Wake events</title>
|
||||
!Iinclude/linux/wait.h
|
||||
!Ekernel/sched/wait.c
|
||||
</sect1>
|
||||
<sect1><title>High-resolution timers</title>
|
||||
!Iinclude/linux/ktime.h
|
||||
!Iinclude/linux/hrtimer.h
|
||||
!Ekernel/time/hrtimer.c
|
||||
</sect1>
|
||||
<sect1><title>Workqueues and Kevents</title>
|
||||
!Iinclude/linux/workqueue.h
|
||||
!Ekernel/workqueue.c
|
||||
</sect1>
|
||||
<sect1><title>Internal Functions</title>
|
||||
!Ikernel/exit.c
|
||||
!Ikernel/signal.c
|
||||
!Iinclude/linux/kthread.h
|
||||
!Ekernel/kthread.c
|
||||
</sect1>
|
||||
|
||||
<sect1><title>Kernel objects manipulation</title>
|
||||
<!--
|
||||
X!Iinclude/linux/kobject.h
|
||||
-->
|
||||
!Elib/kobject.c
|
||||
</sect1>
|
||||
|
||||
<sect1><title>Kernel utility functions</title>
|
||||
!Iinclude/linux/kernel.h
|
||||
!Ekernel/printk/printk.c
|
||||
!Ekernel/panic.c
|
||||
!Ekernel/sys.c
|
||||
!Ekernel/rcu/srcu.c
|
||||
!Ekernel/rcu/tree.c
|
||||
!Ekernel/rcu/tree_plugin.h
|
||||
!Ekernel/rcu/update.c
|
||||
</sect1>
|
||||
|
||||
<sect1><title>Device Resource Management</title>
|
||||
!Edrivers/base/devres.c
|
||||
</sect1>
|
||||
|
||||
</chapter>
|
||||
|
||||
<chapter id="devdrivers">
|
||||
<title>Device drivers infrastructure</title>
|
||||
<sect1><title>The Basic Device Driver-Model Structures </title>
|
||||
!Iinclude/linux/device.h
|
||||
</sect1>
|
||||
<sect1><title>Device Drivers Base</title>
|
||||
!Idrivers/base/init.c
|
||||
!Edrivers/base/driver.c
|
||||
!Edrivers/base/core.c
|
||||
!Edrivers/base/syscore.c
|
||||
!Edrivers/base/class.c
|
||||
!Idrivers/base/node.c
|
||||
!Edrivers/base/firmware_class.c
|
||||
!Edrivers/base/transport_class.c
|
||||
<!-- Cannot be included, because
|
||||
attribute_container_add_class_device_adapter
|
||||
and attribute_container_classdev_to_container
|
||||
exceed allowed 44 characters maximum
|
||||
X!Edrivers/base/attribute_container.c
|
||||
-->
|
||||
!Edrivers/base/dd.c
|
||||
<!--
|
||||
X!Edrivers/base/interface.c
|
||||
-->
|
||||
!Iinclude/linux/platform_device.h
|
||||
!Edrivers/base/platform.c
|
||||
!Edrivers/base/bus.c
|
||||
</sect1>
|
||||
<sect1>
|
||||
<title>Buffer Sharing and Synchronization</title>
|
||||
<para>
|
||||
The dma-buf subsystem provides the framework for sharing buffers
|
||||
for hardware (DMA) access across multiple device drivers and
|
||||
subsystems, and for synchronizing asynchronous hardware access.
|
||||
</para>
|
||||
<para>
|
||||
This is used, for example, by drm "prime" multi-GPU support, but
|
||||
is of course not limited to GPU use cases.
|
||||
</para>
|
||||
<para>
|
||||
The three main components of this are: (1) dma-buf, representing
|
||||
a sg_table and exposed to userspace as a file descriptor to allow
|
||||
passing between devices, (2) fence, which provides a mechanism
|
||||
to signal when one device as finished access, and (3) reservation,
|
||||
which manages the shared or exclusive fence(s) associated with
|
||||
the buffer.
|
||||
</para>
|
||||
<sect2><title>dma-buf</title>
|
||||
!Edrivers/dma-buf/dma-buf.c
|
||||
!Iinclude/linux/dma-buf.h
|
||||
</sect2>
|
||||
<sect2><title>reservation</title>
|
||||
!Pdrivers/dma-buf/reservation.c Reservation Object Overview
|
||||
!Edrivers/dma-buf/reservation.c
|
||||
!Iinclude/linux/reservation.h
|
||||
</sect2>
|
||||
<sect2><title>fence</title>
|
||||
!Edrivers/dma-buf/fence.c
|
||||
!Iinclude/linux/fence.h
|
||||
!Edrivers/dma-buf/seqno-fence.c
|
||||
!Iinclude/linux/seqno-fence.h
|
||||
!Edrivers/dma-buf/fence-array.c
|
||||
!Iinclude/linux/fence-array.h
|
||||
!Edrivers/dma-buf/reservation.c
|
||||
!Iinclude/linux/reservation.h
|
||||
!Edrivers/dma-buf/sync_file.c
|
||||
!Iinclude/linux/sync_file.h
|
||||
</sect2>
|
||||
</sect1>
|
||||
<sect1><title>Device Drivers DMA Management</title>
|
||||
!Edrivers/base/dma-coherent.c
|
||||
!Edrivers/base/dma-mapping.c
|
||||
</sect1>
|
||||
<sect1><title>Device Drivers Power Management</title>
|
||||
!Edrivers/base/power/main.c
|
||||
</sect1>
|
||||
<sect1><title>Device Drivers ACPI Support</title>
|
||||
<!-- Internal functions only
|
||||
X!Edrivers/acpi/sleep/main.c
|
||||
X!Edrivers/acpi/sleep/wakeup.c
|
||||
X!Edrivers/acpi/motherboard.c
|
||||
X!Edrivers/acpi/bus.c
|
||||
-->
|
||||
!Edrivers/acpi/scan.c
|
||||
!Idrivers/acpi/scan.c
|
||||
<!-- No correct structured comments
|
||||
X!Edrivers/acpi/pci_bind.c
|
||||
-->
|
||||
</sect1>
|
||||
<sect1><title>Device drivers PnP support</title>
|
||||
!Idrivers/pnp/core.c
|
||||
<!-- No correct structured comments
|
||||
X!Edrivers/pnp/system.c
|
||||
-->
|
||||
!Edrivers/pnp/card.c
|
||||
!Idrivers/pnp/driver.c
|
||||
!Edrivers/pnp/manager.c
|
||||
!Edrivers/pnp/support.c
|
||||
</sect1>
|
||||
<sect1><title>Userspace IO devices</title>
|
||||
!Edrivers/uio/uio.c
|
||||
!Iinclude/linux/uio_driver.h
|
||||
</sect1>
|
||||
</chapter>
|
||||
|
||||
<chapter id="parportdev">
|
||||
<title>Parallel Port Devices</title>
|
||||
!Iinclude/linux/parport.h
|
||||
!Edrivers/parport/ieee1284.c
|
||||
!Edrivers/parport/share.c
|
||||
!Idrivers/parport/daisy.c
|
||||
</chapter>
|
||||
|
||||
<chapter id="message_devices">
|
||||
<title>Message-based devices</title>
|
||||
<sect1><title>Fusion message devices</title>
|
||||
!Edrivers/message/fusion/mptbase.c
|
||||
!Idrivers/message/fusion/mptbase.c
|
||||
!Edrivers/message/fusion/mptscsih.c
|
||||
!Idrivers/message/fusion/mptscsih.c
|
||||
!Idrivers/message/fusion/mptctl.c
|
||||
!Idrivers/message/fusion/mptspi.c
|
||||
!Idrivers/message/fusion/mptfc.c
|
||||
!Idrivers/message/fusion/mptlan.c
|
||||
</sect1>
|
||||
</chapter>
|
||||
|
||||
<chapter id="snddev">
|
||||
<title>Sound Devices</title>
|
||||
!Iinclude/sound/core.h
|
||||
!Esound/sound_core.c
|
||||
!Iinclude/sound/pcm.h
|
||||
!Esound/core/pcm.c
|
||||
!Esound/core/device.c
|
||||
!Esound/core/info.c
|
||||
!Esound/core/rawmidi.c
|
||||
!Esound/core/sound.c
|
||||
!Esound/core/memory.c
|
||||
!Esound/core/pcm_memory.c
|
||||
!Esound/core/init.c
|
||||
!Esound/core/isadma.c
|
||||
!Esound/core/control.c
|
||||
!Esound/core/pcm_lib.c
|
||||
!Esound/core/hwdep.c
|
||||
!Esound/core/pcm_native.c
|
||||
!Esound/core/memalloc.c
|
||||
<!-- FIXME: Removed for now since no structured comments in source
|
||||
X!Isound/sound_firmware.c
|
||||
-->
|
||||
</chapter>
|
||||
|
||||
|
||||
<chapter id="uart16x50">
|
||||
<title>16x50 UART Driver</title>
|
||||
!Edrivers/tty/serial/serial_core.c
|
||||
!Edrivers/tty/serial/8250/8250_core.c
|
||||
</chapter>
|
||||
|
||||
<chapter id="fbdev">
|
||||
<title>Frame Buffer Library</title>
|
||||
|
||||
<para>
|
||||
The frame buffer drivers depend heavily on four data structures.
|
||||
These structures are declared in include/linux/fb.h. They are
|
||||
fb_info, fb_var_screeninfo, fb_fix_screeninfo and fb_monospecs.
|
||||
The last three can be made available to and from userland.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
fb_info defines the current state of a particular video card.
|
||||
Inside fb_info, there exists a fb_ops structure which is a
|
||||
collection of needed functions to make fbdev and fbcon work.
|
||||
fb_info is only visible to the kernel.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
fb_var_screeninfo is used to describe the features of a video card
|
||||
that are user defined. With fb_var_screeninfo, things such as
|
||||
depth and the resolution may be defined.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The next structure is fb_fix_screeninfo. This defines the
|
||||
properties of a card that are created when a mode is set and can't
|
||||
be changed otherwise. A good example of this is the start of the
|
||||
frame buffer memory. This "locks" the address of the frame buffer
|
||||
memory, so that it cannot be changed or moved.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The last structure is fb_monospecs. In the old API, there was
|
||||
little importance for fb_monospecs. This allowed for forbidden things
|
||||
such as setting a mode of 800x600 on a fix frequency monitor. With
|
||||
the new API, fb_monospecs prevents such things, and if used
|
||||
correctly, can prevent a monitor from being cooked. fb_monospecs
|
||||
will not be useful until kernels 2.5.x.
|
||||
</para>
|
||||
|
||||
<sect1><title>Frame Buffer Memory</title>
|
||||
!Edrivers/video/fbdev/core/fbmem.c
|
||||
</sect1>
|
||||
<!--
|
||||
<sect1><title>Frame Buffer Console</title>
|
||||
X!Edrivers/video/console/fbcon.c
|
||||
</sect1>
|
||||
-->
|
||||
<sect1><title>Frame Buffer Colormap</title>
|
||||
!Edrivers/video/fbdev/core/fbcmap.c
|
||||
</sect1>
|
||||
<!-- FIXME:
|
||||
drivers/video/fbgen.c has no docs, which stuffs up the sgml. Comment
|
||||
out until somebody adds docs. KAO
|
||||
<sect1><title>Frame Buffer Generic Functions</title>
|
||||
X!Idrivers/video/fbgen.c
|
||||
</sect1>
|
||||
KAO -->
|
||||
<sect1><title>Frame Buffer Video Mode Database</title>
|
||||
!Idrivers/video/fbdev/core/modedb.c
|
||||
!Edrivers/video/fbdev/core/modedb.c
|
||||
</sect1>
|
||||
<sect1><title>Frame Buffer Macintosh Video Mode Database</title>
|
||||
!Edrivers/video/fbdev/macmodes.c
|
||||
</sect1>
|
||||
<sect1><title>Frame Buffer Fonts</title>
|
||||
<para>
|
||||
Refer to the file lib/fonts/fonts.c for more information.
|
||||
</para>
|
||||
<!-- FIXME: Removed for now since no structured comments in source
|
||||
X!Ilib/fonts/fonts.c
|
||||
-->
|
||||
</sect1>
|
||||
</chapter>
|
||||
|
||||
<chapter id="input_subsystem">
|
||||
<title>Input Subsystem</title>
|
||||
<sect1><title>Input core</title>
|
||||
!Iinclude/linux/input.h
|
||||
!Edrivers/input/input.c
|
||||
!Edrivers/input/ff-core.c
|
||||
!Edrivers/input/ff-memless.c
|
||||
</sect1>
|
||||
<sect1><title>Multitouch Library</title>
|
||||
!Iinclude/linux/input/mt.h
|
||||
!Edrivers/input/input-mt.c
|
||||
</sect1>
|
||||
<sect1><title>Polled input devices</title>
|
||||
!Iinclude/linux/input-polldev.h
|
||||
!Edrivers/input/input-polldev.c
|
||||
</sect1>
|
||||
<sect1><title>Matrix keyboards/keypads</title>
|
||||
!Iinclude/linux/input/matrix_keypad.h
|
||||
</sect1>
|
||||
<sect1><title>Sparse keymap support</title>
|
||||
!Iinclude/linux/input/sparse-keymap.h
|
||||
!Edrivers/input/sparse-keymap.c
|
||||
</sect1>
|
||||
</chapter>
|
||||
|
||||
<chapter id="spi">
|
||||
<title>Serial Peripheral Interface (SPI)</title>
|
||||
<para>
|
||||
SPI is the "Serial Peripheral Interface", widely used with
|
||||
embedded systems because it is a simple and efficient
|
||||
interface: basically a multiplexed shift register.
|
||||
Its three signal wires hold a clock (SCK, often in the range
|
||||
of 1-20 MHz), a "Master Out, Slave In" (MOSI) data line, and
|
||||
a "Master In, Slave Out" (MISO) data line.
|
||||
SPI is a full duplex protocol; for each bit shifted out the
|
||||
MOSI line (one per clock) another is shifted in on the MISO line.
|
||||
Those bits are assembled into words of various sizes on the
|
||||
way to and from system memory.
|
||||
An additional chipselect line is usually active-low (nCS);
|
||||
four signals are normally used for each peripheral, plus
|
||||
sometimes an interrupt.
|
||||
</para>
|
||||
<para>
|
||||
The SPI bus facilities listed here provide a generalized
|
||||
interface to declare SPI busses and devices, manage them
|
||||
according to the standard Linux driver model, and perform
|
||||
input/output operations.
|
||||
At this time, only "master" side interfaces are supported,
|
||||
where Linux talks to SPI peripherals and does not implement
|
||||
such a peripheral itself.
|
||||
(Interfaces to support implementing SPI slaves would
|
||||
necessarily look different.)
|
||||
</para>
|
||||
<para>
|
||||
The programming interface is structured around two kinds of driver,
|
||||
and two kinds of device.
|
||||
A "Controller Driver" abstracts the controller hardware, which may
|
||||
be as simple as a set of GPIO pins or as complex as a pair of FIFOs
|
||||
connected to dual DMA engines on the other side of the SPI shift
|
||||
register (maximizing throughput). Such drivers bridge between
|
||||
whatever bus they sit on (often the platform bus) and SPI, and
|
||||
expose the SPI side of their device as a
|
||||
<structname>struct spi_master</structname>.
|
||||
SPI devices are children of that master, represented as a
|
||||
<structname>struct spi_device</structname> and manufactured from
|
||||
<structname>struct spi_board_info</structname> descriptors which
|
||||
are usually provided by board-specific initialization code.
|
||||
A <structname>struct spi_driver</structname> is called a
|
||||
"Protocol Driver", and is bound to a spi_device using normal
|
||||
driver model calls.
|
||||
</para>
|
||||
<para>
|
||||
The I/O model is a set of queued messages. Protocol drivers
|
||||
submit one or more <structname>struct spi_message</structname>
|
||||
objects, which are processed and completed asynchronously.
|
||||
(There are synchronous wrappers, however.) Messages are
|
||||
built from one or more <structname>struct spi_transfer</structname>
|
||||
objects, each of which wraps a full duplex SPI transfer.
|
||||
A variety of protocol tweaking options are needed, because
|
||||
different chips adopt very different policies for how they
|
||||
use the bits transferred with SPI.
|
||||
</para>
|
||||
!Iinclude/linux/spi/spi.h
|
||||
!Fdrivers/spi/spi.c spi_register_board_info
|
||||
!Edrivers/spi/spi.c
|
||||
</chapter>
|
||||
|
||||
<chapter id="i2c">
|
||||
<title>I<superscript>2</superscript>C and SMBus Subsystem</title>
|
||||
|
||||
<para>
|
||||
I<superscript>2</superscript>C (or without fancy typography, "I2C")
|
||||
is an acronym for the "Inter-IC" bus, a simple bus protocol which is
|
||||
widely used where low data rate communications suffice.
|
||||
Since it's also a licensed trademark, some vendors use another
|
||||
name (such as "Two-Wire Interface", TWI) for the same bus.
|
||||
I2C only needs two signals (SCL for clock, SDA for data), conserving
|
||||
board real estate and minimizing signal quality issues.
|
||||
Most I2C devices use seven bit addresses, and bus speeds of up
|
||||
to 400 kHz; there's a high speed extension (3.4 MHz) that's not yet
|
||||
found wide use.
|
||||
I2C is a multi-master bus; open drain signaling is used to
|
||||
arbitrate between masters, as well as to handshake and to
|
||||
synchronize clocks from slower clients.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The Linux I2C programming interfaces support only the master
|
||||
side of bus interactions, not the slave side.
|
||||
The programming interface is structured around two kinds of driver,
|
||||
and two kinds of device.
|
||||
An I2C "Adapter Driver" abstracts the controller hardware; it binds
|
||||
to a physical device (perhaps a PCI device or platform_device) and
|
||||
exposes a <structname>struct i2c_adapter</structname> representing
|
||||
each I2C bus segment it manages.
|
||||
On each I2C bus segment will be I2C devices represented by a
|
||||
<structname>struct i2c_client</structname>. Those devices will
|
||||
be bound to a <structname>struct i2c_driver</structname>,
|
||||
which should follow the standard Linux driver model.
|
||||
(At this writing, a legacy model is more widely used.)
|
||||
There are functions to perform various I2C protocol operations; at
|
||||
this writing all such functions are usable only from task context.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The System Management Bus (SMBus) is a sibling protocol. Most SMBus
|
||||
systems are also I2C conformant. The electrical constraints are
|
||||
tighter for SMBus, and it standardizes particular protocol messages
|
||||
and idioms. Controllers that support I2C can also support most
|
||||
SMBus operations, but SMBus controllers don't support all the protocol
|
||||
options that an I2C controller will.
|
||||
There are functions to perform various SMBus protocol operations,
|
||||
either using I2C primitives or by issuing SMBus commands to
|
||||
i2c_adapter devices which don't support those I2C operations.
|
||||
</para>
|
||||
|
||||
!Iinclude/linux/i2c.h
|
||||
!Fdrivers/i2c/i2c-boardinfo.c i2c_register_board_info
|
||||
!Edrivers/i2c/i2c-core.c
|
||||
</chapter>
|
||||
|
||||
<chapter id="hsi">
|
||||
<title>High Speed Synchronous Serial Interface (HSI)</title>
|
||||
|
||||
<para>
|
||||
High Speed Synchronous Serial Interface (HSI) is a
|
||||
serial interface mainly used for connecting application
|
||||
engines (APE) with cellular modem engines (CMT) in cellular
|
||||
handsets.
|
||||
|
||||
HSI provides multiplexing for up to 16 logical channels,
|
||||
low-latency and full duplex communication.
|
||||
</para>
|
||||
|
||||
!Iinclude/linux/hsi/hsi.h
|
||||
!Edrivers/hsi/hsi_core.c
|
||||
</chapter>
|
||||
|
||||
<chapter id="pwm">
|
||||
<title>Pulse-Width Modulation (PWM)</title>
|
||||
<para>
|
||||
Pulse-width modulation is a modulation technique primarily used to
|
||||
control power supplied to electrical devices.
|
||||
</para>
|
||||
<para>
|
||||
The PWM framework provides an abstraction for providers and consumers
|
||||
of PWM signals. A controller that provides one or more PWM signals is
|
||||
registered as <structname>struct pwm_chip</structname>. Providers are
|
||||
expected to embed this structure in a driver-specific structure. This
|
||||
structure contains fields that describe a particular chip.
|
||||
</para>
|
||||
<para>
|
||||
A chip exposes one or more PWM signal sources, each of which exposed
|
||||
as a <structname>struct pwm_device</structname>. Operations can be
|
||||
performed on PWM devices to control the period, duty cycle, polarity
|
||||
and active state of the signal.
|
||||
</para>
|
||||
<para>
|
||||
Note that PWM devices are exclusive resources: they can always only be
|
||||
used by one consumer at a time.
|
||||
</para>
|
||||
!Iinclude/linux/pwm.h
|
||||
!Edrivers/pwm/core.c
|
||||
</chapter>
|
||||
|
||||
</book>
|
|
@ -1,5 +1,5 @@
|
|||
HOWTO do Linux kernel development
|
||||
---------------------------------
|
||||
=================================
|
||||
|
||||
This is the be-all, end-all document on this topic. It contains
|
||||
instructions on how to become a Linux kernel developer and how to learn
|
||||
|
@ -28,6 +28,7 @@ kernel development. Assembly (any architecture) is not required unless
|
|||
you plan to do low-level development for that architecture. Though they
|
||||
are not a good substitute for a solid C education and/or years of
|
||||
experience, the following books are good for, if anything, reference:
|
||||
|
||||
- "The C Programming Language" by Kernighan and Ritchie [Prentice Hall]
|
||||
- "Practical C Programming" by Steve Oualline [O'Reilly]
|
||||
- "C: A Reference Manual" by Harbison and Steele [Prentice Hall]
|
||||
|
@ -64,7 +65,8 @@ people on the mailing lists are not lawyers, and you should not rely on
|
|||
their statements on legal matters.
|
||||
|
||||
For common questions and answers about the GPL, please see:
|
||||
http://www.gnu.org/licenses/gpl-faq.html
|
||||
|
||||
https://www.gnu.org/licenses/gpl-faq.html
|
||||
|
||||
|
||||
Documentation
|
||||
|
@ -82,96 +84,118 @@ linux-api@vger.kernel.org.
|
|||
|
||||
Here is a list of files that are in the kernel source tree that are
|
||||
required reading:
|
||||
|
||||
README
|
||||
This file gives a short background on the Linux kernel and describes
|
||||
what is necessary to do to configure and build the kernel. People
|
||||
who are new to the kernel should start here.
|
||||
|
||||
Documentation/Changes
|
||||
:ref:`Documentation/Changes <changes>`
|
||||
This file gives a list of the minimum levels of various software
|
||||
packages that are necessary to build and run the kernel
|
||||
successfully.
|
||||
|
||||
Documentation/CodingStyle
|
||||
:ref:`Documentation/CodingStyle <codingstyle>`
|
||||
This describes the Linux kernel coding style, and some of the
|
||||
rationale behind it. All new code is expected to follow the
|
||||
guidelines in this document. Most maintainers will only accept
|
||||
patches if these rules are followed, and many people will only
|
||||
review code if it is in the proper style.
|
||||
|
||||
Documentation/SubmittingPatches
|
||||
Documentation/SubmittingDrivers
|
||||
:ref:`Documentation/SubmittingPatches <submittingpatches>` and :ref:`Documentation/SubmittingDrivers <submittingdrivers>`
|
||||
These files describe in explicit detail how to successfully create
|
||||
and send a patch, including (but not limited to):
|
||||
|
||||
- Email contents
|
||||
- Email format
|
||||
- Who to send it to
|
||||
|
||||
Following these rules will not guarantee success (as all patches are
|
||||
subject to scrutiny for content and style), but not following them
|
||||
will almost always prevent it.
|
||||
|
||||
Other excellent descriptions of how to create patches properly are:
|
||||
|
||||
"The Perfect Patch"
|
||||
http://www.ozlabs.org/~akpm/stuff/tpp.txt
|
||||
https://www.ozlabs.org/~akpm/stuff/tpp.txt
|
||||
|
||||
"Linux kernel patch submission format"
|
||||
http://linux.yyz.us/patch-format.html
|
||||
|
||||
Documentation/stable_api_nonsense.txt
|
||||
:ref:`Documentation/stable_api_nonsense.txt <stable_api_nonsense>`
|
||||
This file describes the rationale behind the conscious decision to
|
||||
not have a stable API within the kernel, including things like:
|
||||
|
||||
- Subsystem shim-layers (for compatibility?)
|
||||
- Driver portability between Operating Systems.
|
||||
- Mitigating rapid change within the kernel source tree (or
|
||||
preventing rapid change)
|
||||
|
||||
This document is crucial for understanding the Linux development
|
||||
philosophy and is very important for people moving to Linux from
|
||||
development on other Operating Systems.
|
||||
|
||||
Documentation/SecurityBugs
|
||||
:ref:`Documentation/SecurityBugs <securitybugs>`
|
||||
If you feel you have found a security problem in the Linux kernel,
|
||||
please follow the steps in this document to help notify the kernel
|
||||
developers, and help solve the issue.
|
||||
|
||||
Documentation/ManagementStyle
|
||||
:ref:`Documentation/ManagementStyle <managementstyle>`
|
||||
This document describes how Linux kernel maintainers operate and the
|
||||
shared ethos behind their methodologies. This is important reading
|
||||
for anyone new to kernel development (or anyone simply curious about
|
||||
it), as it resolves a lot of common misconceptions and confusion
|
||||
about the unique behavior of kernel maintainers.
|
||||
|
||||
Documentation/stable_kernel_rules.txt
|
||||
:ref:`Documentation/stable_kernel_rules.txt <stable_kernel_rules>`
|
||||
This file describes the rules on how the stable kernel releases
|
||||
happen, and what to do if you want to get a change into one of these
|
||||
releases.
|
||||
|
||||
Documentation/kernel-docs.txt
|
||||
:ref:`Documentation/kernel-docs.txt <kernel_docs>`
|
||||
A list of external documentation that pertains to kernel
|
||||
development. Please consult this list if you do not find what you
|
||||
are looking for within the in-kernel documentation.
|
||||
|
||||
Documentation/applying-patches.txt
|
||||
:ref:`Documentation/applying-patches.txt <applying_patches>`
|
||||
A good introduction describing exactly what a patch is and how to
|
||||
apply it to the different development branches of the kernel.
|
||||
|
||||
The kernel also has a large number of documents that can be
|
||||
automatically generated from the source code itself. This includes a
|
||||
automatically generated from the source code itself or from
|
||||
ReStructuredText markups (ReST), like this one. This includes a
|
||||
full description of the in-kernel API, and rules on how to handle
|
||||
locking properly. The documents will be created in the
|
||||
Documentation/DocBook/ directory and can be generated as PDF,
|
||||
Postscript, HTML, and man pages by running:
|
||||
locking properly.
|
||||
|
||||
All such documents can be generated as PDF or HTML by running::
|
||||
|
||||
make pdfdocs
|
||||
make psdocs
|
||||
make htmldocs
|
||||
make mandocs
|
||||
|
||||
respectively from the main kernel source directory.
|
||||
|
||||
The documents that uses ReST markup will be generated at Documentation/output.
|
||||
They can also be generated on LaTeX and ePub formats with::
|
||||
|
||||
make latexdocs
|
||||
make epubdocs
|
||||
|
||||
Currently, there are some documents written on DocBook that are in
|
||||
the process of conversion to ReST. Such documents will be created in the
|
||||
Documentation/DocBook/ directory and can be generated also as
|
||||
Postscript or man pages by running::
|
||||
|
||||
make psdocs
|
||||
make mandocs
|
||||
|
||||
Becoming A Kernel Developer
|
||||
---------------------------
|
||||
|
||||
If you do not know anything about Linux kernel development, you should
|
||||
look at the Linux KernelNewbies project:
|
||||
http://kernelnewbies.org
|
||||
|
||||
https://kernelnewbies.org
|
||||
|
||||
It consists of a helpful mailing list where you can ask almost any type
|
||||
of basic kernel development question (make sure to search the archives
|
||||
first, before asking something that has already been answered in the
|
||||
|
@ -187,7 +211,9 @@ apply a patch.
|
|||
If you do not know where you want to start, but you want to look for
|
||||
some task to start doing to join into the kernel development community,
|
||||
go to the Linux Kernel Janitor's project:
|
||||
http://kernelnewbies.org/KernelJanitors
|
||||
|
||||
https://kernelnewbies.org/KernelJanitors
|
||||
|
||||
It is a great place to start. It describes a list of relatively simple
|
||||
problems that need to be cleaned up and fixed within the Linux kernel
|
||||
source tree. Working with the developers in charge of this project, you
|
||||
|
@ -199,7 +225,8 @@ If you already have a chunk of code that you want to put into the kernel
|
|||
tree, but need some help getting it in the proper form, the
|
||||
kernel-mentors project was created to help you out with this. It is a
|
||||
mailing list, and can be found at:
|
||||
http://selenic.com/mailman/listinfo/kernel-mentors
|
||||
|
||||
https://selenic.com/mailman/listinfo/kernel-mentors
|
||||
|
||||
Before making any actual modifications to the Linux kernel code, it is
|
||||
imperative to understand how the code in question works. For this
|
||||
|
@ -209,6 +236,7 @@ tools. One such tool that is particularly recommended is the Linux
|
|||
Cross-Reference project, which is able to present source code in a
|
||||
self-referential, indexed webpage format. An excellent up-to-date
|
||||
repository of the kernel code may be found at:
|
||||
|
||||
http://lxr.free-electrons.com/
|
||||
|
||||
|
||||
|
@ -218,6 +246,7 @@ The development process
|
|||
Linux kernel development process currently consists of a few different
|
||||
main kernel "branches" and lots of different subsystem-specific kernel
|
||||
branches. These different branches are:
|
||||
|
||||
- main 4.x kernel tree
|
||||
- 4.x.y -stable kernel tree
|
||||
- 4.x -git kernel patches
|
||||
|
@ -227,14 +256,15 @@ branches. These different branches are:
|
|||
4.x kernel tree
|
||||
-----------------
|
||||
4.x kernels are maintained by Linus Torvalds, and can be found on
|
||||
kernel.org in the pub/linux/kernel/v4.x/ directory. Its development
|
||||
https://kernel.org in the pub/linux/kernel/v4.x/ directory. Its development
|
||||
process is as follows:
|
||||
|
||||
- As soon as a new kernel is released a two weeks window is open,
|
||||
during this period of time maintainers can submit big diffs to
|
||||
Linus, usually the patches that have already been included in the
|
||||
-next kernel for a few weeks. The preferred way to submit big changes
|
||||
is using git (the kernel's source management tool, more information
|
||||
can be found at http://git-scm.com/) but plain patches are also just
|
||||
can be found at https://git-scm.com/) but plain patches are also just
|
||||
fine.
|
||||
- After two weeks a -rc1 kernel is released it is now possible to push
|
||||
only patches that do not include new features that could affect the
|
||||
|
@ -253,9 +283,10 @@ process is as follows:
|
|||
|
||||
It is worth mentioning what Andrew Morton wrote on the linux-kernel
|
||||
mailing list about kernel releases:
|
||||
"Nobody knows when a kernel will be released, because it's
|
||||
|
||||
*"Nobody knows when a kernel will be released, because it's
|
||||
released according to perceived bug status, not according to a
|
||||
preconceived timeline."
|
||||
preconceived timeline."*
|
||||
|
||||
4.x.y -stable kernel tree
|
||||
-------------------------
|
||||
|
@ -301,7 +332,7 @@ submission and other already ongoing work are avoided.
|
|||
Most of these repositories are git trees, but there are also other SCMs
|
||||
in use, or patch queues being published as quilt series. Addresses of
|
||||
these subsystem repositories are listed in the MAINTAINERS file. Many
|
||||
of them can be browsed at http://git.kernel.org/.
|
||||
of them can be browsed at https://git.kernel.org/.
|
||||
|
||||
Before a proposed patch is committed to such a subsystem tree, it is
|
||||
subject to review which primarily happens on mailing lists (see the
|
||||
|
@ -310,7 +341,7 @@ process is tracked with the tool patchwork. Patchwork offers a web
|
|||
interface which shows patch postings, any comments on a patch or
|
||||
revisions to it, and maintainers can mark patches as under review,
|
||||
accepted, or rejected. Most of these patchwork sites are listed at
|
||||
http://patchwork.kernel.org/.
|
||||
https://patchwork.kernel.org/.
|
||||
|
||||
4.x -next kernel tree for integration tests
|
||||
-------------------------------------------
|
||||
|
@ -318,7 +349,8 @@ Before updates from subsystem trees are merged into the mainline 4.x
|
|||
tree, they need to be integration-tested. For this purpose, a special
|
||||
testing repository exists into which virtually all subsystem trees are
|
||||
pulled on an almost daily basis:
|
||||
http://git.kernel.org/?p=linux/kernel/git/next/linux-next.git
|
||||
|
||||
https://git.kernel.org/?p=linux/kernel/git/next/linux-next.git
|
||||
|
||||
This way, the -next kernel gives a summary outlook onto what will be
|
||||
expected to go into the mainline kernel at the next merge period.
|
||||
|
@ -328,10 +360,11 @@ Adventurous testers are very welcome to runtime-test the -next kernel.
|
|||
Bug Reporting
|
||||
-------------
|
||||
|
||||
bugzilla.kernel.org is where the Linux kernel developers track kernel
|
||||
https://bugzilla.kernel.org is where the Linux kernel developers track kernel
|
||||
bugs. Users are encouraged to report all bugs that they find in this
|
||||
tool. For details on how to use the kernel bugzilla, please see:
|
||||
http://bugzilla.kernel.org/page.cgi?id=faq.html
|
||||
|
||||
https://bugzilla.kernel.org/page.cgi?id=faq.html
|
||||
|
||||
The file REPORTING-BUGS in the main kernel source directory has a good
|
||||
template for how to report a possible kernel bug, and details what kind
|
||||
|
@ -349,13 +382,14 @@ your skills, and other developers will be aware of your presence. Fixing
|
|||
bugs is one of the best ways to get merits among other developers, because
|
||||
not many people like wasting time fixing other people's bugs.
|
||||
|
||||
To work in the already reported bug reports, go to http://bugzilla.kernel.org.
|
||||
To work in the already reported bug reports, go to https://bugzilla.kernel.org.
|
||||
If you want to be advised of the future bug reports, you can subscribe to the
|
||||
bugme-new mailing list (only new bug reports are mailed here) or to the
|
||||
bugme-janitor mailing list (every change in the bugzilla is mailed here)
|
||||
|
||||
http://lists.linux-foundation.org/mailman/listinfo/bugme-new
|
||||
http://lists.linux-foundation.org/mailman/listinfo/bugme-janitors
|
||||
https://lists.linux-foundation.org/mailman/listinfo/bugme-new
|
||||
|
||||
https://lists.linux-foundation.org/mailman/listinfo/bugme-janitors
|
||||
|
||||
|
||||
|
||||
|
@ -365,10 +399,14 @@ Mailing lists
|
|||
As some of the above documents describe, the majority of the core kernel
|
||||
developers participate on the Linux Kernel Mailing list. Details on how
|
||||
to subscribe and unsubscribe from the list can be found at:
|
||||
|
||||
http://vger.kernel.org/vger-lists.html#linux-kernel
|
||||
|
||||
There are archives of the mailing list on the web in many different
|
||||
places. Use a search engine to find these archives. For example:
|
||||
|
||||
http://dir.gmane.org/gmane.linux.kernel
|
||||
|
||||
It is highly recommended that you search the archives about the topic
|
||||
you want to bring up, before you post it to the list. A lot of things
|
||||
already discussed in detail are only recorded at the mailing list
|
||||
|
@ -381,11 +419,13 @@ groups.
|
|||
|
||||
Many of the lists are hosted on kernel.org. Information on them can be
|
||||
found at:
|
||||
|
||||
http://vger.kernel.org/vger-lists.html
|
||||
|
||||
Please remember to follow good behavioral habits when using the lists.
|
||||
Though a bit cheesy, the following URL has some simple guidelines for
|
||||
interacting with the list (or any list):
|
||||
|
||||
http://www.albion.com/netiquette/
|
||||
|
||||
If multiple people respond to your mail, the CC: list of recipients may
|
||||
|
@ -400,13 +440,14 @@ add your statements between the individual quoted sections instead of
|
|||
writing at the top of the mail.
|
||||
|
||||
If you add patches to your mail, make sure they are plain readable text
|
||||
as stated in Documentation/SubmittingPatches. Kernel developers don't
|
||||
want to deal with attachments or compressed patches; they may want
|
||||
to comment on individual lines of your patch, which works only that way.
|
||||
Make sure you use a mail program that does not mangle spaces and tab
|
||||
characters. A good first test is to send the mail to yourself and try
|
||||
to apply your own patch by yourself. If that doesn't work, get your
|
||||
mail program fixed or change it until it works.
|
||||
as stated in Documentation/SubmittingPatches.
|
||||
Kernel developers don't want to deal with
|
||||
attachments or compressed patches; they may want to comment on
|
||||
individual lines of your patch, which works only that way. Make sure you
|
||||
use a mail program that does not mangle spaces and tab characters. A
|
||||
good first test is to send the mail to yourself and try to apply your
|
||||
own patch by yourself. If that doesn't work, get your mail program fixed
|
||||
or change it until it works.
|
||||
|
||||
Above all, please remember to show respect to other subscribers.
|
||||
|
||||
|
@ -418,6 +459,7 @@ The goal of the kernel community is to provide the best possible kernel
|
|||
there is. When you submit a patch for acceptance, it will be reviewed
|
||||
on its technical merits and those alone. So, what should you be
|
||||
expecting?
|
||||
|
||||
- criticism
|
||||
- comments
|
||||
- requests for change
|
||||
|
@ -432,6 +474,7 @@ If there are no responses to your posting, wait a few days and try
|
|||
again, sometimes things get lost in the huge volume.
|
||||
|
||||
What should you not do?
|
||||
|
||||
- expect your patch to be accepted without question
|
||||
- become defensive
|
||||
- ignore comments
|
||||
|
@ -445,8 +488,8 @@ Remember, being wrong is acceptable as long as you are willing to work
|
|||
toward a solution that is right.
|
||||
|
||||
It is normal that the answers to your first patch might simply be a list
|
||||
of a dozen things you should correct. This does _not_ imply that your
|
||||
patch will not be accepted, and it is _not_ meant against you
|
||||
of a dozen things you should correct. This does **not** imply that your
|
||||
patch will not be accepted, and it is **not** meant against you
|
||||
personally. Simply correct all issues raised against your patch and
|
||||
resend it.
|
||||
|
||||
|
@ -457,7 +500,9 @@ Differences between the kernel community and corporate structures
|
|||
The kernel community works differently than most traditional corporate
|
||||
development environments. Here are a list of things that you can try to
|
||||
do to avoid problems:
|
||||
|
||||
Good things to say regarding your proposed changes:
|
||||
|
||||
- "This solves multiple problems."
|
||||
- "This deletes 2000 lines of code."
|
||||
- "Here is a patch that explains what I am trying to describe."
|
||||
|
@ -466,6 +511,7 @@ do to avoid problems:
|
|||
- "This increases performance on typical machines..."
|
||||
|
||||
Bad things you should avoid saying:
|
||||
|
||||
- "We did it this way in AIX/ptx/Solaris, so therefore it must be
|
||||
good..."
|
||||
- "I've being doing this for 20 years, so..."
|
||||
|
@ -527,17 +573,18 @@ The reasons for breaking things up are the following:
|
|||
and simplify (or simply re-order) patches before submitting them.
|
||||
|
||||
Here is an analogy from kernel developer Al Viro:
|
||||
"Think of a teacher grading homework from a math student. The
|
||||
|
||||
*"Think of a teacher grading homework from a math student. The
|
||||
teacher does not want to see the student's trials and errors
|
||||
before they came up with the solution. They want to see the
|
||||
cleanest, most elegant answer. A good student knows this, and
|
||||
would never submit her intermediate work before the final
|
||||
solution."
|
||||
solution.*
|
||||
|
||||
The same is true of kernel development. The maintainers and
|
||||
*The same is true of kernel development. The maintainers and
|
||||
reviewers do not want to see the thought process behind the
|
||||
solution to the problem one is solving. They want to see a
|
||||
simple and elegant solution."
|
||||
simple and elegant solution."*
|
||||
|
||||
It may be challenging to keep the balance between presenting an elegant
|
||||
solution and working together with the community and discussing your
|
||||
|
@ -565,6 +612,7 @@ When sending in your patches, pay special attention to what you say in
|
|||
the text in your email. This information will become the ChangeLog
|
||||
information for the patch, and will be preserved for everyone to see for
|
||||
all time. It should describe the patch completely, containing:
|
||||
|
||||
- why the change is necessary
|
||||
- the overall design approach in the patch
|
||||
- implementation details
|
||||
|
@ -572,12 +620,11 @@ all time. It should describe the patch completely, containing:
|
|||
|
||||
For more details on what this should all look like, please see the
|
||||
ChangeLog section of the document:
|
||||
|
||||
"The Perfect Patch"
|
||||
http://www.ozlabs.org/~akpm/stuff/tpp.txt
|
||||
|
||||
|
||||
|
||||
|
||||
All of these things are sometimes very hard to do. It can take years to
|
||||
perfect these practices (if at all). It's a continuous process of
|
||||
improvement that requires a lot of patience and determination. But
|
||||
|
@ -588,8 +635,9 @@ start exactly where you are now.
|
|||
|
||||
|
||||
----------
|
||||
|
||||
Thanks to Paolo Ciarrocchi who allowed the "Development Process"
|
||||
(http://lwn.net/Articles/94386/) section
|
||||
(https://lwn.net/Articles/94386/) section
|
||||
to be based on text he had written, and to Randy Dunlap and Gerrit
|
||||
Huizenga for some of the list of things you should and should not say.
|
||||
Also thanks to Pat Mochel, Hanna Linder, Randy Dunlap, Kay Sievers,
|
||||
|
|
|
@ -5,6 +5,9 @@
|
|||
# You can set these variables from the command line.
|
||||
SPHINXBUILD = sphinx-build
|
||||
SPHINXOPTS =
|
||||
SPHINXDIRS = .
|
||||
_SPHINXDIRS = $(patsubst $(srctree)/Documentation/%/conf.py,%,$(wildcard $(srctree)/Documentation/*/conf.py))
|
||||
SPHINX_CONF = conf.py
|
||||
PAPER =
|
||||
BUILDDIR = $(obj)/output
|
||||
|
||||
|
@ -25,38 +28,62 @@ else ifneq ($(DOCBOOKS),)
|
|||
|
||||
else # HAVE_SPHINX
|
||||
|
||||
# User-friendly check for rst2pdf
|
||||
HAVE_RST2PDF := $(shell if python -c "import rst2pdf" >/dev/null 2>&1; then echo 1; else echo 0; fi)
|
||||
# User-friendly check for pdflatex
|
||||
HAVE_PDFLATEX := $(shell if which xelatex >/dev/null 2>&1; then echo 1; else echo 0; fi)
|
||||
|
||||
# Internal variables.
|
||||
PAPEROPT_a4 = -D latex_paper_size=a4
|
||||
PAPEROPT_letter = -D latex_paper_size=letter
|
||||
KERNELDOC = $(srctree)/scripts/kernel-doc
|
||||
KERNELDOC_CONF = -D kerneldoc_srctree=$(srctree) -D kerneldoc_bin=$(KERNELDOC)
|
||||
ALLSPHINXOPTS = -D version=$(KERNELVERSION) -D release=$(KERNELRELEASE) -d $(BUILDDIR)/.doctrees $(KERNELDOC_CONF) $(PAPEROPT_$(PAPER)) -c $(srctree)/$(src) $(SPHINXOPTS) $(srctree)/$(src)
|
||||
ALLSPHINXOPTS = $(KERNELDOC_CONF) $(PAPEROPT_$(PAPER)) $(SPHINXOPTS)
|
||||
# the i18n builder cannot share the environment and doctrees with the others
|
||||
I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
|
||||
|
||||
quiet_cmd_sphinx = SPHINX $@
|
||||
cmd_sphinx = BUILDDIR=$(BUILDDIR) $(SPHINXBUILD) -b $2 $(ALLSPHINXOPTS) $(BUILDDIR)/$2
|
||||
# commands; the 'cmd' from scripts/Kbuild.include is not *loopable*
|
||||
loop_cmd = $(echo-cmd) $(cmd_$(1))
|
||||
|
||||
# $2 sphinx builder e.g. "html"
|
||||
# $3 name of the build subfolder / e.g. "media", used as:
|
||||
# * dest folder relative to $(BUILDDIR) and
|
||||
# * cache folder relative to $(BUILDDIR)/.doctrees
|
||||
# $4 dest subfolder e.g. "man" for man pages at media/man
|
||||
# $5 reST source folder relative to $(srctree)/$(src),
|
||||
# e.g. "media" for the linux-tv book-set at ./Documentation/media
|
||||
|
||||
quiet_cmd_sphinx = SPHINX $@ --> file://$(abspath $(BUILDDIR)/$3/$4);
|
||||
cmd_sphinx = $(MAKE) BUILDDIR=$(abspath $(BUILDDIR)) $(build)=Documentation/media all;\
|
||||
BUILDDIR=$(abspath $(BUILDDIR)) SPHINX_CONF=$(abspath $(srctree)/$(src)/$5/$(SPHINX_CONF)) \
|
||||
$(SPHINXBUILD) \
|
||||
-b $2 \
|
||||
-c $(abspath $(srctree)/$(src)) \
|
||||
-d $(abspath $(BUILDDIR)/.doctrees/$3) \
|
||||
-D version=$(KERNELVERSION) -D release=$(KERNELRELEASE) \
|
||||
$(ALLSPHINXOPTS) \
|
||||
$(abspath $(srctree)/$(src)/$5) \
|
||||
$(abspath $(BUILDDIR)/$3/$4);
|
||||
|
||||
htmldocs:
|
||||
$(MAKE) BUILDDIR=$(BUILDDIR) -f $(srctree)/Documentation/media/Makefile $@
|
||||
$(call cmd,sphinx,html)
|
||||
@$(foreach var,$(SPHINXDIRS),$(call loop_cmd,sphinx,html,$(var),,$(var)))
|
||||
|
||||
pdfdocs:
|
||||
ifeq ($(HAVE_RST2PDF),0)
|
||||
$(warning The Python 'rst2pdf' module was not found. Make sure you have the module installed to produce PDF output.)
|
||||
latexdocs:
|
||||
ifeq ($(HAVE_PDFLATEX),0)
|
||||
$(warning The 'xelatex' command was not found. Make sure you have it installed and in PATH to produce PDF output.)
|
||||
@echo " SKIP Sphinx $@ target."
|
||||
else # HAVE_RST2PDF
|
||||
$(call cmd,sphinx,pdf)
|
||||
endif # HAVE_RST2PDF
|
||||
else # HAVE_PDFLATEX
|
||||
@$(foreach var,$(SPHINXDIRS),$(call loop_cmd,sphinx,latex,$(var),latex,$(var)))
|
||||
endif # HAVE_PDFLATEX
|
||||
|
||||
pdfdocs: latexdocs
|
||||
ifneq ($(HAVE_PDFLATEX),0)
|
||||
$(foreach var,$(SPHINXDIRS), $(MAKE) PDFLATEX=xelatex LATEXOPTS="-interaction=nonstopmode" -C $(BUILDDIR)/$(var)/latex)
|
||||
endif # HAVE_PDFLATEX
|
||||
|
||||
epubdocs:
|
||||
$(call cmd,sphinx,epub)
|
||||
@$(foreach var,$(SPHINXDIRS),$(call loop_cmd,sphinx,epub,$(var),epub,$(var)))
|
||||
|
||||
xmldocs:
|
||||
$(call cmd,sphinx,xml)
|
||||
@$(foreach var,$(SPHINXDIRS),$(call loop_cmd,sphinx,xml,$(var),xml,$(var)))
|
||||
|
||||
# no-ops for the Sphinx toolchain
|
||||
sgmldocs:
|
||||
|
@ -72,7 +99,14 @@ endif # HAVE_SPHINX
|
|||
dochelp:
|
||||
@echo ' Linux kernel internal documentation in different formats (Sphinx):'
|
||||
@echo ' htmldocs - HTML'
|
||||
@echo ' latexdocs - LaTeX'
|
||||
@echo ' pdfdocs - PDF'
|
||||
@echo ' epubdocs - EPUB'
|
||||
@echo ' xmldocs - XML'
|
||||
@echo ' cleandocs - clean all generated files'
|
||||
@echo
|
||||
@echo ' make SPHINXDIRS="s1 s2" [target] Generate only docs of folder s1, s2'
|
||||
@echo ' valid values for SPHINXDIRS are: $(_SPHINXDIRS)'
|
||||
@echo
|
||||
@echo ' make SPHINX_CONF={conf-file} [target] use *additional* sphinx-build'
|
||||
@echo ' configuration. This is e.g. useful to build with nit-picking config.'
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
.. _managementstyle:
|
||||
|
||||
Linux kernel management style
|
||||
Linux kernel management style
|
||||
=============================
|
||||
|
||||
This is a short document describing the preferred (or made up, depending
|
||||
on who you ask) management style for the linux kernel. It's meant to
|
||||
mirror the CodingStyle document to some degree, and mainly written to
|
||||
avoid answering (*) the same (or similar) questions over and over again.
|
||||
avoid answering [#f1]_ the same (or similar) questions over and over again.
|
||||
|
||||
Management style is very personal and much harder to quantify than
|
||||
simple coding style rules, so this document may or may not have anything
|
||||
|
@ -14,50 +16,52 @@ might not actually be true. You'll have to decide for yourself.
|
|||
Btw, when talking about "kernel manager", it's all about the technical
|
||||
lead persons, not the people who do traditional management inside
|
||||
companies. If you sign purchase orders or you have any clue about the
|
||||
budget of your group, you're almost certainly not a kernel manager.
|
||||
These suggestions may or may not apply to you.
|
||||
budget of your group, you're almost certainly not a kernel manager.
|
||||
These suggestions may or may not apply to you.
|
||||
|
||||
First off, I'd suggest buying "Seven Habits of Highly Effective
|
||||
People", and NOT read it. Burn it, it's a great symbolic gesture.
|
||||
People", and NOT read it. Burn it, it's a great symbolic gesture.
|
||||
|
||||
(*) This document does so not so much by answering the question, but by
|
||||
making it painfully obvious to the questioner that we don't have a clue
|
||||
to what the answer is.
|
||||
.. [#f1] This document does so not so much by answering the question, but by
|
||||
making it painfully obvious to the questioner that we don't have a clue
|
||||
to what the answer is.
|
||||
|
||||
Anyway, here goes:
|
||||
|
||||
.. _decisions:
|
||||
|
||||
Chapter 1: Decisions
|
||||
1) Decisions
|
||||
------------
|
||||
|
||||
Everybody thinks managers make decisions, and that decision-making is
|
||||
important. The bigger and more painful the decision, the bigger the
|
||||
manager must be to make it. That's very deep and obvious, but it's not
|
||||
actually true.
|
||||
actually true.
|
||||
|
||||
The name of the game is to _avoid_ having to make a decision. In
|
||||
The name of the game is to **avoid** having to make a decision. In
|
||||
particular, if somebody tells you "choose (a) or (b), we really need you
|
||||
to decide on this", you're in trouble as a manager. The people you
|
||||
manage had better know the details better than you, so if they come to
|
||||
you for a technical decision, you're screwed. You're clearly not
|
||||
competent to make that decision for them.
|
||||
competent to make that decision for them.
|
||||
|
||||
(Corollary:if the people you manage don't know the details better than
|
||||
you, you're also screwed, although for a totally different reason.
|
||||
Namely that you are in the wrong job, and that _they_ should be managing
|
||||
your brilliance instead).
|
||||
you, you're also screwed, although for a totally different reason.
|
||||
Namely that you are in the wrong job, and that **they** should be managing
|
||||
your brilliance instead).
|
||||
|
||||
So the name of the game is to _avoid_ decisions, at least the big and
|
||||
So the name of the game is to **avoid** decisions, at least the big and
|
||||
painful ones. Making small and non-consequential decisions is fine, and
|
||||
makes you look like you know what you're doing, so what a kernel manager
|
||||
needs to do is to turn the big and painful ones into small things where
|
||||
nobody really cares.
|
||||
nobody really cares.
|
||||
|
||||
It helps to realize that the key difference between a big decision and a
|
||||
small one is whether you can fix your decision afterwards. Any decision
|
||||
can be made small by just always making sure that if you were wrong (and
|
||||
you _will_ be wrong), you can always undo the damage later by
|
||||
you **will** be wrong), you can always undo the damage later by
|
||||
backtracking. Suddenly, you get to be doubly managerial for making
|
||||
_two_ inconsequential decisions - the wrong one _and_ the right one.
|
||||
**two** inconsequential decisions - the wrong one **and** the right one.
|
||||
|
||||
And people will even see that as true leadership (*cough* bullshit
|
||||
*cough*).
|
||||
|
@ -65,10 +69,10 @@ And people will even see that as true leadership (*cough* bullshit
|
|||
Thus the key to avoiding big decisions becomes to just avoiding to do
|
||||
things that can't be undone. Don't get ushered into a corner from which
|
||||
you cannot escape. A cornered rat may be dangerous - a cornered manager
|
||||
is just pitiful.
|
||||
is just pitiful.
|
||||
|
||||
It turns out that since nobody would be stupid enough to ever really let
|
||||
a kernel manager have huge fiscal responsibility _anyway_, it's usually
|
||||
a kernel manager have huge fiscal responsibility **anyway**, it's usually
|
||||
fairly easy to backtrack. Since you're not going to be able to waste
|
||||
huge amounts of money that you might not be able to repay, the only
|
||||
thing you can backtrack on is a technical decision, and there
|
||||
|
@ -76,113 +80,118 @@ back-tracking is very easy: just tell everybody that you were an
|
|||
incompetent nincompoop, say you're sorry, and undo all the worthless
|
||||
work you had people work on for the last year. Suddenly the decision
|
||||
you made a year ago wasn't a big decision after all, since it could be
|
||||
easily undone.
|
||||
easily undone.
|
||||
|
||||
It turns out that some people have trouble with this approach, for two
|
||||
reasons:
|
||||
|
||||
- admitting you were an idiot is harder than it looks. We all like to
|
||||
maintain appearances, and coming out in public to say that you were
|
||||
wrong is sometimes very hard indeed.
|
||||
wrong is sometimes very hard indeed.
|
||||
- having somebody tell you that what you worked on for the last year
|
||||
wasn't worthwhile after all can be hard on the poor lowly engineers
|
||||
too, and while the actual _work_ was easy enough to undo by just
|
||||
too, and while the actual **work** was easy enough to undo by just
|
||||
deleting it, you may have irrevocably lost the trust of that
|
||||
engineer. And remember: "irrevocable" was what we tried to avoid in
|
||||
the first place, and your decision ended up being a big one after
|
||||
all.
|
||||
all.
|
||||
|
||||
Happily, both of these reasons can be mitigated effectively by just
|
||||
admitting up-front that you don't have a friggin' clue, and telling
|
||||
people ahead of the fact that your decision is purely preliminary, and
|
||||
might be the wrong thing. You should always reserve the right to change
|
||||
your mind, and make people very _aware_ of that. And it's much easier
|
||||
to admit that you are stupid when you haven't _yet_ done the really
|
||||
your mind, and make people very **aware** of that. And it's much easier
|
||||
to admit that you are stupid when you haven't **yet** done the really
|
||||
stupid thing.
|
||||
|
||||
Then, when it really does turn out to be stupid, people just roll their
|
||||
eyes and say "Oops, he did it again".
|
||||
eyes and say "Oops, he did it again".
|
||||
|
||||
This preemptive admission of incompetence might also make the people who
|
||||
actually do the work also think twice about whether it's worth doing or
|
||||
not. After all, if _they_ aren't certain whether it's a good idea, you
|
||||
not. After all, if **they** aren't certain whether it's a good idea, you
|
||||
sure as hell shouldn't encourage them by promising them that what they
|
||||
work on will be included. Make them at least think twice before they
|
||||
embark on a big endeavor.
|
||||
embark on a big endeavor.
|
||||
|
||||
Remember: they'd better know more about the details than you do, and
|
||||
they usually already think they have the answer to everything. The best
|
||||
thing you can do as a manager is not to instill confidence, but rather a
|
||||
healthy dose of critical thinking on what they do.
|
||||
healthy dose of critical thinking on what they do.
|
||||
|
||||
Btw, another way to avoid a decision is to plaintively just whine "can't
|
||||
we just do both?" and look pitiful. Trust me, it works. If it's not
|
||||
clear which approach is better, they'll eventually figure it out. The
|
||||
answer may end up being that both teams get so frustrated by the
|
||||
situation that they just give up.
|
||||
situation that they just give up.
|
||||
|
||||
That may sound like a failure, but it's usually a sign that there was
|
||||
something wrong with both projects, and the reason the people involved
|
||||
couldn't decide was that they were both wrong. You end up coming up
|
||||
smelling like roses, and you avoided yet another decision that you could
|
||||
have screwed up on.
|
||||
have screwed up on.
|
||||
|
||||
|
||||
Chapter 2: People
|
||||
2) People
|
||||
---------
|
||||
|
||||
Most people are idiots, and being a manager means you'll have to deal
|
||||
with it, and perhaps more importantly, that _they_ have to deal with
|
||||
_you_.
|
||||
with it, and perhaps more importantly, that **they** have to deal with
|
||||
**you**.
|
||||
|
||||
It turns out that while it's easy to undo technical mistakes, it's not
|
||||
as easy to undo personality disorders. You just have to live with
|
||||
theirs - and yours.
|
||||
theirs - and yours.
|
||||
|
||||
However, in order to prepare yourself as a kernel manager, it's best to
|
||||
remember not to burn any bridges, bomb any innocent villagers, or
|
||||
alienate too many kernel developers. It turns out that alienating people
|
||||
is fairly easy, and un-alienating them is hard. Thus "alienating"
|
||||
immediately falls under the heading of "not reversible", and becomes a
|
||||
no-no according to Chapter 1.
|
||||
no-no according to :ref:`decisions`.
|
||||
|
||||
There's just a few simple rules here:
|
||||
|
||||
(1) don't call people d*ckheads (at least not in public)
|
||||
(2) learn how to apologize when you forgot rule (1)
|
||||
|
||||
The problem with #1 is that it's very easy to do, since you can say
|
||||
"you're a d*ckhead" in millions of different ways (*), sometimes without
|
||||
"you're a d*ckhead" in millions of different ways [#f2]_, sometimes without
|
||||
even realizing it, and almost always with a white-hot conviction that
|
||||
you are right.
|
||||
you are right.
|
||||
|
||||
And the more convinced you are that you are right (and let's face it,
|
||||
you can call just about _anybody_ a d*ckhead, and you often _will_ be
|
||||
right), the harder it ends up being to apologize afterwards.
|
||||
you can call just about **anybody** a d*ckhead, and you often **will** be
|
||||
right), the harder it ends up being to apologize afterwards.
|
||||
|
||||
To solve this problem, you really only have two options:
|
||||
|
||||
- get really good at apologies
|
||||
- spread the "love" out so evenly that nobody really ends up feeling
|
||||
like they get unfairly targeted. Make it inventive enough, and they
|
||||
might even be amused.
|
||||
might even be amused.
|
||||
|
||||
The option of being unfailingly polite really doesn't exist. Nobody will
|
||||
trust somebody who is so clearly hiding his true character.
|
||||
|
||||
(*) Paul Simon sang "Fifty Ways to Leave Your Lover", because quite
|
||||
frankly, "A Million Ways to Tell a Developer He Is a D*ckhead" doesn't
|
||||
scan nearly as well. But I'm sure he thought about it.
|
||||
.. [#f2] Paul Simon sang "Fifty Ways to Leave Your Lover", because quite
|
||||
frankly, "A Million Ways to Tell a Developer He Is a D*ckhead" doesn't
|
||||
scan nearly as well. But I'm sure he thought about it.
|
||||
|
||||
|
||||
Chapter 3: People II - the Good Kind
|
||||
3) People II - the Good Kind
|
||||
----------------------------
|
||||
|
||||
While it turns out that most people are idiots, the corollary to that is
|
||||
sadly that you are one too, and that while we can all bask in the secure
|
||||
knowledge that we're better than the average person (let's face it,
|
||||
nobody ever believes that they're average or below-average), we should
|
||||
also admit that we're not the sharpest knife around, and there will be
|
||||
other people that are less of an idiot than you are.
|
||||
other people that are less of an idiot than you are.
|
||||
|
||||
Some people react badly to smart people. Others take advantage of them.
|
||||
Some people react badly to smart people. Others take advantage of them.
|
||||
|
||||
Make sure that you, as a kernel maintainer, are in the second group.
|
||||
Make sure that you, as a kernel maintainer, are in the second group.
|
||||
Suck up to them, because they are the people who will make your job
|
||||
easier. In particular, they'll be able to make your decisions for you,
|
||||
which is what the game is all about.
|
||||
|
@ -191,7 +200,7 @@ So when you find somebody smarter than you are, just coast along. Your
|
|||
management responsibilities largely become ones of saying "Sounds like a
|
||||
good idea - go wild", or "That sounds good, but what about xxx?". The
|
||||
second version in particular is a great way to either learn something
|
||||
new about "xxx" or seem _extra_ managerial by pointing out something the
|
||||
new about "xxx" or seem **extra** managerial by pointing out something the
|
||||
smarter person hadn't thought about. In either case, you win.
|
||||
|
||||
One thing to look out for is to realize that greatness in one area does
|
||||
|
@ -199,47 +208,49 @@ not necessarily translate to other areas. So you might prod people in
|
|||
specific directions, but let's face it, they might be good at what they
|
||||
do, and suck at everything else. The good news is that people tend to
|
||||
naturally gravitate back to what they are good at, so it's not like you
|
||||
are doing something irreversible when you _do_ prod them in some
|
||||
are doing something irreversible when you **do** prod them in some
|
||||
direction, just don't push too hard.
|
||||
|
||||
|
||||
Chapter 4: Placing blame
|
||||
4) Placing blame
|
||||
----------------
|
||||
|
||||
Things will go wrong, and people want somebody to blame. Tag, you're it.
|
||||
|
||||
It's not actually that hard to accept the blame, especially if people
|
||||
kind of realize that it wasn't _all_ your fault. Which brings us to the
|
||||
kind of realize that it wasn't **all** your fault. Which brings us to the
|
||||
best way of taking the blame: do it for another guy. You'll feel good
|
||||
for taking the fall, he'll feel good about not getting blamed, and the
|
||||
guy who lost his whole 36GB porn-collection because of your incompetence
|
||||
will grudgingly admit that you at least didn't try to weasel out of it.
|
||||
|
||||
Then make the developer who really screwed up (if you can find him) know
|
||||
_in_private_ that he screwed up. Not just so he can avoid it in the
|
||||
**in_private** that he screwed up. Not just so he can avoid it in the
|
||||
future, but so that he knows he owes you one. And, perhaps even more
|
||||
importantly, he's also likely the person who can fix it. Because, let's
|
||||
face it, it sure ain't you.
|
||||
face it, it sure ain't you.
|
||||
|
||||
Taking the blame is also why you get to be manager in the first place.
|
||||
Taking the blame is also why you get to be manager in the first place.
|
||||
It's part of what makes people trust you, and allow you the potential
|
||||
glory, because you're the one who gets to say "I screwed up". And if
|
||||
you've followed the previous rules, you'll be pretty good at saying that
|
||||
by now.
|
||||
by now.
|
||||
|
||||
|
||||
Chapter 5: Things to avoid
|
||||
5) Things to avoid
|
||||
------------------
|
||||
|
||||
There's one thing people hate even more than being called "d*ckhead",
|
||||
and that is being called a "d*ckhead" in a sanctimonious voice. The
|
||||
first you can apologize for, the second one you won't really get the
|
||||
chance. They likely will no longer be listening even if you otherwise
|
||||
do a good job.
|
||||
do a good job.
|
||||
|
||||
We all think we're better than anybody else, which means that when
|
||||
somebody else puts on airs, it _really_ rubs us the wrong way. You may
|
||||
somebody else puts on airs, it **really** rubs us the wrong way. You may
|
||||
be morally and intellectually superior to everybody around you, but
|
||||
don't try to make it too obvious unless you really _intend_ to irritate
|
||||
somebody (*).
|
||||
don't try to make it too obvious unless you really **intend** to irritate
|
||||
somebody [#f3]_.
|
||||
|
||||
Similarly, don't be too polite or subtle about things. Politeness easily
|
||||
ends up going overboard and hiding the problem, and as they say, "On the
|
||||
|
@ -251,15 +262,16 @@ Some humor can help pad both the bluntness and the moralizing. Going
|
|||
overboard to the point of being ridiculous can drive a point home
|
||||
without making it painful to the recipient, who just thinks you're being
|
||||
silly. It can thus help get through the personal mental block we all
|
||||
have about criticism.
|
||||
have about criticism.
|
||||
|
||||
(*) Hint: internet newsgroups that are not directly related to your work
|
||||
are great ways to take out your frustrations at other people. Write
|
||||
insulting posts with a sneer just to get into a good flame every once in
|
||||
a while, and you'll feel cleansed. Just don't crap too close to home.
|
||||
.. [#f3] Hint: internet newsgroups that are not directly related to your work
|
||||
are great ways to take out your frustrations at other people. Write
|
||||
insulting posts with a sneer just to get into a good flame every once in
|
||||
a while, and you'll feel cleansed. Just don't crap too close to home.
|
||||
|
||||
|
||||
Chapter 6: Why me?
|
||||
6) Why me?
|
||||
----------
|
||||
|
||||
Since your main responsibility seems to be to take the blame for other
|
||||
peoples mistakes, and make it painfully obvious to everybody else that
|
||||
|
@ -268,9 +280,9 @@ first place?
|
|||
|
||||
First off, while you may or may not get screaming teenage girls (or
|
||||
boys, let's not be judgmental or sexist here) knocking on your dressing
|
||||
room door, you _will_ get an immense feeling of personal accomplishment
|
||||
room door, you **will** get an immense feeling of personal accomplishment
|
||||
for being "in charge". Never mind the fact that you're really leading
|
||||
by trying to keep up with everybody else and running after them as fast
|
||||
as you can. Everybody will still think you're the person in charge.
|
||||
as you can. Everybody will still think you're the person in charge.
|
||||
|
||||
It's a great job if you can hack it.
|
||||
|
|
|
@ -1,9 +1,15 @@
|
|||
.. _securitybugs:
|
||||
|
||||
Security bugs
|
||||
=============
|
||||
|
||||
Linux kernel developers take security very seriously. As such, we'd
|
||||
like to know when a security bug is found so that it can be fixed and
|
||||
disclosed as quickly as possible. Please report security bugs to the
|
||||
Linux kernel security team.
|
||||
|
||||
1) Contact
|
||||
----------
|
||||
|
||||
The Linux kernel security team can be contacted by email at
|
||||
<security@kernel.org>. This is a private list of security officers
|
||||
|
@ -18,6 +24,7 @@ Any exploit code is very helpful and will not be released without
|
|||
consent from the reporter unless it has already been made public.
|
||||
|
||||
2) Disclosure
|
||||
-------------
|
||||
|
||||
The goal of the Linux kernel security team is to work with the
|
||||
bug submitter to bug resolution as well as disclosure. We prefer
|
||||
|
@ -33,6 +40,7 @@ to a few weeks. As a basic default policy, we expect report date to
|
|||
disclosure date to be on the order of 7 days.
|
||||
|
||||
3) Non-disclosure agreements
|
||||
----------------------------
|
||||
|
||||
The Linux kernel security team is not a formal body and therefore unable
|
||||
to enter any non-disclosure agreements.
|
||||
|
|
|
@ -1,109 +1,120 @@
|
|||
.. _submitchecklist:
|
||||
|
||||
Linux Kernel patch submission checklist
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Here are some basic things that developers should do if they want to see their
|
||||
kernel patch submissions accepted more quickly.
|
||||
|
||||
These are all above and beyond the documentation that is provided in
|
||||
Documentation/SubmittingPatches and elsewhere regarding submitting Linux
|
||||
kernel patches.
|
||||
:ref:`Documentation/SubmittingPatches <submittingpatches>`
|
||||
and elsewhere regarding submitting Linux kernel patches.
|
||||
|
||||
|
||||
1: If you use a facility then #include the file that defines/declares
|
||||
1) If you use a facility then #include the file that defines/declares
|
||||
that facility. Don't depend on other header files pulling in ones
|
||||
that you use.
|
||||
|
||||
2: Builds cleanly with applicable or modified CONFIG options =y, =m, and
|
||||
=n. No gcc warnings/errors, no linker warnings/errors.
|
||||
2) Builds cleanly:
|
||||
|
||||
2b: Passes allnoconfig, allmodconfig
|
||||
a) with applicable or modified ``CONFIG`` options ``=y``, ``=m``, and
|
||||
``=n``. No ``gcc`` warnings/errors, no linker warnings/errors.
|
||||
|
||||
2c: Builds successfully when using O=builddir
|
||||
b) Passes ``allnoconfig``, ``allmodconfig``
|
||||
|
||||
3: Builds on multiple CPU architectures by using local cross-compile tools
|
||||
c) Builds successfully when using ``O=builddir``
|
||||
|
||||
3) Builds on multiple CPU architectures by using local cross-compile tools
|
||||
or some other build farm.
|
||||
|
||||
4: ppc64 is a good architecture for cross-compilation checking because it
|
||||
tends to use `unsigned long' for 64-bit quantities.
|
||||
4) ppc64 is a good architecture for cross-compilation checking because it
|
||||
tends to use ``unsigned long`` for 64-bit quantities.
|
||||
|
||||
5: Check your patch for general style as detailed in
|
||||
Documentation/CodingStyle. Check for trivial violations with the
|
||||
patch style checker prior to submission (scripts/checkpatch.pl).
|
||||
5) Check your patch for general style as detailed in
|
||||
:ref:`Documentation/CodingStyle <codingstyle>`.
|
||||
Check for trivial violations with the patch style checker prior to
|
||||
submission (``scripts/checkpatch.pl``).
|
||||
You should be able to justify all violations that remain in
|
||||
your patch.
|
||||
|
||||
6: Any new or modified CONFIG options don't muck up the config menu.
|
||||
6) Any new or modified ``CONFIG`` options don't muck up the config menu.
|
||||
|
||||
7: All new Kconfig options have help text.
|
||||
7) All new ``Kconfig`` options have help text.
|
||||
|
||||
8: Has been carefully reviewed with respect to relevant Kconfig
|
||||
8) Has been carefully reviewed with respect to relevant ``Kconfig``
|
||||
combinations. This is very hard to get right with testing -- brainpower
|
||||
pays off here.
|
||||
|
||||
9: Check cleanly with sparse.
|
||||
9) Check cleanly with sparse.
|
||||
|
||||
10: Use 'make checkstack' and 'make namespacecheck' and fix any problems
|
||||
that they find. Note: checkstack does not point out problems explicitly,
|
||||
but any one function that uses more than 512 bytes on the stack is a
|
||||
candidate for change.
|
||||
10) Use ``make checkstack`` and ``make namespacecheck`` and fix any problems
|
||||
that they find.
|
||||
|
||||
11: Include kernel-doc to document global kernel APIs. (Not required for
|
||||
static functions, but OK there also.) Use 'make htmldocs' or 'make
|
||||
mandocs' to check the kernel-doc and fix any issues.
|
||||
.. note::
|
||||
|
||||
12: Has been tested with CONFIG_PREEMPT, CONFIG_DEBUG_PREEMPT,
|
||||
CONFIG_DEBUG_SLAB, CONFIG_DEBUG_PAGEALLOC, CONFIG_DEBUG_MUTEXES,
|
||||
CONFIG_DEBUG_SPINLOCK, CONFIG_DEBUG_ATOMIC_SLEEP, CONFIG_PROVE_RCU
|
||||
and CONFIG_DEBUG_OBJECTS_RCU_HEAD all simultaneously enabled.
|
||||
``checkstack`` does not point out problems explicitly,
|
||||
but any one function that uses more than 512 bytes on the stack is a
|
||||
candidate for change.
|
||||
|
||||
13: Has been build- and runtime tested with and without CONFIG_SMP and
|
||||
CONFIG_PREEMPT.
|
||||
11) Include :ref:`kernel-doc <kernel_doc>` to document global kernel APIs.
|
||||
(Not required for static functions, but OK there also.) Use
|
||||
``make htmldocs`` or ``make pdfdocs`` to check the
|
||||
:ref:`kernel-doc <kernel_doc>` and fix any issues.
|
||||
|
||||
14: If the patch affects IO/Disk, etc: has been tested with and without
|
||||
CONFIG_LBDAF.
|
||||
12) Has been tested with ``CONFIG_PREEMPT``, ``CONFIG_DEBUG_PREEMPT``,
|
||||
``CONFIG_DEBUG_SLAB``, ``CONFIG_DEBUG_PAGEALLOC``, ``CONFIG_DEBUG_MUTEXES``,
|
||||
``CONFIG_DEBUG_SPINLOCK``, ``CONFIG_DEBUG_ATOMIC_SLEEP``,
|
||||
``CONFIG_PROVE_RCU`` and ``CONFIG_DEBUG_OBJECTS_RCU_HEAD`` all
|
||||
simultaneously enabled.
|
||||
|
||||
15: All codepaths have been exercised with all lockdep features enabled.
|
||||
13) Has been build- and runtime tested with and without ``CONFIG_SMP`` and
|
||||
``CONFIG_PREEMPT.``
|
||||
|
||||
16: All new /proc entries are documented under Documentation/
|
||||
14) If the patch affects IO/Disk, etc: has been tested with and without
|
||||
``CONFIG_LBDAF.``
|
||||
|
||||
17: All new kernel boot parameters are documented in
|
||||
Documentation/kernel-parameters.txt.
|
||||
15) All codepaths have been exercised with all lockdep features enabled.
|
||||
|
||||
18: All new module parameters are documented with MODULE_PARM_DESC()
|
||||
16) All new ``/proc`` entries are documented under ``Documentation/``
|
||||
|
||||
19: All new userspace interfaces are documented in Documentation/ABI/.
|
||||
See Documentation/ABI/README for more information.
|
||||
17) All new kernel boot parameters are documented in
|
||||
``Documentation/kernel-parameters.txt``.
|
||||
|
||||
18) All new module parameters are documented with ``MODULE_PARM_DESC()``
|
||||
|
||||
19) All new userspace interfaces are documented in ``Documentation/ABI/``.
|
||||
See ``Documentation/ABI/README`` for more information.
|
||||
Patches that change userspace interfaces should be CCed to
|
||||
linux-api@vger.kernel.org.
|
||||
|
||||
20: Check that it all passes `make headers_check'.
|
||||
20) Check that it all passes ``make headers_check``.
|
||||
|
||||
21: Has been checked with injection of at least slab and page-allocation
|
||||
failures. See Documentation/fault-injection/.
|
||||
21) Has been checked with injection of at least slab and page-allocation
|
||||
failures. See ``Documentation/fault-injection/``.
|
||||
|
||||
If the new code is substantial, addition of subsystem-specific fault
|
||||
injection might be appropriate.
|
||||
|
||||
22: Newly-added code has been compiled with `gcc -W' (use "make
|
||||
EXTRA_CFLAGS=-W"). This will generate lots of noise, but is good for
|
||||
finding bugs like "warning: comparison between signed and unsigned".
|
||||
22) Newly-added code has been compiled with ``gcc -W`` (use
|
||||
``make EXTRA_CFLAGS=-W``). This will generate lots of noise, but is good
|
||||
for finding bugs like "warning: comparison between signed and unsigned".
|
||||
|
||||
23: Tested after it has been merged into the -mm patchset to make sure
|
||||
23) Tested after it has been merged into the -mm patchset to make sure
|
||||
that it still works with all of the other queued patches and various
|
||||
changes in the VM, VFS, and other subsystems.
|
||||
|
||||
24: All memory barriers {e.g., barrier(), rmb(), wmb()} need a comment in the
|
||||
source code that explains the logic of what they are doing and why.
|
||||
24) All memory barriers {e.g., ``barrier()``, ``rmb()``, ``wmb()``} need a
|
||||
comment in the source code that explains the logic of what they are doing
|
||||
and why.
|
||||
|
||||
25: If any ioctl's are added by the patch, then also update
|
||||
Documentation/ioctl/ioctl-number.txt.
|
||||
25) If any ioctl's are added by the patch, then also update
|
||||
``Documentation/ioctl/ioctl-number.txt``.
|
||||
|
||||
26: If your modified source code depends on or uses any of the kernel
|
||||
APIs or features that are related to the following kconfig symbols,
|
||||
then test multiple builds with the related kconfig symbols disabled
|
||||
and/or =m (if that option is available) [not all of these at the
|
||||
26) If your modified source code depends on or uses any of the kernel
|
||||
APIs or features that are related to the following ``Kconfig`` symbols,
|
||||
then test multiple builds with the related ``Kconfig`` symbols disabled
|
||||
and/or ``=m`` (if that option is available) [not all of these at the
|
||||
same time, just various/random combinations of them]:
|
||||
|
||||
CONFIG_SMP, CONFIG_SYSFS, CONFIG_PROC_FS, CONFIG_INPUT, CONFIG_PCI,
|
||||
CONFIG_BLOCK, CONFIG_PM, CONFIG_MAGIC_SYSRQ,
|
||||
CONFIG_NET, CONFIG_INET=n (but latter with CONFIG_NET=y)
|
||||
``CONFIG_SMP``, ``CONFIG_SYSFS``, ``CONFIG_PROC_FS``, ``CONFIG_INPUT``, ``CONFIG_PCI``, ``CONFIG_BLOCK``, ``CONFIG_PM``, ``CONFIG_MAGIC_SYSRQ``,
|
||||
``CONFIG_NET``, ``CONFIG_INET=n`` (but latter with ``CONFIG_NET=y``).
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
.. _submittingdrivers:
|
||||
|
||||
Submitting Drivers For The Linux Kernel
|
||||
---------------------------------------
|
||||
=======================================
|
||||
|
||||
This document is intended to explain how to submit device drivers to the
|
||||
various kernel trees. Note that if you are interested in video card drivers
|
||||
|
@ -38,42 +40,48 @@ Linux 2.4:
|
|||
maintainer does not respond or you cannot find the appropriate
|
||||
maintainer then please contact Willy Tarreau <w@1wt.eu>.
|
||||
|
||||
Linux 2.6:
|
||||
Linux 2.6 and upper:
|
||||
The same rules apply as 2.4 except that you should follow linux-kernel
|
||||
to track changes in API's. The final contact point for Linux 2.6
|
||||
to track changes in API's. The final contact point for Linux 2.6+
|
||||
submissions is Andrew Morton.
|
||||
|
||||
What Criteria Determine Acceptance
|
||||
----------------------------------
|
||||
|
||||
Licensing: The code must be released to us under the
|
||||
Licensing:
|
||||
The code must be released to us under the
|
||||
GNU General Public License. We don't insist on any kind
|
||||
of exclusive GPL licensing, and if you wish the driver
|
||||
to be useful to other communities such as BSD you may well
|
||||
wish to release under multiple licenses.
|
||||
See accepted licenses at include/linux/module.h
|
||||
|
||||
Copyright: The copyright owner must agree to use of GPL.
|
||||
Copyright:
|
||||
The copyright owner must agree to use of GPL.
|
||||
It's best if the submitter and copyright owner
|
||||
are the same person/entity. If not, the name of
|
||||
the person/entity authorizing use of GPL should be
|
||||
listed in case it's necessary to verify the will of
|
||||
the copyright owner.
|
||||
|
||||
Interfaces: If your driver uses existing interfaces and behaves like
|
||||
Interfaces:
|
||||
If your driver uses existing interfaces and behaves like
|
||||
other drivers in the same class it will be much more likely
|
||||
to be accepted than if it invents gratuitous new ones.
|
||||
If you need to implement a common API over Linux and NT
|
||||
drivers do it in userspace.
|
||||
|
||||
Code: Please use the Linux style of code formatting as documented
|
||||
in Documentation/CodingStyle. If you have sections of code
|
||||
Code:
|
||||
Please use the Linux style of code formatting as documented
|
||||
in :ref:`Documentation/CodingStyle <codingStyle>`.
|
||||
If you have sections of code
|
||||
that need to be in other formats, for example because they
|
||||
are shared with a windows driver kit and you want to
|
||||
maintain them just once separate them out nicely and note
|
||||
this fact.
|
||||
|
||||
Portability: Pointers are not always 32bits, not all computers are little
|
||||
Portability:
|
||||
Pointers are not always 32bits, not all computers are little
|
||||
endian, people do not all have floating point and you
|
||||
shouldn't use inline x86 assembler in your driver without
|
||||
careful thought. Pure x86 drivers generally are not popular.
|
||||
|
@ -81,12 +89,14 @@ Portability: Pointers are not always 32bits, not all computers are little
|
|||
but it is easy to make sure the code can easily be made
|
||||
portable.
|
||||
|
||||
Clarity: It helps if anyone can see how to fix the driver. It helps
|
||||
Clarity:
|
||||
It helps if anyone can see how to fix the driver. It helps
|
||||
you because you get patches not bug reports. If you submit a
|
||||
driver that intentionally obfuscates how the hardware works
|
||||
it will go in the bitbucket.
|
||||
|
||||
PM support: Since Linux is used on many portable and desktop systems, your
|
||||
PM support:
|
||||
Since Linux is used on many portable and desktop systems, your
|
||||
driver is likely to be used on such a system and therefore it
|
||||
should support basic power management by implementing, if
|
||||
necessary, the .suspend and .resume methods used during the
|
||||
|
@ -101,7 +111,8 @@ PM support: Since Linux is used on many portable and desktop systems, your
|
|||
complete overview of the power management issues related to
|
||||
drivers see Documentation/power/devices.txt .
|
||||
|
||||
Control: In general if there is active maintenance of a driver by
|
||||
Control:
|
||||
In general if there is active maintenance of a driver by
|
||||
the author then patches will be redirected to them unless
|
||||
they are totally obvious and without need of checking.
|
||||
If you want to be the contact and update point for the
|
||||
|
@ -111,13 +122,15 @@ Control: In general if there is active maintenance of a driver by
|
|||
What Criteria Do Not Determine Acceptance
|
||||
-----------------------------------------
|
||||
|
||||
Vendor: Being the hardware vendor and maintaining the driver is
|
||||
Vendor:
|
||||
Being the hardware vendor and maintaining the driver is
|
||||
often a good thing. If there is a stable working driver from
|
||||
other people already in the tree don't expect 'we are the
|
||||
vendor' to get your driver chosen. Ideally work with the
|
||||
existing driver author to build a single perfect driver.
|
||||
|
||||
Author: It doesn't matter if a large Linux company wrote the driver,
|
||||
Author:
|
||||
It doesn't matter if a large Linux company wrote the driver,
|
||||
or you did. Nobody has any special access to the kernel
|
||||
tree. Anyone who tells you otherwise isn't telling the
|
||||
whole story.
|
||||
|
@ -127,8 +140,10 @@ Resources
|
|||
---------
|
||||
|
||||
Linux kernel master tree:
|
||||
ftp.??.kernel.org:/pub/linux/kernel/...
|
||||
?? == your country code, such as "us", "uk", "fr", etc.
|
||||
ftp.\ *country_code*\ .kernel.org:/pub/linux/kernel/...
|
||||
|
||||
where *country_code* == your country code, such as
|
||||
**us**, **uk**, **fr**, etc.
|
||||
|
||||
http://git.kernel.org/?p=linux/kernel/git/torvalds/linux.git
|
||||
|
||||
|
@ -141,14 +156,19 @@ Linux Device Drivers, Third Edition (covers 2.6.10):
|
|||
|
||||
LWN.net:
|
||||
Weekly summary of kernel development activity - http://lwn.net/
|
||||
|
||||
2.6 API changes:
|
||||
|
||||
http://lwn.net/Articles/2.6-kernel-api/
|
||||
|
||||
Porting drivers from prior kernels to 2.6:
|
||||
|
||||
http://lwn.net/Articles/driver-porting/
|
||||
|
||||
KernelNewbies:
|
||||
Documentation and assistance for new kernel programmers
|
||||
http://kernelnewbies.org/
|
||||
|
||||
http://kernelnewbies.org/
|
||||
|
||||
Linux USB project:
|
||||
http://www.linux-usb.org/
|
||||
|
|
|
@ -1,9 +1,7 @@
|
|||
.. _submittingpatches:
|
||||
|
||||
How to Get Your Change Into the Linux Kernel
|
||||
or
|
||||
Care And Operation Of Your Linus Torvalds
|
||||
|
||||
|
||||
How to Get Your Change Into the Linux Kernel or Care And Operation Of Your Linus Torvalds
|
||||
=========================================================================================
|
||||
|
||||
For a person or company who wishes to submit a change to the Linux
|
||||
kernel, the process can sometimes be daunting if you're not familiar
|
||||
|
@ -12,57 +10,59 @@ can greatly increase the chances of your change being accepted.
|
|||
|
||||
This document contains a large number of suggestions in a relatively terse
|
||||
format. For detailed information on how the kernel development process
|
||||
works, see Documentation/development-process. Also, read
|
||||
Documentation/SubmitChecklist for a list of items to check before
|
||||
works, see :ref:`Documentation/development-process <development_process_main>`.
|
||||
Also, read :ref:`Documentation/SubmitChecklist <submitchecklist>`
|
||||
for a list of items to check before
|
||||
submitting code. If you are submitting a driver, also read
|
||||
Documentation/SubmittingDrivers; for device tree binding patches, read
|
||||
:ref:`Documentation/SubmittingDrivers <submittingdrivers>`;
|
||||
for device tree binding patches, read
|
||||
Documentation/devicetree/bindings/submitting-patches.txt.
|
||||
|
||||
Many of these steps describe the default behavior of the git version
|
||||
control system; if you use git to prepare your patches, you'll find much
|
||||
Many of these steps describe the default behavior of the ``git`` version
|
||||
control system; if you use ``git`` to prepare your patches, you'll find much
|
||||
of the mechanical work done for you, though you'll still need to prepare
|
||||
and document a sensible set of patches. In general, use of git will make
|
||||
and document a sensible set of patches. In general, use of ``git`` will make
|
||||
your life as a kernel developer easier.
|
||||
|
||||
--------------------------------------------
|
||||
SECTION 1 - CREATING AND SENDING YOUR CHANGE
|
||||
--------------------------------------------
|
||||
Creating and Sending your Change
|
||||
********************************
|
||||
|
||||
|
||||
0) Obtain a current source tree
|
||||
-------------------------------
|
||||
|
||||
If you do not have a repository with the current kernel source handy, use
|
||||
git to obtain one. You'll want to start with the mainline repository,
|
||||
which can be grabbed with:
|
||||
``git`` to obtain one. You'll want to start with the mainline repository,
|
||||
which can be grabbed with::
|
||||
|
||||
git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
|
||||
git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
|
||||
|
||||
Note, however, that you may not want to develop against the mainline tree
|
||||
directly. Most subsystem maintainers run their own trees and want to see
|
||||
patches prepared against those trees. See the "T:" entry for the subsystem
|
||||
patches prepared against those trees. See the **T:** entry for the subsystem
|
||||
in the MAINTAINERS file to find that tree, or simply ask the maintainer if
|
||||
the tree is not listed there.
|
||||
|
||||
It is still possible to download kernel releases via tarballs (as described
|
||||
in the next section), but that is the hard way to do kernel development.
|
||||
|
||||
1) "diff -up"
|
||||
------------
|
||||
1) ``diff -up``
|
||||
---------------
|
||||
|
||||
If you must generate your patches by hand, use "diff -up" or "diff -uprN"
|
||||
If you must generate your patches by hand, use ``diff -up`` or ``diff -uprN``
|
||||
to create patches. Git generates patches in this form by default; if
|
||||
you're using git, you can skip this section entirely.
|
||||
you're using ``git``, you can skip this section entirely.
|
||||
|
||||
All changes to the Linux kernel occur in the form of patches, as
|
||||
generated by diff(1). When creating your patch, make sure to create it
|
||||
in "unified diff" format, as supplied by the '-u' argument to diff(1).
|
||||
Also, please use the '-p' argument which shows which C function each
|
||||
change is in - that makes the resultant diff a lot easier to read.
|
||||
generated by :manpage:`diff(1)`. When creating your patch, make sure to
|
||||
create it in "unified diff" format, as supplied by the ``-u`` argument
|
||||
to :manpage:`diff(1)`.
|
||||
Also, please use the ``-p`` argument which shows which C function each
|
||||
change is in - that makes the resultant ``diff`` a lot easier to read.
|
||||
Patches should be based in the root kernel source directory,
|
||||
not in any lower subdirectory.
|
||||
|
||||
To create a patch for a single file, it is often sufficient to do:
|
||||
To create a patch for a single file, it is often sufficient to do::
|
||||
|
||||
SRCTREE= linux
|
||||
MYFILE= drivers/net/mydriver.c
|
||||
|
@ -74,8 +74,8 @@ To create a patch for a single file, it is often sufficient to do:
|
|||
diff -up $SRCTREE/$MYFILE{.orig,} > /tmp/patch
|
||||
|
||||
To create a patch for multiple files, you should unpack a "vanilla",
|
||||
or unmodified kernel source tree, and generate a diff against your
|
||||
own source tree. For example:
|
||||
or unmodified kernel source tree, and generate a ``diff`` against your
|
||||
own source tree. For example::
|
||||
|
||||
MYSRC= /devel/linux
|
||||
|
||||
|
@ -84,27 +84,27 @@ own source tree. For example:
|
|||
diff -uprN -X linux-3.19-vanilla/Documentation/dontdiff \
|
||||
linux-3.19-vanilla $MYSRC > /tmp/patch
|
||||
|
||||
"dontdiff" is a list of files which are generated by the kernel during
|
||||
the build process, and should be ignored in any diff(1)-generated
|
||||
``dontdiff`` is a list of files which are generated by the kernel during
|
||||
the build process, and should be ignored in any :manpage:`diff(1)`-generated
|
||||
patch.
|
||||
|
||||
Make sure your patch does not include any extra files which do not
|
||||
belong in a patch submission. Make sure to review your patch -after-
|
||||
generating it with diff(1), to ensure accuracy.
|
||||
generating it with :manpage:`diff(1)`, to ensure accuracy.
|
||||
|
||||
If your changes produce a lot of deltas, you need to split them into
|
||||
individual patches which modify things in logical stages; see section
|
||||
#3. This will facilitate review by other kernel developers,
|
||||
individual patches which modify things in logical stages; see
|
||||
:ref:`split_changes`. This will facilitate review by other kernel developers,
|
||||
very important if you want your patch accepted.
|
||||
|
||||
If you're using git, "git rebase -i" can help you with this process. If
|
||||
you're not using git, quilt <http://savannah.nongnu.org/projects/quilt>
|
||||
If you're using ``git``, ``git rebase -i`` can help you with this process. If
|
||||
you're not using ``git``, ``quilt`` <http://savannah.nongnu.org/projects/quilt>
|
||||
is another popular alternative.
|
||||
|
||||
.. _describe_changes:
|
||||
|
||||
|
||||
2) Describe your changes.
|
||||
-------------------------
|
||||
2) Describe your changes
|
||||
------------------------
|
||||
|
||||
Describe your problem. Whether your patch is a one-line bug fix or
|
||||
5000 lines of a new feature, there must be an underlying problem that
|
||||
|
@ -137,11 +137,11 @@ as you intend it to.
|
|||
|
||||
The maintainer will thank you if you write your patch description in a
|
||||
form which can be easily pulled into Linux's source code management
|
||||
system, git, as a "commit log". See #15, below.
|
||||
system, ``git``, as a "commit log". See :ref:`explicit_in_reply_to`.
|
||||
|
||||
Solve only one problem per patch. If your description starts to get
|
||||
long, that's a sign that you probably need to split up your patch.
|
||||
See #3, next.
|
||||
See :ref:`split_changes`.
|
||||
|
||||
When you submit or resubmit a patch or patch series, include the
|
||||
complete patch description and justification for it. Don't just
|
||||
|
@ -160,7 +160,7 @@ its behaviour.
|
|||
If the patch fixes a logged bug entry, refer to that bug entry by
|
||||
number and URL. If the patch follows from a mailing list discussion,
|
||||
give a URL to the mailing list archive; use the https://lkml.kernel.org/
|
||||
redirector with a Message-Id, to ensure that the links cannot become
|
||||
redirector with a ``Message-Id``, to ensure that the links cannot become
|
||||
stale.
|
||||
|
||||
However, try to make your explanation understandable without external
|
||||
|
@ -171,7 +171,7 @@ patch as submitted.
|
|||
If you want to refer to a specific commit, don't just refer to the
|
||||
SHA-1 ID of the commit. Please also include the oneline summary of
|
||||
the commit, to make it easier for reviewers to know what it is about.
|
||||
Example:
|
||||
Example::
|
||||
|
||||
Commit e21d2170f36602ae2708 ("video: remove unnecessary
|
||||
platform_set_drvdata()") removed the unnecessary
|
||||
|
@ -185,23 +185,25 @@ there is no collision with your six-character ID now, that condition may
|
|||
change five years from now.
|
||||
|
||||
If your patch fixes a bug in a specific commit, e.g. you found an issue using
|
||||
git-bisect, please use the 'Fixes:' tag with the first 12 characters of the
|
||||
SHA-1 ID, and the one line summary. For example:
|
||||
``git bisect``, please use the 'Fixes:' tag with the first 12 characters of
|
||||
the SHA-1 ID, and the one line summary. For example::
|
||||
|
||||
Fixes: e21d2170f366 ("video: remove unnecessary platform_set_drvdata()")
|
||||
|
||||
The following git-config settings can be used to add a pretty format for
|
||||
outputting the above style in the git log or git show commands
|
||||
The following ``git config`` settings can be used to add a pretty format for
|
||||
outputting the above style in the ``git log`` or ``git show`` commands::
|
||||
|
||||
[core]
|
||||
abbrev = 12
|
||||
[pretty]
|
||||
fixes = Fixes: %h (\"%s\")
|
||||
|
||||
3) Separate your changes.
|
||||
-------------------------
|
||||
.. _split_changes:
|
||||
|
||||
Separate each _logical change_ into a separate patch.
|
||||
3) Separate your changes
|
||||
------------------------
|
||||
|
||||
Separate each **logical change** into a separate patch.
|
||||
|
||||
For example, if your changes include both bug fixes and performance
|
||||
enhancements for a single driver, separate those changes into two
|
||||
|
@ -217,12 +219,12 @@ change that can be verified by reviewers. Each patch should be justifiable
|
|||
on its own merits.
|
||||
|
||||
If one patch depends on another patch in order for a change to be
|
||||
complete, that is OK. Simply note "this patch depends on patch X"
|
||||
complete, that is OK. Simply note **"this patch depends on patch X"**
|
||||
in your patch description.
|
||||
|
||||
When dividing your change into a series of patches, take special care to
|
||||
ensure that the kernel builds and runs properly after each patch in the
|
||||
series. Developers using "git bisect" to track down a problem can end up
|
||||
series. Developers using ``git bisect`` to track down a problem can end up
|
||||
splitting your patch series at any point; they will not thank you if you
|
||||
introduce bugs in the middle.
|
||||
|
||||
|
@ -231,11 +233,13 @@ then only post say 15 or so at a time and wait for review and integration.
|
|||
|
||||
|
||||
|
||||
4) Style-check your changes.
|
||||
----------------------------
|
||||
4) Style-check your changes
|
||||
---------------------------
|
||||
|
||||
Check your patch for basic style violations, details of which can be
|
||||
found in Documentation/CodingStyle. Failure to do so simply wastes
|
||||
found in
|
||||
:ref:`Documentation/CodingStyle <codingstyle>`.
|
||||
Failure to do so simply wastes
|
||||
the reviewers time and will get your patch rejected, probably
|
||||
without even being read.
|
||||
|
||||
|
@ -260,8 +264,8 @@ You should be able to justify all violations that remain in your
|
|||
patch.
|
||||
|
||||
|
||||
5) Select the recipients for your patch.
|
||||
----------------------------------------
|
||||
5) Select the recipients for your patch
|
||||
---------------------------------------
|
||||
|
||||
You should always copy the appropriate subsystem maintainer(s) on any patch
|
||||
to code that they maintain; look through the MAINTAINERS file and the
|
||||
|
@ -295,13 +299,14 @@ to allow distributors to get the patch out to users; in such cases,
|
|||
obviously, the patch should not be sent to any public lists.
|
||||
|
||||
Patches that fix a severe bug in a released kernel should be directed
|
||||
toward the stable maintainers by putting a line like this:
|
||||
toward the stable maintainers by putting a line like this::
|
||||
|
||||
Cc: stable@vger.kernel.org
|
||||
|
||||
into the sign-off area of your patch (note, NOT an email recipient). You
|
||||
should also read Documentation/stable_kernel_rules.txt in addition to this
|
||||
file.
|
||||
should also read
|
||||
:ref:`Documentation/stable_kernel_rules.txt <stable_kernel_rules>`
|
||||
in addition to this file.
|
||||
|
||||
Note, however, that some subsystem maintainers want to come to their own
|
||||
conclusions on which patches should go to the stable trees. The networking
|
||||
|
@ -312,28 +317,30 @@ If changes affect userland-kernel interfaces, please send the MAN-PAGES
|
|||
maintainer (as listed in the MAINTAINERS file) a man-pages patch, or at
|
||||
least a notification of the change, so that some information makes its way
|
||||
into the manual pages. User-space API changes should also be copied to
|
||||
linux-api@vger.kernel.org.
|
||||
linux-api@vger.kernel.org.
|
||||
|
||||
For small patches you may want to CC the Trivial Patch Monkey
|
||||
trivial@kernel.org which collects "trivial" patches. Have a look
|
||||
into the MAINTAINERS file for its current manager.
|
||||
|
||||
Trivial patches must qualify for one of the following rules:
|
||||
Spelling fixes in documentation
|
||||
Spelling fixes for errors which could break grep(1)
|
||||
Warning fixes (cluttering with useless warnings is bad)
|
||||
Compilation fixes (only if they are actually correct)
|
||||
Runtime fixes (only if they actually fix things)
|
||||
Removing use of deprecated functions/macros
|
||||
Contact detail and documentation fixes
|
||||
Non-portable code replaced by portable code (even in arch-specific,
|
||||
since people copy, as long as it's trivial)
|
||||
Any fix by the author/maintainer of the file (ie. patch monkey
|
||||
in re-transmission mode)
|
||||
|
||||
- Spelling fixes in documentation
|
||||
- Spelling fixes for errors which could break :manpage:`grep(1)`
|
||||
- Warning fixes (cluttering with useless warnings is bad)
|
||||
- Compilation fixes (only if they are actually correct)
|
||||
- Runtime fixes (only if they actually fix things)
|
||||
- Removing use of deprecated functions/macros
|
||||
- Contact detail and documentation fixes
|
||||
- Non-portable code replaced by portable code (even in arch-specific,
|
||||
since people copy, as long as it's trivial)
|
||||
- Any fix by the author/maintainer of the file (ie. patch monkey
|
||||
in re-transmission mode)
|
||||
|
||||
|
||||
|
||||
6) No MIME, no links, no compression, no attachments. Just plain text.
|
||||
-----------------------------------------------------------------------
|
||||
6) No MIME, no links, no compression, no attachments. Just plain text
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Linus and other kernel developers need to be able to read and comment
|
||||
on the changes you are submitting. It is important for a kernel
|
||||
|
@ -341,8 +348,11 @@ developer to be able to "quote" your changes, using standard e-mail
|
|||
tools, so that they may comment on specific portions of your code.
|
||||
|
||||
For this reason, all patches should be submitted by e-mail "inline".
|
||||
WARNING: Be wary of your editor's word-wrap corrupting your patch,
|
||||
if you choose to cut-n-paste your patch.
|
||||
|
||||
.. warning::
|
||||
|
||||
Be wary of your editor's word-wrap corrupting your patch,
|
||||
if you choose to cut-n-paste your patch.
|
||||
|
||||
Do not attach the patch as a MIME attachment, compressed or not.
|
||||
Many popular e-mail applications will not always transmit a MIME
|
||||
|
@ -353,11 +363,12 @@ decreasing the likelihood of your MIME-attached change being accepted.
|
|||
Exception: If your mailer is mangling patches then someone may ask
|
||||
you to re-send them using MIME.
|
||||
|
||||
See Documentation/email-clients.txt for hints about configuring
|
||||
your e-mail client so that it sends your patches untouched.
|
||||
See :ref:`Documentation/email-clients.txt <email_clients>`
|
||||
for hints about configuring your e-mail client so that it sends your patches
|
||||
untouched.
|
||||
|
||||
7) E-mail size.
|
||||
---------------
|
||||
7) E-mail size
|
||||
--------------
|
||||
|
||||
Large changes are not appropriate for mailing lists, and some
|
||||
maintainers. If your patch, uncompressed, exceeds 300 kB in size,
|
||||
|
@ -366,8 +377,8 @@ server, and provide instead a URL (link) pointing to your patch. But note
|
|||
that if your patch exceeds 300 kB, it almost certainly needs to be broken up
|
||||
anyway.
|
||||
|
||||
8) Respond to review comments.
|
||||
------------------------------
|
||||
8) Respond to review comments
|
||||
-----------------------------
|
||||
|
||||
Your patch will almost certainly get comments from reviewers on ways in
|
||||
which the patch can be improved. You must respond to those comments;
|
||||
|
@ -382,8 +393,8 @@ reviewers sometimes get grumpy. Even in that case, though, respond
|
|||
politely and address the problems they have pointed out.
|
||||
|
||||
|
||||
9) Don't get discouraged - or impatient.
|
||||
----------------------------------------
|
||||
9) Don't get discouraged - or impatient
|
||||
---------------------------------------
|
||||
|
||||
After you have submitted your change, be patient and wait. Reviewers are
|
||||
busy people and may not get to your patch right away.
|
||||
|
@ -419,9 +430,10 @@ patch, which certifies that you wrote it or otherwise have the right to
|
|||
pass it on as an open-source patch. The rules are pretty simple: if you
|
||||
can certify the below:
|
||||
|
||||
Developer's Certificate of Origin 1.1
|
||||
Developer's Certificate of Origin 1.1
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
By making a contribution to this project, I certify that:
|
||||
By making a contribution to this project, I certify that:
|
||||
|
||||
(a) The contribution was created in whole or in part by me and I
|
||||
have the right to submit it under the open source license
|
||||
|
@ -445,7 +457,7 @@ can certify the below:
|
|||
maintained indefinitely and may be redistributed consistent with
|
||||
this project or the open source license(s) involved.
|
||||
|
||||
then you just add a line saying
|
||||
then you just add a line saying::
|
||||
|
||||
Signed-off-by: Random J Developer <random@developer.example.org>
|
||||
|
||||
|
@ -466,7 +478,7 @@ you add a line between the last Signed-off-by header and yours, indicating
|
|||
the nature of your changes. While there is nothing mandatory about this, it
|
||||
seems like prepending the description with your mail and/or name, all
|
||||
enclosed in square brackets, is noticeable enough to make it obvious that
|
||||
you are responsible for last-minute changes. Example :
|
||||
you are responsible for last-minute changes. Example::
|
||||
|
||||
Signed-off-by: Random J Developer <random@developer.example.org>
|
||||
[lucky@maintainer.example.org: struct foo moved from foo.c to foo.h]
|
||||
|
@ -481,15 +493,15 @@ which appears in the changelog.
|
|||
Special note to back-porters: It seems to be a common and useful practice
|
||||
to insert an indication of the origin of a patch at the top of the commit
|
||||
message (just after the subject line) to facilitate tracking. For instance,
|
||||
here's what we see in a 3.x-stable release:
|
||||
here's what we see in a 3.x-stable release::
|
||||
|
||||
Date: Tue Oct 7 07:26:38 2014 -0400
|
||||
Date: Tue Oct 7 07:26:38 2014 -0400
|
||||
|
||||
libata: Un-break ATA blacklist
|
||||
|
||||
commit 1c40279960bcd7d52dbdf1d466b20d24b99176c8 upstream.
|
||||
|
||||
And here's what might appear in an older kernel once a patch is backported:
|
||||
And here's what might appear in an older kernel once a patch is backported::
|
||||
|
||||
Date: Tue May 13 22:12:27 2008 +0200
|
||||
|
||||
|
@ -529,7 +541,7 @@ When in doubt people should refer to the original discussion in the mailing
|
|||
list archives.
|
||||
|
||||
If a person has had the opportunity to comment on a patch, but has not
|
||||
provided such comments, you may optionally add a "Cc:" tag to the patch.
|
||||
provided such comments, you may optionally add a ``Cc:`` tag to the patch.
|
||||
This is the only tag which might be added without an explicit action by the
|
||||
person it names - but it should indicate that this person was copied on the
|
||||
patch. This tag documents that potentially interested parties
|
||||
|
@ -552,11 +564,12 @@ future patches, and ensures credit for the testers.
|
|||
Reviewed-by:, instead, indicates that the patch has been reviewed and found
|
||||
acceptable according to the Reviewer's Statement:
|
||||
|
||||
Reviewer's statement of oversight
|
||||
Reviewer's statement of oversight
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
By offering my Reviewed-by: tag, I state that:
|
||||
By offering my Reviewed-by: tag, I state that:
|
||||
|
||||
(a) I have carried out a technical review of this patch to
|
||||
(a) I have carried out a technical review of this patch to
|
||||
evaluate its appropriateness and readiness for inclusion into
|
||||
the mainline kernel.
|
||||
|
||||
|
@ -594,24 +607,25 @@ A Fixes: tag indicates that the patch fixes an issue in a previous commit. It
|
|||
is used to make it easy to determine where a bug originated, which can help
|
||||
review a bug fix. This tag also assists the stable kernel team in determining
|
||||
which stable kernel versions should receive your fix. This is the preferred
|
||||
method for indicating a bug fixed by the patch. See #2 above for more details.
|
||||
method for indicating a bug fixed by the patch. See :ref:`describe_changes`
|
||||
for more details.
|
||||
|
||||
|
||||
14) The canonical patch format
|
||||
------------------------------
|
||||
|
||||
This section describes how the patch itself should be formatted. Note
|
||||
that, if you have your patches stored in a git repository, proper patch
|
||||
formatting can be had with "git format-patch". The tools cannot create
|
||||
that, if you have your patches stored in a ``git`` repository, proper patch
|
||||
formatting can be had with ``git format-patch``. The tools cannot create
|
||||
the necessary text, though, so read the instructions below anyway.
|
||||
|
||||
The canonical patch subject line is:
|
||||
The canonical patch subject line is::
|
||||
|
||||
Subject: [PATCH 001/123] subsystem: summary phrase
|
||||
|
||||
The canonical patch message body contains the following:
|
||||
|
||||
- A "from" line specifying the patch author (only needed if the person
|
||||
- A ``from`` line specifying the patch author (only needed if the person
|
||||
sending the patch is not the author).
|
||||
|
||||
- An empty line.
|
||||
|
@ -619,46 +633,46 @@ The canonical patch message body contains the following:
|
|||
- The body of the explanation, line wrapped at 75 columns, which will
|
||||
be copied to the permanent changelog to describe this patch.
|
||||
|
||||
- The "Signed-off-by:" lines, described above, which will
|
||||
- The ``Signed-off-by:`` lines, described above, which will
|
||||
also go in the changelog.
|
||||
|
||||
- A marker line containing simply "---".
|
||||
- A marker line containing simply ``---``.
|
||||
|
||||
- Any additional comments not suitable for the changelog.
|
||||
|
||||
- The actual patch (diff output).
|
||||
- The actual patch (``diff`` output).
|
||||
|
||||
The Subject line format makes it very easy to sort the emails
|
||||
alphabetically by subject line - pretty much any email reader will
|
||||
support that - since because the sequence number is zero-padded,
|
||||
the numerical and alphabetic sort is the same.
|
||||
|
||||
The "subsystem" in the email's Subject should identify which
|
||||
The ``subsystem`` in the email's Subject should identify which
|
||||
area or subsystem of the kernel is being patched.
|
||||
|
||||
The "summary phrase" in the email's Subject should concisely
|
||||
describe the patch which that email contains. The "summary
|
||||
phrase" should not be a filename. Do not use the same "summary
|
||||
phrase" for every patch in a whole patch series (where a "patch
|
||||
series" is an ordered sequence of multiple, related patches).
|
||||
The ``summary phrase`` in the email's Subject should concisely
|
||||
describe the patch which that email contains. The ``summary
|
||||
phrase`` should not be a filename. Do not use the same ``summary
|
||||
phrase`` for every patch in a whole patch series (where a ``patch
|
||||
series`` is an ordered sequence of multiple, related patches).
|
||||
|
||||
Bear in mind that the "summary phrase" of your email becomes a
|
||||
Bear in mind that the ``summary phrase`` of your email becomes a
|
||||
globally-unique identifier for that patch. It propagates all the way
|
||||
into the git changelog. The "summary phrase" may later be used in
|
||||
into the ``git`` changelog. The ``summary phrase`` may later be used in
|
||||
developer discussions which refer to the patch. People will want to
|
||||
google for the "summary phrase" to read discussion regarding that
|
||||
google for the ``summary phrase`` to read discussion regarding that
|
||||
patch. It will also be the only thing that people may quickly see
|
||||
when, two or three months later, they are going through perhaps
|
||||
thousands of patches using tools such as "gitk" or "git log
|
||||
--oneline".
|
||||
thousands of patches using tools such as ``gitk`` or ``git log
|
||||
--oneline``.
|
||||
|
||||
For these reasons, the "summary" must be no more than 70-75
|
||||
For these reasons, the ``summary`` must be no more than 70-75
|
||||
characters, and it must describe both what the patch changes, as well
|
||||
as why the patch might be necessary. It is challenging to be both
|
||||
succinct and descriptive, but that is what a well-written summary
|
||||
should do.
|
||||
|
||||
The "summary phrase" may be prefixed by tags enclosed in square
|
||||
The ``summary phrase`` may be prefixed by tags enclosed in square
|
||||
brackets: "Subject: [PATCH <tag>...] <summary phrase>". The tags are
|
||||
not considered part of the summary phrase, but describe how the patch
|
||||
should be treated. Common tags might include a version descriptor if
|
||||
|
@ -670,19 +684,19 @@ that developers understand the order in which the patches should be
|
|||
applied and that they have reviewed or applied all of the patches in
|
||||
the patch series.
|
||||
|
||||
A couple of example Subjects:
|
||||
A couple of example Subjects::
|
||||
|
||||
Subject: [PATCH 2/5] ext2: improve scalability of bitmap searching
|
||||
Subject: [PATCH v2 01/27] x86: fix eflags tracking
|
||||
|
||||
The "from" line must be the very first line in the message body,
|
||||
The ``from`` line must be the very first line in the message body,
|
||||
and has the form:
|
||||
|
||||
From: Original Author <author@example.com>
|
||||
|
||||
The "from" line specifies who will be credited as the author of the
|
||||
patch in the permanent changelog. If the "from" line is missing,
|
||||
then the "From:" line from the email header will be used to determine
|
||||
The ``from`` line specifies who will be credited as the author of the
|
||||
patch in the permanent changelog. If the ``from`` line is missing,
|
||||
then the ``From:`` line from the email header will be used to determine
|
||||
the patch author in the changelog.
|
||||
|
||||
The explanation body will be committed to the permanent source
|
||||
|
@ -694,35 +708,37 @@ especially useful for people who might be searching the commit logs
|
|||
looking for the applicable patch. If a patch fixes a compile failure,
|
||||
it may not be necessary to include _all_ of the compile failures; just
|
||||
enough that it is likely that someone searching for the patch can find
|
||||
it. As in the "summary phrase", it is important to be both succinct as
|
||||
it. As in the ``summary phrase``, it is important to be both succinct as
|
||||
well as descriptive.
|
||||
|
||||
The "---" marker line serves the essential purpose of marking for patch
|
||||
The ``---`` marker line serves the essential purpose of marking for patch
|
||||
handling tools where the changelog message ends.
|
||||
|
||||
One good use for the additional comments after the "---" marker is for
|
||||
a diffstat, to show what files have changed, and the number of
|
||||
inserted and deleted lines per file. A diffstat is especially useful
|
||||
One good use for the additional comments after the ``---`` marker is for
|
||||
a ``diffstat``, to show what files have changed, and the number of
|
||||
inserted and deleted lines per file. A ``diffstat`` is especially useful
|
||||
on bigger patches. Other comments relevant only to the moment or the
|
||||
maintainer, not suitable for the permanent changelog, should also go
|
||||
here. A good example of such comments might be "patch changelogs"
|
||||
here. A good example of such comments might be ``patch changelogs``
|
||||
which describe what has changed between the v1 and v2 version of the
|
||||
patch.
|
||||
|
||||
If you are going to include a diffstat after the "---" marker, please
|
||||
use diffstat options "-p 1 -w 70" so that filenames are listed from
|
||||
If you are going to include a ``diffstat`` after the ``---`` marker, please
|
||||
use ``diffstat`` options ``-p 1 -w 70`` so that filenames are listed from
|
||||
the top of the kernel source tree and don't use too much horizontal
|
||||
space (easily fit in 80 columns, maybe with some indentation). (git
|
||||
space (easily fit in 80 columns, maybe with some indentation). (``git``
|
||||
generates appropriate diffstats by default.)
|
||||
|
||||
See more details on the proper patch format in the following
|
||||
references.
|
||||
|
||||
.. _explicit_in_reply_to:
|
||||
|
||||
15) Explicit In-Reply-To headers
|
||||
--------------------------------
|
||||
|
||||
It can be helpful to manually add In-Reply-To: headers to a patch
|
||||
(e.g., when using "git send-email") to associate the patch with
|
||||
(e.g., when using ``git send-email``) to associate the patch with
|
||||
previous relevant discussion, e.g. to link a bug fix to the email with
|
||||
the bug report. However, for a multi-patch series, it is generally
|
||||
best to avoid using In-Reply-To: to link to older versions of the
|
||||
|
@ -732,12 +748,12 @@ helpful, you can use the https://lkml.kernel.org/ redirector (e.g., in
|
|||
the cover email text) to link to an earlier version of the patch series.
|
||||
|
||||
|
||||
16) Sending "git pull" requests
|
||||
-------------------------------
|
||||
16) Sending ``git pull`` requests
|
||||
---------------------------------
|
||||
|
||||
If you have a series of patches, it may be most convenient to have the
|
||||
maintainer pull them directly into the subsystem repository with a
|
||||
"git pull" operation. Note, however, that pulling patches from a developer
|
||||
``git pull`` operation. Note, however, that pulling patches from a developer
|
||||
requires a higher degree of trust than taking patches from a mailing list.
|
||||
As a result, many subsystem maintainers are reluctant to take pull
|
||||
requests, especially from new, unknown developers. If in doubt you can use
|
||||
|
@ -746,7 +762,7 @@ series, giving the maintainer the option of using either.
|
|||
|
||||
A pull request should have [GIT] or [PULL] in the subject line. The
|
||||
request itself should include the repository name and the branch of
|
||||
interest on a single line; it should look something like:
|
||||
interest on a single line; it should look something like::
|
||||
|
||||
Please pull from
|
||||
|
||||
|
@ -755,10 +771,10 @@ interest on a single line; it should look something like:
|
|||
to get these changes:
|
||||
|
||||
A pull request should also include an overall message saying what will be
|
||||
included in the request, a "git shortlog" listing of the patches
|
||||
themselves, and a diffstat showing the overall effect of the patch series.
|
||||
included in the request, a ``git shortlog`` listing of the patches
|
||||
themselves, and a ``diffstat`` showing the overall effect of the patch series.
|
||||
The easiest way to get all this information together is, of course, to let
|
||||
git do it for you with the "git request-pull" command.
|
||||
``git`` do it for you with the ``git request-pull`` command.
|
||||
|
||||
Some maintainers (including Linus) want to see pull requests from signed
|
||||
commits; that increases their confidence that the request actually came
|
||||
|
@ -770,8 +786,8 @@ signed by one or more core kernel developers. This step can be hard for
|
|||
new developers, but there is no way around it. Attending conferences can
|
||||
be a good way to find developers who can sign your key.
|
||||
|
||||
Once you have prepared a patch series in git that you wish to have somebody
|
||||
pull, create a signed tag with "git tag -s". This will create a new tag
|
||||
Once you have prepared a patch series in ``git`` that you wish to have somebody
|
||||
pull, create a signed tag with ``git tag -s``. This will create a new tag
|
||||
identifying the last commit in the series and containing a signature
|
||||
created with your private key. You will also have the opportunity to add a
|
||||
changelog-style message to the tag; this is an ideal place to describe the
|
||||
|
@ -782,14 +798,13 @@ are working from, don't forget to push the signed tag explicitly to the
|
|||
public tree.
|
||||
|
||||
When generating your pull request, use the signed tag as the target. A
|
||||
command like this will do the trick:
|
||||
command like this will do the trick::
|
||||
|
||||
git request-pull master git://my.public.tree/linux.git my-signed-tag
|
||||
|
||||
|
||||
----------------------
|
||||
SECTION 2 - REFERENCES
|
||||
----------------------
|
||||
REFERENCES
|
||||
**********
|
||||
|
||||
Andrew Morton, "The perfect patch" (tpp).
|
||||
<http://www.ozlabs.org/~akpm/stuff/tpp.txt>
|
||||
|
@ -799,23 +814,28 @@ Jeff Garzik, "Linux kernel patch submission format".
|
|||
|
||||
Greg Kroah-Hartman, "How to piss off a kernel subsystem maintainer".
|
||||
<http://www.kroah.com/log/linux/maintainer.html>
|
||||
|
||||
<http://www.kroah.com/log/linux/maintainer-02.html>
|
||||
|
||||
<http://www.kroah.com/log/linux/maintainer-03.html>
|
||||
|
||||
<http://www.kroah.com/log/linux/maintainer-04.html>
|
||||
|
||||
<http://www.kroah.com/log/linux/maintainer-05.html>
|
||||
|
||||
<http://www.kroah.com/log/linux/maintainer-06.html>
|
||||
|
||||
NO!!!! No more huge patch bombs to linux-kernel@vger.kernel.org people!
|
||||
<https://lkml.org/lkml/2005/7/11/336>
|
||||
|
||||
Kernel Documentation/CodingStyle:
|
||||
<Documentation/CodingStyle>
|
||||
:ref:`Documentation/CodingStyle <codingstyle>`
|
||||
|
||||
Linus Torvalds's mail on the canonical patch format:
|
||||
<http://lkml.org/lkml/2005/4/7/183>
|
||||
|
||||
Andi Kleen, "On submitting kernel patches"
|
||||
Some strategies to get difficult or controversial changes in.
|
||||
|
||||
http://halobates.de/on-submitting-patches.pdf
|
||||
|
||||
--
|
||||
|
|
|
@ -1,9 +1,13 @@
|
|||
.. _applying_patches:
|
||||
|
||||
Applying Patches To The Linux Kernel
|
||||
------------------------------------
|
||||
Applying Patches To The Linux Kernel
|
||||
++++++++++++++++++++++++++++++++++++
|
||||
|
||||
Original by: Jesper Juhl, August 2005
|
||||
Last update: 2006-01-05
|
||||
Original by:
|
||||
Jesper Juhl, August 2005
|
||||
|
||||
Last update:
|
||||
2016-09-14
|
||||
|
||||
|
||||
A frequently asked question on the Linux Kernel Mailing List is how to apply
|
||||
|
@ -17,10 +21,12 @@ their specific patches) is also provided.
|
|||
|
||||
|
||||
What is a patch?
|
||||
---
|
||||
A patch is a small text document containing a delta of changes between two
|
||||
different versions of a source tree. Patches are created with the `diff'
|
||||
================
|
||||
|
||||
A patch is a small text document containing a delta of changes between two
|
||||
different versions of a source tree. Patches are created with the ``diff``
|
||||
program.
|
||||
|
||||
To correctly apply a patch you need to know what base it was generated from
|
||||
and what new version the patch will change the source tree into. These
|
||||
should both be present in the patch file metadata or be possible to deduce
|
||||
|
@ -28,8 +34,9 @@ from the filename.
|
|||
|
||||
|
||||
How do I apply or revert a patch?
|
||||
---
|
||||
You apply a patch with the `patch' program. The patch program reads a diff
|
||||
=================================
|
||||
|
||||
You apply a patch with the ``patch`` program. The patch program reads a diff
|
||||
(or patch) file and makes the changes to the source tree described in it.
|
||||
|
||||
Patches for the Linux kernel are generated relative to the parent directory
|
||||
|
@ -38,26 +45,33 @@ holding the kernel source dir.
|
|||
This means that paths to files inside the patch file contain the name of the
|
||||
kernel source directories it was generated against (or some other directory
|
||||
names like "a/" and "b/").
|
||||
|
||||
Since this is unlikely to match the name of the kernel source dir on your
|
||||
local machine (but is often useful info to see what version an otherwise
|
||||
unlabeled patch was generated against) you should change into your kernel
|
||||
source directory and then strip the first element of the path from filenames
|
||||
in the patch file when applying it (the -p1 argument to `patch' does this).
|
||||
in the patch file when applying it (the ``-p1`` argument to ``patch`` does
|
||||
this).
|
||||
|
||||
To revert a previously applied patch, use the -R argument to patch.
|
||||
So, if you applied a patch like this:
|
||||
So, if you applied a patch like this::
|
||||
|
||||
patch -p1 < ../patch-x.y.z
|
||||
|
||||
You can revert (undo) it like this:
|
||||
You can revert (undo) it like this::
|
||||
|
||||
patch -R -p1 < ../patch-x.y.z
|
||||
|
||||
|
||||
How do I feed a patch/diff file to `patch'?
|
||||
---
|
||||
This (as usual with Linux and other UNIX like operating systems) can be
|
||||
How do I feed a patch/diff file to ``patch``?
|
||||
=============================================
|
||||
|
||||
This (as usual with Linux and other UNIX like operating systems) can be
|
||||
done in several different ways.
|
||||
|
||||
In all the examples below I feed the file (in uncompressed form) to patch
|
||||
via stdin using the following syntax:
|
||||
via stdin using the following syntax::
|
||||
|
||||
patch -p1 < path/to/patch-x.y.z
|
||||
|
||||
If you just want to be able to follow the examples below and don't want to
|
||||
|
@ -65,35 +79,40 @@ know of more than one way to use patch, then you can stop reading this
|
|||
section here.
|
||||
|
||||
Patch can also get the name of the file to use via the -i argument, like
|
||||
this:
|
||||
this::
|
||||
|
||||
patch -p1 -i path/to/patch-x.y.z
|
||||
|
||||
If your patch file is compressed with gzip or bzip2 and you don't want to
|
||||
If your patch file is compressed with gzip or xz and you don't want to
|
||||
uncompress it before applying it, then you can feed it to patch like this
|
||||
instead:
|
||||
zcat path/to/patch-x.y.z.gz | patch -p1
|
||||
bzcat path/to/patch-x.y.z.bz2 | patch -p1
|
||||
instead::
|
||||
|
||||
xzcat path/to/patch-x.y.z.xz | patch -p1
|
||||
bzcat path/to/patch-x.y.z.gz | patch -p1
|
||||
|
||||
If you wish to uncompress the patch file by hand first before applying it
|
||||
(what I assume you've done in the examples below), then you simply run
|
||||
gunzip or bunzip2 on the file -- like this:
|
||||
gunzip or xz on the file -- like this::
|
||||
|
||||
gunzip patch-x.y.z.gz
|
||||
bunzip2 patch-x.y.z.bz2
|
||||
xz -d patch-x.y.z.xz
|
||||
|
||||
Which will leave you with a plain text patch-x.y.z file that you can feed to
|
||||
patch via stdin or the -i argument, as you prefer.
|
||||
patch via stdin or the ``-i`` argument, as you prefer.
|
||||
|
||||
A few other nice arguments for patch are -s which causes patch to be silent
|
||||
A few other nice arguments for patch are ``-s`` which causes patch to be silent
|
||||
except for errors which is nice to prevent errors from scrolling out of the
|
||||
screen too fast, and --dry-run which causes patch to just print a listing of
|
||||
what would happen, but doesn't actually make any changes. Finally --verbose
|
||||
screen too fast, and ``--dry-run`` which causes patch to just print a listing of
|
||||
what would happen, but doesn't actually make any changes. Finally ``--verbose``
|
||||
tells patch to print more information about the work being done.
|
||||
|
||||
|
||||
Common errors when patching
|
||||
---
|
||||
When patch applies a patch file it attempts to verify the sanity of the
|
||||
===========================
|
||||
|
||||
When patch applies a patch file it attempts to verify the sanity of the
|
||||
file in different ways.
|
||||
|
||||
Checking that the file looks like a valid patch file and checking the code
|
||||
around the bits being modified matches the context provided in the patch are
|
||||
just two of the basic sanity checks patch does.
|
||||
|
@ -111,13 +130,13 @@ everything looks good it has just moved up or down a bit, and patch will
|
|||
usually adjust the line numbers and apply the patch.
|
||||
|
||||
Whenever patch applies a patch that it had to modify a bit to make it fit
|
||||
it'll tell you about it by saying the patch applied with 'fuzz'.
|
||||
it'll tell you about it by saying the patch applied with **fuzz**.
|
||||
You should be wary of such changes since even though patch probably got it
|
||||
right it doesn't /always/ get it right, and the result will sometimes be
|
||||
wrong.
|
||||
|
||||
When patch encounters a change that it can't fix up with fuzz it rejects it
|
||||
outright and leaves a file with a .rej extension (a reject file). You can
|
||||
outright and leaves a file with a ``.rej`` extension (a reject file). You can
|
||||
read this file to see exactly what change couldn't be applied, so you can
|
||||
go fix it up by hand if you wish.
|
||||
|
||||
|
@ -132,43 +151,47 @@ to start with a fresh tree downloaded in full from kernel.org.
|
|||
|
||||
Let's look a bit more at some of the messages patch can produce.
|
||||
|
||||
If patch stops and presents a "File to patch:" prompt, then patch could not
|
||||
If patch stops and presents a ``File to patch:`` prompt, then patch could not
|
||||
find a file to be patched. Most likely you forgot to specify -p1 or you are
|
||||
in the wrong directory. Less often, you'll find patches that need to be
|
||||
applied with -p0 instead of -p1 (reading the patch file should reveal if
|
||||
applied with ``-p0`` instead of ``-p1`` (reading the patch file should reveal if
|
||||
this is the case -- if so, then this is an error by the person who created
|
||||
the patch but is not fatal).
|
||||
|
||||
If you get "Hunk #2 succeeded at 1887 with fuzz 2 (offset 7 lines)." or a
|
||||
If you get ``Hunk #2 succeeded at 1887 with fuzz 2 (offset 7 lines).`` or a
|
||||
message similar to that, then it means that patch had to adjust the location
|
||||
of the change (in this example it needed to move 7 lines from where it
|
||||
expected to make the change to make it fit).
|
||||
|
||||
The resulting file may or may not be OK, depending on the reason the file
|
||||
was different than expected.
|
||||
|
||||
This often happens if you try to apply a patch that was generated against a
|
||||
different kernel version than the one you are trying to patch.
|
||||
|
||||
If you get a message like "Hunk #3 FAILED at 2387.", then it means that the
|
||||
If you get a message like ``Hunk #3 FAILED at 2387.``, then it means that the
|
||||
patch could not be applied correctly and the patch program was unable to
|
||||
fuzz its way through. This will generate a .rej file with the change that
|
||||
caused the patch to fail and also a .orig file showing you the original
|
||||
fuzz its way through. This will generate a ``.rej`` file with the change that
|
||||
caused the patch to fail and also a ``.orig`` file showing you the original
|
||||
content that couldn't be changed.
|
||||
|
||||
If you get "Reversed (or previously applied) patch detected! Assume -R? [n]"
|
||||
If you get ``Reversed (or previously applied) patch detected! Assume -R? [n]``
|
||||
then patch detected that the change contained in the patch seems to have
|
||||
already been made.
|
||||
|
||||
If you actually did apply this patch previously and you just re-applied it
|
||||
in error, then just say [n]o and abort this patch. If you applied this patch
|
||||
previously and actually intended to revert it, but forgot to specify -R,
|
||||
then you can say [y]es here to make patch revert it for you.
|
||||
then you can say [**y**]es here to make patch revert it for you.
|
||||
|
||||
This can also happen if the creator of the patch reversed the source and
|
||||
destination directories when creating the patch, and in that case reverting
|
||||
the patch will in fact apply it.
|
||||
|
||||
A message similar to "patch: **** unexpected end of file in patch" or "patch
|
||||
unexpectedly ends in middle of line" means that patch could make no sense of
|
||||
the file you fed to it. Either your download is broken, you tried to feed
|
||||
patch a compressed patch file without uncompressing it first, or the patch
|
||||
A message similar to ``patch: **** unexpected end of file in patch`` or
|
||||
``patch unexpectedly ends in middle of line`` means that patch could make no
|
||||
sense of the file you fed to it. Either your download is broken, you tried to
|
||||
feed patch a compressed patch file without uncompressing it first, or the patch
|
||||
file that you are using has been mangled by a mail client or mail transfer
|
||||
agent along the way somewhere, e.g., by splitting a long line into two lines.
|
||||
Often these warnings can easily be fixed by joining (concatenating) the
|
||||
|
@ -182,28 +205,32 @@ to start over with a fresh download of a full kernel tree and the patch you
|
|||
wish to apply.
|
||||
|
||||
|
||||
Are there any alternatives to `patch'?
|
||||
---
|
||||
Yes there are alternatives.
|
||||
Are there any alternatives to ``patch``?
|
||||
========================================
|
||||
|
||||
You can use the `interdiff' program (http://cyberelk.net/tim/patchutils/) to
|
||||
|
||||
Yes there are alternatives.
|
||||
|
||||
You can use the ``interdiff`` program (http://cyberelk.net/tim/patchutils/) to
|
||||
generate a patch representing the differences between two patches and then
|
||||
apply the result.
|
||||
This will let you move from something like 2.6.12.2 to 2.6.12.3 in a single
|
||||
|
||||
This will let you move from something like 4.7.2 to 4.7.3 in a single
|
||||
step. The -z flag to interdiff will even let you feed it patches in gzip or
|
||||
bzip2 compressed form directly without the use of zcat or bzcat or manual
|
||||
decompression.
|
||||
|
||||
Here's how you'd go from 2.6.12.2 to 2.6.12.3 in a single step:
|
||||
interdiff -z ../patch-2.6.12.2.bz2 ../patch-2.6.12.3.gz | patch -p1
|
||||
Here's how you'd go from 4.7.2 to 4.7.3 in a single step::
|
||||
|
||||
interdiff -z ../patch-4.7.2.gz ../patch-4.7.3.gz | patch -p1
|
||||
|
||||
Although interdiff may save you a step or two you are generally advised to
|
||||
do the additional steps since interdiff can get things wrong in some cases.
|
||||
|
||||
Another alternative is `ketchup', which is a python script for automatic
|
||||
Another alternative is ``ketchup``, which is a python script for automatic
|
||||
downloading and applying of patches (http://www.selenic.com/ketchup/).
|
||||
|
||||
Other nice tools are diffstat, which shows a summary of changes made by a
|
||||
Other nice tools are diffstat, which shows a summary of changes made by a
|
||||
patch; lsdiff, which displays a short listing of affected files in a patch
|
||||
file, along with (optionally) the line numbers of the start of each patch;
|
||||
and grepdiff, which displays a list of the files modified by a patch where
|
||||
|
@ -211,99 +238,103 @@ the patch contains a given regular expression.
|
|||
|
||||
|
||||
Where can I download the patches?
|
||||
---
|
||||
The patches are available at http://kernel.org/
|
||||
=================================
|
||||
|
||||
The patches are available at http://kernel.org/
|
||||
Most recent patches are linked from the front page, but they also have
|
||||
specific homes.
|
||||
|
||||
The 2.6.x.y (-stable) and 2.6.x patches live at
|
||||
ftp://ftp.kernel.org/pub/linux/kernel/v2.6/
|
||||
The 4.x.y (-stable) and 4.x patches live at
|
||||
|
||||
ftp://ftp.kernel.org/pub/linux/kernel/v4.x/
|
||||
|
||||
The -rc patches live at
|
||||
ftp://ftp.kernel.org/pub/linux/kernel/v2.6/testing/
|
||||
|
||||
The -git patches live at
|
||||
ftp://ftp.kernel.org/pub/linux/kernel/v2.6/snapshots/
|
||||
ftp://ftp.kernel.org/pub/linux/kernel/v4.x/testing/
|
||||
|
||||
The -mm kernels live at
|
||||
ftp://ftp.kernel.org/pub/linux/kernel/people/akpm/patches/2.6/
|
||||
|
||||
In place of ftp.kernel.org you can use ftp.cc.kernel.org, where cc is a
|
||||
In place of ``ftp.kernel.org`` you can use ``ftp.cc.kernel.org``, where cc is a
|
||||
country code. This way you'll be downloading from a mirror site that's most
|
||||
likely geographically closer to you, resulting in faster downloads for you,
|
||||
less bandwidth used globally and less load on the main kernel.org servers --
|
||||
these are good things, so do use mirrors when possible.
|
||||
|
||||
|
||||
The 2.6.x kernels
|
||||
---
|
||||
These are the base stable releases released by Linus. The highest numbered
|
||||
The 4.x kernels
|
||||
===============
|
||||
|
||||
These are the base stable releases released by Linus. The highest numbered
|
||||
release is the most recent.
|
||||
|
||||
If regressions or other serious flaws are found, then a -stable fix patch
|
||||
will be released (see below) on top of this base. Once a new 2.6.x base
|
||||
will be released (see below) on top of this base. Once a new 4.x base
|
||||
kernel is released, a patch is made available that is a delta between the
|
||||
previous 2.6.x kernel and the new one.
|
||||
previous 4.x kernel and the new one.
|
||||
|
||||
To apply a patch moving from 2.6.11 to 2.6.12, you'd do the following (note
|
||||
that such patches do *NOT* apply on top of 2.6.x.y kernels but on top of the
|
||||
base 2.6.x kernel -- if you need to move from 2.6.x.y to 2.6.x+1 you need to
|
||||
first revert the 2.6.x.y patch).
|
||||
To apply a patch moving from 4.6 to 4.7, you'd do the following (note
|
||||
that such patches do **NOT** apply on top of 4.x.y kernels but on top of the
|
||||
base 4.x kernel -- if you need to move from 4.x.y to 4.x+1 you need to
|
||||
first revert the 4.x.y patch).
|
||||
|
||||
Here are some examples:
|
||||
Here are some examples::
|
||||
|
||||
# moving from 2.6.11 to 2.6.12
|
||||
$ cd ~/linux-2.6.11 # change to kernel source dir
|
||||
$ patch -p1 < ../patch-2.6.12 # apply the 2.6.12 patch
|
||||
$ cd ..
|
||||
$ mv linux-2.6.11 linux-2.6.12 # rename source dir
|
||||
# moving from 4.6 to 4.7
|
||||
|
||||
# moving from 2.6.11.1 to 2.6.12
|
||||
$ cd ~/linux-2.6.11.1 # change to kernel source dir
|
||||
$ patch -p1 -R < ../patch-2.6.11.1 # revert the 2.6.11.1 patch
|
||||
# source dir is now 2.6.11
|
||||
$ patch -p1 < ../patch-2.6.12 # apply new 2.6.12 patch
|
||||
$ cd ..
|
||||
$ mv linux-2.6.11.1 linux-2.6.12 # rename source dir
|
||||
$ cd ~/linux-4.6 # change to kernel source dir
|
||||
$ patch -p1 < ../patch-4.7 # apply the 4.7 patch
|
||||
$ cd ..
|
||||
$ mv linux-4.6 linux-4.7 # rename source dir
|
||||
|
||||
# moving from 4.6.1 to 4.7
|
||||
|
||||
$ cd ~/linux-4.6.1 # change to kernel source dir
|
||||
$ patch -p1 -R < ../patch-4.6.1 # revert the 4.6.1 patch
|
||||
# source dir is now 4.6
|
||||
$ patch -p1 < ../patch-4.7 # apply new 4.7 patch
|
||||
$ cd ..
|
||||
$ mv linux-4.6.1 linux-4.7 # rename source dir
|
||||
|
||||
|
||||
The 2.6.x.y kernels
|
||||
---
|
||||
Kernels with 4-digit versions are -stable kernels. They contain small(ish)
|
||||
The 4.x.y kernels
|
||||
=================
|
||||
|
||||
Kernels with 3-digit versions are -stable kernels. They contain small(ish)
|
||||
critical fixes for security problems or significant regressions discovered
|
||||
in a given 2.6.x kernel.
|
||||
in a given 4.x kernel.
|
||||
|
||||
This is the recommended branch for users who want the most recent stable
|
||||
kernel and are not interested in helping test development/experimental
|
||||
versions.
|
||||
|
||||
If no 2.6.x.y kernel is available, then the highest numbered 2.6.x kernel is
|
||||
If no 4.x.y kernel is available, then the highest numbered 4.x kernel is
|
||||
the current stable kernel.
|
||||
|
||||
note: the -stable team usually do make incremental patches available as well
|
||||
.. note::
|
||||
|
||||
The -stable team usually do make incremental patches available as well
|
||||
as patches against the latest mainline release, but I only cover the
|
||||
non-incremental ones below. The incremental ones can be found at
|
||||
ftp://ftp.kernel.org/pub/linux/kernel/v2.6/incr/
|
||||
ftp://ftp.kernel.org/pub/linux/kernel/v4.x/incr/
|
||||
|
||||
These patches are not incremental, meaning that for example the 2.6.12.3
|
||||
patch does not apply on top of the 2.6.12.2 kernel source, but rather on top
|
||||
of the base 2.6.12 kernel source .
|
||||
So, in order to apply the 2.6.12.3 patch to your existing 2.6.12.2 kernel
|
||||
source you have to first back out the 2.6.12.2 patch (so you are left with a
|
||||
base 2.6.12 kernel source) and then apply the new 2.6.12.3 patch.
|
||||
These patches are not incremental, meaning that for example the 4.7.3
|
||||
patch does not apply on top of the 4.7.2 kernel source, but rather on top
|
||||
of the base 4.7 kernel source.
|
||||
|
||||
Here's a small example:
|
||||
So, in order to apply the 4.7.3 patch to your existing 4.7.2 kernel
|
||||
source you have to first back out the 4.7.2 patch (so you are left with a
|
||||
base 4.7 kernel source) and then apply the new 4.7.3 patch.
|
||||
|
||||
$ cd ~/linux-2.6.12.2 # change into the kernel source dir
|
||||
$ patch -p1 -R < ../patch-2.6.12.2 # revert the 2.6.12.2 patch
|
||||
$ patch -p1 < ../patch-2.6.12.3 # apply the new 2.6.12.3 patch
|
||||
$ cd ..
|
||||
$ mv linux-2.6.12.2 linux-2.6.12.3 # rename the kernel source dir
|
||||
Here's a small example::
|
||||
|
||||
$ cd ~/linux-4.7.2 # change to the kernel source dir
|
||||
$ patch -p1 -R < ../patch-4.7.2 # revert the 4.7.2 patch
|
||||
$ patch -p1 < ../patch-4.7.3 # apply the new 4.7.3 patch
|
||||
$ cd ..
|
||||
$ mv linux-4.7.2 linux-4.7.3 # rename the kernel source dir
|
||||
|
||||
The -rc kernels
|
||||
---
|
||||
These are release-candidate kernels. These are development kernels released
|
||||
===============
|
||||
|
||||
These are release-candidate kernels. These are development kernels released
|
||||
by Linus whenever he deems the current git (the kernel's source management
|
||||
tool) tree to be in a reasonably sane state adequate for testing.
|
||||
|
||||
|
@ -317,39 +348,44 @@ This is a good branch to run for people who want to help out testing
|
|||
development kernels but do not want to run some of the really experimental
|
||||
stuff (such people should see the sections about -git and -mm kernels below).
|
||||
|
||||
The -rc patches are not incremental, they apply to a base 2.6.x kernel, just
|
||||
like the 2.6.x.y patches described above. The kernel version before the -rcN
|
||||
The -rc patches are not incremental, they apply to a base 4.x kernel, just
|
||||
like the 4.x.y patches described above. The kernel version before the -rcN
|
||||
suffix denotes the version of the kernel that this -rc kernel will eventually
|
||||
turn into.
|
||||
So, 2.6.13-rc5 means that this is the fifth release candidate for the 2.6.13
|
||||
kernel and the patch should be applied on top of the 2.6.12 kernel source.
|
||||
|
||||
Here are 3 examples of how to apply these patches:
|
||||
So, 4.8-rc5 means that this is the fifth release candidate for the 4.8
|
||||
kernel and the patch should be applied on top of the 4.7 kernel source.
|
||||
|
||||
# first an example of moving from 2.6.12 to 2.6.13-rc3
|
||||
$ cd ~/linux-2.6.12 # change into the 2.6.12 source dir
|
||||
$ patch -p1 < ../patch-2.6.13-rc3 # apply the 2.6.13-rc3 patch
|
||||
$ cd ..
|
||||
$ mv linux-2.6.12 linux-2.6.13-rc3 # rename the source dir
|
||||
Here are 3 examples of how to apply these patches::
|
||||
|
||||
# now let's move from 2.6.13-rc3 to 2.6.13-rc5
|
||||
$ cd ~/linux-2.6.13-rc3 # change into the 2.6.13-rc3 dir
|
||||
$ patch -p1 -R < ../patch-2.6.13-rc3 # revert the 2.6.13-rc3 patch
|
||||
$ patch -p1 < ../patch-2.6.13-rc5 # apply the new 2.6.13-rc5 patch
|
||||
$ cd ..
|
||||
$ mv linux-2.6.13-rc3 linux-2.6.13-rc5 # rename the source dir
|
||||
# first an example of moving from 4.7 to 4.8-rc3
|
||||
|
||||
# finally let's try and move from 2.6.12.3 to 2.6.13-rc5
|
||||
$ cd ~/linux-2.6.12.3 # change to the kernel source dir
|
||||
$ patch -p1 -R < ../patch-2.6.12.3 # revert the 2.6.12.3 patch
|
||||
$ patch -p1 < ../patch-2.6.13-rc5 # apply new 2.6.13-rc5 patch
|
||||
$ cd ..
|
||||
$ mv linux-2.6.12.3 linux-2.6.13-rc5 # rename the kernel source dir
|
||||
$ cd ~/linux-4.7 # change to the 4.7 source dir
|
||||
$ patch -p1 < ../patch-4.8-rc3 # apply the 4.8-rc3 patch
|
||||
$ cd ..
|
||||
$ mv linux-4.7 linux-4.8-rc3 # rename the source dir
|
||||
|
||||
# now let's move from 4.8-rc3 to 4.8-rc5
|
||||
|
||||
$ cd ~/linux-4.8-rc3 # change to the 4.8-rc3 dir
|
||||
$ patch -p1 -R < ../patch-4.8-rc3 # revert the 4.8-rc3 patch
|
||||
$ patch -p1 < ../patch-4.8-rc5 # apply the new 4.8-rc5 patch
|
||||
$ cd ..
|
||||
$ mv linux-4.8-rc3 linux-4.8-rc5 # rename the source dir
|
||||
|
||||
# finally let's try and move from 4.7.3 to 4.8-rc5
|
||||
|
||||
$ cd ~/linux-4.7.3 # change to the kernel source dir
|
||||
$ patch -p1 -R < ../patch-4.7.3 # revert the 4.7.3 patch
|
||||
$ patch -p1 < ../patch-4.8-rc5 # apply new 4.8-rc5 patch
|
||||
$ cd ..
|
||||
$ mv linux-4.7.3 linux-4.8-rc5 # rename the kernel source dir
|
||||
|
||||
|
||||
The -git kernels
|
||||
---
|
||||
These are daily snapshots of Linus' kernel tree (managed in a git
|
||||
================
|
||||
|
||||
These are daily snapshots of Linus' kernel tree (managed in a git
|
||||
repository, hence the name).
|
||||
|
||||
These patches are usually released daily and represent the current state of
|
||||
|
@ -357,91 +393,66 @@ Linus's tree. They are more experimental than -rc kernels since they are
|
|||
generated automatically without even a cursory glance to see if they are
|
||||
sane.
|
||||
|
||||
-git patches are not incremental and apply either to a base 2.6.x kernel or
|
||||
a base 2.6.x-rc kernel -- you can see which from their name.
|
||||
A patch named 2.6.12-git1 applies to the 2.6.12 kernel source and a patch
|
||||
named 2.6.13-rc3-git2 applies to the source of the 2.6.13-rc3 kernel.
|
||||
-git patches are not incremental and apply either to a base 4.x kernel or
|
||||
a base 4.x-rc kernel -- you can see which from their name.
|
||||
A patch named 4.7-git1 applies to the 4.7 kernel source and a patch
|
||||
named 4.8-rc3-git2 applies to the source of the 4.8-rc3 kernel.
|
||||
|
||||
Here are some examples of how to apply these patches:
|
||||
Here are some examples of how to apply these patches::
|
||||
|
||||
# moving from 2.6.12 to 2.6.12-git1
|
||||
$ cd ~/linux-2.6.12 # change to the kernel source dir
|
||||
$ patch -p1 < ../patch-2.6.12-git1 # apply the 2.6.12-git1 patch
|
||||
$ cd ..
|
||||
$ mv linux-2.6.12 linux-2.6.12-git1 # rename the kernel source dir
|
||||
# moving from 4.7 to 4.7-git1
|
||||
|
||||
# moving from 2.6.12-git1 to 2.6.13-rc2-git3
|
||||
$ cd ~/linux-2.6.12-git1 # change to the kernel source dir
|
||||
$ patch -p1 -R < ../patch-2.6.12-git1 # revert the 2.6.12-git1 patch
|
||||
# we now have a 2.6.12 kernel
|
||||
$ patch -p1 < ../patch-2.6.13-rc2 # apply the 2.6.13-rc2 patch
|
||||
# the kernel is now 2.6.13-rc2
|
||||
$ patch -p1 < ../patch-2.6.13-rc2-git3 # apply the 2.6.13-rc2-git3 patch
|
||||
# the kernel is now 2.6.13-rc2-git3
|
||||
$ cd ..
|
||||
$ mv linux-2.6.12-git1 linux-2.6.13-rc2-git3 # rename source dir
|
||||
$ cd ~/linux-4.7 # change to the kernel source dir
|
||||
$ patch -p1 < ../patch-4.7-git1 # apply the 4.7-git1 patch
|
||||
$ cd ..
|
||||
$ mv linux-4.7 linux-4.7-git1 # rename the kernel source dir
|
||||
|
||||
# moving from 4.7-git1 to 4.8-rc2-git3
|
||||
|
||||
$ cd ~/linux-4.7-git1 # change to the kernel source dir
|
||||
$ patch -p1 -R < ../patch-4.7-git1 # revert the 4.7-git1 patch
|
||||
# we now have a 4.7 kernel
|
||||
$ patch -p1 < ../patch-4.8-rc2 # apply the 4.8-rc2 patch
|
||||
# the kernel is now 4.8-rc2
|
||||
$ patch -p1 < ../patch-4.8-rc2-git3 # apply the 4.8-rc2-git3 patch
|
||||
# the kernel is now 4.8-rc2-git3
|
||||
$ cd ..
|
||||
$ mv linux-4.7-git1 linux-4.8-rc2-git3 # rename source dir
|
||||
|
||||
|
||||
The -mm kernels
|
||||
---
|
||||
These are experimental kernels released by Andrew Morton.
|
||||
The -mm patches and the linux-next tree
|
||||
=======================================
|
||||
|
||||
The -mm tree serves as a sort of proving ground for new features and other
|
||||
experimental patches.
|
||||
Once a patch has proved its worth in -mm for a while Andrew pushes it on to
|
||||
Linus for inclusion in mainline.
|
||||
The -mm patches are experimental patches released by Andrew Morton.
|
||||
|
||||
Although it's encouraged that patches flow to Linus via the -mm tree, this
|
||||
is not always enforced.
|
||||
Subsystem maintainers (or individuals) sometimes push their patches directly
|
||||
to Linus, even though (or after) they have been merged and tested in -mm (or
|
||||
sometimes even without prior testing in -mm).
|
||||
In the past, -mm tree were used to also test subsystem patches, but this
|
||||
function is now done via the
|
||||
:ref:`linux-next <https://www.kernel.org/doc/man-pages/linux-next.html>`
|
||||
tree. The Subsystem maintainers push their patches first to linux-next,
|
||||
and, during the merge window, sends them directly to Linus.
|
||||
|
||||
You should generally strive to get your patches into mainline via -mm to
|
||||
ensure maximum testing.
|
||||
The -mm patches serve as a sort of proving ground for new features and other
|
||||
experimental patches that aren't merged via a subsystem tree.
|
||||
Once such patches has proved its worth in -mm for a while Andrew pushes
|
||||
it on to Linus for inclusion in mainline.
|
||||
|
||||
This branch is in constant flux and contains many experimental features, a
|
||||
The linux-next tree is daily updated, and includes the -mm patches.
|
||||
Both are in constant flux and contains many experimental features, a
|
||||
lot of debugging patches not appropriate for mainline etc., and is the most
|
||||
experimental of the branches described in this document.
|
||||
|
||||
These kernels are not appropriate for use on systems that are supposed to be
|
||||
These patches are not appropriate for use on systems that are supposed to be
|
||||
stable and they are more risky to run than any of the other branches (make
|
||||
sure you have up-to-date backups -- that goes for any experimental kernel but
|
||||
even more so for -mm kernels).
|
||||
even more so for -mm patches or using a Kernel from the linux-next tree).
|
||||
|
||||
These kernels in addition to all the other experimental patches they contain
|
||||
usually also contain any changes in the mainline -git kernels available at
|
||||
the time of release.
|
||||
Testing of -mm patches and linux-next is greatly appreciated since the whole
|
||||
point of those are to weed out regressions, crashes, data corruption bugs,
|
||||
build breakage (and any other bug in general) before changes are merged into
|
||||
the more stable mainline Linus tree.
|
||||
|
||||
Testing of -mm kernels is greatly appreciated since the whole point of the
|
||||
tree is to weed out regressions, crashes, data corruption bugs, build
|
||||
breakage (and any other bug in general) before changes are merged into the
|
||||
more stable mainline Linus tree.
|
||||
But testers of -mm should be aware that breakage in this tree is more common
|
||||
than in any other tree.
|
||||
|
||||
The -mm kernels are not released on a fixed schedule, but usually a few -mm
|
||||
kernels are released in between each -rc kernel (1 to 3 is common).
|
||||
The -mm kernels apply to either a base 2.6.x kernel (when no -rc kernels
|
||||
have been released yet) or to a Linus -rc kernel.
|
||||
|
||||
Here are some examples of applying the -mm patches:
|
||||
|
||||
# moving from 2.6.12 to 2.6.12-mm1
|
||||
$ cd ~/linux-2.6.12 # change to the 2.6.12 source dir
|
||||
$ patch -p1 < ../2.6.12-mm1 # apply the 2.6.12-mm1 patch
|
||||
$ cd ..
|
||||
$ mv linux-2.6.12 linux-2.6.12-mm1 # rename the source appropriately
|
||||
|
||||
# moving from 2.6.12-mm1 to 2.6.13-rc3-mm3
|
||||
$ cd ~/linux-2.6.12-mm1
|
||||
$ patch -p1 -R < ../2.6.12-mm1 # revert the 2.6.12-mm1 patch
|
||||
# we now have a 2.6.12 source
|
||||
$ patch -p1 < ../patch-2.6.13-rc3 # apply the 2.6.13-rc3 patch
|
||||
# we now have a 2.6.13-rc3 source
|
||||
$ patch -p1 < ../2.6.13-rc3-mm3 # apply the 2.6.13-rc3-mm3 patch
|
||||
$ cd ..
|
||||
$ mv linux-2.6.12-mm1 linux-2.6.13-rc3-mm3 # rename the source dir
|
||||
But testers of -mm and linux-next should be aware that breakages are
|
||||
more common than in any other tree.
|
||||
|
||||
|
||||
This concludes this list of explanations of the various kernel trees.
|
||||
|
|
|
@ -73,4 +73,13 @@ SunXi family
|
|||
* Octa ARM Cortex-A7 based SoCs
|
||||
- Allwinner A83T
|
||||
+ Datasheet
|
||||
http://dl.linux-sunxi.org/A83T/A83T_datasheet_Revision_1.1.pdf
|
||||
https://github.com/allwinner-zh/documents/raw/master/A83T/A83T_Datasheet_v1.3_20150510.pdf
|
||||
+ User Manual
|
||||
https://github.com/allwinner-zh/documents/raw/master/A83T/A83T_User_Manual_v1.5.1_20150513.pdf
|
||||
|
||||
* Quad ARM Cortex-A53 based SoCs
|
||||
- Allwinner A64
|
||||
+ Datasheet
|
||||
http://dl.linux-sunxi.org/A64/A64_Datasheet_V1.1.pdf
|
||||
+ User Manual
|
||||
http://dl.linux-sunxi.org/A64/Allwinner%20A64%20User%20Manual%20v1.0.pdf
|
||||
|
|
|
@ -31,24 +31,25 @@ serve as a convenient shorthand for the implementation of the
|
|||
hardware-specific bits for the hypothetical "foo" hardware.
|
||||
|
||||
Tying the two halves of this interface together is struct clk_hw, which
|
||||
is defined in struct clk_foo and pointed to within struct clk. This
|
||||
is defined in struct clk_foo and pointed to within struct clk_core. This
|
||||
allows for easy navigation between the two discrete halves of the common
|
||||
clock interface.
|
||||
|
||||
Part 2 - common data structures and api
|
||||
|
||||
Below is the common struct clk definition from
|
||||
include/linux/clk-private.h, modified for brevity:
|
||||
Below is the common struct clk_core definition from
|
||||
drivers/clk/clk.c, modified for brevity:
|
||||
|
||||
struct clk {
|
||||
struct clk_core {
|
||||
const char *name;
|
||||
const struct clk_ops *ops;
|
||||
struct clk_hw *hw;
|
||||
char **parent_names;
|
||||
struct clk **parents;
|
||||
struct clk *parent;
|
||||
struct hlist_head children;
|
||||
struct hlist_node child_node;
|
||||
struct module *owner;
|
||||
struct clk_core *parent;
|
||||
const char **parent_names;
|
||||
struct clk_core **parents;
|
||||
u8 num_parents;
|
||||
u8 new_parent_index;
|
||||
...
|
||||
};
|
||||
|
||||
|
@ -56,16 +57,19 @@ The members above make up the core of the clk tree topology. The clk
|
|||
api itself defines several driver-facing functions which operate on
|
||||
struct clk. That api is documented in include/linux/clk.h.
|
||||
|
||||
Platforms and devices utilizing the common struct clk use the struct
|
||||
clk_ops pointer in struct clk to perform the hardware-specific parts of
|
||||
the operations defined in clk.h:
|
||||
Platforms and devices utilizing the common struct clk_core use the struct
|
||||
clk_ops pointer in struct clk_core to perform the hardware-specific parts of
|
||||
the operations defined in clk-provider.h:
|
||||
|
||||
struct clk_ops {
|
||||
int (*prepare)(struct clk_hw *hw);
|
||||
void (*unprepare)(struct clk_hw *hw);
|
||||
int (*is_prepared)(struct clk_hw *hw);
|
||||
void (*unprepare_unused)(struct clk_hw *hw);
|
||||
int (*enable)(struct clk_hw *hw);
|
||||
void (*disable)(struct clk_hw *hw);
|
||||
int (*is_enabled)(struct clk_hw *hw);
|
||||
void (*disable_unused)(struct clk_hw *hw);
|
||||
unsigned long (*recalc_rate)(struct clk_hw *hw,
|
||||
unsigned long parent_rate);
|
||||
long (*round_rate)(struct clk_hw *hw,
|
||||
|
@ -84,6 +88,8 @@ the operations defined in clk.h:
|
|||
u8 index);
|
||||
unsigned long (*recalc_accuracy)(struct clk_hw *hw,
|
||||
unsigned long parent_accuracy);
|
||||
int (*get_phase)(struct clk_hw *hw);
|
||||
int (*set_phase)(struct clk_hw *hw, int degrees);
|
||||
void (*init)(struct clk_hw *hw);
|
||||
int (*debug_init)(struct clk_hw *hw,
|
||||
struct dentry *dentry);
|
||||
|
@ -91,7 +97,7 @@ the operations defined in clk.h:
|
|||
|
||||
Part 3 - hardware clk implementations
|
||||
|
||||
The strength of the common struct clk comes from its .ops and .hw pointers
|
||||
The strength of the common struct clk_core comes from its .ops and .hw pointers
|
||||
which abstract the details of struct clk from the hardware-specific bits, and
|
||||
vice versa. To illustrate consider the simple gateable clk implementation in
|
||||
drivers/clk/clk-gate.c:
|
||||
|
@ -107,7 +113,7 @@ struct clk_gate contains struct clk_hw hw as well as hardware-specific
|
|||
knowledge about which register and bit controls this clk's gating.
|
||||
Nothing about clock topology or accounting, such as enable_count or
|
||||
notifier_count, is needed here. That is all handled by the common
|
||||
framework code and struct clk.
|
||||
framework code and struct clk_core.
|
||||
|
||||
Let's walk through enabling this clk from driver code:
|
||||
|
||||
|
@ -139,22 +145,18 @@ static void clk_gate_set_bit(struct clk_gate *gate)
|
|||
|
||||
Note that to_clk_gate is defined as:
|
||||
|
||||
#define to_clk_gate(_hw) container_of(_hw, struct clk_gate, clk)
|
||||
#define to_clk_gate(_hw) container_of(_hw, struct clk_gate, hw)
|
||||
|
||||
This pattern of abstraction is used for every clock hardware
|
||||
representation.
|
||||
|
||||
Part 4 - supporting your own clk hardware
|
||||
|
||||
When implementing support for a new type of clock it only necessary to
|
||||
When implementing support for a new type of clock it is only necessary to
|
||||
include the following header:
|
||||
|
||||
#include <linux/clk-provider.h>
|
||||
|
||||
include/linux/clk.h is included within that header and clk-private.h
|
||||
must never be included from the code which implements the operations for
|
||||
a clock. More on that below in Part 5.
|
||||
|
||||
To construct a clk hardware structure for your platform you must define
|
||||
the following:
|
||||
|
||||
|
|
|
@ -14,11 +14,17 @@
|
|||
|
||||
import sys
|
||||
import os
|
||||
import sphinx
|
||||
|
||||
# Get Sphinx version
|
||||
major, minor, patch = map(int, sphinx.__version__.split("."))
|
||||
|
||||
|
||||
# If extensions (or modules to document with autodoc) are in another directory,
|
||||
# add these directories to sys.path here. If the directory is relative to the
|
||||
# documentation root, use os.path.abspath to make it absolute, like shown here.
|
||||
sys.path.insert(0, os.path.abspath('sphinx'))
|
||||
from load_config import loadConfig
|
||||
|
||||
# -- General configuration ------------------------------------------------
|
||||
|
||||
|
@ -28,14 +34,13 @@ sys.path.insert(0, os.path.abspath('sphinx'))
|
|||
# Add any Sphinx extension module names here, as strings. They can be
|
||||
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
|
||||
# ones.
|
||||
extensions = ['kernel-doc', 'rstFlatTable', 'kernel_include']
|
||||
extensions = ['kernel-doc', 'rstFlatTable', 'kernel_include', 'cdomain']
|
||||
|
||||
# Gracefully handle missing rst2pdf.
|
||||
try:
|
||||
import rst2pdf
|
||||
extensions += ['rst2pdf.pdfbuilder']
|
||||
except ImportError:
|
||||
pass
|
||||
# The name of the math extension changed on Sphinx 1.4
|
||||
if minor > 3:
|
||||
extensions.append("sphinx.ext.imgmath")
|
||||
else:
|
||||
extensions.append("sphinx.ext.pngmath")
|
||||
|
||||
# Add any paths that contain templates here, relative to this directory.
|
||||
templates_path = ['_templates']
|
||||
|
@ -252,23 +257,90 @@ htmlhelp_basename = 'TheLinuxKerneldoc'
|
|||
|
||||
latex_elements = {
|
||||
# The paper size ('letterpaper' or 'a4paper').
|
||||
#'papersize': 'letterpaper',
|
||||
'papersize': 'a4paper',
|
||||
|
||||
# The font size ('10pt', '11pt' or '12pt').
|
||||
#'pointsize': '10pt',
|
||||
|
||||
# Additional stuff for the LaTeX preamble.
|
||||
#'preamble': '',
|
||||
'pointsize': '8pt',
|
||||
|
||||
# Latex figure (float) alignment
|
||||
#'figure_align': 'htbp',
|
||||
|
||||
# Don't mangle with UTF-8 chars
|
||||
'inputenc': '',
|
||||
'utf8extra': '',
|
||||
|
||||
# Additional stuff for the LaTeX preamble.
|
||||
'preamble': '''
|
||||
% Adjust margins
|
||||
\\usepackage[margin=0.5in, top=1in, bottom=1in]{geometry}
|
||||
|
||||
% Allow generate some pages in landscape
|
||||
\\usepackage{lscape}
|
||||
|
||||
% Put notes in color and let them be inside a table
|
||||
\\definecolor{NoteColor}{RGB}{204,255,255}
|
||||
\\definecolor{WarningColor}{RGB}{255,204,204}
|
||||
\\definecolor{AttentionColor}{RGB}{255,255,204}
|
||||
\\definecolor{OtherColor}{RGB}{204,204,204}
|
||||
\\newlength{\\mynoticelength}
|
||||
\\makeatletter\\newenvironment{coloredbox}[1]{%
|
||||
\\setlength{\\fboxrule}{1pt}
|
||||
\\setlength{\\fboxsep}{7pt}
|
||||
\\setlength{\\mynoticelength}{\\linewidth}
|
||||
\\addtolength{\\mynoticelength}{-2\\fboxsep}
|
||||
\\addtolength{\\mynoticelength}{-2\\fboxrule}
|
||||
\\begin{lrbox}{\\@tempboxa}\\begin{minipage}{\\mynoticelength}}{\\end{minipage}\\end{lrbox}%
|
||||
\\ifthenelse%
|
||||
{\\equal{\\py@noticetype}{note}}%
|
||||
{\\colorbox{NoteColor}{\\usebox{\\@tempboxa}}}%
|
||||
{%
|
||||
\\ifthenelse%
|
||||
{\\equal{\\py@noticetype}{warning}}%
|
||||
{\\colorbox{WarningColor}{\\usebox{\\@tempboxa}}}%
|
||||
{%
|
||||
\\ifthenelse%
|
||||
{\\equal{\\py@noticetype}{attention}}%
|
||||
{\\colorbox{AttentionColor}{\\usebox{\\@tempboxa}}}%
|
||||
{\\colorbox{OtherColor}{\\usebox{\\@tempboxa}}}%
|
||||
}%
|
||||
}%
|
||||
}\\makeatother
|
||||
|
||||
\\makeatletter
|
||||
\\renewenvironment{notice}[2]{%
|
||||
\\def\\py@noticetype{#1}
|
||||
\\begin{coloredbox}{#1}
|
||||
\\bf\\it
|
||||
\\par\\strong{#2}
|
||||
\\csname py@noticestart@#1\\endcsname
|
||||
}
|
||||
{
|
||||
\\csname py@noticeend@\\py@noticetype\\endcsname
|
||||
\\end{coloredbox}
|
||||
}
|
||||
\\makeatother
|
||||
|
||||
% Use some font with UTF-8 support with XeLaTeX
|
||||
\\usepackage{fontspec}
|
||||
\\setsansfont{DejaVu Serif}
|
||||
\\setromanfont{DejaVu Sans}
|
||||
\\setmonofont{DejaVu Sans Mono}
|
||||
|
||||
% To allow adjusting table sizes
|
||||
\\usepackage{adjustbox}
|
||||
|
||||
'''
|
||||
}
|
||||
|
||||
# Grouping the document tree into LaTeX files. List of tuples
|
||||
# (source start file, target name, title,
|
||||
# author, documentclass [howto, manual, or own class]).
|
||||
latex_documents = [
|
||||
(master_doc, 'TheLinuxKernel.tex', 'The Linux Kernel Documentation',
|
||||
('kernel-documentation', 'kernel-documentation.tex', 'The Linux Kernel Documentation',
|
||||
'The kernel development community', 'manual'),
|
||||
('development-process/index', 'development-process.tex', 'Linux Kernel Development Documentation',
|
||||
'The kernel development community', 'manual'),
|
||||
('gpu/index', 'gpu.tex', 'Linux GPU Driver Developer\'s Guide',
|
||||
'The kernel development community', 'manual'),
|
||||
]
|
||||
|
||||
|
@ -419,3 +491,9 @@ pdf_documents = [
|
|||
# line arguments.
|
||||
kerneldoc_bin = '../scripts/kernel-doc'
|
||||
kerneldoc_srctree = '..'
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Since loadConfig overwrites settings from the global namespace, it has to be
|
||||
# the last statement in the conf.py file
|
||||
# ------------------------------------------------------------------------------
|
||||
loadConfig(globals())
|
||||
|
|
|
@ -1,10 +1,18 @@
|
|||
Copyright 2010 Nicolas Palix <npalix@diku.dk>
|
||||
Copyright 2010 Julia Lawall <julia@diku.dk>
|
||||
Copyright 2010 Gilles Muller <Gilles.Muller@lip6.fr>
|
||||
.. Copyright 2010 Nicolas Palix <npalix@diku.dk>
|
||||
.. Copyright 2010 Julia Lawall <julia@diku.dk>
|
||||
.. Copyright 2010 Gilles Muller <Gilles.Muller@lip6.fr>
|
||||
|
||||
.. highlight:: none
|
||||
|
||||
Getting Coccinelle
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
Coccinelle
|
||||
==========
|
||||
|
||||
Coccinelle is a tool for pattern matching and text transformation that has
|
||||
many uses in kernel development, including the application of complex,
|
||||
tree-wide patches and detection of problematic programming patterns.
|
||||
|
||||
Getting Coccinelle
|
||||
-------------------
|
||||
|
||||
The semantic patches included in the kernel use features and options
|
||||
which are provided by Coccinelle version 1.0.0-rc11 and above.
|
||||
|
@ -22,24 +30,23 @@ of many distributions, e.g. :
|
|||
- NetBSD
|
||||
- FreeBSD
|
||||
|
||||
|
||||
You can get the latest version released from the Coccinelle homepage at
|
||||
http://coccinelle.lip6.fr/
|
||||
|
||||
Information and tips about Coccinelle are also provided on the wiki
|
||||
pages at http://cocci.ekstranet.diku.dk/wiki/doku.php
|
||||
|
||||
Once you have it, run the following command:
|
||||
Once you have it, run the following command::
|
||||
|
||||
./configure
|
||||
make
|
||||
|
||||
as a regular user, and install it with
|
||||
as a regular user, and install it with::
|
||||
|
||||
sudo make install
|
||||
|
||||
Supplemental documentation
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Supplemental documentation
|
||||
---------------------------
|
||||
|
||||
For supplemental documentation refer to the wiki:
|
||||
|
||||
|
@ -47,49 +54,52 @@ https://bottest.wiki.kernel.org/coccicheck
|
|||
|
||||
The wiki documentation always refers to the linux-next version of the script.
|
||||
|
||||
Using Coccinelle on the Linux kernel
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Using Coccinelle on the Linux kernel
|
||||
------------------------------------
|
||||
|
||||
A Coccinelle-specific target is defined in the top level
|
||||
Makefile. This target is named 'coccicheck' and calls the 'coccicheck'
|
||||
front-end in the 'scripts' directory.
|
||||
Makefile. This target is named ``coccicheck`` and calls the ``coccicheck``
|
||||
front-end in the ``scripts`` directory.
|
||||
|
||||
Four basic modes are defined: patch, report, context, and org. The mode to
|
||||
use is specified by setting the MODE variable with 'MODE=<mode>'.
|
||||
Four basic modes are defined: ``patch``, ``report``, ``context``, and
|
||||
``org``. The mode to use is specified by setting the MODE variable with
|
||||
``MODE=<mode>``.
|
||||
|
||||
'patch' proposes a fix, when possible.
|
||||
- ``patch`` proposes a fix, when possible.
|
||||
|
||||
'report' generates a list in the following format:
|
||||
- ``report`` generates a list in the following format:
|
||||
file:line:column-column: message
|
||||
|
||||
'context' highlights lines of interest and their context in a
|
||||
diff-like style.Lines of interest are indicated with '-'.
|
||||
- ``context`` highlights lines of interest and their context in a
|
||||
diff-like style.Lines of interest are indicated with ``-``.
|
||||
|
||||
'org' generates a report in the Org mode format of Emacs.
|
||||
- ``org`` generates a report in the Org mode format of Emacs.
|
||||
|
||||
Note that not all semantic patches implement all modes. For easy use
|
||||
of Coccinelle, the default mode is "report".
|
||||
|
||||
Two other modes provide some common combinations of these modes.
|
||||
|
||||
'chain' tries the previous modes in the order above until one succeeds.
|
||||
- ``chain`` tries the previous modes in the order above until one succeeds.
|
||||
|
||||
'rep+ctxt' runs successively the report mode and the context mode.
|
||||
It should be used with the C option (described later)
|
||||
which checks the code on a file basis.
|
||||
- ``rep+ctxt`` runs successively the report mode and the context mode.
|
||||
It should be used with the C option (described later)
|
||||
which checks the code on a file basis.
|
||||
|
||||
Examples:
|
||||
To make a report for every semantic patch, run the following command:
|
||||
Examples
|
||||
~~~~~~~~
|
||||
|
||||
To make a report for every semantic patch, run the following command::
|
||||
|
||||
make coccicheck MODE=report
|
||||
|
||||
To produce patches, run:
|
||||
To produce patches, run::
|
||||
|
||||
make coccicheck MODE=patch
|
||||
|
||||
|
||||
The coccicheck target applies every semantic patch available in the
|
||||
sub-directories of 'scripts/coccinelle' to the entire Linux kernel.
|
||||
sub-directories of ``scripts/coccinelle`` to the entire Linux kernel.
|
||||
|
||||
For each semantic patch, a commit message is proposed. It gives a
|
||||
description of the problem being checked by the semantic patch, and
|
||||
|
@ -99,15 +109,15 @@ As any static code analyzer, Coccinelle produces false
|
|||
positives. Thus, reports must be carefully checked, and patches
|
||||
reviewed.
|
||||
|
||||
To enable verbose messages set the V= variable, for example:
|
||||
To enable verbose messages set the V= variable, for example::
|
||||
|
||||
make coccicheck MODE=report V=1
|
||||
|
||||
Coccinelle parallelization
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Coccinelle parallelization
|
||||
---------------------------
|
||||
|
||||
By default, coccicheck tries to run as parallel as possible. To change
|
||||
the parallelism, set the J= variable. For example, to run across 4 CPUs:
|
||||
the parallelism, set the J= variable. For example, to run across 4 CPUs::
|
||||
|
||||
make coccicheck MODE=report J=4
|
||||
|
||||
|
@ -115,44 +125,47 @@ As of Coccinelle 1.0.2 Coccinelle uses Ocaml parmap for parallelization,
|
|||
if support for this is detected you will benefit from parmap parallelization.
|
||||
|
||||
When parmap is enabled coccicheck will enable dynamic load balancing by using
|
||||
'--chunksize 1' argument, this ensures we keep feeding threads with work
|
||||
``--chunksize 1`` argument, this ensures we keep feeding threads with work
|
||||
one by one, so that we avoid the situation where most work gets done by only
|
||||
a few threads. With dynamic load balancing, if a thread finishes early we keep
|
||||
feeding it more work.
|
||||
|
||||
When parmap is enabled, if an error occurs in Coccinelle, this error
|
||||
value is propagated back, the return value of the 'make coccicheck'
|
||||
value is propagated back, the return value of the ``make coccicheck``
|
||||
captures this return value.
|
||||
|
||||
Using Coccinelle with a single semantic patch
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Using Coccinelle with a single semantic patch
|
||||
---------------------------------------------
|
||||
|
||||
The optional make variable COCCI can be used to check a single
|
||||
semantic patch. In that case, the variable must be initialized with
|
||||
the name of the semantic patch to apply.
|
||||
|
||||
For instance:
|
||||
For instance::
|
||||
|
||||
make coccicheck COCCI=<my_SP.cocci> MODE=patch
|
||||
or
|
||||
|
||||
or::
|
||||
|
||||
make coccicheck COCCI=<my_SP.cocci> MODE=report
|
||||
|
||||
|
||||
Controlling Which Files are Processed by Coccinelle
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Controlling Which Files are Processed by Coccinelle
|
||||
---------------------------------------------------
|
||||
|
||||
By default the entire kernel source tree is checked.
|
||||
|
||||
To apply Coccinelle to a specific directory, M= can be used.
|
||||
For example, to check drivers/net/wireless/ one may write:
|
||||
To apply Coccinelle to a specific directory, ``M=`` can be used.
|
||||
For example, to check drivers/net/wireless/ one may write::
|
||||
|
||||
make coccicheck M=drivers/net/wireless/
|
||||
|
||||
To apply Coccinelle on a file basis, instead of a directory basis, the
|
||||
following command may be used:
|
||||
following command may be used::
|
||||
|
||||
make C=1 CHECK="scripts/coccicheck"
|
||||
|
||||
To check only newly edited code, use the value 2 for the C flag, i.e.
|
||||
To check only newly edited code, use the value 2 for the C flag, i.e.::
|
||||
|
||||
make C=2 CHECK="scripts/coccicheck"
|
||||
|
||||
|
@ -166,8 +179,8 @@ semantic patch as shown in the previous section.
|
|||
The "report" mode is the default. You can select another one with the
|
||||
MODE variable explained above.
|
||||
|
||||
Debugging Coccinelle SmPL patches
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Debugging Coccinelle SmPL patches
|
||||
---------------------------------
|
||||
|
||||
Using coccicheck is best as it provides in the spatch command line
|
||||
include options matching the options used when we compile the kernel.
|
||||
|
@ -177,8 +190,8 @@ manually run Coccinelle with debug options added.
|
|||
Alternatively you can debug running Coccinelle against SmPL patches
|
||||
by asking for stderr to be redirected to stderr, by default stderr
|
||||
is redirected to /dev/null, if you'd like to capture stderr you
|
||||
can specify the DEBUG_FILE="file.txt" option to coccicheck. For
|
||||
instance:
|
||||
can specify the ``DEBUG_FILE="file.txt"`` option to coccicheck. For
|
||||
instance::
|
||||
|
||||
rm -f cocci.err
|
||||
make coccicheck COCCI=scripts/coccinelle/free/kfree.cocci MODE=report DEBUG_FILE=cocci.err
|
||||
|
@ -186,7 +199,7 @@ instance:
|
|||
|
||||
You can use SPFLAGS to add debugging flags, for instance you may want to
|
||||
add both --profile --show-trying to SPFLAGS when debugging. For instance
|
||||
you may want to use:
|
||||
you may want to use::
|
||||
|
||||
rm -f err.log
|
||||
export COCCI=scripts/coccinelle/misc/irqf_oneshot.cocci
|
||||
|
@ -198,24 +211,24 @@ work.
|
|||
|
||||
DEBUG_FILE support is only supported when using coccinelle >= 1.2.
|
||||
|
||||
.cocciconfig support
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
.cocciconfig support
|
||||
--------------------
|
||||
|
||||
Coccinelle supports reading .cocciconfig for default Coccinelle options that
|
||||
should be used every time spatch is spawned, the order of precedence for
|
||||
variables for .cocciconfig is as follows:
|
||||
|
||||
o Your current user's home directory is processed first
|
||||
o Your directory from which spatch is called is processed next
|
||||
o The directory provided with the --dir option is processed last, if used
|
||||
- Your current user's home directory is processed first
|
||||
- Your directory from which spatch is called is processed next
|
||||
- The directory provided with the --dir option is processed last, if used
|
||||
|
||||
Since coccicheck runs through make, it naturally runs from the kernel
|
||||
proper dir, as such the second rule above would be implied for picking up a
|
||||
.cocciconfig when using 'make coccicheck'.
|
||||
.cocciconfig when using ``make coccicheck``.
|
||||
|
||||
'make coccicheck' also supports using M= targets.If you do not supply
|
||||
``make coccicheck`` also supports using M= targets.If you do not supply
|
||||
any M= target, it is assumed you want to target the entire kernel.
|
||||
The kernel coccicheck script has:
|
||||
The kernel coccicheck script has::
|
||||
|
||||
if [ "$KBUILD_EXTMOD" = "" ] ; then
|
||||
OPTIONS="--dir $srctree $COCCIINCLUDE"
|
||||
|
@ -235,12 +248,12 @@ override any of the kernel's .coccicheck's settings using SPFLAGS.
|
|||
|
||||
We help Coccinelle when used against Linux with a set of sensible defaults
|
||||
options for Linux with our own Linux .cocciconfig. This hints to coccinelle
|
||||
git can be used for 'git grep' queries over coccigrep. A timeout of 200
|
||||
git can be used for ``git grep`` queries over coccigrep. A timeout of 200
|
||||
seconds should suffice for now.
|
||||
|
||||
The options picked up by coccinelle when reading a .cocciconfig do not appear
|
||||
as arguments to spatch processes running on your system, to confirm what
|
||||
options will be used by Coccinelle run:
|
||||
options will be used by Coccinelle run::
|
||||
|
||||
spatch --print-options-only
|
||||
|
||||
|
@ -252,219 +265,227 @@ carries its own .cocciconfig, you will need to use SPFLAGS to use idutils if
|
|||
desired. See below section "Additional flags" for more details on how to use
|
||||
idutils.
|
||||
|
||||
Additional flags
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
Additional flags
|
||||
----------------
|
||||
|
||||
Additional flags can be passed to spatch through the SPFLAGS
|
||||
variable. This works as Coccinelle respects the last flags
|
||||
given to it when options are in conflict.
|
||||
given to it when options are in conflict. ::
|
||||
|
||||
make SPFLAGS=--use-glimpse coccicheck
|
||||
|
||||
Coccinelle supports idutils as well but requires coccinelle >= 1.0.6.
|
||||
When no ID file is specified coccinelle assumes your ID database file
|
||||
is in the file .id-utils.index on the top level of the kernel, coccinelle
|
||||
carries a script scripts/idutils_index.sh which creates the database with
|
||||
carries a script scripts/idutils_index.sh which creates the database with::
|
||||
|
||||
mkid -i C --output .id-utils.index
|
||||
|
||||
If you have another database filename you can also just symlink with this
|
||||
name.
|
||||
name. ::
|
||||
|
||||
make SPFLAGS=--use-idutils coccicheck
|
||||
|
||||
Alternatively you can specify the database filename explicitly, for
|
||||
instance:
|
||||
instance::
|
||||
|
||||
make SPFLAGS="--use-idutils /full-path/to/ID" coccicheck
|
||||
|
||||
See spatch --help to learn more about spatch options.
|
||||
See ``spatch --help`` to learn more about spatch options.
|
||||
|
||||
Note that the '--use-glimpse' and '--use-idutils' options
|
||||
Note that the ``--use-glimpse`` and ``--use-idutils`` options
|
||||
require external tools for indexing the code. None of them is
|
||||
thus active by default. However, by indexing the code with
|
||||
one of these tools, and according to the cocci file used,
|
||||
spatch could proceed the entire code base more quickly.
|
||||
|
||||
SmPL patch specific options
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
SmPL patch specific options
|
||||
---------------------------
|
||||
|
||||
SmPL patches can have their own requirements for options passed
|
||||
to Coccinelle. SmPL patch specific options can be provided by
|
||||
providing them at the top of the SmPL patch, for instance:
|
||||
providing them at the top of the SmPL patch, for instance::
|
||||
|
||||
// Options: --no-includes --include-headers
|
||||
// Options: --no-includes --include-headers
|
||||
|
||||
SmPL patch Coccinelle requirements
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
SmPL patch Coccinelle requirements
|
||||
----------------------------------
|
||||
|
||||
As Coccinelle features get added some more advanced SmPL patches
|
||||
may require newer versions of Coccinelle. If an SmPL patch requires
|
||||
at least a version of Coccinelle, this can be specified as follows,
|
||||
as an example if requiring at least Coccinelle >= 1.0.5:
|
||||
as an example if requiring at least Coccinelle >= 1.0.5::
|
||||
|
||||
// Requires: 1.0.5
|
||||
// Requires: 1.0.5
|
||||
|
||||
Proposing new semantic patches
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Proposing new semantic patches
|
||||
-------------------------------
|
||||
|
||||
New semantic patches can be proposed and submitted by kernel
|
||||
developers. For sake of clarity, they should be organized in the
|
||||
sub-directories of 'scripts/coccinelle/'.
|
||||
sub-directories of ``scripts/coccinelle/``.
|
||||
|
||||
|
||||
Detailed description of the 'report' mode
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Detailed description of the ``report`` mode
|
||||
-------------------------------------------
|
||||
|
||||
``report`` generates a list in the following format::
|
||||
|
||||
'report' generates a list in the following format:
|
||||
file:line:column-column: message
|
||||
|
||||
Example:
|
||||
Example
|
||||
~~~~~~~
|
||||
|
||||
Running
|
||||
Running::
|
||||
|
||||
make coccicheck MODE=report COCCI=scripts/coccinelle/api/err_cast.cocci
|
||||
|
||||
will execute the following part of the SmPL script.
|
||||
will execute the following part of the SmPL script::
|
||||
|
||||
<smpl>
|
||||
@r depends on !context && !patch && (org || report)@
|
||||
expression x;
|
||||
position p;
|
||||
@@
|
||||
<smpl>
|
||||
@r depends on !context && !patch && (org || report)@
|
||||
expression x;
|
||||
position p;
|
||||
@@
|
||||
|
||||
ERR_PTR@p(PTR_ERR(x))
|
||||
ERR_PTR@p(PTR_ERR(x))
|
||||
|
||||
@script:python depends on report@
|
||||
p << r.p;
|
||||
x << r.x;
|
||||
@@
|
||||
@script:python depends on report@
|
||||
p << r.p;
|
||||
x << r.x;
|
||||
@@
|
||||
|
||||
msg="ERR_CAST can be used with %s" % (x)
|
||||
coccilib.report.print_report(p[0], msg)
|
||||
</smpl>
|
||||
msg="ERR_CAST can be used with %s" % (x)
|
||||
coccilib.report.print_report(p[0], msg)
|
||||
</smpl>
|
||||
|
||||
This SmPL excerpt generates entries on the standard output, as
|
||||
illustrated below:
|
||||
illustrated below::
|
||||
|
||||
/home/user/linux/crypto/ctr.c:188:9-16: ERR_CAST can be used with alg
|
||||
/home/user/linux/crypto/authenc.c:619:9-16: ERR_CAST can be used with auth
|
||||
/home/user/linux/crypto/xts.c:227:9-16: ERR_CAST can be used with alg
|
||||
/home/user/linux/crypto/ctr.c:188:9-16: ERR_CAST can be used with alg
|
||||
/home/user/linux/crypto/authenc.c:619:9-16: ERR_CAST can be used with auth
|
||||
/home/user/linux/crypto/xts.c:227:9-16: ERR_CAST can be used with alg
|
||||
|
||||
|
||||
Detailed description of the 'patch' mode
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Detailed description of the ``patch`` mode
|
||||
------------------------------------------
|
||||
|
||||
When the 'patch' mode is available, it proposes a fix for each problem
|
||||
When the ``patch`` mode is available, it proposes a fix for each problem
|
||||
identified.
|
||||
|
||||
Example:
|
||||
Example
|
||||
~~~~~~~
|
||||
|
||||
Running::
|
||||
|
||||
Running
|
||||
make coccicheck MODE=patch COCCI=scripts/coccinelle/api/err_cast.cocci
|
||||
|
||||
will execute the following part of the SmPL script.
|
||||
will execute the following part of the SmPL script::
|
||||
|
||||
<smpl>
|
||||
@ depends on !context && patch && !org && !report @
|
||||
expression x;
|
||||
@@
|
||||
<smpl>
|
||||
@ depends on !context && patch && !org && !report @
|
||||
expression x;
|
||||
@@
|
||||
|
||||
- ERR_PTR(PTR_ERR(x))
|
||||
+ ERR_CAST(x)
|
||||
</smpl>
|
||||
- ERR_PTR(PTR_ERR(x))
|
||||
+ ERR_CAST(x)
|
||||
</smpl>
|
||||
|
||||
This SmPL excerpt generates patch hunks on the standard output, as
|
||||
illustrated below:
|
||||
illustrated below::
|
||||
|
||||
diff -u -p a/crypto/ctr.c b/crypto/ctr.c
|
||||
--- a/crypto/ctr.c 2010-05-26 10:49:38.000000000 +0200
|
||||
+++ b/crypto/ctr.c 2010-06-03 23:44:49.000000000 +0200
|
||||
@@ -185,7 +185,7 @@ static struct crypto_instance *crypto_ct
|
||||
diff -u -p a/crypto/ctr.c b/crypto/ctr.c
|
||||
--- a/crypto/ctr.c 2010-05-26 10:49:38.000000000 +0200
|
||||
+++ b/crypto/ctr.c 2010-06-03 23:44:49.000000000 +0200
|
||||
@@ -185,7 +185,7 @@ static struct crypto_instance *crypto_ct
|
||||
alg = crypto_attr_alg(tb[1], CRYPTO_ALG_TYPE_CIPHER,
|
||||
CRYPTO_ALG_TYPE_MASK);
|
||||
if (IS_ERR(alg))
|
||||
- return ERR_PTR(PTR_ERR(alg));
|
||||
+ return ERR_CAST(alg);
|
||||
|
||||
- return ERR_PTR(PTR_ERR(alg));
|
||||
+ return ERR_CAST(alg);
|
||||
|
||||
/* Block size must be >= 4 bytes. */
|
||||
err = -EINVAL;
|
||||
|
||||
Detailed description of the 'context' mode
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Detailed description of the ``context`` mode
|
||||
--------------------------------------------
|
||||
|
||||
'context' highlights lines of interest and their context
|
||||
``context`` highlights lines of interest and their context
|
||||
in a diff-like style.
|
||||
|
||||
NOTE: The diff-like output generated is NOT an applicable patch. The
|
||||
intent of the 'context' mode is to highlight the important lines
|
||||
(annotated with minus, '-') and gives some surrounding context
|
||||
**NOTE**: The diff-like output generated is NOT an applicable patch. The
|
||||
intent of the ``context`` mode is to highlight the important lines
|
||||
(annotated with minus, ``-``) and gives some surrounding context
|
||||
lines around. This output can be used with the diff mode of
|
||||
Emacs to review the code.
|
||||
|
||||
Example:
|
||||
Example
|
||||
~~~~~~~
|
||||
|
||||
Running::
|
||||
|
||||
Running
|
||||
make coccicheck MODE=context COCCI=scripts/coccinelle/api/err_cast.cocci
|
||||
|
||||
will execute the following part of the SmPL script.
|
||||
will execute the following part of the SmPL script::
|
||||
|
||||
<smpl>
|
||||
@ depends on context && !patch && !org && !report@
|
||||
expression x;
|
||||
@@
|
||||
<smpl>
|
||||
@ depends on context && !patch && !org && !report@
|
||||
expression x;
|
||||
@@
|
||||
|
||||
* ERR_PTR(PTR_ERR(x))
|
||||
</smpl>
|
||||
* ERR_PTR(PTR_ERR(x))
|
||||
</smpl>
|
||||
|
||||
This SmPL excerpt generates diff hunks on the standard output, as
|
||||
illustrated below:
|
||||
illustrated below::
|
||||
|
||||
diff -u -p /home/user/linux/crypto/ctr.c /tmp/nothing
|
||||
--- /home/user/linux/crypto/ctr.c 2010-05-26 10:49:38.000000000 +0200
|
||||
+++ /tmp/nothing
|
||||
@@ -185,7 +185,6 @@ static struct crypto_instance *crypto_ct
|
||||
diff -u -p /home/user/linux/crypto/ctr.c /tmp/nothing
|
||||
--- /home/user/linux/crypto/ctr.c 2010-05-26 10:49:38.000000000 +0200
|
||||
+++ /tmp/nothing
|
||||
@@ -185,7 +185,6 @@ static struct crypto_instance *crypto_ct
|
||||
alg = crypto_attr_alg(tb[1], CRYPTO_ALG_TYPE_CIPHER,
|
||||
CRYPTO_ALG_TYPE_MASK);
|
||||
if (IS_ERR(alg))
|
||||
- return ERR_PTR(PTR_ERR(alg));
|
||||
|
||||
- return ERR_PTR(PTR_ERR(alg));
|
||||
|
||||
/* Block size must be >= 4 bytes. */
|
||||
err = -EINVAL;
|
||||
|
||||
Detailed description of the 'org' mode
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Detailed description of the ``org`` mode
|
||||
----------------------------------------
|
||||
|
||||
'org' generates a report in the Org mode format of Emacs.
|
||||
``org`` generates a report in the Org mode format of Emacs.
|
||||
|
||||
Example:
|
||||
Example
|
||||
~~~~~~~
|
||||
|
||||
Running::
|
||||
|
||||
Running
|
||||
make coccicheck MODE=org COCCI=scripts/coccinelle/api/err_cast.cocci
|
||||
|
||||
will execute the following part of the SmPL script.
|
||||
will execute the following part of the SmPL script::
|
||||
|
||||
<smpl>
|
||||
@r depends on !context && !patch && (org || report)@
|
||||
expression x;
|
||||
position p;
|
||||
@@
|
||||
<smpl>
|
||||
@r depends on !context && !patch && (org || report)@
|
||||
expression x;
|
||||
position p;
|
||||
@@
|
||||
|
||||
ERR_PTR@p(PTR_ERR(x))
|
||||
ERR_PTR@p(PTR_ERR(x))
|
||||
|
||||
@script:python depends on org@
|
||||
p << r.p;
|
||||
x << r.x;
|
||||
@@
|
||||
@script:python depends on org@
|
||||
p << r.p;
|
||||
x << r.x;
|
||||
@@
|
||||
|
||||
msg="ERR_CAST can be used with %s" % (x)
|
||||
msg_safe=msg.replace("[","@(").replace("]",")")
|
||||
coccilib.org.print_todo(p[0], msg_safe)
|
||||
</smpl>
|
||||
msg="ERR_CAST can be used with %s" % (x)
|
||||
msg_safe=msg.replace("[","@(").replace("]",")")
|
||||
coccilib.org.print_todo(p[0], msg_safe)
|
||||
</smpl>
|
||||
|
||||
This SmPL excerpt generates Org entries on the standard output, as
|
||||
illustrated below:
|
||||
illustrated below::
|
||||
|
||||
* TODO [[view:/home/user/linux/crypto/ctr.c::face=ovl-face1::linb=188::colb=9::cole=16][ERR_CAST can be used with alg]]
|
||||
* TODO [[view:/home/user/linux/crypto/authenc.c::face=ovl-face1::linb=619::colb=9::cole=16][ERR_CAST can be used with auth]]
|
||||
* TODO [[view:/home/user/linux/crypto/xts.c::face=ovl-face1::linb=227::colb=9::cole=16][ERR_CAST can be used with alg]]
|
||||
* TODO [[view:/home/user/linux/crypto/ctr.c::face=ovl-face1::linb=188::colb=9::cole=16][ERR_CAST can be used with alg]]
|
||||
* TODO [[view:/home/user/linux/crypto/authenc.c::face=ovl-face1::linb=619::colb=9::cole=16][ERR_CAST can be used with auth]]
|
||||
* TODO [[view:/home/user/linux/crypto/xts.c::face=ovl-face1::linb=227::colb=9::cole=16][ERR_CAST can be used with alg]]
|
|
@ -0,0 +1,256 @@
|
|||
Using gcov with the Linux kernel
|
||||
================================
|
||||
|
||||
gcov profiling kernel support enables the use of GCC's coverage testing
|
||||
tool gcov_ with the Linux kernel. Coverage data of a running kernel
|
||||
is exported in gcov-compatible format via the "gcov" debugfs directory.
|
||||
To get coverage data for a specific file, change to the kernel build
|
||||
directory and use gcov with the ``-o`` option as follows (requires root)::
|
||||
|
||||
# cd /tmp/linux-out
|
||||
# gcov -o /sys/kernel/debug/gcov/tmp/linux-out/kernel spinlock.c
|
||||
|
||||
This will create source code files annotated with execution counts
|
||||
in the current directory. In addition, graphical gcov front-ends such
|
||||
as lcov_ can be used to automate the process of collecting data
|
||||
for the entire kernel and provide coverage overviews in HTML format.
|
||||
|
||||
Possible uses:
|
||||
|
||||
* debugging (has this line been reached at all?)
|
||||
* test improvement (how do I change my test to cover these lines?)
|
||||
* minimizing kernel configurations (do I need this option if the
|
||||
associated code is never run?)
|
||||
|
||||
.. _gcov: http://gcc.gnu.org/onlinedocs/gcc/Gcov.html
|
||||
.. _lcov: http://ltp.sourceforge.net/coverage/lcov.php
|
||||
|
||||
|
||||
Preparation
|
||||
-----------
|
||||
|
||||
Configure the kernel with::
|
||||
|
||||
CONFIG_DEBUG_FS=y
|
||||
CONFIG_GCOV_KERNEL=y
|
||||
|
||||
select the gcc's gcov format, default is autodetect based on gcc version::
|
||||
|
||||
CONFIG_GCOV_FORMAT_AUTODETECT=y
|
||||
|
||||
and to get coverage data for the entire kernel::
|
||||
|
||||
CONFIG_GCOV_PROFILE_ALL=y
|
||||
|
||||
Note that kernels compiled with profiling flags will be significantly
|
||||
larger and run slower. Also CONFIG_GCOV_PROFILE_ALL may not be supported
|
||||
on all architectures.
|
||||
|
||||
Profiling data will only become accessible once debugfs has been
|
||||
mounted::
|
||||
|
||||
mount -t debugfs none /sys/kernel/debug
|
||||
|
||||
|
||||
Customization
|
||||
-------------
|
||||
|
||||
To enable profiling for specific files or directories, add a line
|
||||
similar to the following to the respective kernel Makefile:
|
||||
|
||||
- For a single file (e.g. main.o)::
|
||||
|
||||
GCOV_PROFILE_main.o := y
|
||||
|
||||
- For all files in one directory::
|
||||
|
||||
GCOV_PROFILE := y
|
||||
|
||||
To exclude files from being profiled even when CONFIG_GCOV_PROFILE_ALL
|
||||
is specified, use::
|
||||
|
||||
GCOV_PROFILE_main.o := n
|
||||
|
||||
and::
|
||||
|
||||
GCOV_PROFILE := n
|
||||
|
||||
Only files which are linked to the main kernel image or are compiled as
|
||||
kernel modules are supported by this mechanism.
|
||||
|
||||
|
||||
Files
|
||||
-----
|
||||
|
||||
The gcov kernel support creates the following files in debugfs:
|
||||
|
||||
``/sys/kernel/debug/gcov``
|
||||
Parent directory for all gcov-related files.
|
||||
|
||||
``/sys/kernel/debug/gcov/reset``
|
||||
Global reset file: resets all coverage data to zero when
|
||||
written to.
|
||||
|
||||
``/sys/kernel/debug/gcov/path/to/compile/dir/file.gcda``
|
||||
The actual gcov data file as understood by the gcov
|
||||
tool. Resets file coverage data to zero when written to.
|
||||
|
||||
``/sys/kernel/debug/gcov/path/to/compile/dir/file.gcno``
|
||||
Symbolic link to a static data file required by the gcov
|
||||
tool. This file is generated by gcc when compiling with
|
||||
option ``-ftest-coverage``.
|
||||
|
||||
|
||||
Modules
|
||||
-------
|
||||
|
||||
Kernel modules may contain cleanup code which is only run during
|
||||
module unload time. The gcov mechanism provides a means to collect
|
||||
coverage data for such code by keeping a copy of the data associated
|
||||
with the unloaded module. This data remains available through debugfs.
|
||||
Once the module is loaded again, the associated coverage counters are
|
||||
initialized with the data from its previous instantiation.
|
||||
|
||||
This behavior can be deactivated by specifying the gcov_persist kernel
|
||||
parameter::
|
||||
|
||||
gcov_persist=0
|
||||
|
||||
At run-time, a user can also choose to discard data for an unloaded
|
||||
module by writing to its data file or the global reset file.
|
||||
|
||||
|
||||
Separated build and test machines
|
||||
---------------------------------
|
||||
|
||||
The gcov kernel profiling infrastructure is designed to work out-of-the
|
||||
box for setups where kernels are built and run on the same machine. In
|
||||
cases where the kernel runs on a separate machine, special preparations
|
||||
must be made, depending on where the gcov tool is used:
|
||||
|
||||
a) gcov is run on the TEST machine
|
||||
|
||||
The gcov tool version on the test machine must be compatible with the
|
||||
gcc version used for kernel build. Also the following files need to be
|
||||
copied from build to test machine:
|
||||
|
||||
from the source tree:
|
||||
- all C source files + headers
|
||||
|
||||
from the build tree:
|
||||
- all C source files + headers
|
||||
- all .gcda and .gcno files
|
||||
- all links to directories
|
||||
|
||||
It is important to note that these files need to be placed into the
|
||||
exact same file system location on the test machine as on the build
|
||||
machine. If any of the path components is symbolic link, the actual
|
||||
directory needs to be used instead (due to make's CURDIR handling).
|
||||
|
||||
b) gcov is run on the BUILD machine
|
||||
|
||||
The following files need to be copied after each test case from test
|
||||
to build machine:
|
||||
|
||||
from the gcov directory in sysfs:
|
||||
- all .gcda files
|
||||
- all links to .gcno files
|
||||
|
||||
These files can be copied to any location on the build machine. gcov
|
||||
must then be called with the -o option pointing to that directory.
|
||||
|
||||
Example directory setup on the build machine::
|
||||
|
||||
/tmp/linux: kernel source tree
|
||||
/tmp/out: kernel build directory as specified by make O=
|
||||
/tmp/coverage: location of the files copied from the test machine
|
||||
|
||||
[user@build] cd /tmp/out
|
||||
[user@build] gcov -o /tmp/coverage/tmp/out/init main.c
|
||||
|
||||
|
||||
Troubleshooting
|
||||
---------------
|
||||
|
||||
Problem
|
||||
Compilation aborts during linker step.
|
||||
|
||||
Cause
|
||||
Profiling flags are specified for source files which are not
|
||||
linked to the main kernel or which are linked by a custom
|
||||
linker procedure.
|
||||
|
||||
Solution
|
||||
Exclude affected source files from profiling by specifying
|
||||
``GCOV_PROFILE := n`` or ``GCOV_PROFILE_basename.o := n`` in the
|
||||
corresponding Makefile.
|
||||
|
||||
Problem
|
||||
Files copied from sysfs appear empty or incomplete.
|
||||
|
||||
Cause
|
||||
Due to the way seq_file works, some tools such as cp or tar
|
||||
may not correctly copy files from sysfs.
|
||||
|
||||
Solution
|
||||
Use ``cat``' to read ``.gcda`` files and ``cp -d`` to copy links.
|
||||
Alternatively use the mechanism shown in Appendix B.
|
||||
|
||||
|
||||
Appendix A: gather_on_build.sh
|
||||
------------------------------
|
||||
|
||||
Sample script to gather coverage meta files on the build machine
|
||||
(see 6a)::
|
||||
|
||||
#!/bin/bash
|
||||
|
||||
KSRC=$1
|
||||
KOBJ=$2
|
||||
DEST=$3
|
||||
|
||||
if [ -z "$KSRC" ] || [ -z "$KOBJ" ] || [ -z "$DEST" ]; then
|
||||
echo "Usage: $0 <ksrc directory> <kobj directory> <output.tar.gz>" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
KSRC=$(cd $KSRC; printf "all:\n\t@echo \${CURDIR}\n" | make -f -)
|
||||
KOBJ=$(cd $KOBJ; printf "all:\n\t@echo \${CURDIR}\n" | make -f -)
|
||||
|
||||
find $KSRC $KOBJ \( -name '*.gcno' -o -name '*.[ch]' -o -type l \) -a \
|
||||
-perm /u+r,g+r | tar cfz $DEST -P -T -
|
||||
|
||||
if [ $? -eq 0 ] ; then
|
||||
echo "$DEST successfully created, copy to test system and unpack with:"
|
||||
echo " tar xfz $DEST -P"
|
||||
else
|
||||
echo "Could not create file $DEST"
|
||||
fi
|
||||
|
||||
|
||||
Appendix B: gather_on_test.sh
|
||||
-----------------------------
|
||||
|
||||
Sample script to gather coverage data files on the test machine
|
||||
(see 6b)::
|
||||
|
||||
#!/bin/bash -e
|
||||
|
||||
DEST=$1
|
||||
GCDA=/sys/kernel/debug/gcov
|
||||
|
||||
if [ -z "$DEST" ] ; then
|
||||
echo "Usage: $0 <output.tar.gz>" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
TEMPDIR=$(mktemp -d)
|
||||
echo Collecting data..
|
||||
find $GCDA -type d -exec mkdir -p $TEMPDIR/\{\} \;
|
||||
find $GCDA -name '*.gcda' -exec sh -c 'cat < $0 > '$TEMPDIR'/$0' {} \;
|
||||
find $GCDA -name '*.gcno' -exec sh -c 'cp -d $0 '$TEMPDIR'/$0' {} \;
|
||||
tar czf $DEST -C $TEMPDIR sys
|
||||
rm -rf $TEMPDIR
|
||||
|
||||
echo "$DEST successfully created, copy to build system and unpack with:"
|
||||
echo " tar xfz $DEST"
|
|
@ -1,3 +1,5 @@
|
|||
.. highlight:: none
|
||||
|
||||
Debugging kernel and modules via gdb
|
||||
====================================
|
||||
|
||||
|
@ -13,54 +15,58 @@ be transferred to the other gdb stubs as well.
|
|||
Requirements
|
||||
------------
|
||||
|
||||
o gdb 7.2+ (recommended: 7.4+) with python support enabled (typically true
|
||||
for distributions)
|
||||
- gdb 7.2+ (recommended: 7.4+) with python support enabled (typically true
|
||||
for distributions)
|
||||
|
||||
|
||||
Setup
|
||||
-----
|
||||
|
||||
o Create a virtual Linux machine for QEMU/KVM (see www.linux-kvm.org and
|
||||
www.qemu.org for more details). For cross-development,
|
||||
http://landley.net/aboriginal/bin keeps a pool of machine images and
|
||||
toolchains that can be helpful to start from.
|
||||
- Create a virtual Linux machine for QEMU/KVM (see www.linux-kvm.org and
|
||||
www.qemu.org for more details). For cross-development,
|
||||
http://landley.net/aboriginal/bin keeps a pool of machine images and
|
||||
toolchains that can be helpful to start from.
|
||||
|
||||
o Build the kernel with CONFIG_GDB_SCRIPTS enabled, but leave
|
||||
CONFIG_DEBUG_INFO_REDUCED off. If your architecture supports
|
||||
CONFIG_FRAME_POINTER, keep it enabled.
|
||||
- Build the kernel with CONFIG_GDB_SCRIPTS enabled, but leave
|
||||
CONFIG_DEBUG_INFO_REDUCED off. If your architecture supports
|
||||
CONFIG_FRAME_POINTER, keep it enabled.
|
||||
|
||||
o Install that kernel on the guest.
|
||||
- Install that kernel on the guest.
|
||||
Alternatively, QEMU allows to boot the kernel directly using -kernel,
|
||||
-append, -initrd command line switches. This is generally only useful if
|
||||
you do not depend on modules. See QEMU documentation for more details on
|
||||
this mode.
|
||||
|
||||
Alternatively, QEMU allows to boot the kernel directly using -kernel,
|
||||
-append, -initrd command line switches. This is generally only useful if
|
||||
you do not depend on modules. See QEMU documentation for more details on
|
||||
this mode.
|
||||
- Enable the gdb stub of QEMU/KVM, either
|
||||
|
||||
o Enable the gdb stub of QEMU/KVM, either
|
||||
- at VM startup time by appending "-s" to the QEMU command line
|
||||
or
|
||||
|
||||
or
|
||||
|
||||
- during runtime by issuing "gdbserver" from the QEMU monitor
|
||||
console
|
||||
|
||||
o cd /path/to/linux-build
|
||||
- cd /path/to/linux-build
|
||||
|
||||
o Start gdb: gdb vmlinux
|
||||
- Start gdb: gdb vmlinux
|
||||
|
||||
Note: Some distros may restrict auto-loading of gdb scripts to known safe
|
||||
directories. In case gdb reports to refuse loading vmlinux-gdb.py, add
|
||||
Note: Some distros may restrict auto-loading of gdb scripts to known safe
|
||||
directories. In case gdb reports to refuse loading vmlinux-gdb.py, add::
|
||||
|
||||
add-auto-load-safe-path /path/to/linux-build
|
||||
|
||||
to ~/.gdbinit. See gdb help for more details.
|
||||
to ~/.gdbinit. See gdb help for more details.
|
||||
|
||||
- Attach to the booted guest::
|
||||
|
||||
o Attach to the booted guest:
|
||||
(gdb) target remote :1234
|
||||
|
||||
|
||||
Examples of using the Linux-provided gdb helpers
|
||||
------------------------------------------------
|
||||
|
||||
o Load module (and main kernel) symbols:
|
||||
- Load module (and main kernel) symbols::
|
||||
|
||||
(gdb) lx-symbols
|
||||
loading vmlinux
|
||||
scanning for modules in /home/user/linux/build
|
||||
|
@ -72,17 +78,20 @@ Examples of using the Linux-provided gdb helpers
|
|||
...
|
||||
loading @0xffffffffa0000000: /home/user/linux/build/drivers/ata/ata_generic.ko
|
||||
|
||||
o Set a breakpoint on some not yet loaded module function, e.g.:
|
||||
- Set a breakpoint on some not yet loaded module function, e.g.::
|
||||
|
||||
(gdb) b btrfs_init_sysfs
|
||||
Function "btrfs_init_sysfs" not defined.
|
||||
Make breakpoint pending on future shared library load? (y or [n]) y
|
||||
Breakpoint 1 (btrfs_init_sysfs) pending.
|
||||
|
||||
o Continue the target
|
||||
- Continue the target::
|
||||
|
||||
(gdb) c
|
||||
|
||||
o Load the module on the target and watch the symbols being loaded as well as
|
||||
the breakpoint hit:
|
||||
- Load the module on the target and watch the symbols being loaded as well as
|
||||
the breakpoint hit::
|
||||
|
||||
loading @0xffffffffa0034000: /home/user/linux/build/lib/libcrc32c.ko
|
||||
loading @0xffffffffa0050000: /home/user/linux/build/lib/lzo/lzo_compress.ko
|
||||
loading @0xffffffffa006e000: /home/user/linux/build/lib/zlib_deflate/zlib_deflate.ko
|
||||
|
@ -91,7 +100,8 @@ Examples of using the Linux-provided gdb helpers
|
|||
Breakpoint 1, btrfs_init_sysfs () at /home/user/linux/fs/btrfs/sysfs.c:36
|
||||
36 btrfs_kset = kset_create_and_add("btrfs", NULL, fs_kobj);
|
||||
|
||||
o Dump the log buffer of the target kernel:
|
||||
- Dump the log buffer of the target kernel::
|
||||
|
||||
(gdb) lx-dmesg
|
||||
[ 0.000000] Initializing cgroup subsys cpuset
|
||||
[ 0.000000] Initializing cgroup subsys cpu
|
||||
|
@ -102,19 +112,22 @@ Examples of using the Linux-provided gdb helpers
|
|||
[ 0.000000] BIOS-e820: [mem 0x000000000009fc00-0x000000000009ffff] reserved
|
||||
....
|
||||
|
||||
o Examine fields of the current task struct:
|
||||
- Examine fields of the current task struct::
|
||||
|
||||
(gdb) p $lx_current().pid
|
||||
$1 = 4998
|
||||
(gdb) p $lx_current().comm
|
||||
$2 = "modprobe\000\000\000\000\000\000\000"
|
||||
|
||||
o Make use of the per-cpu function for the current or a specified CPU:
|
||||
- Make use of the per-cpu function for the current or a specified CPU::
|
||||
|
||||
(gdb) p $lx_per_cpu("runqueues").nr_running
|
||||
$3 = 1
|
||||
(gdb) p $lx_per_cpu("runqueues", 2).nr_running
|
||||
$4 = 0
|
||||
|
||||
o Dig into hrtimers using the container_of helper:
|
||||
- Dig into hrtimers using the container_of helper::
|
||||
|
||||
(gdb) set $next = $lx_per_cpu("hrtimer_bases").clock_base[0].active.next
|
||||
(gdb) p *$container_of($next, "struct hrtimer", "node")
|
||||
$5 = {
|
||||
|
@ -144,7 +157,7 @@ List of commands and functions
|
|||
------------------------------
|
||||
|
||||
The number of commands and convenience functions may evolve over the time,
|
||||
this is just a snapshot of the initial version:
|
||||
this is just a snapshot of the initial version::
|
||||
|
||||
(gdb) apropos lx
|
||||
function lx_current -- Return current task
|
|
@ -0,0 +1,173 @@
|
|||
The Kernel Address Sanitizer (KASAN)
|
||||
====================================
|
||||
|
||||
Overview
|
||||
--------
|
||||
|
||||
KernelAddressSANitizer (KASAN) is a dynamic memory error detector. It provides
|
||||
a fast and comprehensive solution for finding use-after-free and out-of-bounds
|
||||
bugs.
|
||||
|
||||
KASAN uses compile-time instrumentation for checking every memory access,
|
||||
therefore you will need a GCC version 4.9.2 or later. GCC 5.0 or later is
|
||||
required for detection of out-of-bounds accesses to stack or global variables.
|
||||
|
||||
Currently KASAN is supported only for the x86_64 and arm64 architectures.
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
||||
To enable KASAN configure kernel with::
|
||||
|
||||
CONFIG_KASAN = y
|
||||
|
||||
and choose between CONFIG_KASAN_OUTLINE and CONFIG_KASAN_INLINE. Outline and
|
||||
inline are compiler instrumentation types. The former produces smaller binary
|
||||
the latter is 1.1 - 2 times faster. Inline instrumentation requires a GCC
|
||||
version 5.0 or later.
|
||||
|
||||
KASAN works with both SLUB and SLAB memory allocators.
|
||||
For better bug detection and nicer reporting, enable CONFIG_STACKTRACE.
|
||||
|
||||
To disable instrumentation for specific files or directories, add a line
|
||||
similar to the following to the respective kernel Makefile:
|
||||
|
||||
- For a single file (e.g. main.o)::
|
||||
|
||||
KASAN_SANITIZE_main.o := n
|
||||
|
||||
- For all files in one directory::
|
||||
|
||||
KASAN_SANITIZE := n
|
||||
|
||||
Error reports
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
A typical out of bounds access report looks like this::
|
||||
|
||||
==================================================================
|
||||
BUG: AddressSanitizer: out of bounds access in kmalloc_oob_right+0x65/0x75 [test_kasan] at addr ffff8800693bc5d3
|
||||
Write of size 1 by task modprobe/1689
|
||||
=============================================================================
|
||||
BUG kmalloc-128 (Not tainted): kasan error
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
Disabling lock debugging due to kernel taint
|
||||
INFO: Allocated in kmalloc_oob_right+0x3d/0x75 [test_kasan] age=0 cpu=0 pid=1689
|
||||
__slab_alloc+0x4b4/0x4f0
|
||||
kmem_cache_alloc_trace+0x10b/0x190
|
||||
kmalloc_oob_right+0x3d/0x75 [test_kasan]
|
||||
init_module+0x9/0x47 [test_kasan]
|
||||
do_one_initcall+0x99/0x200
|
||||
load_module+0x2cb3/0x3b20
|
||||
SyS_finit_module+0x76/0x80
|
||||
system_call_fastpath+0x12/0x17
|
||||
INFO: Slab 0xffffea0001a4ef00 objects=17 used=7 fp=0xffff8800693bd728 flags=0x100000000004080
|
||||
INFO: Object 0xffff8800693bc558 @offset=1368 fp=0xffff8800693bc720
|
||||
|
||||
Bytes b4 ffff8800693bc548: 00 00 00 00 00 00 00 00 5a 5a 5a 5a 5a 5a 5a 5a ........ZZZZZZZZ
|
||||
Object ffff8800693bc558: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk
|
||||
Object ffff8800693bc568: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk
|
||||
Object ffff8800693bc578: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk
|
||||
Object ffff8800693bc588: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk
|
||||
Object ffff8800693bc598: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk
|
||||
Object ffff8800693bc5a8: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk
|
||||
Object ffff8800693bc5b8: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk
|
||||
Object ffff8800693bc5c8: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b a5 kkkkkkkkkkkkkkk.
|
||||
Redzone ffff8800693bc5d8: cc cc cc cc cc cc cc cc ........
|
||||
Padding ffff8800693bc718: 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZ
|
||||
CPU: 0 PID: 1689 Comm: modprobe Tainted: G B 3.18.0-rc1-mm1+ #98
|
||||
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.7.5-0-ge51488c-20140602_164612-nilsson.home.kraxel.org 04/01/2014
|
||||
ffff8800693bc000 0000000000000000 ffff8800693bc558 ffff88006923bb78
|
||||
ffffffff81cc68ae 00000000000000f3 ffff88006d407600 ffff88006923bba8
|
||||
ffffffff811fd848 ffff88006d407600 ffffea0001a4ef00 ffff8800693bc558
|
||||
Call Trace:
|
||||
[<ffffffff81cc68ae>] dump_stack+0x46/0x58
|
||||
[<ffffffff811fd848>] print_trailer+0xf8/0x160
|
||||
[<ffffffffa00026a7>] ? kmem_cache_oob+0xc3/0xc3 [test_kasan]
|
||||
[<ffffffff811ff0f5>] object_err+0x35/0x40
|
||||
[<ffffffffa0002065>] ? kmalloc_oob_right+0x65/0x75 [test_kasan]
|
||||
[<ffffffff8120b9fa>] kasan_report_error+0x38a/0x3f0
|
||||
[<ffffffff8120a79f>] ? kasan_poison_shadow+0x2f/0x40
|
||||
[<ffffffff8120b344>] ? kasan_unpoison_shadow+0x14/0x40
|
||||
[<ffffffff8120a79f>] ? kasan_poison_shadow+0x2f/0x40
|
||||
[<ffffffffa00026a7>] ? kmem_cache_oob+0xc3/0xc3 [test_kasan]
|
||||
[<ffffffff8120a995>] __asan_store1+0x75/0xb0
|
||||
[<ffffffffa0002601>] ? kmem_cache_oob+0x1d/0xc3 [test_kasan]
|
||||
[<ffffffffa0002065>] ? kmalloc_oob_right+0x65/0x75 [test_kasan]
|
||||
[<ffffffffa0002065>] kmalloc_oob_right+0x65/0x75 [test_kasan]
|
||||
[<ffffffffa00026b0>] init_module+0x9/0x47 [test_kasan]
|
||||
[<ffffffff810002d9>] do_one_initcall+0x99/0x200
|
||||
[<ffffffff811e4e5c>] ? __vunmap+0xec/0x160
|
||||
[<ffffffff81114f63>] load_module+0x2cb3/0x3b20
|
||||
[<ffffffff8110fd70>] ? m_show+0x240/0x240
|
||||
[<ffffffff81115f06>] SyS_finit_module+0x76/0x80
|
||||
[<ffffffff81cd3129>] system_call_fastpath+0x12/0x17
|
||||
Memory state around the buggy address:
|
||||
ffff8800693bc300: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
|
||||
ffff8800693bc380: fc fc 00 00 00 00 00 00 00 00 00 00 00 00 00 fc
|
||||
ffff8800693bc400: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
|
||||
ffff8800693bc480: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
|
||||
ffff8800693bc500: fc fc fc fc fc fc fc fc fc fc fc 00 00 00 00 00
|
||||
>ffff8800693bc580: 00 00 00 00 00 00 00 00 00 00 03 fc fc fc fc fc
|
||||
^
|
||||
ffff8800693bc600: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
|
||||
ffff8800693bc680: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
|
||||
ffff8800693bc700: fc fc fc fc fb fb fb fb fb fb fb fb fb fb fb fb
|
||||
ffff8800693bc780: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
|
||||
ffff8800693bc800: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
|
||||
==================================================================
|
||||
|
||||
The header of the report discribe what kind of bug happened and what kind of
|
||||
access caused it. It's followed by the description of the accessed slub object
|
||||
(see 'SLUB Debug output' section in Documentation/vm/slub.txt for details) and
|
||||
the description of the accessed memory page.
|
||||
|
||||
In the last section the report shows memory state around the accessed address.
|
||||
Reading this part requires some understanding of how KASAN works.
|
||||
|
||||
The state of each 8 aligned bytes of memory is encoded in one shadow byte.
|
||||
Those 8 bytes can be accessible, partially accessible, freed or be a redzone.
|
||||
We use the following encoding for each shadow byte: 0 means that all 8 bytes
|
||||
of the corresponding memory region are accessible; number N (1 <= N <= 7) means
|
||||
that the first N bytes are accessible, and other (8 - N) bytes are not;
|
||||
any negative value indicates that the entire 8-byte word is inaccessible.
|
||||
We use different negative values to distinguish between different kinds of
|
||||
inaccessible memory like redzones or freed memory (see mm/kasan/kasan.h).
|
||||
|
||||
In the report above the arrows point to the shadow byte 03, which means that
|
||||
the accessed address is partially accessible.
|
||||
|
||||
|
||||
Implementation details
|
||||
----------------------
|
||||
|
||||
From a high level, our approach to memory error detection is similar to that
|
||||
of kmemcheck: use shadow memory to record whether each byte of memory is safe
|
||||
to access, and use compile-time instrumentation to check shadow memory on each
|
||||
memory access.
|
||||
|
||||
AddressSanitizer dedicates 1/8 of kernel memory to its shadow memory
|
||||
(e.g. 16TB to cover 128TB on x86_64) and uses direct mapping with a scale and
|
||||
offset to translate a memory address to its corresponding shadow address.
|
||||
|
||||
Here is the function which translates an address to its corresponding shadow
|
||||
address::
|
||||
|
||||
static inline void *kasan_mem_to_shadow(const void *addr)
|
||||
{
|
||||
return ((unsigned long)addr >> KASAN_SHADOW_SCALE_SHIFT)
|
||||
+ KASAN_SHADOW_OFFSET;
|
||||
}
|
||||
|
||||
where ``KASAN_SHADOW_SCALE_SHIFT = 3``.
|
||||
|
||||
Compile-time instrumentation used for checking memory accesses. Compiler inserts
|
||||
function calls (__asan_load*(addr), __asan_store*(addr)) before each memory
|
||||
access of size 1, 2, 4, 8 or 16. These functions check whether memory access is
|
||||
valid or not by checking corresponding shadow memory.
|
||||
|
||||
GCC 5.0 has possibility to perform inline instrumentation. Instead of making
|
||||
function calls GCC directly inserts the code to check the shadow memory.
|
||||
This option significantly enlarges kernel but it gives x1.1-x2 performance
|
||||
boost over outline instrumented kernel.
|
|
@ -12,38 +12,38 @@ To achieve this goal it does not collect coverage in soft/hard interrupts
|
|||
and instrumentation of some inherently non-deterministic parts of kernel is
|
||||
disbled (e.g. scheduler, locking).
|
||||
|
||||
Usage:
|
||||
======
|
||||
Usage
|
||||
-----
|
||||
|
||||
Configure kernel with:
|
||||
Configure the kernel with::
|
||||
|
||||
CONFIG_KCOV=y
|
||||
|
||||
CONFIG_KCOV requires gcc built on revision 231296 or later.
|
||||
Profiling data will only become accessible once debugfs has been mounted:
|
||||
Profiling data will only become accessible once debugfs has been mounted::
|
||||
|
||||
mount -t debugfs none /sys/kernel/debug
|
||||
|
||||
The following program demonstrates kcov usage from within a test program:
|
||||
The following program demonstrates kcov usage from within a test program::
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/mman.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/mman.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#define KCOV_INIT_TRACE _IOR('c', 1, unsigned long)
|
||||
#define KCOV_ENABLE _IO('c', 100)
|
||||
#define KCOV_DISABLE _IO('c', 101)
|
||||
#define COVER_SIZE (64<<10)
|
||||
#define KCOV_INIT_TRACE _IOR('c', 1, unsigned long)
|
||||
#define KCOV_ENABLE _IO('c', 100)
|
||||
#define KCOV_DISABLE _IO('c', 101)
|
||||
#define COVER_SIZE (64<<10)
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int fd;
|
||||
unsigned long *cover, n, i;
|
||||
|
||||
|
@ -83,24 +83,24 @@ int main(int argc, char **argv)
|
|||
if (close(fd))
|
||||
perror("close"), exit(1);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
After piping through addr2line output of the program looks as follows:
|
||||
After piping through addr2line output of the program looks as follows::
|
||||
|
||||
SyS_read
|
||||
fs/read_write.c:562
|
||||
__fdget_pos
|
||||
fs/file.c:774
|
||||
__fget_light
|
||||
fs/file.c:746
|
||||
__fget_light
|
||||
fs/file.c:750
|
||||
__fget_light
|
||||
fs/file.c:760
|
||||
__fdget_pos
|
||||
fs/file.c:784
|
||||
SyS_read
|
||||
fs/read_write.c:562
|
||||
SyS_read
|
||||
fs/read_write.c:562
|
||||
__fdget_pos
|
||||
fs/file.c:774
|
||||
__fget_light
|
||||
fs/file.c:746
|
||||
__fget_light
|
||||
fs/file.c:750
|
||||
__fget_light
|
||||
fs/file.c:760
|
||||
__fdget_pos
|
||||
fs/file.c:784
|
||||
SyS_read
|
||||
fs/read_write.c:562
|
||||
|
||||
If a program needs to collect coverage from several threads (independently),
|
||||
it needs to open /sys/kernel/debug/kcov in each thread separately.
|
|
@ -0,0 +1,733 @@
|
|||
Getting started with kmemcheck
|
||||
==============================
|
||||
|
||||
Vegard Nossum <vegardno@ifi.uio.no>
|
||||
|
||||
|
||||
Introduction
|
||||
------------
|
||||
|
||||
kmemcheck is a debugging feature for the Linux Kernel. More specifically, it
|
||||
is a dynamic checker that detects and warns about some uses of uninitialized
|
||||
memory.
|
||||
|
||||
Userspace programmers might be familiar with Valgrind's memcheck. The main
|
||||
difference between memcheck and kmemcheck is that memcheck works for userspace
|
||||
programs only, and kmemcheck works for the kernel only. The implementations
|
||||
are of course vastly different. Because of this, kmemcheck is not as accurate
|
||||
as memcheck, but it turns out to be good enough in practice to discover real
|
||||
programmer errors that the compiler is not able to find through static
|
||||
analysis.
|
||||
|
||||
Enabling kmemcheck on a kernel will probably slow it down to the extent that
|
||||
the machine will not be usable for normal workloads such as e.g. an
|
||||
interactive desktop. kmemcheck will also cause the kernel to use about twice
|
||||
as much memory as normal. For this reason, kmemcheck is strictly a debugging
|
||||
feature.
|
||||
|
||||
|
||||
Downloading
|
||||
-----------
|
||||
|
||||
As of version 2.6.31-rc1, kmemcheck is included in the mainline kernel.
|
||||
|
||||
|
||||
Configuring and compiling
|
||||
-------------------------
|
||||
|
||||
kmemcheck only works for the x86 (both 32- and 64-bit) platform. A number of
|
||||
configuration variables must have specific settings in order for the kmemcheck
|
||||
menu to even appear in "menuconfig". These are:
|
||||
|
||||
- ``CONFIG_CC_OPTIMIZE_FOR_SIZE=n``
|
||||
This option is located under "General setup" / "Optimize for size".
|
||||
|
||||
Without this, gcc will use certain optimizations that usually lead to
|
||||
false positive warnings from kmemcheck. An example of this is a 16-bit
|
||||
field in a struct, where gcc may load 32 bits, then discard the upper
|
||||
16 bits. kmemcheck sees only the 32-bit load, and may trigger a
|
||||
warning for the upper 16 bits (if they're uninitialized).
|
||||
|
||||
- ``CONFIG_SLAB=y`` or ``CONFIG_SLUB=y``
|
||||
This option is located under "General setup" / "Choose SLAB
|
||||
allocator".
|
||||
|
||||
- ``CONFIG_FUNCTION_TRACER=n``
|
||||
This option is located under "Kernel hacking" / "Tracers" / "Kernel
|
||||
Function Tracer"
|
||||
|
||||
When function tracing is compiled in, gcc emits a call to another
|
||||
function at the beginning of every function. This means that when the
|
||||
page fault handler is called, the ftrace framework will be called
|
||||
before kmemcheck has had a chance to handle the fault. If ftrace then
|
||||
modifies memory that was tracked by kmemcheck, the result is an
|
||||
endless recursive page fault.
|
||||
|
||||
- ``CONFIG_DEBUG_PAGEALLOC=n``
|
||||
This option is located under "Kernel hacking" / "Memory Debugging"
|
||||
/ "Debug page memory allocations".
|
||||
|
||||
In addition, I highly recommend turning on ``CONFIG_DEBUG_INFO=y``. This is also
|
||||
located under "Kernel hacking". With this, you will be able to get line number
|
||||
information from the kmemcheck warnings, which is extremely valuable in
|
||||
debugging a problem. This option is not mandatory, however, because it slows
|
||||
down the compilation process and produces a much bigger kernel image.
|
||||
|
||||
Now the kmemcheck menu should be visible (under "Kernel hacking" / "Memory
|
||||
Debugging" / "kmemcheck: trap use of uninitialized memory"). Here follows
|
||||
a description of the kmemcheck configuration variables:
|
||||
|
||||
- ``CONFIG_KMEMCHECK``
|
||||
This must be enabled in order to use kmemcheck at all...
|
||||
|
||||
- ``CONFIG_KMEMCHECK_``[``DISABLED`` | ``ENABLED`` | ``ONESHOT``]``_BY_DEFAULT``
|
||||
This option controls the status of kmemcheck at boot-time. "Enabled"
|
||||
will enable kmemcheck right from the start, "disabled" will boot the
|
||||
kernel as normal (but with the kmemcheck code compiled in, so it can
|
||||
be enabled at run-time after the kernel has booted), and "one-shot" is
|
||||
a special mode which will turn kmemcheck off automatically after
|
||||
detecting the first use of uninitialized memory.
|
||||
|
||||
If you are using kmemcheck to actively debug a problem, then you
|
||||
probably want to choose "enabled" here.
|
||||
|
||||
The one-shot mode is mostly useful in automated test setups because it
|
||||
can prevent floods of warnings and increase the chances of the machine
|
||||
surviving in case something is really wrong. In other cases, the one-
|
||||
shot mode could actually be counter-productive because it would turn
|
||||
itself off at the very first error -- in the case of a false positive
|
||||
too -- and this would come in the way of debugging the specific
|
||||
problem you were interested in.
|
||||
|
||||
If you would like to use your kernel as normal, but with a chance to
|
||||
enable kmemcheck in case of some problem, it might be a good idea to
|
||||
choose "disabled" here. When kmemcheck is disabled, most of the run-
|
||||
time overhead is not incurred, and the kernel will be almost as fast
|
||||
as normal.
|
||||
|
||||
- ``CONFIG_KMEMCHECK_QUEUE_SIZE``
|
||||
Select the maximum number of error reports to store in an internal
|
||||
(fixed-size) buffer. Since errors can occur virtually anywhere and in
|
||||
any context, we need a temporary storage area which is guaranteed not
|
||||
to generate any other page faults when accessed. The queue will be
|
||||
emptied as soon as a tasklet may be scheduled. If the queue is full,
|
||||
new error reports will be lost.
|
||||
|
||||
The default value of 64 is probably fine. If some code produces more
|
||||
than 64 errors within an irqs-off section, then the code is likely to
|
||||
produce many, many more, too, and these additional reports seldom give
|
||||
any more information (the first report is usually the most valuable
|
||||
anyway).
|
||||
|
||||
This number might have to be adjusted if you are not using serial
|
||||
console or similar to capture the kernel log. If you are using the
|
||||
"dmesg" command to save the log, then getting a lot of kmemcheck
|
||||
warnings might overflow the kernel log itself, and the earlier reports
|
||||
will get lost in that way instead. Try setting this to 10 or so on
|
||||
such a setup.
|
||||
|
||||
- ``CONFIG_KMEMCHECK_SHADOW_COPY_SHIFT``
|
||||
Select the number of shadow bytes to save along with each entry of the
|
||||
error-report queue. These bytes indicate what parts of an allocation
|
||||
are initialized, uninitialized, etc. and will be displayed when an
|
||||
error is detected to help the debugging of a particular problem.
|
||||
|
||||
The number entered here is actually the logarithm of the number of
|
||||
bytes that will be saved. So if you pick for example 5 here, kmemcheck
|
||||
will save 2^5 = 32 bytes.
|
||||
|
||||
The default value should be fine for debugging most problems. It also
|
||||
fits nicely within 80 columns.
|
||||
|
||||
- ``CONFIG_KMEMCHECK_PARTIAL_OK``
|
||||
This option (when enabled) works around certain GCC optimizations that
|
||||
produce 32-bit reads from 16-bit variables where the upper 16 bits are
|
||||
thrown away afterwards.
|
||||
|
||||
The default value (enabled) is recommended. This may of course hide
|
||||
some real errors, but disabling it would probably produce a lot of
|
||||
false positives.
|
||||
|
||||
- ``CONFIG_KMEMCHECK_BITOPS_OK``
|
||||
This option silences warnings that would be generated for bit-field
|
||||
accesses where not all the bits are initialized at the same time. This
|
||||
may also hide some real bugs.
|
||||
|
||||
This option is probably obsolete, or it should be replaced with
|
||||
the kmemcheck-/bitfield-annotations for the code in question. The
|
||||
default value is therefore fine.
|
||||
|
||||
Now compile the kernel as usual.
|
||||
|
||||
|
||||
How to use
|
||||
----------
|
||||
|
||||
Booting
|
||||
~~~~~~~
|
||||
|
||||
First some information about the command-line options. There is only one
|
||||
option specific to kmemcheck, and this is called "kmemcheck". It can be used
|
||||
to override the default mode as chosen by the ``CONFIG_KMEMCHECK_*_BY_DEFAULT``
|
||||
option. Its possible settings are:
|
||||
|
||||
- ``kmemcheck=0`` (disabled)
|
||||
- ``kmemcheck=1`` (enabled)
|
||||
- ``kmemcheck=2`` (one-shot mode)
|
||||
|
||||
If SLUB debugging has been enabled in the kernel, it may take precedence over
|
||||
kmemcheck in such a way that the slab caches which are under SLUB debugging
|
||||
will not be tracked by kmemcheck. In order to ensure that this doesn't happen
|
||||
(even though it shouldn't by default), use SLUB's boot option ``slub_debug``,
|
||||
like this: ``slub_debug=-``
|
||||
|
||||
In fact, this option may also be used for fine-grained control over SLUB vs.
|
||||
kmemcheck. For example, if the command line includes
|
||||
``kmemcheck=1 slub_debug=,dentry``, then SLUB debugging will be used only
|
||||
for the "dentry" slab cache, and with kmemcheck tracking all the other
|
||||
caches. This is advanced usage, however, and is not generally recommended.
|
||||
|
||||
|
||||
Run-time enable/disable
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
When the kernel has booted, it is possible to enable or disable kmemcheck at
|
||||
run-time. WARNING: This feature is still experimental and may cause false
|
||||
positive warnings to appear. Therefore, try not to use this. If you find that
|
||||
it doesn't work properly (e.g. you see an unreasonable amount of warnings), I
|
||||
will be happy to take bug reports.
|
||||
|
||||
Use the file ``/proc/sys/kernel/kmemcheck`` for this purpose, e.g.::
|
||||
|
||||
$ echo 0 > /proc/sys/kernel/kmemcheck # disables kmemcheck
|
||||
|
||||
The numbers are the same as for the ``kmemcheck=`` command-line option.
|
||||
|
||||
|
||||
Debugging
|
||||
~~~~~~~~~
|
||||
|
||||
A typical report will look something like this::
|
||||
|
||||
WARNING: kmemcheck: Caught 32-bit read from uninitialized memory (ffff88003e4a2024)
|
||||
80000000000000000000000000000000000000000088ffff0000000000000000
|
||||
i i i i u u u u i i i i i i i i u u u u u u u u u u u u u u u u
|
||||
^
|
||||
|
||||
Pid: 1856, comm: ntpdate Not tainted 2.6.29-rc5 #264 945P-A
|
||||
RIP: 0010:[<ffffffff8104ede8>] [<ffffffff8104ede8>] __dequeue_signal+0xc8/0x190
|
||||
RSP: 0018:ffff88003cdf7d98 EFLAGS: 00210002
|
||||
RAX: 0000000000000030 RBX: ffff88003d4ea968 RCX: 0000000000000009
|
||||
RDX: ffff88003e5d6018 RSI: ffff88003e5d6024 RDI: ffff88003cdf7e84
|
||||
RBP: ffff88003cdf7db8 R08: ffff88003e5d6000 R09: 0000000000000000
|
||||
R10: 0000000000000080 R11: 0000000000000000 R12: 000000000000000e
|
||||
R13: ffff88003cdf7e78 R14: ffff88003d530710 R15: ffff88003d5a98c8
|
||||
FS: 0000000000000000(0000) GS:ffff880001982000(0063) knlGS:00000
|
||||
CS: 0010 DS: 002b ES: 002b CR0: 0000000080050033
|
||||
CR2: ffff88003f806ea0 CR3: 000000003c036000 CR4: 00000000000006a0
|
||||
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
|
||||
DR3: 0000000000000000 DR6: 00000000ffff4ff0 DR7: 0000000000000400
|
||||
[<ffffffff8104f04e>] dequeue_signal+0x8e/0x170
|
||||
[<ffffffff81050bd8>] get_signal_to_deliver+0x98/0x390
|
||||
[<ffffffff8100b87d>] do_notify_resume+0xad/0x7d0
|
||||
[<ffffffff8100c7b5>] int_signal+0x12/0x17
|
||||
[<ffffffffffffffff>] 0xffffffffffffffff
|
||||
|
||||
The single most valuable information in this report is the RIP (or EIP on 32-
|
||||
bit) value. This will help us pinpoint exactly which instruction that caused
|
||||
the warning.
|
||||
|
||||
If your kernel was compiled with ``CONFIG_DEBUG_INFO=y``, then all we have to do
|
||||
is give this address to the addr2line program, like this::
|
||||
|
||||
$ addr2line -e vmlinux -i ffffffff8104ede8
|
||||
arch/x86/include/asm/string_64.h:12
|
||||
include/asm-generic/siginfo.h:287
|
||||
kernel/signal.c:380
|
||||
kernel/signal.c:410
|
||||
|
||||
The "``-e vmlinux``" tells addr2line which file to look in. **IMPORTANT:**
|
||||
This must be the vmlinux of the kernel that produced the warning in the
|
||||
first place! If not, the line number information will almost certainly be
|
||||
wrong.
|
||||
|
||||
The "``-i``" tells addr2line to also print the line numbers of inlined
|
||||
functions. In this case, the flag was very important, because otherwise,
|
||||
it would only have printed the first line, which is just a call to
|
||||
``memcpy()``, which could be called from a thousand places in the kernel, and
|
||||
is therefore not very useful. These inlined functions would not show up in
|
||||
the stack trace above, simply because the kernel doesn't load the extra
|
||||
debugging information. This technique can of course be used with ordinary
|
||||
kernel oopses as well.
|
||||
|
||||
In this case, it's the caller of ``memcpy()`` that is interesting, and it can be
|
||||
found in ``include/asm-generic/siginfo.h``, line 287::
|
||||
|
||||
281 static inline void copy_siginfo(struct siginfo *to, struct siginfo *from)
|
||||
282 {
|
||||
283 if (from->si_code < 0)
|
||||
284 memcpy(to, from, sizeof(*to));
|
||||
285 else
|
||||
286 /* _sigchld is currently the largest know union member */
|
||||
287 memcpy(to, from, __ARCH_SI_PREAMBLE_SIZE + sizeof(from->_sifields._sigchld));
|
||||
288 }
|
||||
|
||||
Since this was a read (kmemcheck usually warns about reads only, though it can
|
||||
warn about writes to unallocated or freed memory as well), it was probably the
|
||||
"from" argument which contained some uninitialized bytes. Following the chain
|
||||
of calls, we move upwards to see where "from" was allocated or initialized,
|
||||
``kernel/signal.c``, line 380::
|
||||
|
||||
359 static void collect_signal(int sig, struct sigpending *list, siginfo_t *info)
|
||||
360 {
|
||||
...
|
||||
367 list_for_each_entry(q, &list->list, list) {
|
||||
368 if (q->info.si_signo == sig) {
|
||||
369 if (first)
|
||||
370 goto still_pending;
|
||||
371 first = q;
|
||||
...
|
||||
377 if (first) {
|
||||
378 still_pending:
|
||||
379 list_del_init(&first->list);
|
||||
380 copy_siginfo(info, &first->info);
|
||||
381 __sigqueue_free(first);
|
||||
...
|
||||
392 }
|
||||
393 }
|
||||
|
||||
Here, it is ``&first->info`` that is being passed on to ``copy_siginfo()``. The
|
||||
variable ``first`` was found on a list -- passed in as the second argument to
|
||||
``collect_signal()``. We continue our journey through the stack, to figure out
|
||||
where the item on "list" was allocated or initialized. We move to line 410::
|
||||
|
||||
395 static int __dequeue_signal(struct sigpending *pending, sigset_t *mask,
|
||||
396 siginfo_t *info)
|
||||
397 {
|
||||
...
|
||||
410 collect_signal(sig, pending, info);
|
||||
...
|
||||
414 }
|
||||
|
||||
Now we need to follow the ``pending`` pointer, since that is being passed on to
|
||||
``collect_signal()`` as ``list``. At this point, we've run out of lines from the
|
||||
"addr2line" output. Not to worry, we just paste the next addresses from the
|
||||
kmemcheck stack dump, i.e.::
|
||||
|
||||
[<ffffffff8104f04e>] dequeue_signal+0x8e/0x170
|
||||
[<ffffffff81050bd8>] get_signal_to_deliver+0x98/0x390
|
||||
[<ffffffff8100b87d>] do_notify_resume+0xad/0x7d0
|
||||
[<ffffffff8100c7b5>] int_signal+0x12/0x17
|
||||
|
||||
$ addr2line -e vmlinux -i ffffffff8104f04e ffffffff81050bd8 \
|
||||
ffffffff8100b87d ffffffff8100c7b5
|
||||
kernel/signal.c:446
|
||||
kernel/signal.c:1806
|
||||
arch/x86/kernel/signal.c:805
|
||||
arch/x86/kernel/signal.c:871
|
||||
arch/x86/kernel/entry_64.S:694
|
||||
|
||||
Remember that since these addresses were found on the stack and not as the
|
||||
RIP value, they actually point to the _next_ instruction (they are return
|
||||
addresses). This becomes obvious when we look at the code for line 446::
|
||||
|
||||
422 int dequeue_signal(struct task_struct *tsk, sigset_t *mask, siginfo_t *info)
|
||||
423 {
|
||||
...
|
||||
431 signr = __dequeue_signal(&tsk->signal->shared_pending,
|
||||
432 mask, info);
|
||||
433 /*
|
||||
434 * itimer signal ?
|
||||
435 *
|
||||
436 * itimers are process shared and we restart periodic
|
||||
437 * itimers in the signal delivery path to prevent DoS
|
||||
438 * attacks in the high resolution timer case. This is
|
||||
439 * compliant with the old way of self restarting
|
||||
440 * itimers, as the SIGALRM is a legacy signal and only
|
||||
441 * queued once. Changing the restart behaviour to
|
||||
442 * restart the timer in the signal dequeue path is
|
||||
443 * reducing the timer noise on heavy loaded !highres
|
||||
444 * systems too.
|
||||
445 */
|
||||
446 if (unlikely(signr == SIGALRM)) {
|
||||
...
|
||||
489 }
|
||||
|
||||
So instead of looking at 446, we should be looking at 431, which is the line
|
||||
that executes just before 446. Here we see that what we are looking for is
|
||||
``&tsk->signal->shared_pending``.
|
||||
|
||||
Our next task is now to figure out which function that puts items on this
|
||||
``shared_pending`` list. A crude, but efficient tool, is ``git grep``::
|
||||
|
||||
$ git grep -n 'shared_pending' kernel/
|
||||
...
|
||||
kernel/signal.c:828: pending = group ? &t->signal->shared_pending : &t->pending;
|
||||
kernel/signal.c:1339: pending = group ? &t->signal->shared_pending : &t->pending;
|
||||
...
|
||||
|
||||
There were more results, but none of them were related to list operations,
|
||||
and these were the only assignments. We inspect the line numbers more closely
|
||||
and find that this is indeed where items are being added to the list::
|
||||
|
||||
816 static int send_signal(int sig, struct siginfo *info, struct task_struct *t,
|
||||
817 int group)
|
||||
818 {
|
||||
...
|
||||
828 pending = group ? &t->signal->shared_pending : &t->pending;
|
||||
...
|
||||
851 q = __sigqueue_alloc(t, GFP_ATOMIC, (sig < SIGRTMIN &&
|
||||
852 (is_si_special(info) ||
|
||||
853 info->si_code >= 0)));
|
||||
854 if (q) {
|
||||
855 list_add_tail(&q->list, &pending->list);
|
||||
...
|
||||
890 }
|
||||
|
||||
and::
|
||||
|
||||
1309 int send_sigqueue(struct sigqueue *q, struct task_struct *t, int group)
|
||||
1310 {
|
||||
....
|
||||
1339 pending = group ? &t->signal->shared_pending : &t->pending;
|
||||
1340 list_add_tail(&q->list, &pending->list);
|
||||
....
|
||||
1347 }
|
||||
|
||||
In the first case, the list element we are looking for, ``q``, is being
|
||||
returned from the function ``__sigqueue_alloc()``, which looks like an
|
||||
allocation function. Let's take a look at it::
|
||||
|
||||
187 static struct sigqueue *__sigqueue_alloc(struct task_struct *t, gfp_t flags,
|
||||
188 int override_rlimit)
|
||||
189 {
|
||||
190 struct sigqueue *q = NULL;
|
||||
191 struct user_struct *user;
|
||||
192
|
||||
193 /*
|
||||
194 * We won't get problems with the target's UID changing under us
|
||||
195 * because changing it requires RCU be used, and if t != current, the
|
||||
196 * caller must be holding the RCU readlock (by way of a spinlock) and
|
||||
197 * we use RCU protection here
|
||||
198 */
|
||||
199 user = get_uid(__task_cred(t)->user);
|
||||
200 atomic_inc(&user->sigpending);
|
||||
201 if (override_rlimit ||
|
||||
202 atomic_read(&user->sigpending) <=
|
||||
203 t->signal->rlim[RLIMIT_SIGPENDING].rlim_cur)
|
||||
204 q = kmem_cache_alloc(sigqueue_cachep, flags);
|
||||
205 if (unlikely(q == NULL)) {
|
||||
206 atomic_dec(&user->sigpending);
|
||||
207 free_uid(user);
|
||||
208 } else {
|
||||
209 INIT_LIST_HEAD(&q->list);
|
||||
210 q->flags = 0;
|
||||
211 q->user = user;
|
||||
212 }
|
||||
213
|
||||
214 return q;
|
||||
215 }
|
||||
|
||||
We see that this function initializes ``q->list``, ``q->flags``, and
|
||||
``q->user``. It seems that now is the time to look at the definition of
|
||||
``struct sigqueue``, e.g.::
|
||||
|
||||
14 struct sigqueue {
|
||||
15 struct list_head list;
|
||||
16 int flags;
|
||||
17 siginfo_t info;
|
||||
18 struct user_struct *user;
|
||||
19 };
|
||||
|
||||
And, you might remember, it was a ``memcpy()`` on ``&first->info`` that
|
||||
caused the warning, so this makes perfect sense. It also seems reasonable
|
||||
to assume that it is the caller of ``__sigqueue_alloc()`` that has the
|
||||
responsibility of filling out (initializing) this member.
|
||||
|
||||
But just which fields of the struct were uninitialized? Let's look at
|
||||
kmemcheck's report again::
|
||||
|
||||
WARNING: kmemcheck: Caught 32-bit read from uninitialized memory (ffff88003e4a2024)
|
||||
80000000000000000000000000000000000000000088ffff0000000000000000
|
||||
i i i i u u u u i i i i i i i i u u u u u u u u u u u u u u u u
|
||||
^
|
||||
|
||||
These first two lines are the memory dump of the memory object itself, and
|
||||
the shadow bytemap, respectively. The memory object itself is in this case
|
||||
``&first->info``. Just beware that the start of this dump is NOT the start
|
||||
of the object itself! The position of the caret (^) corresponds with the
|
||||
address of the read (ffff88003e4a2024).
|
||||
|
||||
The shadow bytemap dump legend is as follows:
|
||||
|
||||
- i: initialized
|
||||
- u: uninitialized
|
||||
- a: unallocated (memory has been allocated by the slab layer, but has not
|
||||
yet been handed off to anybody)
|
||||
- f: freed (memory has been allocated by the slab layer, but has been freed
|
||||
by the previous owner)
|
||||
|
||||
In order to figure out where (relative to the start of the object) the
|
||||
uninitialized memory was located, we have to look at the disassembly. For
|
||||
that, we'll need the RIP address again::
|
||||
|
||||
RIP: 0010:[<ffffffff8104ede8>] [<ffffffff8104ede8>] __dequeue_signal+0xc8/0x190
|
||||
|
||||
$ objdump -d --no-show-raw-insn vmlinux | grep -C 8 ffffffff8104ede8:
|
||||
ffffffff8104edc8: mov %r8,0x8(%r8)
|
||||
ffffffff8104edcc: test %r10d,%r10d
|
||||
ffffffff8104edcf: js ffffffff8104ee88 <__dequeue_signal+0x168>
|
||||
ffffffff8104edd5: mov %rax,%rdx
|
||||
ffffffff8104edd8: mov $0xc,%ecx
|
||||
ffffffff8104eddd: mov %r13,%rdi
|
||||
ffffffff8104ede0: mov $0x30,%eax
|
||||
ffffffff8104ede5: mov %rdx,%rsi
|
||||
ffffffff8104ede8: rep movsl %ds:(%rsi),%es:(%rdi)
|
||||
ffffffff8104edea: test $0x2,%al
|
||||
ffffffff8104edec: je ffffffff8104edf0 <__dequeue_signal+0xd0>
|
||||
ffffffff8104edee: movsw %ds:(%rsi),%es:(%rdi)
|
||||
ffffffff8104edf0: test $0x1,%al
|
||||
ffffffff8104edf2: je ffffffff8104edf5 <__dequeue_signal+0xd5>
|
||||
ffffffff8104edf4: movsb %ds:(%rsi),%es:(%rdi)
|
||||
ffffffff8104edf5: mov %r8,%rdi
|
||||
ffffffff8104edf8: callq ffffffff8104de60 <__sigqueue_free>
|
||||
|
||||
As expected, it's the "``rep movsl``" instruction from the ``memcpy()``
|
||||
that causes the warning. We know about ``REP MOVSL`` that it uses the register
|
||||
``RCX`` to count the number of remaining iterations. By taking a look at the
|
||||
register dump again (from the kmemcheck report), we can figure out how many
|
||||
bytes were left to copy::
|
||||
|
||||
RAX: 0000000000000030 RBX: ffff88003d4ea968 RCX: 0000000000000009
|
||||
|
||||
By looking at the disassembly, we also see that ``%ecx`` is being loaded
|
||||
with the value ``$0xc`` just before (ffffffff8104edd8), so we are very
|
||||
lucky. Keep in mind that this is the number of iterations, not bytes. And
|
||||
since this is a "long" operation, we need to multiply by 4 to get the
|
||||
number of bytes. So this means that the uninitialized value was encountered
|
||||
at 4 * (0xc - 0x9) = 12 bytes from the start of the object.
|
||||
|
||||
We can now try to figure out which field of the "``struct siginfo``" that
|
||||
was not initialized. This is the beginning of the struct::
|
||||
|
||||
40 typedef struct siginfo {
|
||||
41 int si_signo;
|
||||
42 int si_errno;
|
||||
43 int si_code;
|
||||
44
|
||||
45 union {
|
||||
..
|
||||
92 } _sifields;
|
||||
93 } siginfo_t;
|
||||
|
||||
On 64-bit, the int is 4 bytes long, so it must the union member that has
|
||||
not been initialized. We can verify this using gdb::
|
||||
|
||||
$ gdb vmlinux
|
||||
...
|
||||
(gdb) p &((struct siginfo *) 0)->_sifields
|
||||
$1 = (union {...} *) 0x10
|
||||
|
||||
Actually, it seems that the union member is located at offset 0x10 -- which
|
||||
means that gcc has inserted 4 bytes of padding between the members ``si_code``
|
||||
and ``_sifields``. We can now get a fuller picture of the memory dump::
|
||||
|
||||
_----------------------------=> si_code
|
||||
/ _--------------------=> (padding)
|
||||
| / _------------=> _sifields(._kill._pid)
|
||||
| | / _----=> _sifields(._kill._uid)
|
||||
| | | /
|
||||
-------|-------|-------|-------|
|
||||
80000000000000000000000000000000000000000088ffff0000000000000000
|
||||
i i i i u u u u i i i i i i i i u u u u u u u u u u u u u u u u
|
||||
|
||||
This allows us to realize another important fact: ``si_code`` contains the
|
||||
value 0x80. Remember that x86 is little endian, so the first 4 bytes
|
||||
"80000000" are really the number 0x00000080. With a bit of research, we
|
||||
find that this is actually the constant ``SI_KERNEL`` defined in
|
||||
``include/asm-generic/siginfo.h``::
|
||||
|
||||
144 #define SI_KERNEL 0x80 /* sent by the kernel from somewhere */
|
||||
|
||||
This macro is used in exactly one place in the x86 kernel: In ``send_signal()``
|
||||
in ``kernel/signal.c``::
|
||||
|
||||
816 static int send_signal(int sig, struct siginfo *info, struct task_struct *t,
|
||||
817 int group)
|
||||
818 {
|
||||
...
|
||||
828 pending = group ? &t->signal->shared_pending : &t->pending;
|
||||
...
|
||||
851 q = __sigqueue_alloc(t, GFP_ATOMIC, (sig < SIGRTMIN &&
|
||||
852 (is_si_special(info) ||
|
||||
853 info->si_code >= 0)));
|
||||
854 if (q) {
|
||||
855 list_add_tail(&q->list, &pending->list);
|
||||
856 switch ((unsigned long) info) {
|
||||
...
|
||||
865 case (unsigned long) SEND_SIG_PRIV:
|
||||
866 q->info.si_signo = sig;
|
||||
867 q->info.si_errno = 0;
|
||||
868 q->info.si_code = SI_KERNEL;
|
||||
869 q->info.si_pid = 0;
|
||||
870 q->info.si_uid = 0;
|
||||
871 break;
|
||||
...
|
||||
890 }
|
||||
|
||||
Not only does this match with the ``.si_code`` member, it also matches the place
|
||||
we found earlier when looking for where siginfo_t objects are enqueued on the
|
||||
``shared_pending`` list.
|
||||
|
||||
So to sum up: It seems that it is the padding introduced by the compiler
|
||||
between two struct fields that is uninitialized, and this gets reported when
|
||||
we do a ``memcpy()`` on the struct. This means that we have identified a false
|
||||
positive warning.
|
||||
|
||||
Normally, kmemcheck will not report uninitialized accesses in ``memcpy()`` calls
|
||||
when both the source and destination addresses are tracked. (Instead, we copy
|
||||
the shadow bytemap as well). In this case, the destination address clearly
|
||||
was not tracked. We can dig a little deeper into the stack trace from above::
|
||||
|
||||
arch/x86/kernel/signal.c:805
|
||||
arch/x86/kernel/signal.c:871
|
||||
arch/x86/kernel/entry_64.S:694
|
||||
|
||||
And we clearly see that the destination siginfo object is located on the
|
||||
stack::
|
||||
|
||||
782 static void do_signal(struct pt_regs *regs)
|
||||
783 {
|
||||
784 struct k_sigaction ka;
|
||||
785 siginfo_t info;
|
||||
...
|
||||
804 signr = get_signal_to_deliver(&info, &ka, regs, NULL);
|
||||
...
|
||||
854 }
|
||||
|
||||
And this ``&info`` is what eventually gets passed to ``copy_siginfo()`` as the
|
||||
destination argument.
|
||||
|
||||
Now, even though we didn't find an actual error here, the example is still a
|
||||
good one, because it shows how one would go about to find out what the report
|
||||
was all about.
|
||||
|
||||
|
||||
Annotating false positives
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
There are a few different ways to make annotations in the source code that
|
||||
will keep kmemcheck from checking and reporting certain allocations. Here
|
||||
they are:
|
||||
|
||||
- ``__GFP_NOTRACK_FALSE_POSITIVE``
|
||||
This flag can be passed to ``kmalloc()`` or ``kmem_cache_alloc()``
|
||||
(therefore also to other functions that end up calling one of
|
||||
these) to indicate that the allocation should not be tracked
|
||||
because it would lead to a false positive report. This is a "big
|
||||
hammer" way of silencing kmemcheck; after all, even if the false
|
||||
positive pertains to particular field in a struct, for example, we
|
||||
will now lose the ability to find (real) errors in other parts of
|
||||
the same struct.
|
||||
|
||||
Example::
|
||||
|
||||
/* No warnings will ever trigger on accessing any part of x */
|
||||
x = kmalloc(sizeof *x, GFP_KERNEL | __GFP_NOTRACK_FALSE_POSITIVE);
|
||||
|
||||
- ``kmemcheck_bitfield_begin(name)``/``kmemcheck_bitfield_end(name)`` and
|
||||
``kmemcheck_annotate_bitfield(ptr, name)``
|
||||
The first two of these three macros can be used inside struct
|
||||
definitions to signal, respectively, the beginning and end of a
|
||||
bitfield. Additionally, this will assign the bitfield a name, which
|
||||
is given as an argument to the macros.
|
||||
|
||||
Having used these markers, one can later use
|
||||
kmemcheck_annotate_bitfield() at the point of allocation, to indicate
|
||||
which parts of the allocation is part of a bitfield.
|
||||
|
||||
Example::
|
||||
|
||||
struct foo {
|
||||
int x;
|
||||
|
||||
kmemcheck_bitfield_begin(flags);
|
||||
int flag_a:1;
|
||||
int flag_b:1;
|
||||
kmemcheck_bitfield_end(flags);
|
||||
|
||||
int y;
|
||||
};
|
||||
|
||||
struct foo *x = kmalloc(sizeof *x);
|
||||
|
||||
/* No warnings will trigger on accessing the bitfield of x */
|
||||
kmemcheck_annotate_bitfield(x, flags);
|
||||
|
||||
Note that ``kmemcheck_annotate_bitfield()`` can be used even before the
|
||||
return value of ``kmalloc()`` is checked -- in other words, passing NULL
|
||||
as the first argument is legal (and will do nothing).
|
||||
|
||||
|
||||
Reporting errors
|
||||
----------------
|
||||
|
||||
As we have seen, kmemcheck will produce false positive reports. Therefore, it
|
||||
is not very wise to blindly post kmemcheck warnings to mailing lists and
|
||||
maintainers. Instead, I encourage maintainers and developers to find errors
|
||||
in their own code. If you get a warning, you can try to work around it, try
|
||||
to figure out if it's a real error or not, or simply ignore it. Most
|
||||
developers know their own code and will quickly and efficiently determine the
|
||||
root cause of a kmemcheck report. This is therefore also the most efficient
|
||||
way to work with kmemcheck.
|
||||
|
||||
That said, we (the kmemcheck maintainers) will always be on the lookout for
|
||||
false positives that we can annotate and silence. So whatever you find,
|
||||
please drop us a note privately! Kernel configs and steps to reproduce (if
|
||||
available) are of course a great help too.
|
||||
|
||||
Happy hacking!
|
||||
|
||||
|
||||
Technical description
|
||||
---------------------
|
||||
|
||||
kmemcheck works by marking memory pages non-present. This means that whenever
|
||||
somebody attempts to access the page, a page fault is generated. The page
|
||||
fault handler notices that the page was in fact only hidden, and so it calls
|
||||
on the kmemcheck code to make further investigations.
|
||||
|
||||
When the investigations are completed, kmemcheck "shows" the page by marking
|
||||
it present (as it would be under normal circumstances). This way, the
|
||||
interrupted code can continue as usual.
|
||||
|
||||
But after the instruction has been executed, we should hide the page again, so
|
||||
that we can catch the next access too! Now kmemcheck makes use of a debugging
|
||||
feature of the processor, namely single-stepping. When the processor has
|
||||
finished the one instruction that generated the memory access, a debug
|
||||
exception is raised. From here, we simply hide the page again and continue
|
||||
execution, this time with the single-stepping feature turned off.
|
||||
|
||||
kmemcheck requires some assistance from the memory allocator in order to work.
|
||||
The memory allocator needs to
|
||||
|
||||
1. Tell kmemcheck about newly allocated pages and pages that are about to
|
||||
be freed. This allows kmemcheck to set up and tear down the shadow memory
|
||||
for the pages in question. The shadow memory stores the status of each
|
||||
byte in the allocation proper, e.g. whether it is initialized or
|
||||
uninitialized.
|
||||
|
||||
2. Tell kmemcheck which parts of memory should be marked uninitialized.
|
||||
There are actually a few more states, such as "not yet allocated" and
|
||||
"recently freed".
|
||||
|
||||
If a slab cache is set up using the SLAB_NOTRACK flag, it will never return
|
||||
memory that can take page faults because of kmemcheck.
|
||||
|
||||
If a slab cache is NOT set up using the SLAB_NOTRACK flag, callers can still
|
||||
request memory with the __GFP_NOTRACK or __GFP_NOTRACK_FALSE_POSITIVE flags.
|
||||
This does not prevent the page faults from occurring, however, but marks the
|
||||
object in question as being initialized so that no warnings will ever be
|
||||
produced for this object.
|
||||
|
||||
Currently, the SLAB and SLUB allocators are supported by kmemcheck.
|
|
@ -1,15 +1,12 @@
|
|||
Kernel Memory Leak Detector
|
||||
===========================
|
||||
|
||||
Introduction
|
||||
------------
|
||||
|
||||
Kmemleak provides a way of detecting possible kernel memory leaks in a
|
||||
way similar to a tracing garbage collector
|
||||
(https://en.wikipedia.org/wiki/Garbage_collection_%28computer_science%29#Tracing_garbage_collectors),
|
||||
with the difference that the orphan objects are not freed but only
|
||||
reported via /sys/kernel/debug/kmemleak. A similar method is used by the
|
||||
Valgrind tool (memcheck --leak-check) to detect the memory leaks in
|
||||
Valgrind tool (``memcheck --leak-check``) to detect the memory leaks in
|
||||
user-space applications.
|
||||
Kmemleak is supported on x86, arm, powerpc, sparc, sh, microblaze, ppc, mips, s390, metag and tile.
|
||||
|
||||
|
@ -19,20 +16,20 @@ Usage
|
|||
CONFIG_DEBUG_KMEMLEAK in "Kernel hacking" has to be enabled. A kernel
|
||||
thread scans the memory every 10 minutes (by default) and prints the
|
||||
number of new unreferenced objects found. To display the details of all
|
||||
the possible memory leaks:
|
||||
the possible memory leaks::
|
||||
|
||||
# mount -t debugfs nodev /sys/kernel/debug/
|
||||
# cat /sys/kernel/debug/kmemleak
|
||||
|
||||
To trigger an intermediate memory scan:
|
||||
To trigger an intermediate memory scan::
|
||||
|
||||
# echo scan > /sys/kernel/debug/kmemleak
|
||||
|
||||
To clear the list of all current possible memory leaks:
|
||||
To clear the list of all current possible memory leaks::
|
||||
|
||||
# echo clear > /sys/kernel/debug/kmemleak
|
||||
|
||||
New leaks will then come up upon reading /sys/kernel/debug/kmemleak
|
||||
New leaks will then come up upon reading ``/sys/kernel/debug/kmemleak``
|
||||
again.
|
||||
|
||||
Note that the orphan objects are listed in the order they were allocated
|
||||
|
@ -40,22 +37,31 @@ and one object at the beginning of the list may cause other subsequent
|
|||
objects to be reported as orphan.
|
||||
|
||||
Memory scanning parameters can be modified at run-time by writing to the
|
||||
/sys/kernel/debug/kmemleak file. The following parameters are supported:
|
||||
``/sys/kernel/debug/kmemleak`` file. The following parameters are supported:
|
||||
|
||||
off - disable kmemleak (irreversible)
|
||||
stack=on - enable the task stacks scanning (default)
|
||||
stack=off - disable the tasks stacks scanning
|
||||
scan=on - start the automatic memory scanning thread (default)
|
||||
scan=off - stop the automatic memory scanning thread
|
||||
scan=<secs> - set the automatic memory scanning period in seconds
|
||||
(default 600, 0 to stop the automatic scanning)
|
||||
scan - trigger a memory scan
|
||||
clear - clear list of current memory leak suspects, done by
|
||||
marking all current reported unreferenced objects grey,
|
||||
or free all kmemleak objects if kmemleak has been disabled.
|
||||
dump=<addr> - dump information about the object found at <addr>
|
||||
- off
|
||||
disable kmemleak (irreversible)
|
||||
- stack=on
|
||||
enable the task stacks scanning (default)
|
||||
- stack=off
|
||||
disable the tasks stacks scanning
|
||||
- scan=on
|
||||
start the automatic memory scanning thread (default)
|
||||
- scan=off
|
||||
stop the automatic memory scanning thread
|
||||
- scan=<secs>
|
||||
set the automatic memory scanning period in seconds
|
||||
(default 600, 0 to stop the automatic scanning)
|
||||
- scan
|
||||
trigger a memory scan
|
||||
- clear
|
||||
clear list of current memory leak suspects, done by
|
||||
marking all current reported unreferenced objects grey,
|
||||
or free all kmemleak objects if kmemleak has been disabled.
|
||||
- dump=<addr>
|
||||
dump information about the object found at <addr>
|
||||
|
||||
Kmemleak can also be disabled at boot-time by passing "kmemleak=off" on
|
||||
Kmemleak can also be disabled at boot-time by passing ``kmemleak=off`` on
|
||||
the kernel command line.
|
||||
|
||||
Memory may be allocated or freed before kmemleak is initialised and
|
||||
|
@ -63,13 +69,14 @@ these actions are stored in an early log buffer. The size of this buffer
|
|||
is configured via the CONFIG_DEBUG_KMEMLEAK_EARLY_LOG_SIZE option.
|
||||
|
||||
If CONFIG_DEBUG_KMEMLEAK_DEFAULT_OFF are enabled, the kmemleak is
|
||||
disabled by default. Passing "kmemleak=on" on the kernel command
|
||||
disabled by default. Passing ``kmemleak=on`` on the kernel command
|
||||
line enables the function.
|
||||
|
||||
Basic Algorithm
|
||||
---------------
|
||||
|
||||
The memory allocations via kmalloc, vmalloc, kmem_cache_alloc and
|
||||
The memory allocations via :c:func:`kmalloc`, :c:func:`vmalloc`,
|
||||
:c:func:`kmem_cache_alloc` and
|
||||
friends are traced and the pointers, together with additional
|
||||
information like size and stack trace, are stored in a rbtree.
|
||||
The corresponding freeing function calls are tracked and the pointers
|
||||
|
@ -113,13 +120,13 @@ when doing development. To work around these situations you can use the
|
|||
you can find new unreferenced objects; this should help with testing
|
||||
specific sections of code.
|
||||
|
||||
To test a critical section on demand with a clean kmemleak do:
|
||||
To test a critical section on demand with a clean kmemleak do::
|
||||
|
||||
# echo clear > /sys/kernel/debug/kmemleak
|
||||
... test your kernel or modules ...
|
||||
# echo scan > /sys/kernel/debug/kmemleak
|
||||
|
||||
Then as usual to get your report with:
|
||||
Then as usual to get your report with::
|
||||
|
||||
# cat /sys/kernel/debug/kmemleak
|
||||
|
||||
|
@ -131,7 +138,7 @@ disabled by the user or due to an fatal error, internal kmemleak objects
|
|||
won't be freed when kmemleak is disabled, and those objects may occupy
|
||||
a large part of physical memory.
|
||||
|
||||
In this situation, you may reclaim memory with:
|
||||
In this situation, you may reclaim memory with::
|
||||
|
||||
# echo clear > /sys/kernel/debug/kmemleak
|
||||
|
||||
|
@ -140,20 +147,20 @@ Kmemleak API
|
|||
|
||||
See the include/linux/kmemleak.h header for the functions prototype.
|
||||
|
||||
kmemleak_init - initialize kmemleak
|
||||
kmemleak_alloc - notify of a memory block allocation
|
||||
kmemleak_alloc_percpu - notify of a percpu memory block allocation
|
||||
kmemleak_free - notify of a memory block freeing
|
||||
kmemleak_free_part - notify of a partial memory block freeing
|
||||
kmemleak_free_percpu - notify of a percpu memory block freeing
|
||||
kmemleak_update_trace - update object allocation stack trace
|
||||
kmemleak_not_leak - mark an object as not a leak
|
||||
kmemleak_ignore - do not scan or report an object as leak
|
||||
kmemleak_scan_area - add scan areas inside a memory block
|
||||
kmemleak_no_scan - do not scan a memory block
|
||||
kmemleak_erase - erase an old value in a pointer variable
|
||||
kmemleak_alloc_recursive - as kmemleak_alloc but checks the recursiveness
|
||||
kmemleak_free_recursive - as kmemleak_free but checks the recursiveness
|
||||
- ``kmemleak_init`` - initialize kmemleak
|
||||
- ``kmemleak_alloc`` - notify of a memory block allocation
|
||||
- ``kmemleak_alloc_percpu`` - notify of a percpu memory block allocation
|
||||
- ``kmemleak_free`` - notify of a memory block freeing
|
||||
- ``kmemleak_free_part`` - notify of a partial memory block freeing
|
||||
- ``kmemleak_free_percpu`` - notify of a percpu memory block freeing
|
||||
- ``kmemleak_update_trace`` - update object allocation stack trace
|
||||
- ``kmemleak_not_leak`` - mark an object as not a leak
|
||||
- ``kmemleak_ignore`` - do not scan or report an object as leak
|
||||
- ``kmemleak_scan_area`` - add scan areas inside a memory block
|
||||
- ``kmemleak_no_scan`` - do not scan a memory block
|
||||
- ``kmemleak_erase`` - erase an old value in a pointer variable
|
||||
- ``kmemleak_alloc_recursive`` - as kmemleak_alloc but checks the recursiveness
|
||||
- ``kmemleak_free_recursive`` - as kmemleak_free but checks the recursiveness
|
||||
|
||||
Dealing with false positives/negatives
|
||||
--------------------------------------
|
|
@ -1,11 +1,20 @@
|
|||
Copyright 2004 Linus Torvalds
|
||||
Copyright 2004 Pavel Machek <pavel@ucw.cz>
|
||||
Copyright 2006 Bob Copeland <me@bobcopeland.com>
|
||||
.. Copyright 2004 Linus Torvalds
|
||||
.. Copyright 2004 Pavel Machek <pavel@ucw.cz>
|
||||
.. Copyright 2006 Bob Copeland <me@bobcopeland.com>
|
||||
|
||||
Sparse
|
||||
======
|
||||
|
||||
Sparse is a semantic checker for C programs; it can be used to find a
|
||||
number of potential problems with kernel code. See
|
||||
https://lwn.net/Articles/689907/ for an overview of sparse; this document
|
||||
contains some kernel-specific sparse information.
|
||||
|
||||
|
||||
Using sparse for typechecking
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
-----------------------------
|
||||
|
||||
"__bitwise" is a type attribute, so you have to do something like this:
|
||||
"__bitwise" is a type attribute, so you have to do something like this::
|
||||
|
||||
typedef int __bitwise pm_request_t;
|
||||
|
||||
|
@ -20,13 +29,13 @@ but in this case we really _do_ want to force the conversion). And because
|
|||
the enum values are all the same type, now "enum pm_request" will be that
|
||||
type too.
|
||||
|
||||
And with gcc, all the __bitwise/__force stuff goes away, and it all ends
|
||||
up looking just like integers to gcc.
|
||||
And with gcc, all the "__bitwise"/"__force stuff" goes away, and it all
|
||||
ends up looking just like integers to gcc.
|
||||
|
||||
Quite frankly, you don't need the enum there. The above all really just
|
||||
boils down to one special "int __bitwise" type.
|
||||
|
||||
So the simpler way is to just do
|
||||
So the simpler way is to just do::
|
||||
|
||||
typedef int __bitwise pm_request_t;
|
||||
|
||||
|
@ -50,7 +59,7 @@ __bitwise - noisy stuff; in particular, __le*/__be* are that. We really
|
|||
don't want to drown in noise unless we'd explicitly asked for it.
|
||||
|
||||
Using sparse for lock checking
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
------------------------------
|
||||
|
||||
The following macros are undefined for gcc and defined during a sparse
|
||||
run to use the "context" tracking feature of sparse, applied to
|
||||
|
@ -69,22 +78,22 @@ annotation is needed. The tree annotations above are for cases where
|
|||
sparse would otherwise report a context imbalance.
|
||||
|
||||
Getting sparse
|
||||
~~~~~~~~~~~~~~
|
||||
--------------
|
||||
|
||||
You can get latest released versions from the Sparse homepage at
|
||||
https://sparse.wiki.kernel.org/index.php/Main_Page
|
||||
|
||||
Alternatively, you can get snapshots of the latest development version
|
||||
of sparse using git to clone..
|
||||
of sparse using git to clone::
|
||||
|
||||
git://git.kernel.org/pub/scm/devel/sparse/sparse.git
|
||||
|
||||
DaveJ has hourly generated tarballs of the git tree available at..
|
||||
DaveJ has hourly generated tarballs of the git tree available at::
|
||||
|
||||
http://www.codemonkey.org.uk/projects/git-snapshots/sparse/
|
||||
|
||||
|
||||
Once you have it, just do
|
||||
Once you have it, just do::
|
||||
|
||||
make
|
||||
make install
|
||||
|
@ -92,7 +101,7 @@ Once you have it, just do
|
|||
as a regular user, and it will install sparse in your ~/bin directory.
|
||||
|
||||
Using sparse
|
||||
~~~~~~~~~~~~
|
||||
------------
|
||||
|
||||
Do a kernel make with "make C=1" to run sparse on all the C files that get
|
||||
recompiled, or use "make C=2" to run sparse on the files whether they need to
|
||||
|
@ -101,7 +110,7 @@ have already built it.
|
|||
|
||||
The optional make variable CF can be used to pass arguments to sparse. The
|
||||
build system passes -Wbitwise to sparse automatically. To perform endianness
|
||||
checks, you may define __CHECK_ENDIAN__:
|
||||
checks, you may define __CHECK_ENDIAN__::
|
||||
|
||||
make C=2 CF="-D__CHECK_ENDIAN__"
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
================================
|
||||
Development tools for the kernel
|
||||
================================
|
||||
|
||||
This document is a collection of documents about development tools that can
|
||||
be used to work on the kernel. For now, the documents have been pulled
|
||||
together without any significant effot to integrate them into a coherent
|
||||
whole; patches welcome!
|
||||
|
||||
.. class:: toc-title
|
||||
|
||||
Table of contents
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
coccinelle
|
||||
sparse
|
||||
kcov
|
||||
gcov
|
||||
kasan
|
||||
ubsan
|
||||
kmemleak
|
||||
kmemcheck
|
||||
gdb-kernel-debugging
|
|
@ -1,7 +1,5 @@
|
|||
Undefined Behavior Sanitizer - UBSAN
|
||||
|
||||
Overview
|
||||
--------
|
||||
The Undefined Behavior Sanitizer - UBSAN
|
||||
========================================
|
||||
|
||||
UBSAN is a runtime undefined behaviour checker.
|
||||
|
||||
|
@ -10,11 +8,13 @@ Compiler inserts code that perform certain kinds of checks before operations
|
|||
that may cause UB. If check fails (i.e. UB detected) __ubsan_handle_*
|
||||
function called to print error message.
|
||||
|
||||
GCC has that feature since 4.9.x [1] (see -fsanitize=undefined option and
|
||||
its suboptions). GCC 5.x has more checkers implemented [2].
|
||||
GCC has that feature since 4.9.x [1_] (see ``-fsanitize=undefined`` option and
|
||||
its suboptions). GCC 5.x has more checkers implemented [2_].
|
||||
|
||||
Report example
|
||||
---------------
|
||||
--------------
|
||||
|
||||
::
|
||||
|
||||
================================================================================
|
||||
UBSAN: Undefined behaviour in ../include/linux/bitops.h:110:33
|
||||
|
@ -47,29 +47,33 @@ Report example
|
|||
Usage
|
||||
-----
|
||||
|
||||
To enable UBSAN configure kernel with:
|
||||
To enable UBSAN configure kernel with::
|
||||
|
||||
CONFIG_UBSAN=y
|
||||
|
||||
and to check the entire kernel:
|
||||
and to check the entire kernel::
|
||||
|
||||
CONFIG_UBSAN_SANITIZE_ALL=y
|
||||
|
||||
To enable instrumentation for specific files or directories, add a line
|
||||
similar to the following to the respective kernel Makefile:
|
||||
|
||||
For a single file (e.g. main.o):
|
||||
UBSAN_SANITIZE_main.o := y
|
||||
- For a single file (e.g. main.o)::
|
||||
|
||||
For all files in one directory:
|
||||
UBSAN_SANITIZE := y
|
||||
UBSAN_SANITIZE_main.o := y
|
||||
|
||||
- For all files in one directory::
|
||||
|
||||
UBSAN_SANITIZE := y
|
||||
|
||||
To exclude files from being instrumented even if
|
||||
CONFIG_UBSAN_SANITIZE_ALL=y, use:
|
||||
``CONFIG_UBSAN_SANITIZE_ALL=y``, use::
|
||||
|
||||
UBSAN_SANITIZE_main.o := n
|
||||
and:
|
||||
UBSAN_SANITIZE := n
|
||||
UBSAN_SANITIZE_main.o := n
|
||||
|
||||
and::
|
||||
|
||||
UBSAN_SANITIZE := n
|
||||
|
||||
Detection of unaligned accesses controlled through the separate option -
|
||||
CONFIG_UBSAN_ALIGNMENT. It's off by default on architectures that support
|
||||
|
@ -80,5 +84,5 @@ reports.
|
|||
References
|
||||
----------
|
||||
|
||||
[1] - https://gcc.gnu.org/onlinedocs/gcc-4.9.0/gcc/Debugging-Options.html
|
||||
[2] - https://gcc.gnu.org/onlinedocs/gcc/Debugging-Options.html
|
||||
.. _1: https://gcc.gnu.org/onlinedocs/gcc-4.9.0/gcc/Debugging-Options.html
|
||||
.. _2: https://gcc.gnu.org/onlinedocs/gcc/Debugging-Options.html
|
|
@ -1,16 +1,8 @@
|
|||
1: A GUIDE TO THE KERNEL DEVELOPMENT PROCESS
|
||||
Introdution
|
||||
===========
|
||||
|
||||
The purpose of this document is to help developers (and their managers)
|
||||
work with the development community with a minimum of frustration. It is
|
||||
an attempt to document how this community works in a way which is
|
||||
accessible to those who are not intimately familiar with Linux kernel
|
||||
development (or, indeed, free software development in general). While
|
||||
there is some technical material here, this is very much a process-oriented
|
||||
discussion which does not require a deep knowledge of kernel programming to
|
||||
understand.
|
||||
|
||||
|
||||
1.1: EXECUTIVE SUMMARY
|
||||
Executive summary
|
||||
-----------------
|
||||
|
||||
The rest of this section covers the scope of the kernel development process
|
||||
and the kinds of frustrations that developers and their employers can
|
||||
|
@ -20,41 +12,41 @@ availability to users, community support in many forms, and the ability to
|
|||
influence the direction of kernel development. Code contributed to the
|
||||
Linux kernel must be made available under a GPL-compatible license.
|
||||
|
||||
Section 2 introduces the development process, the kernel release cycle, and
|
||||
the mechanics of the merge window. The various phases in the patch
|
||||
development, review, and merging cycle are covered. There is some
|
||||
:ref:`development_process` introduces the development process, the kernel
|
||||
release cycle, and the mechanics of the merge window. The various phases in
|
||||
the patch development, review, and merging cycle are covered. There is some
|
||||
discussion of tools and mailing lists. Developers wanting to get started
|
||||
with kernel development are encouraged to track down and fix bugs as an
|
||||
initial exercise.
|
||||
|
||||
Section 3 covers early-stage project planning, with an emphasis on
|
||||
involving the development community as soon as possible.
|
||||
:ref:`development_early_stage` covers early-stage project planning, with an
|
||||
emphasis on involving the development community as soon as possible.
|
||||
|
||||
Section 4 is about the coding process; several pitfalls which have been
|
||||
encountered by other developers are discussed. Some requirements for
|
||||
:ref:`development_coding` is about the coding process; several pitfalls which
|
||||
have been encountered by other developers are discussed. Some requirements for
|
||||
patches are covered, and there is an introduction to some of the tools
|
||||
which can help to ensure that kernel patches are correct.
|
||||
|
||||
Section 5 talks about the process of posting patches for review. To be
|
||||
taken seriously by the development community, patches must be properly
|
||||
formatted and described, and they must be sent to the right place.
|
||||
:ref:`development_posting` talks about the process of posting patches for
|
||||
review. To be taken seriously by the development community, patches must be
|
||||
properly formatted and described, and they must be sent to the right place.
|
||||
Following the advice in this section should help to ensure the best
|
||||
possible reception for your work.
|
||||
|
||||
Section 6 covers what happens after posting patches; the job is far from
|
||||
done at that point. Working with reviewers is a crucial part of the
|
||||
development process; this section offers a number of tips on how to avoid
|
||||
problems at this important stage. Developers are cautioned against
|
||||
:ref:`development_followthrough` covers what happens after posting patches; the
|
||||
job is far from done at that point. Working with reviewers is a crucial part
|
||||
of the development process; this section offers a number of tips on how to
|
||||
avoid problems at this important stage. Developers are cautioned against
|
||||
assuming that the job is done when a patch is merged into the mainline.
|
||||
|
||||
Section 7 introduces a couple of "advanced" topics: managing patches with
|
||||
git and reviewing patches posted by others.
|
||||
:ref:`development_advancedtopics` introduces a couple of "advanced" topics:
|
||||
managing patches with git and reviewing patches posted by others.
|
||||
|
||||
Section 8 concludes the document with pointers to sources for more
|
||||
information on kernel development.
|
||||
:ref:`development_conclusion` concludes the document with pointers to sources
|
||||
for more information on kernel development.
|
||||
|
||||
|
||||
1.2: WHAT THIS DOCUMENT IS ABOUT
|
||||
What this document is about
|
||||
---------------------------
|
||||
|
||||
The Linux kernel, at over 8 million lines of code and well over 1000
|
||||
contributors to each release, is one of the largest and most active free
|
||||
|
@ -108,8 +100,8 @@ community is always in need of developers who will help to make the kernel
|
|||
better; the following text should help you - or those who work for you -
|
||||
join our community.
|
||||
|
||||
|
||||
1.3: CREDITS
|
||||
Credits
|
||||
-------
|
||||
|
||||
This document was written by Jonathan Corbet, corbet@lwn.net. It has been
|
||||
improved by comments from Johannes Berg, James Berry, Alex Chiang, Roland
|
||||
|
@ -120,8 +112,8 @@ Jochen Voß.
|
|||
This work was supported by the Linux Foundation; thanks especially to
|
||||
Amanda McPherson, who saw the value of this effort and made it all happen.
|
||||
|
||||
|
||||
1.4: THE IMPORTANCE OF GETTING CODE INTO THE MAINLINE
|
||||
The importance of getting code into the mainline
|
||||
------------------------------------------------
|
||||
|
||||
Some companies and developers occasionally wonder why they should bother
|
||||
learning how to work with the kernel community and get their code into the
|
||||
|
@ -233,8 +225,8 @@ commercial life, after which a new version must be released. At that
|
|||
point, vendors whose code is in the mainline and well maintained will be
|
||||
much better positioned to get the new product ready for market quickly.
|
||||
|
||||
|
||||
1.5: LICENSING
|
||||
Licensing
|
||||
---------
|
||||
|
||||
Code is contributed to the Linux kernel under a number of licenses, but all
|
||||
code must be compatible with version 2 of the GNU General Public License
|
|
@ -1,4 +1,7 @@
|
|||
2: HOW THE DEVELOPMENT PROCESS WORKS
|
||||
.. _development_process:
|
||||
|
||||
How the development process works
|
||||
=================================
|
||||
|
||||
Linux kernel development in the early 1990's was a pretty loose affair,
|
||||
with relatively small numbers of users and developers involved. With a
|
||||
|
@ -7,19 +10,21 @@ course of one year, the kernel has since had to evolve a number of
|
|||
processes to keep development happening smoothly. A solid understanding of
|
||||
how the process works is required in order to be an effective part of it.
|
||||
|
||||
|
||||
2.1: THE BIG PICTURE
|
||||
The big picture
|
||||
---------------
|
||||
|
||||
The kernel developers use a loosely time-based release process, with a new
|
||||
major kernel release happening every two or three months. The recent
|
||||
release history looks like this:
|
||||
|
||||
====== =================
|
||||
2.6.38 March 14, 2011
|
||||
2.6.37 January 4, 2011
|
||||
2.6.36 October 20, 2010
|
||||
2.6.35 August 1, 2010
|
||||
2.6.34 May 15, 2010
|
||||
2.6.33 February 24, 2010
|
||||
====== =================
|
||||
|
||||
Every 2.6.x release is a major kernel release with new features, internal
|
||||
API changes, and more. A typical 2.6 release can contain nearly 10,000
|
||||
|
@ -68,6 +73,7 @@ At that point the whole process starts over again.
|
|||
As an example, here is how the 2.6.38 development cycle went (all dates in
|
||||
2011):
|
||||
|
||||
============== ===============================
|
||||
January 4 2.6.37 stable release
|
||||
January 18 2.6.38-rc1, merge window closes
|
||||
January 21 2.6.38-rc2
|
||||
|
@ -78,6 +84,7 @@ As an example, here is how the 2.6.38 development cycle went (all dates in
|
|||
March 1 2.6.38-rc7
|
||||
March 7 2.6.38-rc8
|
||||
March 14 2.6.38 stable release
|
||||
============== ===============================
|
||||
|
||||
How do the developers decide when to close the development cycle and create
|
||||
the stable release? The most significant metric used is the list of
|
||||
|
@ -105,11 +112,13 @@ next development kernel. Kernels will typically receive stable updates for
|
|||
a little more than one development cycle past their initial release. So,
|
||||
for example, the 2.6.36 kernel's history looked like:
|
||||
|
||||
============== ===============================
|
||||
October 10 2.6.36 stable release
|
||||
November 22 2.6.36.1
|
||||
December 9 2.6.36.2
|
||||
January 7 2.6.36.3
|
||||
February 17 2.6.36.4
|
||||
============== ===============================
|
||||
|
||||
2.6.36.4 was the final stable update for the 2.6.36 release.
|
||||
|
||||
|
@ -117,9 +126,11 @@ Some kernels are designated "long term" kernels; they will receive support
|
|||
for a longer period. As of this writing, the current long term kernels
|
||||
and their maintainers are:
|
||||
|
||||
====== ====================== ===========================
|
||||
2.6.27 Willy Tarreau (Deep-frozen stable kernel)
|
||||
2.6.32 Greg Kroah-Hartman
|
||||
2.6.35 Andi Kleen (Embedded flag kernel)
|
||||
====== ====================== ===========================
|
||||
|
||||
The selection of a kernel for long-term support is purely a matter of a
|
||||
maintainer having the need and the time to maintain that release. There
|
||||
|
@ -127,7 +138,8 @@ are no known plans for long-term support for any specific upcoming
|
|||
release.
|
||||
|
||||
|
||||
2.2: THE LIFECYCLE OF A PATCH
|
||||
The lifecycle of a patch
|
||||
------------------------
|
||||
|
||||
Patches do not go directly from the developer's keyboard into the mainline
|
||||
kernel. There is, instead, a somewhat involved (if somewhat informal)
|
||||
|
@ -195,8 +207,8 @@ is to try to cut the process down to a single "merging into the mainline"
|
|||
step. This approach invariably leads to frustration for everybody
|
||||
involved.
|
||||
|
||||
|
||||
2.3: HOW PATCHES GET INTO THE KERNEL
|
||||
How patches get into the Kernel
|
||||
-------------------------------
|
||||
|
||||
There is exactly one person who can merge patches into the mainline kernel
|
||||
repository: Linus Torvalds. But, of the over 9,500 patches which went
|
||||
|
@ -242,7 +254,8 @@ finding the right maintainer. Sending patches directly to Linus is not
|
|||
normally the right way to go.
|
||||
|
||||
|
||||
2.4: NEXT TREES
|
||||
Next trees
|
||||
----------
|
||||
|
||||
The chain of subsystem trees guides the flow of patches into the kernel,
|
||||
but it also raises an interesting question: what if somebody wants to look
|
||||
|
@ -294,7 +307,8 @@ all patches merged during a given merge window should really have found
|
|||
their way into linux-next some time before the merge window opens.
|
||||
|
||||
|
||||
2.4.1: STAGING TREES
|
||||
Staging trees
|
||||
-------------
|
||||
|
||||
The kernel source tree contains the drivers/staging/ directory, where
|
||||
many sub-directories for drivers or filesystems that are on their way to
|
||||
|
@ -322,7 +336,8 @@ staging drivers. So staging is, at best, a stop on the way toward becoming
|
|||
a proper mainline driver.
|
||||
|
||||
|
||||
2.5: TOOLS
|
||||
Tools
|
||||
-----
|
||||
|
||||
As can be seen from the above text, the kernel development process depends
|
||||
heavily on the ability to herd collections of patches in various
|
||||
|
@ -368,7 +383,8 @@ upstream. For the management of certain kinds of trees (-mm, for example),
|
|||
quilt is the best tool for the job.
|
||||
|
||||
|
||||
2.6: MAILING LISTS
|
||||
Mailing lists
|
||||
-------------
|
||||
|
||||
A great deal of Linux kernel development work is done by way of mailing
|
||||
lists. It is hard to be a fully-functioning member of the community
|
||||
|
@ -436,7 +452,8 @@ filesystem, etc. subsystems. The best place to look for mailing lists is
|
|||
in the MAINTAINERS file packaged with the kernel source.
|
||||
|
||||
|
||||
2.7: GETTING STARTED WITH KERNEL DEVELOPMENT
|
||||
Getting started with Kernel development
|
||||
---------------------------------------
|
||||
|
||||
Questions about how to get started with the kernel development process are
|
||||
common - from both individuals and companies. Equally common are missteps
|
||||
|
@ -463,6 +480,8 @@ they wish for by these means.
|
|||
|
||||
Andrew Morton gives this advice for aspiring kernel developers
|
||||
|
||||
::
|
||||
|
||||
The #1 project for all kernel beginners should surely be "make sure
|
||||
that the kernel runs perfectly at all times on all machines which
|
||||
you can lay your hands on". Usually the way to do this is to work
|
|
@ -1,4 +1,7 @@
|
|||
3: EARLY-STAGE PLANNING
|
||||
.. _development_early_stage:
|
||||
|
||||
Early-stage planning
|
||||
====================
|
||||
|
||||
When contemplating a Linux kernel development project, it can be tempting
|
||||
to jump right in and start coding. As with any significant project,
|
||||
|
@ -7,7 +10,8 @@ line of code is written. Some time spent in early planning and
|
|||
communication can save far more time later on.
|
||||
|
||||
|
||||
3.1: SPECIFYING THE PROBLEM
|
||||
Specifying the problem
|
||||
----------------------
|
||||
|
||||
Like any engineering project, a successful kernel enhancement starts with a
|
||||
clear description of the problem to be solved. In some cases, this step is
|
||||
|
@ -64,7 +68,8 @@ answers to a short set of questions:
|
|||
Only then does it make sense to start considering possible solutions.
|
||||
|
||||
|
||||
3.2: EARLY DISCUSSION
|
||||
Early discussion
|
||||
----------------
|
||||
|
||||
When planning a kernel development project, it makes great sense to hold
|
||||
discussions with the community before launching into implementation. Early
|
||||
|
@ -117,7 +122,8 @@ In each of these cases, a great deal of pain and extra work could have been
|
|||
avoided with some early discussion with the kernel developers.
|
||||
|
||||
|
||||
3.3: WHO DO YOU TALK TO?
|
||||
Who do you talk to?
|
||||
-------------------
|
||||
|
||||
When developers decide to take their plans public, the next question will
|
||||
be: where do we start? The answer is to find the right mailing list(s) and
|
||||
|
@ -141,6 +147,8 @@ development project.
|
|||
The task of finding the right maintainer is sometimes challenging enough
|
||||
that the kernel developers have added a script to ease the process:
|
||||
|
||||
::
|
||||
|
||||
.../scripts/get_maintainer.pl
|
||||
|
||||
This script will return the current maintainer(s) for a given file or
|
||||
|
@ -155,7 +163,8 @@ If all else fails, talking to Andrew Morton can be an effective way to
|
|||
track down a maintainer for a specific piece of code.
|
||||
|
||||
|
||||
3.4: WHEN TO POST?
|
||||
When to post?
|
||||
-------------
|
||||
|
||||
If possible, posting your plans during the early stages can only be
|
||||
helpful. Describe the problem being solved and any plans that have been
|
||||
|
@ -179,7 +188,8 @@ idea. The best thing to do in this situation is to proceed, keeping the
|
|||
community informed as you go.
|
||||
|
||||
|
||||
3.5: GETTING OFFICIAL BUY-IN
|
||||
Getting official buy-in
|
||||
-----------------------
|
||||
|
||||
If your work is being done in a corporate environment - as most Linux
|
||||
kernel work is - you must, obviously, have permission from suitably
|
|
@ -1,4 +1,7 @@
|
|||
4: GETTING THE CODE RIGHT
|
||||
.. _development_coding:
|
||||
|
||||
Getting the code right
|
||||
======================
|
||||
|
||||
While there is much to be said for a solid and community-oriented design
|
||||
process, the proof of any kernel development project is in the resulting
|
||||
|
@ -12,9 +15,11 @@ will shift toward doing things right and the tools which can help in that
|
|||
quest.
|
||||
|
||||
|
||||
4.1: PITFALLS
|
||||
Pitfalls
|
||||
---------
|
||||
|
||||
* Coding style
|
||||
Coding style
|
||||
************
|
||||
|
||||
The kernel has long had a standard coding style, described in
|
||||
Documentation/CodingStyle. For much of that time, the policies described
|
||||
|
@ -54,7 +59,8 @@ style (a line which becomes far less readable if split to fit within the
|
|||
80-column limit, for example), just do it.
|
||||
|
||||
|
||||
* Abstraction layers
|
||||
Abstraction layers
|
||||
******************
|
||||
|
||||
Computer Science professors teach students to make extensive use of
|
||||
abstraction layers in the name of flexibility and information hiding.
|
||||
|
@ -87,7 +93,8 @@ implement that functionality at a higher level. There is no value in
|
|||
replicating the same code throughout the kernel.
|
||||
|
||||
|
||||
* #ifdef and preprocessor use in general
|
||||
#ifdef and preprocessor use in general
|
||||
**************************************
|
||||
|
||||
The C preprocessor seems to present a powerful temptation to some C
|
||||
programmers, who see it as a way to efficiently encode a great deal of
|
||||
|
@ -113,7 +120,8 @@ easier to read, do not evaluate their arguments multiple times, and allow
|
|||
the compiler to perform type checking on the arguments and return value.
|
||||
|
||||
|
||||
* Inline functions
|
||||
Inline functions
|
||||
****************
|
||||
|
||||
Inline functions present a hazard of their own, though. Programmers can
|
||||
become enamored of the perceived efficiency inherent in avoiding a function
|
||||
|
@ -137,7 +145,8 @@ placement of "inline" keywords may not just be excessive; it could also be
|
|||
irrelevant.
|
||||
|
||||
|
||||
* Locking
|
||||
Locking
|
||||
*******
|
||||
|
||||
In May, 2006, the "Devicescape" networking stack was, with great
|
||||
fanfare, released under the GPL and made available for inclusion in the
|
||||
|
@ -151,7 +160,7 @@ This code showed a number of signs of having been developed behind
|
|||
corporate doors. But one large problem in particular was that it was not
|
||||
designed to work on multiprocessor systems. Before this networking stack
|
||||
(now called mac80211) could be merged, a locking scheme needed to be
|
||||
retrofitted onto it.
|
||||
retrofitted onto it.
|
||||
|
||||
Once upon a time, Linux kernel code could be developed without thinking
|
||||
about the concurrency issues presented by multiprocessor systems. Now,
|
||||
|
@ -169,7 +178,8 @@ enough to pick the right tool for the job. Code which shows a lack of
|
|||
attention to concurrency will have a difficult path into the mainline.
|
||||
|
||||
|
||||
* Regressions
|
||||
Regressions
|
||||
***********
|
||||
|
||||
One final hazard worth mentioning is this: it can be tempting to make a
|
||||
change (which may bring big improvements) which causes something to break
|
||||
|
@ -185,6 +195,8 @@ change if it brings new functionality to ten systems for each one it
|
|||
breaks? The best answer to this question was expressed by Linus in July,
|
||||
2007:
|
||||
|
||||
::
|
||||
|
||||
So we don't fix bugs by introducing new problems. That way lies
|
||||
madness, and nobody ever knows if you actually make any real
|
||||
progress at all. Is it two steps forwards, one step back, or one
|
||||
|
@ -201,8 +213,8 @@ reason, a great deal of thought, clear documentation, and wide review for
|
|||
user-space interfaces is always required.
|
||||
|
||||
|
||||
|
||||
4.2: CODE CHECKING TOOLS
|
||||
Code checking tools
|
||||
-------------------
|
||||
|
||||
For now, at least, the writing of error-free code remains an ideal that few
|
||||
of us can reach. What we can hope to do, though, is to catch and fix as
|
||||
|
@ -250,7 +262,7 @@ testing purposes. In particular, you should turn on:
|
|||
There are quite a few other debugging options, some of which will be
|
||||
discussed below. Some of them have a significant performance impact and
|
||||
should not be used all of the time. But some time spent learning the
|
||||
available options will likely be paid back many times over in short order.
|
||||
available options will likely be paid back many times over in short order.
|
||||
|
||||
One of the heavier debugging tools is the locking checker, or "lockdep."
|
||||
This tool will track the acquisition and release of every lock (spinlock or
|
||||
|
@ -263,7 +275,7 @@ occasion, deadlock. This kind of problem can be painful (for both
|
|||
developers and users) in a deployed system; lockdep allows them to be found
|
||||
in an automated manner ahead of time. Code with any sort of non-trivial
|
||||
locking should be run with lockdep enabled before being submitted for
|
||||
inclusion.
|
||||
inclusion.
|
||||
|
||||
As a diligent kernel programmer, you will, beyond doubt, check the return
|
||||
status of any operation (such as a memory allocation) which can fail. The
|
||||
|
@ -300,7 +312,7 @@ Documentation/coccinelle.txt for more information.
|
|||
Other kinds of portability errors are best found by compiling your code for
|
||||
other architectures. If you do not happen to have an S/390 system or a
|
||||
Blackfin development board handy, you can still perform the compilation
|
||||
step. A large set of cross compilers for x86 systems can be found at
|
||||
step. A large set of cross compilers for x86 systems can be found at
|
||||
|
||||
http://www.kernel.org/pub/tools/crosstool/
|
||||
|
||||
|
@ -308,7 +320,8 @@ Some time spent installing and using these compilers will help avoid
|
|||
embarrassment later.
|
||||
|
||||
|
||||
4.3: DOCUMENTATION
|
||||
Documentation
|
||||
-------------
|
||||
|
||||
Documentation has often been more the exception than the rule with kernel
|
||||
development. Even so, adequate documentation will help to ease the merging
|
||||
|
@ -364,7 +377,8 @@ out. Anything which might tempt a code janitor to make an incorrect
|
|||
"cleanup" needs a comment saying why it is done the way it is. And so on.
|
||||
|
||||
|
||||
4.4: INTERNAL API CHANGES
|
||||
Internal API changes
|
||||
--------------------
|
||||
|
||||
The binary interface provided by the kernel to user space cannot be broken
|
||||
except under the most severe circumstances. The kernel's internal
|
|
@ -1,4 +1,7 @@
|
|||
5: POSTING PATCHES
|
||||
.. _development_posting:
|
||||
|
||||
Posting patches
|
||||
===============
|
||||
|
||||
Sooner or later, the time comes when your work is ready to be presented to
|
||||
the community for review and, eventually, inclusion into the mainline
|
||||
|
@ -11,7 +14,8 @@ SubmittingDrivers, and SubmitChecklist in the kernel documentation
|
|||
directory.
|
||||
|
||||
|
||||
5.1: WHEN TO POST
|
||||
When to post
|
||||
------------
|
||||
|
||||
There is a constant temptation to avoid posting patches before they are
|
||||
completely "ready." For simple patches, that is not a problem. If the
|
||||
|
@ -27,7 +31,8 @@ patches which are known to be half-baked, but those who do will come in
|
|||
with the idea that they can help you drive the work in the right direction.
|
||||
|
||||
|
||||
5.2: BEFORE CREATING PATCHES
|
||||
Before creating patches
|
||||
-----------------------
|
||||
|
||||
There are a number of things which should be done before you consider
|
||||
sending patches to the development community. These include:
|
||||
|
@ -52,7 +57,8 @@ As a general rule, putting in some extra thought before posting code almost
|
|||
always pays back the effort in short order.
|
||||
|
||||
|
||||
5.3: PATCH PREPARATION
|
||||
Patch preparation
|
||||
-----------------
|
||||
|
||||
The preparation of patches for posting can be a surprising amount of work,
|
||||
but, once again, attempting to save time here is not generally advisable
|
||||
|
@ -122,7 +128,8 @@ which takes quite a bit of time and thought after the "real work" has been
|
|||
done. When done properly, though, it is time well spent.
|
||||
|
||||
|
||||
5.4: PATCH FORMATTING AND CHANGELOGS
|
||||
Patch formatting and changelogs
|
||||
-------------------------------
|
||||
|
||||
So now you have a perfect series of patches for posting, but the work is
|
||||
not done quite yet. Each patch needs to be formatted into a message which
|
||||
|
@ -140,6 +147,8 @@ that end, each patch will be composed of the following:
|
|||
subsystem name first, followed by the purpose of the patch. For
|
||||
example:
|
||||
|
||||
::
|
||||
|
||||
gpio: fix build on CONFIG_GPIO_SYSFS=n
|
||||
|
||||
- A blank line followed by a detailed description of the contents of the
|
||||
|
@ -192,6 +201,8 @@ been associated with the development of this patch. They are described in
|
|||
detail in the SubmittingPatches document; what follows here is a brief
|
||||
summary. Each of these lines has the format:
|
||||
|
||||
::
|
||||
|
||||
tag: Full Name <email address> optional-other-stuff
|
||||
|
||||
The tags in common use are:
|
||||
|
@ -225,7 +236,8 @@ Be careful in the addition of tags to your patches: only Cc: is appropriate
|
|||
for addition without the explicit permission of the person named.
|
||||
|
||||
|
||||
5.5: SENDING THE PATCH
|
||||
Sending the patch
|
||||
-----------------
|
||||
|
||||
Before you mail your patches, there are a couple of other things you should
|
||||
take care of:
|
||||
|
@ -287,6 +299,8 @@ obvious maintainer, Andrew Morton is often the patch target of last resort.
|
|||
Patches need good subject lines. The canonical format for a patch line is
|
||||
something like:
|
||||
|
||||
::
|
||||
|
||||
[PATCH nn/mm] subsys: one-line description of the patch
|
||||
|
||||
where "nn" is the ordinal number of the patch, "mm" is the total number of
|
|
@ -1,4 +1,7 @@
|
|||
6: FOLLOWTHROUGH
|
||||
.. _development_followthrough:
|
||||
|
||||
Followthrough
|
||||
=============
|
||||
|
||||
At this point, you have followed the guidelines given so far and, with the
|
||||
addition of your own engineering skills, have posted a perfect series of
|
||||
|
@ -16,7 +19,8 @@ standards. A failure to participate in this process is quite likely to
|
|||
prevent the inclusion of your patches into the mainline.
|
||||
|
||||
|
||||
6.1: WORKING WITH REVIEWERS
|
||||
Working with reviewers
|
||||
----------------------
|
||||
|
||||
A patch of any significance will result in a number of comments from other
|
||||
developers as they review the code. Working with reviewers can be, for
|
||||
|
@ -97,7 +101,8 @@ though, and not before all other alternatives have been explored. And bear
|
|||
in mind, of course, that he may not agree with you either.
|
||||
|
||||
|
||||
6.2: WHAT HAPPENS NEXT
|
||||
What happens next
|
||||
-----------------
|
||||
|
||||
If a patch is considered to be a good thing to add to the kernel, and once
|
||||
most of the review issues have been resolved, the next step is usually
|
||||
|
@ -177,7 +182,8 @@ it with the assumption that you will not be around to maintain it
|
|||
afterward.
|
||||
|
||||
|
||||
6.3: OTHER THINGS THAT CAN HAPPEN
|
||||
Other things that can happen
|
||||
-----------------------------
|
||||
|
||||
One day, you may open your mail client and see that somebody has mailed you
|
||||
a patch to your code. That is one of the advantages of having your code
|
|
@ -1,11 +1,15 @@
|
|||
7: ADVANCED TOPICS
|
||||
.. _development_advancedtopics:
|
||||
|
||||
Advanced topics
|
||||
===============
|
||||
|
||||
At this point, hopefully, you have a handle on how the development process
|
||||
works. There is still more to learn, however! This section will cover a
|
||||
number of topics which can be helpful for developers wanting to become a
|
||||
regular part of the Linux kernel development process.
|
||||
|
||||
7.1: MANAGING PATCHES WITH GIT
|
||||
Managing patches with git
|
||||
-------------------------
|
||||
|
||||
The use of distributed version control for the kernel began in early 2002,
|
||||
when Linus first started playing with the proprietary BitKeeper
|
||||
|
@ -114,6 +118,8 @@ radar. Kernel developers tend to get unhappy when they see that kind of
|
|||
thing happening; putting up a git tree with unreviewed or off-topic patches
|
||||
can affect your ability to get trees pulled in the future. Quoting Linus:
|
||||
|
||||
::
|
||||
|
||||
You can send me patches, but for me to pull a git patch from you, I
|
||||
need to know that you know what you're doing, and I need to be able
|
||||
to trust things *without* then having to go and check every
|
||||
|
@ -141,7 +147,8 @@ format the request as other developers expect, and will also check to be
|
|||
sure that you have remembered to push those changes to the public server.
|
||||
|
||||
|
||||
7.2: REVIEWING PATCHES
|
||||
Reviewing patches
|
||||
-----------------
|
||||
|
||||
Some readers will certainly object to putting this section with "advanced
|
||||
topics" on the grounds that even beginning kernel developers should be
|
|
@ -1,4 +1,7 @@
|
|||
8: FOR MORE INFORMATION
|
||||
.. _development_conclusion:
|
||||
|
||||
For more information
|
||||
====================
|
||||
|
||||
There are numerous sources of information on Linux kernel development and
|
||||
related topics. First among those will always be the Documentation
|
||||
|
@ -47,7 +50,8 @@ Documentation for git can be found at:
|
|||
http://www.kernel.org/pub/software/scm/git/docs/user-manual.html
|
||||
|
||||
|
||||
9: CONCLUSION
|
||||
Conclusion
|
||||
==========
|
||||
|
||||
Congratulations to anybody who has made it through this long-winded
|
||||
document. Hopefully it has provided a helpful understanding of how the
|
|
@ -0,0 +1,10 @@
|
|||
# -*- coding: utf-8; mode: python -*-
|
||||
|
||||
project = 'Linux Kernel Development Documentation'
|
||||
|
||||
tags.add("subproject")
|
||||
|
||||
latex_documents = [
|
||||
('index', 'development-process.tex', 'Linux Kernel Development Documentation',
|
||||
'The kernel development community', 'manual'),
|
||||
]
|
|
@ -0,0 +1,29 @@
|
|||
.. _development_process_main:
|
||||
|
||||
A guide to the Kernel Development Process
|
||||
=========================================
|
||||
|
||||
Contents:
|
||||
|
||||
.. toctree::
|
||||
:numbered:
|
||||
:maxdepth: 2
|
||||
|
||||
1.Intro
|
||||
2.Process
|
||||
3.Early-stage
|
||||
4.Coding
|
||||
5.Posting
|
||||
6.Followthrough
|
||||
7.AdvancedTopics
|
||||
8.Conclusion
|
||||
|
||||
The purpose of this document is to help developers (and their managers)
|
||||
work with the development community with a minimum of frustration. It is
|
||||
an attempt to document how this community works in a way which is
|
||||
accessible to those who are not intimately familiar with Linux kernel
|
||||
development (or, indeed, free software development in general). While
|
||||
there is some technical material here, this is very much a process-oriented
|
||||
discussion which does not require a deep knowledge of kernel programming to
|
||||
understand.
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
Linux Kernel Development Documentation
|
||||
======================================
|
||||
|
||||
Contents:
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
development-process
|
|
@ -0,0 +1,7 @@
|
|||
# -*- coding: utf-8 mode: conf-colon -*-
|
||||
#
|
||||
# docutils configuration file
|
||||
# http://docutils.sourceforge.net/docs/user/config.html
|
||||
|
||||
[general]
|
||||
halt_level: severe
|
|
@ -0,0 +1,120 @@
|
|||
Driver Basics
|
||||
=============
|
||||
|
||||
Driver Entry and Exit points
|
||||
----------------------------
|
||||
|
||||
.. kernel-doc:: include/linux/init.h
|
||||
:internal:
|
||||
|
||||
Atomic and pointer manipulation
|
||||
-------------------------------
|
||||
|
||||
.. kernel-doc:: arch/x86/include/asm/atomic.h
|
||||
:internal:
|
||||
|
||||
Delaying, scheduling, and timer routines
|
||||
----------------------------------------
|
||||
|
||||
.. kernel-doc:: include/linux/sched.h
|
||||
:internal:
|
||||
|
||||
.. kernel-doc:: kernel/sched/core.c
|
||||
:export:
|
||||
|
||||
.. kernel-doc:: kernel/sched/cpupri.c
|
||||
:internal:
|
||||
|
||||
.. kernel-doc:: kernel/sched/fair.c
|
||||
:internal:
|
||||
|
||||
.. kernel-doc:: include/linux/completion.h
|
||||
:internal:
|
||||
|
||||
.. kernel-doc:: kernel/time/timer.c
|
||||
:export:
|
||||
|
||||
Wait queues and Wake events
|
||||
---------------------------
|
||||
|
||||
.. kernel-doc:: include/linux/wait.h
|
||||
:internal:
|
||||
|
||||
.. kernel-doc:: kernel/sched/wait.c
|
||||
:export:
|
||||
|
||||
High-resolution timers
|
||||
----------------------
|
||||
|
||||
.. kernel-doc:: include/linux/ktime.h
|
||||
:internal:
|
||||
|
||||
.. kernel-doc:: include/linux/hrtimer.h
|
||||
:internal:
|
||||
|
||||
.. kernel-doc:: kernel/time/hrtimer.c
|
||||
:export:
|
||||
|
||||
Workqueues and Kevents
|
||||
----------------------
|
||||
|
||||
.. kernel-doc:: include/linux/workqueue.h
|
||||
:internal:
|
||||
|
||||
.. kernel-doc:: kernel/workqueue.c
|
||||
:export:
|
||||
|
||||
Internal Functions
|
||||
------------------
|
||||
|
||||
.. kernel-doc:: kernel/exit.c
|
||||
:internal:
|
||||
|
||||
.. kernel-doc:: kernel/signal.c
|
||||
:internal:
|
||||
|
||||
.. kernel-doc:: include/linux/kthread.h
|
||||
:internal:
|
||||
|
||||
.. kernel-doc:: kernel/kthread.c
|
||||
:export:
|
||||
|
||||
Kernel objects manipulation
|
||||
---------------------------
|
||||
|
||||
.. kernel-doc:: lib/kobject.c
|
||||
:export:
|
||||
|
||||
Kernel utility functions
|
||||
------------------------
|
||||
|
||||
.. kernel-doc:: include/linux/kernel.h
|
||||
:internal:
|
||||
|
||||
.. kernel-doc:: kernel/printk/printk.c
|
||||
:export:
|
||||
|
||||
.. kernel-doc:: kernel/panic.c
|
||||
:export:
|
||||
|
||||
.. kernel-doc:: kernel/sys.c
|
||||
:export:
|
||||
|
||||
.. kernel-doc:: kernel/rcu/srcu.c
|
||||
:export:
|
||||
|
||||
.. kernel-doc:: kernel/rcu/tree.c
|
||||
:export:
|
||||
|
||||
.. kernel-doc:: kernel/rcu/tree_plugin.h
|
||||
:export:
|
||||
|
||||
.. kernel-doc:: kernel/rcu/update.c
|
||||
:export:
|
||||
|
||||
Device Resource Management
|
||||
--------------------------
|
||||
|
||||
.. kernel-doc:: drivers/base/devres.c
|
||||
:export:
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
Frame Buffer Library
|
||||
====================
|
||||
|
||||
The frame buffer drivers depend heavily on four data structures. These
|
||||
structures are declared in include/linux/fb.h. They are fb_info,
|
||||
fb_var_screeninfo, fb_fix_screeninfo and fb_monospecs. The last
|
||||
three can be made available to and from userland.
|
||||
|
||||
fb_info defines the current state of a particular video card. Inside
|
||||
fb_info, there exists a fb_ops structure which is a collection of
|
||||
needed functions to make fbdev and fbcon work. fb_info is only visible
|
||||
to the kernel.
|
||||
|
||||
fb_var_screeninfo is used to describe the features of a video card
|
||||
that are user defined. With fb_var_screeninfo, things such as depth
|
||||
and the resolution may be defined.
|
||||
|
||||
The next structure is fb_fix_screeninfo. This defines the properties
|
||||
of a card that are created when a mode is set and can't be changed
|
||||
otherwise. A good example of this is the start of the frame buffer
|
||||
memory. This "locks" the address of the frame buffer memory, so that it
|
||||
cannot be changed or moved.
|
||||
|
||||
The last structure is fb_monospecs. In the old API, there was little
|
||||
importance for fb_monospecs. This allowed for forbidden things such as
|
||||
setting a mode of 800x600 on a fix frequency monitor. With the new API,
|
||||
fb_monospecs prevents such things, and if used correctly, can prevent a
|
||||
monitor from being cooked. fb_monospecs will not be useful until
|
||||
kernels 2.5.x.
|
||||
|
||||
Frame Buffer Memory
|
||||
-------------------
|
||||
|
||||
.. kernel-doc:: drivers/video/fbdev/core/fbmem.c
|
||||
:export:
|
||||
|
||||
Frame Buffer Colormap
|
||||
---------------------
|
||||
|
||||
.. kernel-doc:: drivers/video/fbdev/core/fbcmap.c
|
||||
:export:
|
||||
|
||||
Frame Buffer Video Mode Database
|
||||
--------------------------------
|
||||
|
||||
.. kernel-doc:: drivers/video/fbdev/core/modedb.c
|
||||
:internal:
|
||||
|
||||
.. kernel-doc:: drivers/video/fbdev/core/modedb.c
|
||||
:export:
|
||||
|
||||
Frame Buffer Macintosh Video Mode Database
|
||||
------------------------------------------
|
||||
|
||||
.. kernel-doc:: drivers/video/fbdev/macmodes.c
|
||||
:export:
|
||||
|
||||
Frame Buffer Fonts
|
||||
------------------
|
||||
|
||||
Refer to the file lib/fonts/fonts.c for more information.
|
||||
|
|
@ -0,0 +1,88 @@
|
|||
High Speed Synchronous Serial Interface (HSI)
|
||||
=============================================
|
||||
|
||||
Introduction
|
||||
---------------
|
||||
|
||||
High Speed Syncronous Interface (HSI) is a fullduplex, low latency protocol,
|
||||
that is optimized for die-level interconnect between an Application Processor
|
||||
and a Baseband chipset. It has been specified by the MIPI alliance in 2003 and
|
||||
implemented by multiple vendors since then.
|
||||
|
||||
The HSI interface supports full duplex communication over multiple channels
|
||||
(typically 8) and is capable of reaching speeds up to 200 Mbit/s.
|
||||
|
||||
The serial protocol uses two signals, DATA and FLAG as combined data and clock
|
||||
signals and an additional READY signal for flow control. An additional WAKE
|
||||
signal can be used to wakeup the chips from standby modes. The signals are
|
||||
commonly prefixed by AC for signals going from the application die to the
|
||||
cellular die and CA for signals going the other way around.
|
||||
|
||||
::
|
||||
|
||||
+------------+ +---------------+
|
||||
| Cellular | | Application |
|
||||
| Die | | Die |
|
||||
| | - - - - - - CAWAKE - - - - - - >| |
|
||||
| T|------------ CADATA ------------>|R |
|
||||
| X|------------ CAFLAG ------------>|X |
|
||||
| |<----------- ACREADY ------------| |
|
||||
| | | |
|
||||
| | | |
|
||||
| |< - - - - - ACWAKE - - - - - - -| |
|
||||
| R|<----------- ACDATA -------------|T |
|
||||
| X|<----------- ACFLAG -------------|X |
|
||||
| |------------ CAREADY ----------->| |
|
||||
| | | |
|
||||
| | | |
|
||||
+------------+ +---------------+
|
||||
|
||||
HSI Subsystem in Linux
|
||||
-------------------------
|
||||
|
||||
In the Linux kernel the hsi subsystem is supposed to be used for HSI devices.
|
||||
The hsi subsystem contains drivers for hsi controllers including support for
|
||||
multi-port controllers and provides a generic API for using the HSI ports.
|
||||
|
||||
It also contains HSI client drivers, which make use of the generic API to
|
||||
implement a protocol used on the HSI interface. These client drivers can
|
||||
use an arbitrary number of channels.
|
||||
|
||||
hsi-char Device
|
||||
------------------
|
||||
|
||||
Each port automatically registers a generic client driver called hsi_char,
|
||||
which provides a charecter device for userspace representing the HSI port.
|
||||
It can be used to communicate via HSI from userspace. Userspace may
|
||||
configure the hsi_char device using the following ioctl commands:
|
||||
|
||||
HSC_RESET
|
||||
flush the HSI port
|
||||
|
||||
HSC_SET_PM
|
||||
enable or disable the client.
|
||||
|
||||
HSC_SEND_BREAK
|
||||
send break
|
||||
|
||||
HSC_SET_RX
|
||||
set RX configuration
|
||||
|
||||
HSC_GET_RX
|
||||
get RX configuration
|
||||
|
||||
HSC_SET_TX
|
||||
set TX configuration
|
||||
|
||||
HSC_GET_TX
|
||||
get TX configuration
|
||||
|
||||
The kernel HSI API
|
||||
------------------
|
||||
|
||||
.. kernel-doc:: include/linux/hsi/hsi.h
|
||||
:internal:
|
||||
|
||||
.. kernel-doc:: drivers/hsi/hsi_core.c
|
||||
:export:
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
I\ :sup:`2`\ C and SMBus Subsystem
|
||||
==================================
|
||||
|
||||
I\ :sup:`2`\ C (or without fancy typography, "I2C") is an acronym for
|
||||
the "Inter-IC" bus, a simple bus protocol which is widely used where low
|
||||
data rate communications suffice. Since it's also a licensed trademark,
|
||||
some vendors use another name (such as "Two-Wire Interface", TWI) for
|
||||
the same bus. I2C only needs two signals (SCL for clock, SDA for data),
|
||||
conserving board real estate and minimizing signal quality issues. Most
|
||||
I2C devices use seven bit addresses, and bus speeds of up to 400 kHz;
|
||||
there's a high speed extension (3.4 MHz) that's not yet found wide use.
|
||||
I2C is a multi-master bus; open drain signaling is used to arbitrate
|
||||
between masters, as well as to handshake and to synchronize clocks from
|
||||
slower clients.
|
||||
|
||||
The Linux I2C programming interfaces support only the master side of bus
|
||||
interactions, not the slave side. The programming interface is
|
||||
structured around two kinds of driver, and two kinds of device. An I2C
|
||||
"Adapter Driver" abstracts the controller hardware; it binds to a
|
||||
physical device (perhaps a PCI device or platform_device) and exposes a
|
||||
:c:type:`struct i2c_adapter <i2c_adapter>` representing each
|
||||
I2C bus segment it manages. On each I2C bus segment will be I2C devices
|
||||
represented by a :c:type:`struct i2c_client <i2c_client>`.
|
||||
Those devices will be bound to a :c:type:`struct i2c_driver
|
||||
<i2c_driver>`, which should follow the standard Linux driver
|
||||
model. (At this writing, a legacy model is more widely used.) There are
|
||||
functions to perform various I2C protocol operations; at this writing
|
||||
all such functions are usable only from task context.
|
||||
|
||||
The System Management Bus (SMBus) is a sibling protocol. Most SMBus
|
||||
systems are also I2C conformant. The electrical constraints are tighter
|
||||
for SMBus, and it standardizes particular protocol messages and idioms.
|
||||
Controllers that support I2C can also support most SMBus operations, but
|
||||
SMBus controllers don't support all the protocol options that an I2C
|
||||
controller will. There are functions to perform various SMBus protocol
|
||||
operations, either using I2C primitives or by issuing SMBus commands to
|
||||
i2c_adapter devices which don't support those I2C operations.
|
||||
|
||||
.. kernel-doc:: include/linux/i2c.h
|
||||
:internal:
|
||||
|
||||
.. kernel-doc:: drivers/i2c/i2c-boardinfo.c
|
||||
:functions: i2c_register_board_info
|
||||
|
||||
.. kernel-doc:: drivers/i2c/i2c-core.c
|
||||
:export:
|
|
@ -0,0 +1,26 @@
|
|||
========================================
|
||||
The Linux driver implementer's API guide
|
||||
========================================
|
||||
|
||||
The kernel offers a wide variety of interfaces to support the development
|
||||
of device drivers. This document is an only somewhat organized collection
|
||||
of some of those interfaces — it will hopefully get better over time! The
|
||||
available subsections can be seen below.
|
||||
|
||||
.. class:: toc-title
|
||||
|
||||
Table of contents
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
basics
|
||||
infrastructure
|
||||
message-based
|
||||
sound
|
||||
frame-buffer
|
||||
input
|
||||
spi
|
||||
i2c
|
||||
hsi
|
||||
miscellaneous
|
|
@ -0,0 +1,169 @@
|
|||
Device drivers infrastructure
|
||||
=============================
|
||||
|
||||
The Basic Device Driver-Model Structures
|
||||
----------------------------------------
|
||||
|
||||
.. kernel-doc:: include/linux/device.h
|
||||
:internal:
|
||||
|
||||
Device Drivers Base
|
||||
-------------------
|
||||
|
||||
.. kernel-doc:: drivers/base/init.c
|
||||
:internal:
|
||||
|
||||
.. kernel-doc:: drivers/base/driver.c
|
||||
:export:
|
||||
|
||||
.. kernel-doc:: drivers/base/core.c
|
||||
:export:
|
||||
|
||||
.. kernel-doc:: drivers/base/syscore.c
|
||||
:export:
|
||||
|
||||
.. kernel-doc:: drivers/base/class.c
|
||||
:export:
|
||||
|
||||
.. kernel-doc:: drivers/base/node.c
|
||||
:internal:
|
||||
|
||||
.. kernel-doc:: drivers/base/firmware_class.c
|
||||
:export:
|
||||
|
||||
.. kernel-doc:: drivers/base/transport_class.c
|
||||
:export:
|
||||
|
||||
.. kernel-doc:: drivers/base/dd.c
|
||||
:export:
|
||||
|
||||
.. kernel-doc:: include/linux/platform_device.h
|
||||
:internal:
|
||||
|
||||
.. kernel-doc:: drivers/base/platform.c
|
||||
:export:
|
||||
|
||||
.. kernel-doc:: drivers/base/bus.c
|
||||
:export:
|
||||
|
||||
Buffer Sharing and Synchronization
|
||||
----------------------------------
|
||||
|
||||
The dma-buf subsystem provides the framework for sharing buffers for
|
||||
hardware (DMA) access across multiple device drivers and subsystems, and
|
||||
for synchronizing asynchronous hardware access.
|
||||
|
||||
This is used, for example, by drm "prime" multi-GPU support, but is of
|
||||
course not limited to GPU use cases.
|
||||
|
||||
The three main components of this are: (1) dma-buf, representing a
|
||||
sg_table and exposed to userspace as a file descriptor to allow passing
|
||||
between devices, (2) fence, which provides a mechanism to signal when
|
||||
one device as finished access, and (3) reservation, which manages the
|
||||
shared or exclusive fence(s) associated with the buffer.
|
||||
|
||||
dma-buf
|
||||
~~~~~~~
|
||||
|
||||
.. kernel-doc:: drivers/dma-buf/dma-buf.c
|
||||
:export:
|
||||
|
||||
.. kernel-doc:: include/linux/dma-buf.h
|
||||
:internal:
|
||||
|
||||
reservation
|
||||
~~~~~~~~~~~
|
||||
|
||||
.. kernel-doc:: drivers/dma-buf/reservation.c
|
||||
:doc: Reservation Object Overview
|
||||
|
||||
.. kernel-doc:: drivers/dma-buf/reservation.c
|
||||
:export:
|
||||
|
||||
.. kernel-doc:: include/linux/reservation.h
|
||||
:internal:
|
||||
|
||||
fence
|
||||
~~~~~
|
||||
|
||||
.. kernel-doc:: drivers/dma-buf/fence.c
|
||||
:export:
|
||||
|
||||
.. kernel-doc:: include/linux/fence.h
|
||||
:internal:
|
||||
|
||||
.. kernel-doc:: drivers/dma-buf/seqno-fence.c
|
||||
:export:
|
||||
|
||||
.. kernel-doc:: include/linux/seqno-fence.h
|
||||
:internal:
|
||||
|
||||
.. kernel-doc:: drivers/dma-buf/fence-array.c
|
||||
:export:
|
||||
|
||||
.. kernel-doc:: include/linux/fence-array.h
|
||||
:internal:
|
||||
|
||||
.. kernel-doc:: drivers/dma-buf/reservation.c
|
||||
:export:
|
||||
|
||||
.. kernel-doc:: include/linux/reservation.h
|
||||
:internal:
|
||||
|
||||
.. kernel-doc:: drivers/dma-buf/sync_file.c
|
||||
:export:
|
||||
|
||||
.. kernel-doc:: include/linux/sync_file.h
|
||||
:internal:
|
||||
|
||||
Device Drivers DMA Management
|
||||
-----------------------------
|
||||
|
||||
.. kernel-doc:: drivers/base/dma-coherent.c
|
||||
:export:
|
||||
|
||||
.. kernel-doc:: drivers/base/dma-mapping.c
|
||||
:export:
|
||||
|
||||
Device Drivers Power Management
|
||||
-------------------------------
|
||||
|
||||
.. kernel-doc:: drivers/base/power/main.c
|
||||
:export:
|
||||
|
||||
Device Drivers ACPI Support
|
||||
---------------------------
|
||||
|
||||
.. kernel-doc:: drivers/acpi/scan.c
|
||||
:export:
|
||||
|
||||
.. kernel-doc:: drivers/acpi/scan.c
|
||||
:internal:
|
||||
|
||||
Device drivers PnP support
|
||||
--------------------------
|
||||
|
||||
.. kernel-doc:: drivers/pnp/core.c
|
||||
:internal:
|
||||
|
||||
.. kernel-doc:: drivers/pnp/card.c
|
||||
:export:
|
||||
|
||||
.. kernel-doc:: drivers/pnp/driver.c
|
||||
:internal:
|
||||
|
||||
.. kernel-doc:: drivers/pnp/manager.c
|
||||
:export:
|
||||
|
||||
.. kernel-doc:: drivers/pnp/support.c
|
||||
:export:
|
||||
|
||||
Userspace IO devices
|
||||
--------------------
|
||||
|
||||
.. kernel-doc:: drivers/uio/uio.c
|
||||
:export:
|
||||
|
||||
.. kernel-doc:: include/linux/uio_driver.h
|
||||
:internal:
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
Input Subsystem
|
||||
===============
|
||||
|
||||
Input core
|
||||
----------
|
||||
|
||||
.. kernel-doc:: include/linux/input.h
|
||||
:internal:
|
||||
|
||||
.. kernel-doc:: drivers/input/input.c
|
||||
:export:
|
||||
|
||||
.. kernel-doc:: drivers/input/ff-core.c
|
||||
:export:
|
||||
|
||||
.. kernel-doc:: drivers/input/ff-memless.c
|
||||
:export:
|
||||
|
||||
Multitouch Library
|
||||
------------------
|
||||
|
||||
.. kernel-doc:: include/linux/input/mt.h
|
||||
:internal:
|
||||
|
||||
.. kernel-doc:: drivers/input/input-mt.c
|
||||
:export:
|
||||
|
||||
Polled input devices
|
||||
--------------------
|
||||
|
||||
.. kernel-doc:: include/linux/input-polldev.h
|
||||
:internal:
|
||||
|
||||
.. kernel-doc:: drivers/input/input-polldev.c
|
||||
:export:
|
||||
|
||||
Matrix keyboards/keypads
|
||||
------------------------
|
||||
|
||||
.. kernel-doc:: include/linux/input/matrix_keypad.h
|
||||
:internal:
|
||||
|
||||
Sparse keymap support
|
||||
---------------------
|
||||
|
||||
.. kernel-doc:: include/linux/input/sparse-keymap.h
|
||||
:internal:
|
||||
|
||||
.. kernel-doc:: drivers/input/sparse-keymap.c
|
||||
:export:
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
Message-based devices
|
||||
=====================
|
||||
|
||||
Fusion message devices
|
||||
----------------------
|
||||
|
||||
.. kernel-doc:: drivers/message/fusion/mptbase.c
|
||||
:export:
|
||||
|
||||
.. kernel-doc:: drivers/message/fusion/mptscsih.c
|
||||
:export:
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
Parallel Port Devices
|
||||
=====================
|
||||
|
||||
.. kernel-doc:: include/linux/parport.h
|
||||
:internal:
|
||||
|
||||
.. kernel-doc:: drivers/parport/ieee1284.c
|
||||
:export:
|
||||
|
||||
.. kernel-doc:: drivers/parport/share.c
|
||||
:export:
|
||||
|
||||
.. kernel-doc:: drivers/parport/daisy.c
|
||||
:internal:
|
||||
|
||||
16x50 UART Driver
|
||||
=================
|
||||
|
||||
.. kernel-doc:: drivers/tty/serial/serial_core.c
|
||||
:export:
|
||||
|
||||
.. kernel-doc:: drivers/tty/serial/8250/8250_core.c
|
||||
:export:
|
||||
|
||||
Pulse-Width Modulation (PWM)
|
||||
============================
|
||||
|
||||
Pulse-width modulation is a modulation technique primarily used to
|
||||
control power supplied to electrical devices.
|
||||
|
||||
The PWM framework provides an abstraction for providers and consumers of
|
||||
PWM signals. A controller that provides one or more PWM signals is
|
||||
registered as :c:type:`struct pwm_chip <pwm_chip>`. Providers
|
||||
are expected to embed this structure in a driver-specific structure.
|
||||
This structure contains fields that describe a particular chip.
|
||||
|
||||
A chip exposes one or more PWM signal sources, each of which exposed as
|
||||
a :c:type:`struct pwm_device <pwm_device>`. Operations can be
|
||||
performed on PWM devices to control the period, duty cycle, polarity and
|
||||
active state of the signal.
|
||||
|
||||
Note that PWM devices are exclusive resources: they can always only be
|
||||
used by one consumer at a time.
|
||||
|
||||
.. kernel-doc:: include/linux/pwm.h
|
||||
:internal:
|
||||
|
||||
.. kernel-doc:: drivers/pwm/core.c
|
||||
:export:
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
Sound Devices
|
||||
=============
|
||||
|
||||
.. kernel-doc:: include/sound/core.h
|
||||
:internal:
|
||||
|
||||
.. kernel-doc:: sound/sound_core.c
|
||||
:export:
|
||||
|
||||
.. kernel-doc:: include/sound/pcm.h
|
||||
:internal:
|
||||
|
||||
.. kernel-doc:: sound/core/pcm.c
|
||||
:export:
|
||||
|
||||
.. kernel-doc:: sound/core/device.c
|
||||
:export:
|
||||
|
||||
.. kernel-doc:: sound/core/info.c
|
||||
:export:
|
||||
|
||||
.. kernel-doc:: sound/core/rawmidi.c
|
||||
:export:
|
||||
|
||||
.. kernel-doc:: sound/core/sound.c
|
||||
:export:
|
||||
|
||||
.. kernel-doc:: sound/core/memory.c
|
||||
:export:
|
||||
|
||||
.. kernel-doc:: sound/core/pcm_memory.c
|
||||
:export:
|
||||
|
||||
.. kernel-doc:: sound/core/init.c
|
||||
:export:
|
||||
|
||||
.. kernel-doc:: sound/core/isadma.c
|
||||
:export:
|
||||
|
||||
.. kernel-doc:: sound/core/control.c
|
||||
:export:
|
||||
|
||||
.. kernel-doc:: sound/core/pcm_lib.c
|
||||
:export:
|
||||
|
||||
.. kernel-doc:: sound/core/hwdep.c
|
||||
:export:
|
||||
|
||||
.. kernel-doc:: sound/core/pcm_native.c
|
||||
:export:
|
||||
|
||||
.. kernel-doc:: sound/core/memalloc.c
|
||||
:export:
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
Serial Peripheral Interface (SPI)
|
||||
=================================
|
||||
|
||||
SPI is the "Serial Peripheral Interface", widely used with embedded
|
||||
systems because it is a simple and efficient interface: basically a
|
||||
multiplexed shift register. Its three signal wires hold a clock (SCK,
|
||||
often in the range of 1-20 MHz), a "Master Out, Slave In" (MOSI) data
|
||||
line, and a "Master In, Slave Out" (MISO) data line. SPI is a full
|
||||
duplex protocol; for each bit shifted out the MOSI line (one per clock)
|
||||
another is shifted in on the MISO line. Those bits are assembled into
|
||||
words of various sizes on the way to and from system memory. An
|
||||
additional chipselect line is usually active-low (nCS); four signals are
|
||||
normally used for each peripheral, plus sometimes an interrupt.
|
||||
|
||||
The SPI bus facilities listed here provide a generalized interface to
|
||||
declare SPI busses and devices, manage them according to the standard
|
||||
Linux driver model, and perform input/output operations. At this time,
|
||||
only "master" side interfaces are supported, where Linux talks to SPI
|
||||
peripherals and does not implement such a peripheral itself. (Interfaces
|
||||
to support implementing SPI slaves would necessarily look different.)
|
||||
|
||||
The programming interface is structured around two kinds of driver, and
|
||||
two kinds of device. A "Controller Driver" abstracts the controller
|
||||
hardware, which may be as simple as a set of GPIO pins or as complex as
|
||||
a pair of FIFOs connected to dual DMA engines on the other side of the
|
||||
SPI shift register (maximizing throughput). Such drivers bridge between
|
||||
whatever bus they sit on (often the platform bus) and SPI, and expose
|
||||
the SPI side of their device as a :c:type:`struct spi_master
|
||||
<spi_master>`. SPI devices are children of that master,
|
||||
represented as a :c:type:`struct spi_device <spi_device>` and
|
||||
manufactured from :c:type:`struct spi_board_info
|
||||
<spi_board_info>` descriptors which are usually provided by
|
||||
board-specific initialization code. A :c:type:`struct spi_driver
|
||||
<spi_driver>` is called a "Protocol Driver", and is bound to a
|
||||
spi_device using normal driver model calls.
|
||||
|
||||
The I/O model is a set of queued messages. Protocol drivers submit one
|
||||
or more :c:type:`struct spi_message <spi_message>` objects,
|
||||
which are processed and completed asynchronously. (There are synchronous
|
||||
wrappers, however.) Messages are built from one or more
|
||||
:c:type:`struct spi_transfer <spi_transfer>` objects, each of
|
||||
which wraps a full duplex SPI transfer. A variety of protocol tweaking
|
||||
options are needed, because different chips adopt very different
|
||||
policies for how they use the bits transferred with SPI.
|
||||
|
||||
.. kernel-doc:: include/linux/spi/spi.h
|
||||
:internal:
|
||||
|
||||
.. kernel-doc:: drivers/spi/spi.c
|
||||
:functions: spi_register_board_info
|
||||
|
||||
.. kernel-doc:: drivers/spi/spi.c
|
||||
:export:
|
|
@ -50,7 +50,7 @@ Attributes of devices can be exported by a device driver through sysfs.
|
|||
Please see Documentation/filesystems/sysfs.txt for more information
|
||||
on how sysfs works.
|
||||
|
||||
As explained in Documentation/kobject.txt, device attributes must be be
|
||||
As explained in Documentation/kobject.txt, device attributes must be
|
||||
created before the KOBJ_ADD uevent is generated. The only way to realize
|
||||
that is by defining an attribute group.
|
||||
|
||||
|
|
|
@ -1,23 +1,27 @@
|
|||
.. _email_clients:
|
||||
|
||||
Email clients info for Linux
|
||||
======================================================================
|
||||
============================
|
||||
|
||||
Git
|
||||
----------------------------------------------------------------------
|
||||
These days most developers use `git send-email` instead of regular
|
||||
email clients. The man page for this is quite good. On the receiving
|
||||
end, maintainers use `git am` to apply the patches.
|
||||
---
|
||||
|
||||
If you are new to git then send your first patch to yourself. Save it
|
||||
as raw text including all the headers. Run `git am raw_email.txt` and
|
||||
then review the changelog with `git log`. When that works then send
|
||||
These days most developers use ``git send-email`` instead of regular
|
||||
email clients. The man page for this is quite good. On the receiving
|
||||
end, maintainers use ``git am`` to apply the patches.
|
||||
|
||||
If you are new to ``git`` then send your first patch to yourself. Save it
|
||||
as raw text including all the headers. Run ``git am raw_email.txt`` and
|
||||
then review the changelog with ``git log``. When that works then send
|
||||
the patch to the appropriate mailing list(s).
|
||||
|
||||
General Preferences
|
||||
----------------------------------------------------------------------
|
||||
-------------------
|
||||
|
||||
Patches for the Linux kernel are submitted via email, preferably as
|
||||
inline text in the body of the email. Some maintainers accept
|
||||
attachments, but then the attachments should have content-type
|
||||
"text/plain". However, attachments are generally frowned upon because
|
||||
``text/plain``. However, attachments are generally frowned upon because
|
||||
it makes quoting portions of the patch more difficult in the patch
|
||||
review process.
|
||||
|
||||
|
@ -25,7 +29,7 @@ Email clients that are used for Linux kernel patches should send the
|
|||
patch text untouched. For example, they should not modify or delete tabs
|
||||
or spaces, even at the beginning or end of lines.
|
||||
|
||||
Don't send patches with "format=flowed". This can cause unexpected
|
||||
Don't send patches with ``format=flowed``. This can cause unexpected
|
||||
and unwanted line breaks.
|
||||
|
||||
Don't let your email client do automatic word wrapping for you.
|
||||
|
@ -54,57 +58,63 @@ mailing lists.
|
|||
|
||||
|
||||
Some email client (MUA) hints
|
||||
----------------------------------------------------------------------
|
||||
-----------------------------
|
||||
|
||||
Here are some specific MUA configuration hints for editing and sending
|
||||
patches for the Linux kernel. These are not meant to be complete
|
||||
software package configuration summaries.
|
||||
|
||||
Legend:
|
||||
TUI = text-based user interface
|
||||
GUI = graphical user interface
|
||||
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Legend:
|
||||
|
||||
- TUI = text-based user interface
|
||||
- GUI = graphical user interface
|
||||
|
||||
Alpine (TUI)
|
||||
************
|
||||
|
||||
Config options:
|
||||
In the "Sending Preferences" section:
|
||||
|
||||
- "Do Not Send Flowed Text" must be enabled
|
||||
- "Strip Whitespace Before Sending" must be disabled
|
||||
In the :menuselection:`Sending Preferences` section:
|
||||
|
||||
- :menuselection:`Do Not Send Flowed Text` must be ``enabled``
|
||||
- :menuselection:`Strip Whitespace Before Sending` must be ``disabled``
|
||||
|
||||
When composing the message, the cursor should be placed where the patch
|
||||
should appear, and then pressing CTRL-R let you specify the patch file
|
||||
should appear, and then pressing :kbd:`CTRL-R` let you specify the patch file
|
||||
to insert into the message.
|
||||
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Claws Mail (GUI)
|
||||
****************
|
||||
|
||||
Works. Some people use this successfully for patches.
|
||||
|
||||
To insert a patch use Message->Insert File (CTRL+i) or an external editor.
|
||||
To insert a patch use :menuselection:`Message-->Insert` File (:kbd:`CTRL-I`)
|
||||
or an external editor.
|
||||
|
||||
If the inserted patch has to be edited in the Claws composition window
|
||||
"Auto wrapping" in Configuration->Preferences->Compose->Wrapping should be
|
||||
"Auto wrapping" in
|
||||
:menuselection:`Configuration-->Preferences-->Compose-->Wrapping` should be
|
||||
disabled.
|
||||
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Evolution (GUI)
|
||||
***************
|
||||
|
||||
Some people use this successfully for patches.
|
||||
|
||||
When composing mail select: Preformat
|
||||
from Format->Paragraph Style->Preformatted (Ctrl-7)
|
||||
from :menuselection:`Format-->Paragraph Style-->Preformatted` (:kbd:`CTRL-7`)
|
||||
or the toolbar
|
||||
|
||||
Then use:
|
||||
Insert->Text File... (Alt-n x)
|
||||
:menuselection:`Insert-->Text File...` (:kbd:`ALT-N x`)
|
||||
to insert the patch.
|
||||
|
||||
You can also "diff -Nru old.c new.c | xclip", select Preformat, then
|
||||
paste with the middle button.
|
||||
You can also ``diff -Nru old.c new.c | xclip``, select
|
||||
:menuselection:`Preformat`, then paste with the middle button.
|
||||
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Kmail (GUI)
|
||||
***********
|
||||
|
||||
Some people use Kmail successfully for patches.
|
||||
|
||||
|
@ -120,11 +130,12 @@ word-wrapped and you can uncheck "word wrap" without losing the existing
|
|||
wrapping.
|
||||
|
||||
At the bottom of your email, put the commonly-used patch delimiter before
|
||||
inserting your patch: three hyphens (---).
|
||||
inserting your patch: three hyphens (``---``).
|
||||
|
||||
Then from the "Message" menu item, select insert file and choose your patch.
|
||||
Then from the :menuselection:`Message` menu item, select insert file and
|
||||
choose your patch.
|
||||
As an added bonus you can customise the message creation toolbar menu
|
||||
and put the "insert file" icon there.
|
||||
and put the :menuselection:`insert file` icon there.
|
||||
|
||||
Make the composer window wide enough so that no lines wrap. As of
|
||||
KMail 1.13.5 (KDE 4.5.4), KMail will apply word wrapping when sending
|
||||
|
@ -139,86 +150,96 @@ as inlined text will make them tricky to extract from their 7-bit encoding.
|
|||
|
||||
If you absolutely must send patches as attachments instead of inlining
|
||||
them as text, right click on the attachment and select properties, and
|
||||
highlight "Suggest automatic display" to make the attachment inlined to
|
||||
make it more viewable.
|
||||
highlight :menuselection:`Suggest automatic display` to make the attachment
|
||||
inlined to make it more viewable.
|
||||
|
||||
When saving patches that are sent as inlined text, select the email that
|
||||
contains the patch from the message list pane, right click and select
|
||||
"save as". You can use the whole email unmodified as a patch if it was
|
||||
properly composed. There is no option currently to save the email when you
|
||||
are actually viewing it in its own window -- there has been a request filed
|
||||
at kmail's bugzilla and hopefully this will be addressed. Emails are saved
|
||||
as read-write for user only so you will have to chmod them to make them
|
||||
:menuselection:`save as`. You can use the whole email unmodified as a patch
|
||||
if it was properly composed. There is no option currently to save the email
|
||||
when you are actually viewing it in its own window -- there has been a request
|
||||
filed at kmail's bugzilla and hopefully this will be addressed. Emails are
|
||||
saved as read-write for user only so you will have to chmod them to make them
|
||||
group and world readable if you copy them elsewhere.
|
||||
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Lotus Notes (GUI)
|
||||
*****************
|
||||
|
||||
Run away from it.
|
||||
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Mutt (TUI)
|
||||
**********
|
||||
|
||||
Plenty of Linux developers use mutt, so it must work pretty well.
|
||||
Plenty of Linux developers use ``mutt``, so it must work pretty well.
|
||||
|
||||
Mutt doesn't come with an editor, so whatever editor you use should be
|
||||
used in a way that there are no automatic linebreaks. Most editors have
|
||||
an "insert file" option that inserts the contents of a file unaltered.
|
||||
an :menuselection:`insert file` option that inserts the contents of a file
|
||||
unaltered.
|
||||
|
||||
To use ``vim`` with mutt::
|
||||
|
||||
To use 'vim' with mutt:
|
||||
set editor="vi"
|
||||
|
||||
If using xclip, type the command
|
||||
If using xclip, type the command::
|
||||
|
||||
:set paste
|
||||
before middle button or shift-insert or use
|
||||
|
||||
before middle button or shift-insert or use::
|
||||
|
||||
:r filename
|
||||
|
||||
if you want to include the patch inline.
|
||||
(a)ttach works fine without "set paste".
|
||||
(a)ttach works fine without ``set paste``.
|
||||
|
||||
You can also generate patches with ``git format-patch`` and then use Mutt
|
||||
to send them::
|
||||
|
||||
You can also generate patches with 'git format-patch' and then use Mutt
|
||||
to send them:
|
||||
$ mutt -H 0001-some-bug-fix.patch
|
||||
|
||||
Config options:
|
||||
|
||||
It should work with default settings.
|
||||
However, it's a good idea to set the "send_charset" to:
|
||||
However, it's a good idea to set the ``send_charset`` to::
|
||||
|
||||
set send_charset="us-ascii:utf-8"
|
||||
|
||||
Mutt is highly customizable. Here is a minimum configuration to start
|
||||
using Mutt to send patches through Gmail:
|
||||
using Mutt to send patches through Gmail::
|
||||
|
||||
# .muttrc
|
||||
# ================ IMAP ====================
|
||||
set imap_user = 'yourusername@gmail.com'
|
||||
set imap_pass = 'yourpassword'
|
||||
set spoolfile = imaps://imap.gmail.com/INBOX
|
||||
set folder = imaps://imap.gmail.com/
|
||||
set record="imaps://imap.gmail.com/[Gmail]/Sent Mail"
|
||||
set postponed="imaps://imap.gmail.com/[Gmail]/Drafts"
|
||||
set mbox="imaps://imap.gmail.com/[Gmail]/All Mail"
|
||||
# .muttrc
|
||||
# ================ IMAP ====================
|
||||
set imap_user = 'yourusername@gmail.com'
|
||||
set imap_pass = 'yourpassword'
|
||||
set spoolfile = imaps://imap.gmail.com/INBOX
|
||||
set folder = imaps://imap.gmail.com/
|
||||
set record="imaps://imap.gmail.com/[Gmail]/Sent Mail"
|
||||
set postponed="imaps://imap.gmail.com/[Gmail]/Drafts"
|
||||
set mbox="imaps://imap.gmail.com/[Gmail]/All Mail"
|
||||
|
||||
# ================ SMTP ====================
|
||||
set smtp_url = "smtp://username@smtp.gmail.com:587/"
|
||||
set smtp_pass = $imap_pass
|
||||
set ssl_force_tls = yes # Require encrypted connection
|
||||
# ================ SMTP ====================
|
||||
set smtp_url = "smtp://username@smtp.gmail.com:587/"
|
||||
set smtp_pass = $imap_pass
|
||||
set ssl_force_tls = yes # Require encrypted connection
|
||||
|
||||
# ================ Composition ====================
|
||||
set editor = `echo \$EDITOR`
|
||||
set edit_headers = yes # See the headers when editing
|
||||
set charset = UTF-8 # value of $LANG; also fallback for send_charset
|
||||
# Sender, email address, and sign-off line must match
|
||||
unset use_domain # because joe@localhost is just embarrassing
|
||||
set realname = "YOUR NAME"
|
||||
set from = "username@gmail.com"
|
||||
set use_from = yes
|
||||
# ================ Composition ====================
|
||||
set editor = `echo \$EDITOR`
|
||||
set edit_headers = yes # See the headers when editing
|
||||
set charset = UTF-8 # value of $LANG; also fallback for send_charset
|
||||
# Sender, email address, and sign-off line must match
|
||||
unset use_domain # because joe@localhost is just embarrassing
|
||||
set realname = "YOUR NAME"
|
||||
set from = "username@gmail.com"
|
||||
set use_from = yes
|
||||
|
||||
The Mutt docs have lots more information:
|
||||
|
||||
http://dev.mutt.org/trac/wiki/UseCases/Gmail
|
||||
|
||||
http://dev.mutt.org/doc/manual.html
|
||||
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Pine (TUI)
|
||||
**********
|
||||
|
||||
Pine has had some whitespace truncation issues in the past, but these
|
||||
should all be fixed now.
|
||||
|
@ -226,12 +247,13 @@ should all be fixed now.
|
|||
Use alpine (pine's successor) if you can.
|
||||
|
||||
Config options:
|
||||
- quell-flowed-text is needed for recent versions
|
||||
- the "no-strip-whitespace-before-send" option is needed
|
||||
|
||||
- ``quell-flowed-text`` is needed for recent versions
|
||||
- the ``no-strip-whitespace-before-send`` option is needed
|
||||
|
||||
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Sylpheed (GUI)
|
||||
**************
|
||||
|
||||
- Works well for inlining text (or using attachments).
|
||||
- Allows use of an external editor.
|
||||
|
@ -241,50 +263,50 @@ Sylpheed (GUI)
|
|||
- Adding addresses to address book doesn't understand the display name
|
||||
properly.
|
||||
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Thunderbird (GUI)
|
||||
*****************
|
||||
|
||||
Thunderbird is an Outlook clone that likes to mangle text, but there are ways
|
||||
to coerce it into behaving.
|
||||
|
||||
- Allow use of an external editor:
|
||||
The easiest thing to do with Thunderbird and patches is to use an
|
||||
"external editor" extension and then just use your favorite $EDITOR
|
||||
"external editor" extension and then just use your favorite ``$EDITOR``
|
||||
for reading/merging patches into the body text. To do this, download
|
||||
and install the extension, then add a button for it using
|
||||
View->Toolbars->Customize... and finally just click on it when in the
|
||||
Compose dialog.
|
||||
:menuselection:`View-->Toolbars-->Customize...` and finally just click on it
|
||||
when in the :menuselection:`Compose` dialog.
|
||||
|
||||
Please note that "external editor" requires that your editor must not
|
||||
fork, or in other words, the editor must not return before closing.
|
||||
You may have to pass additional flags or change the settings of your
|
||||
editor. Most notably if you are using gvim then you must pass the -f
|
||||
option to gvim by putting "/usr/bin/gvim -f" (if the binary is in
|
||||
/usr/bin) to the text editor field in "external editor" settings. If you
|
||||
are using some other editor then please read its manual to find out how
|
||||
to do this.
|
||||
option to gvim by putting ``/usr/bin/gvim -f`` (if the binary is in
|
||||
``/usr/bin``) to the text editor field in :menuselection:`external editor`
|
||||
settings. If you are using some other editor then please read its manual
|
||||
to find out how to do this.
|
||||
|
||||
To beat some sense out of the internal editor, do this:
|
||||
|
||||
- Edit your Thunderbird config settings so that it won't use format=flowed.
|
||||
Go to "edit->preferences->advanced->config editor" to bring up the
|
||||
thunderbird's registry editor.
|
||||
- Edit your Thunderbird config settings so that it won't use ``format=flowed``.
|
||||
Go to :menuselection:`edit-->preferences-->advanced-->config editor` to bring up
|
||||
the thunderbird's registry editor.
|
||||
|
||||
- Set "mailnews.send_plaintext_flowed" to "false"
|
||||
- Set ``mailnews.send_plaintext_flowed`` to ``false``
|
||||
|
||||
- Set "mailnews.wraplength" from "72" to "0"
|
||||
- Set ``mailnews.wraplength`` from ``72`` to ``0``
|
||||
|
||||
- "View" > "Message Body As" > "Plain Text"
|
||||
- :menuselection:`View-->Message Body As-->Plain Text`
|
||||
|
||||
- "View" > "Character Encoding" > "Unicode (UTF-8)"
|
||||
- :menuselection:`View-->Character Encoding-->Unicode (UTF-8)`
|
||||
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
TkRat (GUI)
|
||||
***********
|
||||
|
||||
Works. Use "Insert file..." or external editor.
|
||||
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Gmail (Web GUI)
|
||||
***************
|
||||
|
||||
Does not work for sending patches.
|
||||
|
||||
|
@ -295,5 +317,3 @@ although tab2space problem can be solved with external editor.
|
|||
|
||||
Another problem is that Gmail will base64-encode any message that has a
|
||||
non-ASCII character. That includes things like European names.
|
||||
|
||||
###
|
||||
|
|
|
@ -123,9 +123,12 @@ The DAX code does not work correctly on architectures which have virtually
|
|||
mapped caches such as ARM, MIPS and SPARC.
|
||||
|
||||
Calling get_user_pages() on a range of user memory that has been mmaped
|
||||
from a DAX file will fail as there are no 'struct page' to describe
|
||||
those pages. This problem is being worked on. That means that O_DIRECT
|
||||
reads/writes to those memory ranges from a non-DAX file will fail (note
|
||||
that O_DIRECT reads/writes _of a DAX file_ do work, it is the memory
|
||||
that is being accessed that is key here). Other things that will not
|
||||
work include RDMA, sendfile() and splice().
|
||||
from a DAX file will fail when there are no 'struct page' to describe
|
||||
those pages. This problem has been addressed in some device drivers
|
||||
by adding optional struct page support for pages under the control of
|
||||
the driver (see CONFIG_NVDIMM_PFN in drivers/nvdimm for an example of
|
||||
how to do this). In the non struct page cases O_DIRECT reads/writes to
|
||||
those memory ranges from a non-DAX file will fail (note that O_DIRECT
|
||||
reads/writes _of a DAX file_ do work, it is the memory that is being
|
||||
accessed that is key here). Other things that will not work in the
|
||||
non struct page case include RDMA, sendfile() and splice().
|
||||
|
|
|
@ -145,7 +145,7 @@ Table 1-1: Process specific entries in /proc
|
|||
symbol the task is blocked in - or "0" if not blocked.
|
||||
pagemap Page table
|
||||
stack Report full stack trace, enable via CONFIG_STACKTRACE
|
||||
smaps a extension based on maps, showing the memory consumption of
|
||||
smaps an extension based on maps, showing the memory consumption of
|
||||
each mapping and flags associated with it
|
||||
numa_maps an extension based on maps, showing the memory locality and
|
||||
binding policy as well as mem usage (in pages) of each mapping.
|
||||
|
|
|
@ -1,257 +0,0 @@
|
|||
Using gcov with the Linux kernel
|
||||
================================
|
||||
|
||||
1. Introduction
|
||||
2. Preparation
|
||||
3. Customization
|
||||
4. Files
|
||||
5. Modules
|
||||
6. Separated build and test machines
|
||||
7. Troubleshooting
|
||||
Appendix A: sample script: gather_on_build.sh
|
||||
Appendix B: sample script: gather_on_test.sh
|
||||
|
||||
|
||||
1. Introduction
|
||||
===============
|
||||
|
||||
gcov profiling kernel support enables the use of GCC's coverage testing
|
||||
tool gcov [1] with the Linux kernel. Coverage data of a running kernel
|
||||
is exported in gcov-compatible format via the "gcov" debugfs directory.
|
||||
To get coverage data for a specific file, change to the kernel build
|
||||
directory and use gcov with the -o option as follows (requires root):
|
||||
|
||||
# cd /tmp/linux-out
|
||||
# gcov -o /sys/kernel/debug/gcov/tmp/linux-out/kernel spinlock.c
|
||||
|
||||
This will create source code files annotated with execution counts
|
||||
in the current directory. In addition, graphical gcov front-ends such
|
||||
as lcov [2] can be used to automate the process of collecting data
|
||||
for the entire kernel and provide coverage overviews in HTML format.
|
||||
|
||||
Possible uses:
|
||||
|
||||
* debugging (has this line been reached at all?)
|
||||
* test improvement (how do I change my test to cover these lines?)
|
||||
* minimizing kernel configurations (do I need this option if the
|
||||
associated code is never run?)
|
||||
|
||||
--
|
||||
|
||||
[1] http://gcc.gnu.org/onlinedocs/gcc/Gcov.html
|
||||
[2] http://ltp.sourceforge.net/coverage/lcov.php
|
||||
|
||||
|
||||
2. Preparation
|
||||
==============
|
||||
|
||||
Configure the kernel with:
|
||||
|
||||
CONFIG_DEBUG_FS=y
|
||||
CONFIG_GCOV_KERNEL=y
|
||||
|
||||
select the gcc's gcov format, default is autodetect based on gcc version:
|
||||
|
||||
CONFIG_GCOV_FORMAT_AUTODETECT=y
|
||||
|
||||
and to get coverage data for the entire kernel:
|
||||
|
||||
CONFIG_GCOV_PROFILE_ALL=y
|
||||
|
||||
Note that kernels compiled with profiling flags will be significantly
|
||||
larger and run slower. Also CONFIG_GCOV_PROFILE_ALL may not be supported
|
||||
on all architectures.
|
||||
|
||||
Profiling data will only become accessible once debugfs has been
|
||||
mounted:
|
||||
|
||||
mount -t debugfs none /sys/kernel/debug
|
||||
|
||||
|
||||
3. Customization
|
||||
================
|
||||
|
||||
To enable profiling for specific files or directories, add a line
|
||||
similar to the following to the respective kernel Makefile:
|
||||
|
||||
For a single file (e.g. main.o):
|
||||
GCOV_PROFILE_main.o := y
|
||||
|
||||
For all files in one directory:
|
||||
GCOV_PROFILE := y
|
||||
|
||||
To exclude files from being profiled even when CONFIG_GCOV_PROFILE_ALL
|
||||
is specified, use:
|
||||
|
||||
GCOV_PROFILE_main.o := n
|
||||
and:
|
||||
GCOV_PROFILE := n
|
||||
|
||||
Only files which are linked to the main kernel image or are compiled as
|
||||
kernel modules are supported by this mechanism.
|
||||
|
||||
|
||||
4. Files
|
||||
========
|
||||
|
||||
The gcov kernel support creates the following files in debugfs:
|
||||
|
||||
/sys/kernel/debug/gcov
|
||||
Parent directory for all gcov-related files.
|
||||
|
||||
/sys/kernel/debug/gcov/reset
|
||||
Global reset file: resets all coverage data to zero when
|
||||
written to.
|
||||
|
||||
/sys/kernel/debug/gcov/path/to/compile/dir/file.gcda
|
||||
The actual gcov data file as understood by the gcov
|
||||
tool. Resets file coverage data to zero when written to.
|
||||
|
||||
/sys/kernel/debug/gcov/path/to/compile/dir/file.gcno
|
||||
Symbolic link to a static data file required by the gcov
|
||||
tool. This file is generated by gcc when compiling with
|
||||
option -ftest-coverage.
|
||||
|
||||
|
||||
5. Modules
|
||||
==========
|
||||
|
||||
Kernel modules may contain cleanup code which is only run during
|
||||
module unload time. The gcov mechanism provides a means to collect
|
||||
coverage data for such code by keeping a copy of the data associated
|
||||
with the unloaded module. This data remains available through debugfs.
|
||||
Once the module is loaded again, the associated coverage counters are
|
||||
initialized with the data from its previous instantiation.
|
||||
|
||||
This behavior can be deactivated by specifying the gcov_persist kernel
|
||||
parameter:
|
||||
|
||||
gcov_persist=0
|
||||
|
||||
At run-time, a user can also choose to discard data for an unloaded
|
||||
module by writing to its data file or the global reset file.
|
||||
|
||||
|
||||
6. Separated build and test machines
|
||||
====================================
|
||||
|
||||
The gcov kernel profiling infrastructure is designed to work out-of-the
|
||||
box for setups where kernels are built and run on the same machine. In
|
||||
cases where the kernel runs on a separate machine, special preparations
|
||||
must be made, depending on where the gcov tool is used:
|
||||
|
||||
a) gcov is run on the TEST machine
|
||||
|
||||
The gcov tool version on the test machine must be compatible with the
|
||||
gcc version used for kernel build. Also the following files need to be
|
||||
copied from build to test machine:
|
||||
|
||||
from the source tree:
|
||||
- all C source files + headers
|
||||
|
||||
from the build tree:
|
||||
- all C source files + headers
|
||||
- all .gcda and .gcno files
|
||||
- all links to directories
|
||||
|
||||
It is important to note that these files need to be placed into the
|
||||
exact same file system location on the test machine as on the build
|
||||
machine. If any of the path components is symbolic link, the actual
|
||||
directory needs to be used instead (due to make's CURDIR handling).
|
||||
|
||||
b) gcov is run on the BUILD machine
|
||||
|
||||
The following files need to be copied after each test case from test
|
||||
to build machine:
|
||||
|
||||
from the gcov directory in sysfs:
|
||||
- all .gcda files
|
||||
- all links to .gcno files
|
||||
|
||||
These files can be copied to any location on the build machine. gcov
|
||||
must then be called with the -o option pointing to that directory.
|
||||
|
||||
Example directory setup on the build machine:
|
||||
|
||||
/tmp/linux: kernel source tree
|
||||
/tmp/out: kernel build directory as specified by make O=
|
||||
/tmp/coverage: location of the files copied from the test machine
|
||||
|
||||
[user@build] cd /tmp/out
|
||||
[user@build] gcov -o /tmp/coverage/tmp/out/init main.c
|
||||
|
||||
|
||||
7. Troubleshooting
|
||||
==================
|
||||
|
||||
Problem: Compilation aborts during linker step.
|
||||
Cause: Profiling flags are specified for source files which are not
|
||||
linked to the main kernel or which are linked by a custom
|
||||
linker procedure.
|
||||
Solution: Exclude affected source files from profiling by specifying
|
||||
GCOV_PROFILE := n or GCOV_PROFILE_basename.o := n in the
|
||||
corresponding Makefile.
|
||||
|
||||
Problem: Files copied from sysfs appear empty or incomplete.
|
||||
Cause: Due to the way seq_file works, some tools such as cp or tar
|
||||
may not correctly copy files from sysfs.
|
||||
Solution: Use 'cat' to read .gcda files and 'cp -d' to copy links.
|
||||
Alternatively use the mechanism shown in Appendix B.
|
||||
|
||||
|
||||
Appendix A: gather_on_build.sh
|
||||
==============================
|
||||
|
||||
Sample script to gather coverage meta files on the build machine
|
||||
(see 6a):
|
||||
#!/bin/bash
|
||||
|
||||
KSRC=$1
|
||||
KOBJ=$2
|
||||
DEST=$3
|
||||
|
||||
if [ -z "$KSRC" ] || [ -z "$KOBJ" ] || [ -z "$DEST" ]; then
|
||||
echo "Usage: $0 <ksrc directory> <kobj directory> <output.tar.gz>" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
KSRC=$(cd $KSRC; printf "all:\n\t@echo \${CURDIR}\n" | make -f -)
|
||||
KOBJ=$(cd $KOBJ; printf "all:\n\t@echo \${CURDIR}\n" | make -f -)
|
||||
|
||||
find $KSRC $KOBJ \( -name '*.gcno' -o -name '*.[ch]' -o -type l \) -a \
|
||||
-perm /u+r,g+r | tar cfz $DEST -P -T -
|
||||
|
||||
if [ $? -eq 0 ] ; then
|
||||
echo "$DEST successfully created, copy to test system and unpack with:"
|
||||
echo " tar xfz $DEST -P"
|
||||
else
|
||||
echo "Could not create file $DEST"
|
||||
fi
|
||||
|
||||
|
||||
Appendix B: gather_on_test.sh
|
||||
=============================
|
||||
|
||||
Sample script to gather coverage data files on the test machine
|
||||
(see 6b):
|
||||
|
||||
#!/bin/bash -e
|
||||
|
||||
DEST=$1
|
||||
GCDA=/sys/kernel/debug/gcov
|
||||
|
||||
if [ -z "$DEST" ] ; then
|
||||
echo "Usage: $0 <output.tar.gz>" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
TEMPDIR=$(mktemp -d)
|
||||
echo Collecting data..
|
||||
find $GCDA -type d -exec mkdir -p $TEMPDIR/\{\} \;
|
||||
find $GCDA -name '*.gcda' -exec sh -c 'cat < $0 > '$TEMPDIR'/$0' {} \;
|
||||
find $GCDA -name '*.gcno' -exec sh -c 'cp -d $0 '$TEMPDIR'/$0' {} \;
|
||||
tar czf $DEST -C $TEMPDIR sys
|
||||
rm -rf $TEMPDIR
|
||||
|
||||
echo "$DEST successfully created, copy to build system and unpack with:"
|
||||
echo " tar xfz $DEST"
|
|
@ -0,0 +1,5 @@
|
|||
# -*- coding: utf-8; mode: python -*-
|
||||
|
||||
project = "Linux GPU Driver Developer's Guide"
|
||||
|
||||
tags.add("subproject")
|
|
@ -12,3 +12,10 @@ Linux GPU Driver Developer's Guide
|
|||
drm-uapi
|
||||
i915
|
||||
vga-switcheroo
|
||||
|
||||
.. only:: subproject
|
||||
|
||||
Indices
|
||||
=======
|
||||
|
||||
* :ref:`genindex`
|
||||
|
|
|
@ -1,75 +0,0 @@
|
|||
HSI - High-speed Synchronous Serial Interface
|
||||
|
||||
1. Introduction
|
||||
~~~~~~~~~~~~~~~
|
||||
|
||||
High Speed Syncronous Interface (HSI) is a fullduplex, low latency protocol,
|
||||
that is optimized for die-level interconnect between an Application Processor
|
||||
and a Baseband chipset. It has been specified by the MIPI alliance in 2003 and
|
||||
implemented by multiple vendors since then.
|
||||
|
||||
The HSI interface supports full duplex communication over multiple channels
|
||||
(typically 8) and is capable of reaching speeds up to 200 Mbit/s.
|
||||
|
||||
The serial protocol uses two signals, DATA and FLAG as combined data and clock
|
||||
signals and an additional READY signal for flow control. An additional WAKE
|
||||
signal can be used to wakeup the chips from standby modes. The signals are
|
||||
commonly prefixed by AC for signals going from the application die to the
|
||||
cellular die and CA for signals going the other way around.
|
||||
|
||||
+------------+ +---------------+
|
||||
| Cellular | | Application |
|
||||
| Die | | Die |
|
||||
| | - - - - - - CAWAKE - - - - - - >| |
|
||||
| T|------------ CADATA ------------>|R |
|
||||
| X|------------ CAFLAG ------------>|X |
|
||||
| |<----------- ACREADY ------------| |
|
||||
| | | |
|
||||
| | | |
|
||||
| |< - - - - - ACWAKE - - - - - - -| |
|
||||
| R|<----------- ACDATA -------------|T |
|
||||
| X|<----------- ACFLAG -------------|X |
|
||||
| |------------ CAREADY ----------->| |
|
||||
| | | |
|
||||
| | | |
|
||||
+------------+ +---------------+
|
||||
|
||||
2. HSI Subsystem in Linux
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
In the Linux kernel the hsi subsystem is supposed to be used for HSI devices.
|
||||
The hsi subsystem contains drivers for hsi controllers including support for
|
||||
multi-port controllers and provides a generic API for using the HSI ports.
|
||||
|
||||
It also contains HSI client drivers, which make use of the generic API to
|
||||
implement a protocol used on the HSI interface. These client drivers can
|
||||
use an arbitrary number of channels.
|
||||
|
||||
3. hsi-char Device
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Each port automatically registers a generic client driver called hsi_char,
|
||||
which provides a charecter device for userspace representing the HSI port.
|
||||
It can be used to communicate via HSI from userspace. Userspace may
|
||||
configure the hsi_char device using the following ioctl commands:
|
||||
|
||||
* HSC_RESET:
|
||||
- flush the HSI port
|
||||
|
||||
* HSC_SET_PM
|
||||
- enable or disable the client.
|
||||
|
||||
* HSC_SEND_BREAK
|
||||
- send break
|
||||
|
||||
* HSC_SET_RX
|
||||
- set RX configuration
|
||||
|
||||
* HSC_GET_RX
|
||||
- get RX configuration
|
||||
|
||||
* HSC_SET_TX
|
||||
- set TX configuration
|
||||
|
||||
* HSC_GET_TX
|
||||
- get TX configuration
|
|
@ -82,8 +82,8 @@ users to create hrtimer triggers under /config/iio/triggers/hrtimer.
|
|||
|
||||
e.g:
|
||||
|
||||
$ mkdir /config/triggers/hrtimer/instance1
|
||||
$ rmdir /config/triggers/hrtimer/instance1
|
||||
$ mkdir /config/iio/triggers/hrtimer/instance1
|
||||
$ rmdir /config/iio/triggers/hrtimer/instance1
|
||||
|
||||
Each trigger can have one or more attributes specific to the trigger type.
|
||||
|
||||
|
|
|
@ -6,22 +6,19 @@
|
|||
Welcome to The Linux Kernel's documentation!
|
||||
============================================
|
||||
|
||||
Nothing for you to see here *yet*. Please move along.
|
||||
|
||||
Contents:
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
kernel-documentation
|
||||
media/media_uapi
|
||||
media/media_kapi
|
||||
media/dvb-drivers/index
|
||||
media/v4l-drivers/index
|
||||
development-process/index
|
||||
dev-tools/tools
|
||||
driver-api/index
|
||||
media/index
|
||||
gpu/index
|
||||
|
||||
Indices and tables
|
||||
==================
|
||||
|
||||
* :ref:`genindex`
|
||||
* :ref:`search`
|
||||
|
|
|
@ -34,15 +34,18 @@ will need to add a a 32-bit compat layer:
|
|||
64-bit platforms do. So we always need padding to the natural size to get
|
||||
this right.
|
||||
|
||||
* Pad the entire struct to a multiple of 64-bits - the structure size will
|
||||
otherwise differ on 32-bit versus 64-bit. Having a different structure size
|
||||
hurts when passing arrays of structures to the kernel, or if the kernel
|
||||
checks the structure size, which e.g. the drm core does.
|
||||
* Pad the entire struct to a multiple of 64-bits if the structure contains
|
||||
64-bit types - the structure size will otherwise differ on 32-bit versus
|
||||
64-bit. Having a different structure size hurts when passing arrays of
|
||||
structures to the kernel, or if the kernel checks the structure size, which
|
||||
e.g. the drm core does.
|
||||
|
||||
* Pointers are __u64, cast from/to a uintprt_t on the userspace side and
|
||||
from/to a void __user * in the kernel. Try really hard not to delay this
|
||||
conversion or worse, fiddle the raw __u64 through your code since that
|
||||
diminishes the checking tools like sparse can provide.
|
||||
diminishes the checking tools like sparse can provide. The macro
|
||||
u64_to_user_ptr can be used in the kernel to avoid warnings about integers
|
||||
and pointres of different sizes.
|
||||
|
||||
|
||||
Basics
|
||||
|
|
|
@ -1,171 +0,0 @@
|
|||
KernelAddressSanitizer (KASAN)
|
||||
==============================
|
||||
|
||||
0. Overview
|
||||
===========
|
||||
|
||||
KernelAddressSANitizer (KASAN) is a dynamic memory error detector. It provides
|
||||
a fast and comprehensive solution for finding use-after-free and out-of-bounds
|
||||
bugs.
|
||||
|
||||
KASAN uses compile-time instrumentation for checking every memory access,
|
||||
therefore you will need a GCC version 4.9.2 or later. GCC 5.0 or later is
|
||||
required for detection of out-of-bounds accesses to stack or global variables.
|
||||
|
||||
Currently KASAN is supported only for x86_64 architecture.
|
||||
|
||||
1. Usage
|
||||
========
|
||||
|
||||
To enable KASAN configure kernel with:
|
||||
|
||||
CONFIG_KASAN = y
|
||||
|
||||
and choose between CONFIG_KASAN_OUTLINE and CONFIG_KASAN_INLINE. Outline and
|
||||
inline are compiler instrumentation types. The former produces smaller binary
|
||||
the latter is 1.1 - 2 times faster. Inline instrumentation requires a GCC
|
||||
version 5.0 or later.
|
||||
|
||||
KASAN works with both SLUB and SLAB memory allocators.
|
||||
For better bug detection and nicer reporting, enable CONFIG_STACKTRACE.
|
||||
|
||||
To disable instrumentation for specific files or directories, add a line
|
||||
similar to the following to the respective kernel Makefile:
|
||||
|
||||
For a single file (e.g. main.o):
|
||||
KASAN_SANITIZE_main.o := n
|
||||
|
||||
For all files in one directory:
|
||||
KASAN_SANITIZE := n
|
||||
|
||||
1.1 Error reports
|
||||
=================
|
||||
|
||||
A typical out of bounds access report looks like this:
|
||||
|
||||
==================================================================
|
||||
BUG: AddressSanitizer: out of bounds access in kmalloc_oob_right+0x65/0x75 [test_kasan] at addr ffff8800693bc5d3
|
||||
Write of size 1 by task modprobe/1689
|
||||
=============================================================================
|
||||
BUG kmalloc-128 (Not tainted): kasan error
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
Disabling lock debugging due to kernel taint
|
||||
INFO: Allocated in kmalloc_oob_right+0x3d/0x75 [test_kasan] age=0 cpu=0 pid=1689
|
||||
__slab_alloc+0x4b4/0x4f0
|
||||
kmem_cache_alloc_trace+0x10b/0x190
|
||||
kmalloc_oob_right+0x3d/0x75 [test_kasan]
|
||||
init_module+0x9/0x47 [test_kasan]
|
||||
do_one_initcall+0x99/0x200
|
||||
load_module+0x2cb3/0x3b20
|
||||
SyS_finit_module+0x76/0x80
|
||||
system_call_fastpath+0x12/0x17
|
||||
INFO: Slab 0xffffea0001a4ef00 objects=17 used=7 fp=0xffff8800693bd728 flags=0x100000000004080
|
||||
INFO: Object 0xffff8800693bc558 @offset=1368 fp=0xffff8800693bc720
|
||||
|
||||
Bytes b4 ffff8800693bc548: 00 00 00 00 00 00 00 00 5a 5a 5a 5a 5a 5a 5a 5a ........ZZZZZZZZ
|
||||
Object ffff8800693bc558: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk
|
||||
Object ffff8800693bc568: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk
|
||||
Object ffff8800693bc578: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk
|
||||
Object ffff8800693bc588: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk
|
||||
Object ffff8800693bc598: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk
|
||||
Object ffff8800693bc5a8: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk
|
||||
Object ffff8800693bc5b8: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk
|
||||
Object ffff8800693bc5c8: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b a5 kkkkkkkkkkkkkkk.
|
||||
Redzone ffff8800693bc5d8: cc cc cc cc cc cc cc cc ........
|
||||
Padding ffff8800693bc718: 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZ
|
||||
CPU: 0 PID: 1689 Comm: modprobe Tainted: G B 3.18.0-rc1-mm1+ #98
|
||||
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.7.5-0-ge51488c-20140602_164612-nilsson.home.kraxel.org 04/01/2014
|
||||
ffff8800693bc000 0000000000000000 ffff8800693bc558 ffff88006923bb78
|
||||
ffffffff81cc68ae 00000000000000f3 ffff88006d407600 ffff88006923bba8
|
||||
ffffffff811fd848 ffff88006d407600 ffffea0001a4ef00 ffff8800693bc558
|
||||
Call Trace:
|
||||
[<ffffffff81cc68ae>] dump_stack+0x46/0x58
|
||||
[<ffffffff811fd848>] print_trailer+0xf8/0x160
|
||||
[<ffffffffa00026a7>] ? kmem_cache_oob+0xc3/0xc3 [test_kasan]
|
||||
[<ffffffff811ff0f5>] object_err+0x35/0x40
|
||||
[<ffffffffa0002065>] ? kmalloc_oob_right+0x65/0x75 [test_kasan]
|
||||
[<ffffffff8120b9fa>] kasan_report_error+0x38a/0x3f0
|
||||
[<ffffffff8120a79f>] ? kasan_poison_shadow+0x2f/0x40
|
||||
[<ffffffff8120b344>] ? kasan_unpoison_shadow+0x14/0x40
|
||||
[<ffffffff8120a79f>] ? kasan_poison_shadow+0x2f/0x40
|
||||
[<ffffffffa00026a7>] ? kmem_cache_oob+0xc3/0xc3 [test_kasan]
|
||||
[<ffffffff8120a995>] __asan_store1+0x75/0xb0
|
||||
[<ffffffffa0002601>] ? kmem_cache_oob+0x1d/0xc3 [test_kasan]
|
||||
[<ffffffffa0002065>] ? kmalloc_oob_right+0x65/0x75 [test_kasan]
|
||||
[<ffffffffa0002065>] kmalloc_oob_right+0x65/0x75 [test_kasan]
|
||||
[<ffffffffa00026b0>] init_module+0x9/0x47 [test_kasan]
|
||||
[<ffffffff810002d9>] do_one_initcall+0x99/0x200
|
||||
[<ffffffff811e4e5c>] ? __vunmap+0xec/0x160
|
||||
[<ffffffff81114f63>] load_module+0x2cb3/0x3b20
|
||||
[<ffffffff8110fd70>] ? m_show+0x240/0x240
|
||||
[<ffffffff81115f06>] SyS_finit_module+0x76/0x80
|
||||
[<ffffffff81cd3129>] system_call_fastpath+0x12/0x17
|
||||
Memory state around the buggy address:
|
||||
ffff8800693bc300: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
|
||||
ffff8800693bc380: fc fc 00 00 00 00 00 00 00 00 00 00 00 00 00 fc
|
||||
ffff8800693bc400: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
|
||||
ffff8800693bc480: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
|
||||
ffff8800693bc500: fc fc fc fc fc fc fc fc fc fc fc 00 00 00 00 00
|
||||
>ffff8800693bc580: 00 00 00 00 00 00 00 00 00 00 03 fc fc fc fc fc
|
||||
^
|
||||
ffff8800693bc600: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
|
||||
ffff8800693bc680: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
|
||||
ffff8800693bc700: fc fc fc fc fb fb fb fb fb fb fb fb fb fb fb fb
|
||||
ffff8800693bc780: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
|
||||
ffff8800693bc800: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
|
||||
==================================================================
|
||||
|
||||
The header of the report discribe what kind of bug happened and what kind of
|
||||
access caused it. It's followed by the description of the accessed slub object
|
||||
(see 'SLUB Debug output' section in Documentation/vm/slub.txt for details) and
|
||||
the description of the accessed memory page.
|
||||
|
||||
In the last section the report shows memory state around the accessed address.
|
||||
Reading this part requires some understanding of how KASAN works.
|
||||
|
||||
The state of each 8 aligned bytes of memory is encoded in one shadow byte.
|
||||
Those 8 bytes can be accessible, partially accessible, freed or be a redzone.
|
||||
We use the following encoding for each shadow byte: 0 means that all 8 bytes
|
||||
of the corresponding memory region are accessible; number N (1 <= N <= 7) means
|
||||
that the first N bytes are accessible, and other (8 - N) bytes are not;
|
||||
any negative value indicates that the entire 8-byte word is inaccessible.
|
||||
We use different negative values to distinguish between different kinds of
|
||||
inaccessible memory like redzones or freed memory (see mm/kasan/kasan.h).
|
||||
|
||||
In the report above the arrows point to the shadow byte 03, which means that
|
||||
the accessed address is partially accessible.
|
||||
|
||||
|
||||
2. Implementation details
|
||||
=========================
|
||||
|
||||
From a high level, our approach to memory error detection is similar to that
|
||||
of kmemcheck: use shadow memory to record whether each byte of memory is safe
|
||||
to access, and use compile-time instrumentation to check shadow memory on each
|
||||
memory access.
|
||||
|
||||
AddressSanitizer dedicates 1/8 of kernel memory to its shadow memory
|
||||
(e.g. 16TB to cover 128TB on x86_64) and uses direct mapping with a scale and
|
||||
offset to translate a memory address to its corresponding shadow address.
|
||||
|
||||
Here is the function which translates an address to its corresponding shadow
|
||||
address:
|
||||
|
||||
static inline void *kasan_mem_to_shadow(const void *addr)
|
||||
{
|
||||
return ((unsigned long)addr >> KASAN_SHADOW_SCALE_SHIFT)
|
||||
+ KASAN_SHADOW_OFFSET;
|
||||
}
|
||||
|
||||
where KASAN_SHADOW_SCALE_SHIFT = 3.
|
||||
|
||||
Compile-time instrumentation used for checking memory accesses. Compiler inserts
|
||||
function calls (__asan_load*(addr), __asan_store*(addr)) before each memory
|
||||
access of size 1, 2, 4, 8 or 16. These functions check whether memory access is
|
||||
valid or not by checking corresponding shadow memory.
|
||||
|
||||
GCC 5.0 has possibility to perform inline instrumentation. Instead of making
|
||||
function calls GCC directly inserts the code to check the shadow memory.
|
||||
This option significantly enlarges kernel but it gives x1.1-x2 performance
|
||||
boost over outline instrumented kernel.
|
|
@ -274,7 +274,44 @@ menuconfig:
|
|||
|
||||
This is similar to the simple config entry above, but it also gives a
|
||||
hint to front ends, that all suboptions should be displayed as a
|
||||
separate list of options.
|
||||
separate list of options. To make sure all the suboptions will really
|
||||
show up under the menuconfig entry and not outside of it, every item
|
||||
from the <config options> list must depend on the menuconfig symbol.
|
||||
In practice, this is achieved by using one of the next two constructs:
|
||||
|
||||
(1):
|
||||
menuconfig M
|
||||
if M
|
||||
config C1
|
||||
config C2
|
||||
endif
|
||||
|
||||
(2):
|
||||
menuconfig M
|
||||
config C1
|
||||
depends on M
|
||||
config C2
|
||||
depends on M
|
||||
|
||||
In the following examples (3) and (4), C1 and C2 still have the M
|
||||
dependency, but will not appear under menuconfig M anymore, because
|
||||
of C0, which doesn't depend on M:
|
||||
|
||||
(3):
|
||||
menuconfig M
|
||||
config C0
|
||||
if M
|
||||
config C1
|
||||
config C2
|
||||
endif
|
||||
|
||||
(4):
|
||||
menuconfig M
|
||||
config C0
|
||||
config C1
|
||||
depends on M
|
||||
config C2
|
||||
depends on M
|
||||
|
||||
choices:
|
||||
|
||||
|
|
|
@ -393,6 +393,15 @@ Notes on loading the dump-capture kernel:
|
|||
* We generally don' have to bring up a SMP kernel just to capture the
|
||||
dump. Hence generally it is useful either to build a UP dump-capture
|
||||
kernel or specify maxcpus=1 option while loading dump-capture kernel.
|
||||
Note, though maxcpus always works, you had better replace it with
|
||||
nr_cpus to save memory if supported by the current ARCH, such as x86.
|
||||
|
||||
* You should enable multi-cpu support in dump-capture kernel if you intend
|
||||
to use multi-thread programs with it, such as parallel dump feature of
|
||||
makedumpfile. Otherwise, the multi-thread program may have a great
|
||||
performance degradation. To enable multi-cpu support, you should bring up an
|
||||
SMP dump-capture kernel and specify maxcpus/nr_cpus, disable_cpu_apicid=[X]
|
||||
options while loading it.
|
||||
|
||||
* For s390x there are two kdump modes: If a ELF header is specified with
|
||||
the elfcorehdr= kernel parameter, it is used by the kdump kernel as it
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -107,6 +107,35 @@ Here are some specific guidelines for the kernel documentation:
|
|||
the order as encountered."), having the higher levels the same overall makes
|
||||
it easier to follow the documents.
|
||||
|
||||
|
||||
the C domain
|
||||
------------
|
||||
|
||||
The `Sphinx C Domain`_ (name c) is suited for documentation of C API. E.g. a
|
||||
function prototype:
|
||||
|
||||
.. code-block:: rst
|
||||
|
||||
.. c:function:: int ioctl( int fd, int request )
|
||||
|
||||
The C domain of the kernel-doc has some additional features. E.g. you can
|
||||
*rename* the reference name of a function with a common name like ``open`` or
|
||||
``ioctl``:
|
||||
|
||||
.. code-block:: rst
|
||||
|
||||
.. c:function:: int ioctl( int fd, int request )
|
||||
:name: VIDIOC_LOG_STATUS
|
||||
|
||||
The func-name (e.g. ioctl) remains in the output but the ref-name changed from
|
||||
``ioctl`` to ``VIDIOC_LOG_STATUS``. The index entry for this function is also
|
||||
changed to ``VIDIOC_LOG_STATUS`` and the function can now referenced by:
|
||||
|
||||
.. code-block:: rst
|
||||
|
||||
:c:func:`VIDIOC_LOG_STATUS`
|
||||
|
||||
|
||||
list tables
|
||||
-----------
|
||||
|
||||
|
@ -265,6 +294,8 @@ The kernel-doc extension is included in the kernel source tree, at
|
|||
``scripts/kernel-doc`` script to extract the documentation comments from the
|
||||
source.
|
||||
|
||||
.. _kernel_doc:
|
||||
|
||||
Writing kernel-doc comments
|
||||
===========================
|
||||
|
||||
|
|
|
@ -1698,7 +1698,7 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
|
|||
|
||||
intel_idle.max_cstate= [KNL,HW,ACPI,X86]
|
||||
0 disables intel_idle and fall back on acpi_idle.
|
||||
1 to 6 specify maximum depth of C-state.
|
||||
1 to 9 specify maximum depth of C-state.
|
||||
|
||||
intel_pstate= [X86]
|
||||
disable
|
||||
|
@ -2171,10 +2171,13 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
|
|||
than or equal to this physical address is ignored.
|
||||
|
||||
maxcpus= [SMP] Maximum number of processors that an SMP kernel
|
||||
should make use of. maxcpus=n : n >= 0 limits the
|
||||
kernel to using 'n' processors. n=0 is a special case,
|
||||
it is equivalent to "nosmp", which also disables
|
||||
the IO APIC.
|
||||
will bring up during bootup. maxcpus=n : n >= 0 limits
|
||||
the kernel to bring up 'n' processors. Surely after
|
||||
bootup you can bring up the other plugged cpu by executing
|
||||
"echo 1 > /sys/devices/system/cpu/cpuX/online". So maxcpus
|
||||
only takes effect during system bootup.
|
||||
While n=0 is a special case, it is equivalent to "nosmp",
|
||||
which also disables the IO APIC.
|
||||
|
||||
max_loop= [LOOP] The number of loop block devices that get
|
||||
(loop.max_loop) unconditionally pre-created at init time. The default
|
||||
|
@ -2581,8 +2584,6 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
|
|||
|
||||
nodelayacct [KNL] Disable per-task delay accounting
|
||||
|
||||
nodisconnect [HW,SCSI,M68K] Disables SCSI disconnects.
|
||||
|
||||
nodsp [SH] Disable hardware DSP at boot time.
|
||||
|
||||
noefi Disable EFI runtime services support.
|
||||
|
@ -2783,9 +2784,12 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
|
|||
|
||||
nr_cpus= [SMP] Maximum number of processors that an SMP kernel
|
||||
could support. nr_cpus=n : n >= 1 limits the kernel to
|
||||
supporting 'n' processors. Later in runtime you can not
|
||||
use hotplug cpu feature to put more cpu back to online.
|
||||
just like you compile the kernel NR_CPUS=n
|
||||
support 'n' processors. It could be larger than the
|
||||
number of already plugged CPU during bootup, later in
|
||||
runtime you can physically add extra cpu until it reaches
|
||||
n. So during boot up some boot time memory for per-cpu
|
||||
variables need be pre-allocated for later physical cpu
|
||||
hot plugging.
|
||||
|
||||
nr_uarts= [SERIAL] maximum number of UARTs to be registered.
|
||||
|
||||
|
|
|
@ -1,754 +0,0 @@
|
|||
GETTING STARTED WITH KMEMCHECK
|
||||
==============================
|
||||
|
||||
Vegard Nossum <vegardno@ifi.uio.no>
|
||||
|
||||
|
||||
Contents
|
||||
========
|
||||
0. Introduction
|
||||
1. Downloading
|
||||
2. Configuring and compiling
|
||||
3. How to use
|
||||
3.1. Booting
|
||||
3.2. Run-time enable/disable
|
||||
3.3. Debugging
|
||||
3.4. Annotating false positives
|
||||
4. Reporting errors
|
||||
5. Technical description
|
||||
|
||||
|
||||
0. Introduction
|
||||
===============
|
||||
|
||||
kmemcheck is a debugging feature for the Linux Kernel. More specifically, it
|
||||
is a dynamic checker that detects and warns about some uses of uninitialized
|
||||
memory.
|
||||
|
||||
Userspace programmers might be familiar with Valgrind's memcheck. The main
|
||||
difference between memcheck and kmemcheck is that memcheck works for userspace
|
||||
programs only, and kmemcheck works for the kernel only. The implementations
|
||||
are of course vastly different. Because of this, kmemcheck is not as accurate
|
||||
as memcheck, but it turns out to be good enough in practice to discover real
|
||||
programmer errors that the compiler is not able to find through static
|
||||
analysis.
|
||||
|
||||
Enabling kmemcheck on a kernel will probably slow it down to the extent that
|
||||
the machine will not be usable for normal workloads such as e.g. an
|
||||
interactive desktop. kmemcheck will also cause the kernel to use about twice
|
||||
as much memory as normal. For this reason, kmemcheck is strictly a debugging
|
||||
feature.
|
||||
|
||||
|
||||
1. Downloading
|
||||
==============
|
||||
|
||||
As of version 2.6.31-rc1, kmemcheck is included in the mainline kernel.
|
||||
|
||||
|
||||
2. Configuring and compiling
|
||||
============================
|
||||
|
||||
kmemcheck only works for the x86 (both 32- and 64-bit) platform. A number of
|
||||
configuration variables must have specific settings in order for the kmemcheck
|
||||
menu to even appear in "menuconfig". These are:
|
||||
|
||||
o CONFIG_CC_OPTIMIZE_FOR_SIZE=n
|
||||
|
||||
This option is located under "General setup" / "Optimize for size".
|
||||
|
||||
Without this, gcc will use certain optimizations that usually lead to
|
||||
false positive warnings from kmemcheck. An example of this is a 16-bit
|
||||
field in a struct, where gcc may load 32 bits, then discard the upper
|
||||
16 bits. kmemcheck sees only the 32-bit load, and may trigger a
|
||||
warning for the upper 16 bits (if they're uninitialized).
|
||||
|
||||
o CONFIG_SLAB=y or CONFIG_SLUB=y
|
||||
|
||||
This option is located under "General setup" / "Choose SLAB
|
||||
allocator".
|
||||
|
||||
o CONFIG_FUNCTION_TRACER=n
|
||||
|
||||
This option is located under "Kernel hacking" / "Tracers" / "Kernel
|
||||
Function Tracer"
|
||||
|
||||
When function tracing is compiled in, gcc emits a call to another
|
||||
function at the beginning of every function. This means that when the
|
||||
page fault handler is called, the ftrace framework will be called
|
||||
before kmemcheck has had a chance to handle the fault. If ftrace then
|
||||
modifies memory that was tracked by kmemcheck, the result is an
|
||||
endless recursive page fault.
|
||||
|
||||
o CONFIG_DEBUG_PAGEALLOC=n
|
||||
|
||||
This option is located under "Kernel hacking" / "Memory Debugging"
|
||||
/ "Debug page memory allocations".
|
||||
|
||||
In addition, I highly recommend turning on CONFIG_DEBUG_INFO=y. This is also
|
||||
located under "Kernel hacking". With this, you will be able to get line number
|
||||
information from the kmemcheck warnings, which is extremely valuable in
|
||||
debugging a problem. This option is not mandatory, however, because it slows
|
||||
down the compilation process and produces a much bigger kernel image.
|
||||
|
||||
Now the kmemcheck menu should be visible (under "Kernel hacking" / "Memory
|
||||
Debugging" / "kmemcheck: trap use of uninitialized memory"). Here follows
|
||||
a description of the kmemcheck configuration variables:
|
||||
|
||||
o CONFIG_KMEMCHECK
|
||||
|
||||
This must be enabled in order to use kmemcheck at all...
|
||||
|
||||
o CONFIG_KMEMCHECK_[DISABLED | ENABLED | ONESHOT]_BY_DEFAULT
|
||||
|
||||
This option controls the status of kmemcheck at boot-time. "Enabled"
|
||||
will enable kmemcheck right from the start, "disabled" will boot the
|
||||
kernel as normal (but with the kmemcheck code compiled in, so it can
|
||||
be enabled at run-time after the kernel has booted), and "one-shot" is
|
||||
a special mode which will turn kmemcheck off automatically after
|
||||
detecting the first use of uninitialized memory.
|
||||
|
||||
If you are using kmemcheck to actively debug a problem, then you
|
||||
probably want to choose "enabled" here.
|
||||
|
||||
The one-shot mode is mostly useful in automated test setups because it
|
||||
can prevent floods of warnings and increase the chances of the machine
|
||||
surviving in case something is really wrong. In other cases, the one-
|
||||
shot mode could actually be counter-productive because it would turn
|
||||
itself off at the very first error -- in the case of a false positive
|
||||
too -- and this would come in the way of debugging the specific
|
||||
problem you were interested in.
|
||||
|
||||
If you would like to use your kernel as normal, but with a chance to
|
||||
enable kmemcheck in case of some problem, it might be a good idea to
|
||||
choose "disabled" here. When kmemcheck is disabled, most of the run-
|
||||
time overhead is not incurred, and the kernel will be almost as fast
|
||||
as normal.
|
||||
|
||||
o CONFIG_KMEMCHECK_QUEUE_SIZE
|
||||
|
||||
Select the maximum number of error reports to store in an internal
|
||||
(fixed-size) buffer. Since errors can occur virtually anywhere and in
|
||||
any context, we need a temporary storage area which is guaranteed not
|
||||
to generate any other page faults when accessed. The queue will be
|
||||
emptied as soon as a tasklet may be scheduled. If the queue is full,
|
||||
new error reports will be lost.
|
||||
|
||||
The default value of 64 is probably fine. If some code produces more
|
||||
than 64 errors within an irqs-off section, then the code is likely to
|
||||
produce many, many more, too, and these additional reports seldom give
|
||||
any more information (the first report is usually the most valuable
|
||||
anyway).
|
||||
|
||||
This number might have to be adjusted if you are not using serial
|
||||
console or similar to capture the kernel log. If you are using the
|
||||
"dmesg" command to save the log, then getting a lot of kmemcheck
|
||||
warnings might overflow the kernel log itself, and the earlier reports
|
||||
will get lost in that way instead. Try setting this to 10 or so on
|
||||
such a setup.
|
||||
|
||||
o CONFIG_KMEMCHECK_SHADOW_COPY_SHIFT
|
||||
|
||||
Select the number of shadow bytes to save along with each entry of the
|
||||
error-report queue. These bytes indicate what parts of an allocation
|
||||
are initialized, uninitialized, etc. and will be displayed when an
|
||||
error is detected to help the debugging of a particular problem.
|
||||
|
||||
The number entered here is actually the logarithm of the number of
|
||||
bytes that will be saved. So if you pick for example 5 here, kmemcheck
|
||||
will save 2^5 = 32 bytes.
|
||||
|
||||
The default value should be fine for debugging most problems. It also
|
||||
fits nicely within 80 columns.
|
||||
|
||||
o CONFIG_KMEMCHECK_PARTIAL_OK
|
||||
|
||||
This option (when enabled) works around certain GCC optimizations that
|
||||
produce 32-bit reads from 16-bit variables where the upper 16 bits are
|
||||
thrown away afterwards.
|
||||
|
||||
The default value (enabled) is recommended. This may of course hide
|
||||
some real errors, but disabling it would probably produce a lot of
|
||||
false positives.
|
||||
|
||||
o CONFIG_KMEMCHECK_BITOPS_OK
|
||||
|
||||
This option silences warnings that would be generated for bit-field
|
||||
accesses where not all the bits are initialized at the same time. This
|
||||
may also hide some real bugs.
|
||||
|
||||
This option is probably obsolete, or it should be replaced with
|
||||
the kmemcheck-/bitfield-annotations for the code in question. The
|
||||
default value is therefore fine.
|
||||
|
||||
Now compile the kernel as usual.
|
||||
|
||||
|
||||
3. How to use
|
||||
=============
|
||||
|
||||
3.1. Booting
|
||||
============
|
||||
|
||||
First some information about the command-line options. There is only one
|
||||
option specific to kmemcheck, and this is called "kmemcheck". It can be used
|
||||
to override the default mode as chosen by the CONFIG_KMEMCHECK_*_BY_DEFAULT
|
||||
option. Its possible settings are:
|
||||
|
||||
o kmemcheck=0 (disabled)
|
||||
o kmemcheck=1 (enabled)
|
||||
o kmemcheck=2 (one-shot mode)
|
||||
|
||||
If SLUB debugging has been enabled in the kernel, it may take precedence over
|
||||
kmemcheck in such a way that the slab caches which are under SLUB debugging
|
||||
will not be tracked by kmemcheck. In order to ensure that this doesn't happen
|
||||
(even though it shouldn't by default), use SLUB's boot option "slub_debug",
|
||||
like this: slub_debug=-
|
||||
|
||||
In fact, this option may also be used for fine-grained control over SLUB vs.
|
||||
kmemcheck. For example, if the command line includes "kmemcheck=1
|
||||
slub_debug=,dentry", then SLUB debugging will be used only for the "dentry"
|
||||
slab cache, and with kmemcheck tracking all the other caches. This is advanced
|
||||
usage, however, and is not generally recommended.
|
||||
|
||||
|
||||
3.2. Run-time enable/disable
|
||||
============================
|
||||
|
||||
When the kernel has booted, it is possible to enable or disable kmemcheck at
|
||||
run-time. WARNING: This feature is still experimental and may cause false
|
||||
positive warnings to appear. Therefore, try not to use this. If you find that
|
||||
it doesn't work properly (e.g. you see an unreasonable amount of warnings), I
|
||||
will be happy to take bug reports.
|
||||
|
||||
Use the file /proc/sys/kernel/kmemcheck for this purpose, e.g.:
|
||||
|
||||
$ echo 0 > /proc/sys/kernel/kmemcheck # disables kmemcheck
|
||||
|
||||
The numbers are the same as for the kmemcheck= command-line option.
|
||||
|
||||
|
||||
3.3. Debugging
|
||||
==============
|
||||
|
||||
A typical report will look something like this:
|
||||
|
||||
WARNING: kmemcheck: Caught 32-bit read from uninitialized memory (ffff88003e4a2024)
|
||||
80000000000000000000000000000000000000000088ffff0000000000000000
|
||||
i i i i u u u u i i i i i i i i u u u u u u u u u u u u u u u u
|
||||
^
|
||||
|
||||
Pid: 1856, comm: ntpdate Not tainted 2.6.29-rc5 #264 945P-A
|
||||
RIP: 0010:[<ffffffff8104ede8>] [<ffffffff8104ede8>] __dequeue_signal+0xc8/0x190
|
||||
RSP: 0018:ffff88003cdf7d98 EFLAGS: 00210002
|
||||
RAX: 0000000000000030 RBX: ffff88003d4ea968 RCX: 0000000000000009
|
||||
RDX: ffff88003e5d6018 RSI: ffff88003e5d6024 RDI: ffff88003cdf7e84
|
||||
RBP: ffff88003cdf7db8 R08: ffff88003e5d6000 R09: 0000000000000000
|
||||
R10: 0000000000000080 R11: 0000000000000000 R12: 000000000000000e
|
||||
R13: ffff88003cdf7e78 R14: ffff88003d530710 R15: ffff88003d5a98c8
|
||||
FS: 0000000000000000(0000) GS:ffff880001982000(0063) knlGS:00000
|
||||
CS: 0010 DS: 002b ES: 002b CR0: 0000000080050033
|
||||
CR2: ffff88003f806ea0 CR3: 000000003c036000 CR4: 00000000000006a0
|
||||
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
|
||||
DR3: 0000000000000000 DR6: 00000000ffff4ff0 DR7: 0000000000000400
|
||||
[<ffffffff8104f04e>] dequeue_signal+0x8e/0x170
|
||||
[<ffffffff81050bd8>] get_signal_to_deliver+0x98/0x390
|
||||
[<ffffffff8100b87d>] do_notify_resume+0xad/0x7d0
|
||||
[<ffffffff8100c7b5>] int_signal+0x12/0x17
|
||||
[<ffffffffffffffff>] 0xffffffffffffffff
|
||||
|
||||
The single most valuable information in this report is the RIP (or EIP on 32-
|
||||
bit) value. This will help us pinpoint exactly which instruction that caused
|
||||
the warning.
|
||||
|
||||
If your kernel was compiled with CONFIG_DEBUG_INFO=y, then all we have to do
|
||||
is give this address to the addr2line program, like this:
|
||||
|
||||
$ addr2line -e vmlinux -i ffffffff8104ede8
|
||||
arch/x86/include/asm/string_64.h:12
|
||||
include/asm-generic/siginfo.h:287
|
||||
kernel/signal.c:380
|
||||
kernel/signal.c:410
|
||||
|
||||
The "-e vmlinux" tells addr2line which file to look in. IMPORTANT: This must
|
||||
be the vmlinux of the kernel that produced the warning in the first place! If
|
||||
not, the line number information will almost certainly be wrong.
|
||||
|
||||
The "-i" tells addr2line to also print the line numbers of inlined functions.
|
||||
In this case, the flag was very important, because otherwise, it would only
|
||||
have printed the first line, which is just a call to memcpy(), which could be
|
||||
called from a thousand places in the kernel, and is therefore not very useful.
|
||||
These inlined functions would not show up in the stack trace above, simply
|
||||
because the kernel doesn't load the extra debugging information. This
|
||||
technique can of course be used with ordinary kernel oopses as well.
|
||||
|
||||
In this case, it's the caller of memcpy() that is interesting, and it can be
|
||||
found in include/asm-generic/siginfo.h, line 287:
|
||||
|
||||
281 static inline void copy_siginfo(struct siginfo *to, struct siginfo *from)
|
||||
282 {
|
||||
283 if (from->si_code < 0)
|
||||
284 memcpy(to, from, sizeof(*to));
|
||||
285 else
|
||||
286 /* _sigchld is currently the largest know union member */
|
||||
287 memcpy(to, from, __ARCH_SI_PREAMBLE_SIZE + sizeof(from->_sifields._sigchld));
|
||||
288 }
|
||||
|
||||
Since this was a read (kmemcheck usually warns about reads only, though it can
|
||||
warn about writes to unallocated or freed memory as well), it was probably the
|
||||
"from" argument which contained some uninitialized bytes. Following the chain
|
||||
of calls, we move upwards to see where "from" was allocated or initialized,
|
||||
kernel/signal.c, line 380:
|
||||
|
||||
359 static void collect_signal(int sig, struct sigpending *list, siginfo_t *info)
|
||||
360 {
|
||||
...
|
||||
367 list_for_each_entry(q, &list->list, list) {
|
||||
368 if (q->info.si_signo == sig) {
|
||||
369 if (first)
|
||||
370 goto still_pending;
|
||||
371 first = q;
|
||||
...
|
||||
377 if (first) {
|
||||
378 still_pending:
|
||||
379 list_del_init(&first->list);
|
||||
380 copy_siginfo(info, &first->info);
|
||||
381 __sigqueue_free(first);
|
||||
...
|
||||
392 }
|
||||
393 }
|
||||
|
||||
Here, it is &first->info that is being passed on to copy_siginfo(). The
|
||||
variable "first" was found on a list -- passed in as the second argument to
|
||||
collect_signal(). We continue our journey through the stack, to figure out
|
||||
where the item on "list" was allocated or initialized. We move to line 410:
|
||||
|
||||
395 static int __dequeue_signal(struct sigpending *pending, sigset_t *mask,
|
||||
396 siginfo_t *info)
|
||||
397 {
|
||||
...
|
||||
410 collect_signal(sig, pending, info);
|
||||
...
|
||||
414 }
|
||||
|
||||
Now we need to follow the "pending" pointer, since that is being passed on to
|
||||
collect_signal() as "list". At this point, we've run out of lines from the
|
||||
"addr2line" output. Not to worry, we just paste the next addresses from the
|
||||
kmemcheck stack dump, i.e.:
|
||||
|
||||
[<ffffffff8104f04e>] dequeue_signal+0x8e/0x170
|
||||
[<ffffffff81050bd8>] get_signal_to_deliver+0x98/0x390
|
||||
[<ffffffff8100b87d>] do_notify_resume+0xad/0x7d0
|
||||
[<ffffffff8100c7b5>] int_signal+0x12/0x17
|
||||
|
||||
$ addr2line -e vmlinux -i ffffffff8104f04e ffffffff81050bd8 \
|
||||
ffffffff8100b87d ffffffff8100c7b5
|
||||
kernel/signal.c:446
|
||||
kernel/signal.c:1806
|
||||
arch/x86/kernel/signal.c:805
|
||||
arch/x86/kernel/signal.c:871
|
||||
arch/x86/kernel/entry_64.S:694
|
||||
|
||||
Remember that since these addresses were found on the stack and not as the
|
||||
RIP value, they actually point to the _next_ instruction (they are return
|
||||
addresses). This becomes obvious when we look at the code for line 446:
|
||||
|
||||
422 int dequeue_signal(struct task_struct *tsk, sigset_t *mask, siginfo_t *info)
|
||||
423 {
|
||||
...
|
||||
431 signr = __dequeue_signal(&tsk->signal->shared_pending,
|
||||
432 mask, info);
|
||||
433 /*
|
||||
434 * itimer signal ?
|
||||
435 *
|
||||
436 * itimers are process shared and we restart periodic
|
||||
437 * itimers in the signal delivery path to prevent DoS
|
||||
438 * attacks in the high resolution timer case. This is
|
||||
439 * compliant with the old way of self restarting
|
||||
440 * itimers, as the SIGALRM is a legacy signal and only
|
||||
441 * queued once. Changing the restart behaviour to
|
||||
442 * restart the timer in the signal dequeue path is
|
||||
443 * reducing the timer noise on heavy loaded !highres
|
||||
444 * systems too.
|
||||
445 */
|
||||
446 if (unlikely(signr == SIGALRM)) {
|
||||
...
|
||||
489 }
|
||||
|
||||
So instead of looking at 446, we should be looking at 431, which is the line
|
||||
that executes just before 446. Here we see that what we are looking for is
|
||||
&tsk->signal->shared_pending.
|
||||
|
||||
Our next task is now to figure out which function that puts items on this
|
||||
"shared_pending" list. A crude, but efficient tool, is git grep:
|
||||
|
||||
$ git grep -n 'shared_pending' kernel/
|
||||
...
|
||||
kernel/signal.c:828: pending = group ? &t->signal->shared_pending : &t->pending;
|
||||
kernel/signal.c:1339: pending = group ? &t->signal->shared_pending : &t->pending;
|
||||
...
|
||||
|
||||
There were more results, but none of them were related to list operations,
|
||||
and these were the only assignments. We inspect the line numbers more closely
|
||||
and find that this is indeed where items are being added to the list:
|
||||
|
||||
816 static int send_signal(int sig, struct siginfo *info, struct task_struct *t,
|
||||
817 int group)
|
||||
818 {
|
||||
...
|
||||
828 pending = group ? &t->signal->shared_pending : &t->pending;
|
||||
...
|
||||
851 q = __sigqueue_alloc(t, GFP_ATOMIC, (sig < SIGRTMIN &&
|
||||
852 (is_si_special(info) ||
|
||||
853 info->si_code >= 0)));
|
||||
854 if (q) {
|
||||
855 list_add_tail(&q->list, &pending->list);
|
||||
...
|
||||
890 }
|
||||
|
||||
and:
|
||||
|
||||
1309 int send_sigqueue(struct sigqueue *q, struct task_struct *t, int group)
|
||||
1310 {
|
||||
....
|
||||
1339 pending = group ? &t->signal->shared_pending : &t->pending;
|
||||
1340 list_add_tail(&q->list, &pending->list);
|
||||
....
|
||||
1347 }
|
||||
|
||||
In the first case, the list element we are looking for, "q", is being returned
|
||||
from the function __sigqueue_alloc(), which looks like an allocation function.
|
||||
Let's take a look at it:
|
||||
|
||||
187 static struct sigqueue *__sigqueue_alloc(struct task_struct *t, gfp_t flags,
|
||||
188 int override_rlimit)
|
||||
189 {
|
||||
190 struct sigqueue *q = NULL;
|
||||
191 struct user_struct *user;
|
||||
192
|
||||
193 /*
|
||||
194 * We won't get problems with the target's UID changing under us
|
||||
195 * because changing it requires RCU be used, and if t != current, the
|
||||
196 * caller must be holding the RCU readlock (by way of a spinlock) and
|
||||
197 * we use RCU protection here
|
||||
198 */
|
||||
199 user = get_uid(__task_cred(t)->user);
|
||||
200 atomic_inc(&user->sigpending);
|
||||
201 if (override_rlimit ||
|
||||
202 atomic_read(&user->sigpending) <=
|
||||
203 t->signal->rlim[RLIMIT_SIGPENDING].rlim_cur)
|
||||
204 q = kmem_cache_alloc(sigqueue_cachep, flags);
|
||||
205 if (unlikely(q == NULL)) {
|
||||
206 atomic_dec(&user->sigpending);
|
||||
207 free_uid(user);
|
||||
208 } else {
|
||||
209 INIT_LIST_HEAD(&q->list);
|
||||
210 q->flags = 0;
|
||||
211 q->user = user;
|
||||
212 }
|
||||
213
|
||||
214 return q;
|
||||
215 }
|
||||
|
||||
We see that this function initializes q->list, q->flags, and q->user. It seems
|
||||
that now is the time to look at the definition of "struct sigqueue", e.g.:
|
||||
|
||||
14 struct sigqueue {
|
||||
15 struct list_head list;
|
||||
16 int flags;
|
||||
17 siginfo_t info;
|
||||
18 struct user_struct *user;
|
||||
19 };
|
||||
|
||||
And, you might remember, it was a memcpy() on &first->info that caused the
|
||||
warning, so this makes perfect sense. It also seems reasonable to assume that
|
||||
it is the caller of __sigqueue_alloc() that has the responsibility of filling
|
||||
out (initializing) this member.
|
||||
|
||||
But just which fields of the struct were uninitialized? Let's look at
|
||||
kmemcheck's report again:
|
||||
|
||||
WARNING: kmemcheck: Caught 32-bit read from uninitialized memory (ffff88003e4a2024)
|
||||
80000000000000000000000000000000000000000088ffff0000000000000000
|
||||
i i i i u u u u i i i i i i i i u u u u u u u u u u u u u u u u
|
||||
^
|
||||
|
||||
These first two lines are the memory dump of the memory object itself, and the
|
||||
shadow bytemap, respectively. The memory object itself is in this case
|
||||
&first->info. Just beware that the start of this dump is NOT the start of the
|
||||
object itself! The position of the caret (^) corresponds with the address of
|
||||
the read (ffff88003e4a2024).
|
||||
|
||||
The shadow bytemap dump legend is as follows:
|
||||
|
||||
i - initialized
|
||||
u - uninitialized
|
||||
a - unallocated (memory has been allocated by the slab layer, but has not
|
||||
yet been handed off to anybody)
|
||||
f - freed (memory has been allocated by the slab layer, but has been freed
|
||||
by the previous owner)
|
||||
|
||||
In order to figure out where (relative to the start of the object) the
|
||||
uninitialized memory was located, we have to look at the disassembly. For
|
||||
that, we'll need the RIP address again:
|
||||
|
||||
RIP: 0010:[<ffffffff8104ede8>] [<ffffffff8104ede8>] __dequeue_signal+0xc8/0x190
|
||||
|
||||
$ objdump -d --no-show-raw-insn vmlinux | grep -C 8 ffffffff8104ede8:
|
||||
ffffffff8104edc8: mov %r8,0x8(%r8)
|
||||
ffffffff8104edcc: test %r10d,%r10d
|
||||
ffffffff8104edcf: js ffffffff8104ee88 <__dequeue_signal+0x168>
|
||||
ffffffff8104edd5: mov %rax,%rdx
|
||||
ffffffff8104edd8: mov $0xc,%ecx
|
||||
ffffffff8104eddd: mov %r13,%rdi
|
||||
ffffffff8104ede0: mov $0x30,%eax
|
||||
ffffffff8104ede5: mov %rdx,%rsi
|
||||
ffffffff8104ede8: rep movsl %ds:(%rsi),%es:(%rdi)
|
||||
ffffffff8104edea: test $0x2,%al
|
||||
ffffffff8104edec: je ffffffff8104edf0 <__dequeue_signal+0xd0>
|
||||
ffffffff8104edee: movsw %ds:(%rsi),%es:(%rdi)
|
||||
ffffffff8104edf0: test $0x1,%al
|
||||
ffffffff8104edf2: je ffffffff8104edf5 <__dequeue_signal+0xd5>
|
||||
ffffffff8104edf4: movsb %ds:(%rsi),%es:(%rdi)
|
||||
ffffffff8104edf5: mov %r8,%rdi
|
||||
ffffffff8104edf8: callq ffffffff8104de60 <__sigqueue_free>
|
||||
|
||||
As expected, it's the "rep movsl" instruction from the memcpy() that causes
|
||||
the warning. We know about REP MOVSL that it uses the register RCX to count
|
||||
the number of remaining iterations. By taking a look at the register dump
|
||||
again (from the kmemcheck report), we can figure out how many bytes were left
|
||||
to copy:
|
||||
|
||||
RAX: 0000000000000030 RBX: ffff88003d4ea968 RCX: 0000000000000009
|
||||
|
||||
By looking at the disassembly, we also see that %ecx is being loaded with the
|
||||
value $0xc just before (ffffffff8104edd8), so we are very lucky. Keep in mind
|
||||
that this is the number of iterations, not bytes. And since this is a "long"
|
||||
operation, we need to multiply by 4 to get the number of bytes. So this means
|
||||
that the uninitialized value was encountered at 4 * (0xc - 0x9) = 12 bytes
|
||||
from the start of the object.
|
||||
|
||||
We can now try to figure out which field of the "struct siginfo" that was not
|
||||
initialized. This is the beginning of the struct:
|
||||
|
||||
40 typedef struct siginfo {
|
||||
41 int si_signo;
|
||||
42 int si_errno;
|
||||
43 int si_code;
|
||||
44
|
||||
45 union {
|
||||
..
|
||||
92 } _sifields;
|
||||
93 } siginfo_t;
|
||||
|
||||
On 64-bit, the int is 4 bytes long, so it must the union member that has
|
||||
not been initialized. We can verify this using gdb:
|
||||
|
||||
$ gdb vmlinux
|
||||
...
|
||||
(gdb) p &((struct siginfo *) 0)->_sifields
|
||||
$1 = (union {...} *) 0x10
|
||||
|
||||
Actually, it seems that the union member is located at offset 0x10 -- which
|
||||
means that gcc has inserted 4 bytes of padding between the members si_code
|
||||
and _sifields. We can now get a fuller picture of the memory dump:
|
||||
|
||||
_----------------------------=> si_code
|
||||
/ _--------------------=> (padding)
|
||||
| / _------------=> _sifields(._kill._pid)
|
||||
| | / _----=> _sifields(._kill._uid)
|
||||
| | | /
|
||||
-------|-------|-------|-------|
|
||||
80000000000000000000000000000000000000000088ffff0000000000000000
|
||||
i i i i u u u u i i i i i i i i u u u u u u u u u u u u u u u u
|
||||
|
||||
This allows us to realize another important fact: si_code contains the value
|
||||
0x80. Remember that x86 is little endian, so the first 4 bytes "80000000" are
|
||||
really the number 0x00000080. With a bit of research, we find that this is
|
||||
actually the constant SI_KERNEL defined in include/asm-generic/siginfo.h:
|
||||
|
||||
144 #define SI_KERNEL 0x80 /* sent by the kernel from somewhere */
|
||||
|
||||
This macro is used in exactly one place in the x86 kernel: In send_signal()
|
||||
in kernel/signal.c:
|
||||
|
||||
816 static int send_signal(int sig, struct siginfo *info, struct task_struct *t,
|
||||
817 int group)
|
||||
818 {
|
||||
...
|
||||
828 pending = group ? &t->signal->shared_pending : &t->pending;
|
||||
...
|
||||
851 q = __sigqueue_alloc(t, GFP_ATOMIC, (sig < SIGRTMIN &&
|
||||
852 (is_si_special(info) ||
|
||||
853 info->si_code >= 0)));
|
||||
854 if (q) {
|
||||
855 list_add_tail(&q->list, &pending->list);
|
||||
856 switch ((unsigned long) info) {
|
||||
...
|
||||
865 case (unsigned long) SEND_SIG_PRIV:
|
||||
866 q->info.si_signo = sig;
|
||||
867 q->info.si_errno = 0;
|
||||
868 q->info.si_code = SI_KERNEL;
|
||||
869 q->info.si_pid = 0;
|
||||
870 q->info.si_uid = 0;
|
||||
871 break;
|
||||
...
|
||||
890 }
|
||||
|
||||
Not only does this match with the .si_code member, it also matches the place
|
||||
we found earlier when looking for where siginfo_t objects are enqueued on the
|
||||
"shared_pending" list.
|
||||
|
||||
So to sum up: It seems that it is the padding introduced by the compiler
|
||||
between two struct fields that is uninitialized, and this gets reported when
|
||||
we do a memcpy() on the struct. This means that we have identified a false
|
||||
positive warning.
|
||||
|
||||
Normally, kmemcheck will not report uninitialized accesses in memcpy() calls
|
||||
when both the source and destination addresses are tracked. (Instead, we copy
|
||||
the shadow bytemap as well). In this case, the destination address clearly
|
||||
was not tracked. We can dig a little deeper into the stack trace from above:
|
||||
|
||||
arch/x86/kernel/signal.c:805
|
||||
arch/x86/kernel/signal.c:871
|
||||
arch/x86/kernel/entry_64.S:694
|
||||
|
||||
And we clearly see that the destination siginfo object is located on the
|
||||
stack:
|
||||
|
||||
782 static void do_signal(struct pt_regs *regs)
|
||||
783 {
|
||||
784 struct k_sigaction ka;
|
||||
785 siginfo_t info;
|
||||
...
|
||||
804 signr = get_signal_to_deliver(&info, &ka, regs, NULL);
|
||||
...
|
||||
854 }
|
||||
|
||||
And this &info is what eventually gets passed to copy_siginfo() as the
|
||||
destination argument.
|
||||
|
||||
Now, even though we didn't find an actual error here, the example is still a
|
||||
good one, because it shows how one would go about to find out what the report
|
||||
was all about.
|
||||
|
||||
|
||||
3.4. Annotating false positives
|
||||
===============================
|
||||
|
||||
There are a few different ways to make annotations in the source code that
|
||||
will keep kmemcheck from checking and reporting certain allocations. Here
|
||||
they are:
|
||||
|
||||
o __GFP_NOTRACK_FALSE_POSITIVE
|
||||
|
||||
This flag can be passed to kmalloc() or kmem_cache_alloc() (therefore
|
||||
also to other functions that end up calling one of these) to indicate
|
||||
that the allocation should not be tracked because it would lead to
|
||||
a false positive report. This is a "big hammer" way of silencing
|
||||
kmemcheck; after all, even if the false positive pertains to
|
||||
particular field in a struct, for example, we will now lose the
|
||||
ability to find (real) errors in other parts of the same struct.
|
||||
|
||||
Example:
|
||||
|
||||
/* No warnings will ever trigger on accessing any part of x */
|
||||
x = kmalloc(sizeof *x, GFP_KERNEL | __GFP_NOTRACK_FALSE_POSITIVE);
|
||||
|
||||
o kmemcheck_bitfield_begin(name)/kmemcheck_bitfield_end(name) and
|
||||
kmemcheck_annotate_bitfield(ptr, name)
|
||||
|
||||
The first two of these three macros can be used inside struct
|
||||
definitions to signal, respectively, the beginning and end of a
|
||||
bitfield. Additionally, this will assign the bitfield a name, which
|
||||
is given as an argument to the macros.
|
||||
|
||||
Having used these markers, one can later use
|
||||
kmemcheck_annotate_bitfield() at the point of allocation, to indicate
|
||||
which parts of the allocation is part of a bitfield.
|
||||
|
||||
Example:
|
||||
|
||||
struct foo {
|
||||
int x;
|
||||
|
||||
kmemcheck_bitfield_begin(flags);
|
||||
int flag_a:1;
|
||||
int flag_b:1;
|
||||
kmemcheck_bitfield_end(flags);
|
||||
|
||||
int y;
|
||||
};
|
||||
|
||||
struct foo *x = kmalloc(sizeof *x);
|
||||
|
||||
/* No warnings will trigger on accessing the bitfield of x */
|
||||
kmemcheck_annotate_bitfield(x, flags);
|
||||
|
||||
Note that kmemcheck_annotate_bitfield() can be used even before the
|
||||
return value of kmalloc() is checked -- in other words, passing NULL
|
||||
as the first argument is legal (and will do nothing).
|
||||
|
||||
|
||||
4. Reporting errors
|
||||
===================
|
||||
|
||||
As we have seen, kmemcheck will produce false positive reports. Therefore, it
|
||||
is not very wise to blindly post kmemcheck warnings to mailing lists and
|
||||
maintainers. Instead, I encourage maintainers and developers to find errors
|
||||
in their own code. If you get a warning, you can try to work around it, try
|
||||
to figure out if it's a real error or not, or simply ignore it. Most
|
||||
developers know their own code and will quickly and efficiently determine the
|
||||
root cause of a kmemcheck report. This is therefore also the most efficient
|
||||
way to work with kmemcheck.
|
||||
|
||||
That said, we (the kmemcheck maintainers) will always be on the lookout for
|
||||
false positives that we can annotate and silence. So whatever you find,
|
||||
please drop us a note privately! Kernel configs and steps to reproduce (if
|
||||
available) are of course a great help too.
|
||||
|
||||
Happy hacking!
|
||||
|
||||
|
||||
5. Technical description
|
||||
========================
|
||||
|
||||
kmemcheck works by marking memory pages non-present. This means that whenever
|
||||
somebody attempts to access the page, a page fault is generated. The page
|
||||
fault handler notices that the page was in fact only hidden, and so it calls
|
||||
on the kmemcheck code to make further investigations.
|
||||
|
||||
When the investigations are completed, kmemcheck "shows" the page by marking
|
||||
it present (as it would be under normal circumstances). This way, the
|
||||
interrupted code can continue as usual.
|
||||
|
||||
But after the instruction has been executed, we should hide the page again, so
|
||||
that we can catch the next access too! Now kmemcheck makes use of a debugging
|
||||
feature of the processor, namely single-stepping. When the processor has
|
||||
finished the one instruction that generated the memory access, a debug
|
||||
exception is raised. From here, we simply hide the page again and continue
|
||||
execution, this time with the single-stepping feature turned off.
|
||||
|
||||
kmemcheck requires some assistance from the memory allocator in order to work.
|
||||
The memory allocator needs to
|
||||
|
||||
1. Tell kmemcheck about newly allocated pages and pages that are about to
|
||||
be freed. This allows kmemcheck to set up and tear down the shadow memory
|
||||
for the pages in question. The shadow memory stores the status of each
|
||||
byte in the allocation proper, e.g. whether it is initialized or
|
||||
uninitialized.
|
||||
|
||||
2. Tell kmemcheck which parts of memory should be marked uninitialized.
|
||||
There are actually a few more states, such as "not yet allocated" and
|
||||
"recently freed".
|
||||
|
||||
If a slab cache is set up using the SLAB_NOTRACK flag, it will never return
|
||||
memory that can take page faults because of kmemcheck.
|
||||
|
||||
If a slab cache is NOT set up using the SLAB_NOTRACK flag, callers can still
|
||||
request memory with the __GFP_NOTRACK or __GFP_NOTRACK_FALSE_POSITIVE flags.
|
||||
This does not prevent the page faults from occurring, however, but marks the
|
||||
object in question as being initialized so that no warnings will ever be
|
||||
produced for this object.
|
||||
|
||||
Currently, the SLAB and SLUB allocators are supported by kmemcheck.
|
|
@ -103,6 +103,16 @@ Note that the probed function's args may be passed on the stack
|
|||
or in registers. The jprobe will work in either case, so long as the
|
||||
handler's prototype matches that of the probed function.
|
||||
|
||||
Note that in some architectures (e.g.: arm64 and sparc64) the stack
|
||||
copy is not done, as the actual location of stacked parameters may be
|
||||
outside of a reasonable MAX_STACK_SIZE value and because that location
|
||||
cannot be determined by the jprobes code. In this case the jprobes
|
||||
user must be careful to make certain the calling signature of the
|
||||
function does not cause parameters to be passed on the stack (e.g.:
|
||||
more than eight function arguments, an argument of more than sixteen
|
||||
bytes, or more than 64 bytes of argument data, depending on
|
||||
architecture).
|
||||
|
||||
1.3 Return Probes
|
||||
|
||||
1.3.1 How Does a Return Probe Work?
|
||||
|
|
|
@ -10,7 +10,8 @@ FILES = audio.h.rst ca.h.rst dmx.h.rst frontend.h.rst net.h.rst video.h.rst \
|
|||
|
||||
TARGETS := $(addprefix $(BUILDDIR)/, $(FILES))
|
||||
|
||||
htmldocs: $(BUILDDIR) ${TARGETS}
|
||||
.PHONY: all
|
||||
all: $(BUILDDIR) ${TARGETS}
|
||||
|
||||
$(BUILDDIR):
|
||||
$(Q)mkdir -p $@
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
# -*- coding: utf-8; mode: python -*-
|
||||
|
||||
project = 'Linux Media Subsystem Documentation'
|
||||
|
||||
tags.add("subproject")
|
||||
|
||||
latex_documents = [
|
||||
('index', 'media.tex', 'Linux Media Subsystem Documentation',
|
||||
'The kernel development community', 'manual'),
|
||||
]
|
|
@ -0,0 +1,93 @@
|
|||
# -*- coding: utf-8; mode: python -*-
|
||||
|
||||
project = 'Linux Media Subsystem Documentation'
|
||||
|
||||
# It is possible to run Sphinx in nickpick mode with:
|
||||
nitpicky = True
|
||||
|
||||
# within nit-picking build, do not refer to any intersphinx object
|
||||
intersphinx_mapping = {}
|
||||
|
||||
# In nickpick mode, it will complain about lots of missing references that
|
||||
#
|
||||
# 1) are just typedefs like: bool, __u32, etc;
|
||||
# 2) It will complain for things like: enum, NULL;
|
||||
# 3) It will complain for symbols that should be on different
|
||||
# books (but currently aren't ported to ReST)
|
||||
#
|
||||
# The list below has a list of such symbols to be ignored in nitpick mode
|
||||
#
|
||||
nitpick_ignore = [
|
||||
("c:func", "clock_gettime"),
|
||||
("c:func", "close"),
|
||||
("c:func", "container_of"),
|
||||
("c:func", "determine_valid_ioctls"),
|
||||
("c:func", "ERR_PTR"),
|
||||
("c:func", "ioctl"),
|
||||
("c:func", "IS_ERR"),
|
||||
("c:func", "mmap"),
|
||||
("c:func", "open"),
|
||||
("c:func", "pci_name"),
|
||||
("c:func", "poll"),
|
||||
("c:func", "PTR_ERR"),
|
||||
("c:func", "read"),
|
||||
("c:func", "release"),
|
||||
("c:func", "set"),
|
||||
("c:func", "struct fd_set"),
|
||||
("c:func", "struct pollfd"),
|
||||
("c:func", "usb_make_path"),
|
||||
("c:func", "write"),
|
||||
("c:type", "atomic_t"),
|
||||
("c:type", "bool"),
|
||||
("c:type", "buf_queue"),
|
||||
("c:type", "device"),
|
||||
("c:type", "device_driver"),
|
||||
("c:type", "device_node"),
|
||||
("c:type", "enum"),
|
||||
("c:type", "file"),
|
||||
("c:type", "i2c_adapter"),
|
||||
("c:type", "i2c_board_info"),
|
||||
("c:type", "i2c_client"),
|
||||
("c:type", "ktime_t"),
|
||||
("c:type", "led_classdev_flash"),
|
||||
("c:type", "list_head"),
|
||||
("c:type", "lock_class_key"),
|
||||
("c:type", "module"),
|
||||
("c:type", "mutex"),
|
||||
("c:type", "pci_dev"),
|
||||
("c:type", "pdvbdev"),
|
||||
("c:type", "poll_table_struct"),
|
||||
("c:type", "s32"),
|
||||
("c:type", "s64"),
|
||||
("c:type", "sd"),
|
||||
("c:type", "spi_board_info"),
|
||||
("c:type", "spi_device"),
|
||||
("c:type", "spi_master"),
|
||||
("c:type", "struct fb_fix_screeninfo"),
|
||||
("c:type", "struct pollfd"),
|
||||
("c:type", "struct timeval"),
|
||||
("c:type", "struct video_capability"),
|
||||
("c:type", "u16"),
|
||||
("c:type", "u32"),
|
||||
("c:type", "u64"),
|
||||
("c:type", "u8"),
|
||||
("c:type", "union"),
|
||||
("c:type", "usb_device"),
|
||||
|
||||
("cpp:type", "boolean"),
|
||||
("cpp:type", "fd"),
|
||||
("cpp:type", "fd_set"),
|
||||
("cpp:type", "int16_t"),
|
||||
("cpp:type", "NULL"),
|
||||
("cpp:type", "off_t"),
|
||||
("cpp:type", "pollfd"),
|
||||
("cpp:type", "size_t"),
|
||||
("cpp:type", "ssize_t"),
|
||||
("cpp:type", "timeval"),
|
||||
("cpp:type", "__u16"),
|
||||
("cpp:type", "__u32"),
|
||||
("cpp:type", "__u64"),
|
||||
("cpp:type", "uint16_t"),
|
||||
("cpp:type", "uint32_t"),
|
||||
("cpp:type", "video_system_t"),
|
||||
]
|
|
@ -0,0 +1,19 @@
|
|||
Linux Media Subsystem Documentation
|
||||
===================================
|
||||
|
||||
Contents:
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
media_uapi
|
||||
media_kapi
|
||||
dvb-drivers/index
|
||||
v4l-drivers/index
|
||||
|
||||
.. only:: subproject
|
||||
|
||||
Indices
|
||||
=======
|
||||
|
||||
* :ref:`genindex`
|
|
@ -32,7 +32,7 @@ Arguments
|
|||
Open flags. Access mode must be ``O_RDWR``.
|
||||
|
||||
When the ``O_NONBLOCK`` flag is given, the
|
||||
:ref:`CEC_RECEIVE <CEC_RECEIVE>` and :ref:`CEC_DQEVENT <CEC_DQEVENT>` ioctls
|
||||
:ref:`CEC_RECEIVE <CEC_RECEIVE>` and :c:func:`CEC_DQEVENT` ioctls
|
||||
will return the ``EAGAIN`` error code when no message or event is available, and
|
||||
ioctls :ref:`CEC_TRANSMIT <CEC_TRANSMIT>`,
|
||||
:ref:`CEC_ADAP_S_PHYS_ADDR <CEC_ADAP_S_PHYS_ADDR>` and
|
||||
|
|
|
@ -15,7 +15,8 @@ CEC_DQEVENT - Dequeue a CEC event
|
|||
Synopsis
|
||||
========
|
||||
|
||||
.. cpp:function:: int ioctl( int fd, int request, struct cec_event *argp )
|
||||
.. c:function:: int ioctl( int fd, int request, struct cec_event *argp )
|
||||
:name: CEC_DQEVENT
|
||||
|
||||
Arguments
|
||||
=========
|
||||
|
@ -36,7 +37,7 @@ Description
|
|||
and is currently only available as a staging kernel module.
|
||||
|
||||
CEC devices can send asynchronous events. These can be retrieved by
|
||||
calling :ref:`ioctl CEC_DQEVENT <CEC_DQEVENT>`. If the file descriptor is in
|
||||
calling :c:func:`CEC_DQEVENT`. If the file descriptor is in
|
||||
non-blocking mode and no event is pending, then it will return -1 and
|
||||
set errno to the ``EAGAIN`` error code.
|
||||
|
||||
|
|
|
@ -79,8 +79,6 @@ parameters may be changed at runtime by the command
|
|||
|
||||
ncr53c8xx= [HW,SCSI]
|
||||
|
||||
nodisconnect [HW,SCSI,M68K] Disables SCSI disconnects.
|
||||
|
||||
osst= [HW,SCSI] SCSI Tape Driver
|
||||
Format: <buffer_size>,<write_threshold>
|
||||
See also Documentation/scsi/st.txt.
|
||||
|
|
|
@ -45,9 +45,8 @@
|
|||
|
||||
#include <linux/serial.h>
|
||||
|
||||
/* RS485 ioctls: */
|
||||
#define TIOCGRS485 0x542E
|
||||
#define TIOCSRS485 0x542F
|
||||
/* Include definition for RS485 ioctls: TIOCGRS485 and TIOCSRS485 */
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
/* Open your specific device (e.g., /dev/mydevice): */
|
||||
int fd = open ("/dev/mydevice", O_RDWR);
|
||||
|
|
|
@ -42,6 +42,20 @@
|
|||
caption a.headerlink { opacity: 0; }
|
||||
caption a.headerlink:hover { opacity: 1; }
|
||||
|
||||
/* Menu selection and keystrokes */
|
||||
|
||||
span.menuselection {
|
||||
color: blue;
|
||||
font-family: "Courier New", Courier, monospace
|
||||
}
|
||||
|
||||
code.kbd, code.kbd span {
|
||||
color: white;
|
||||
background-color: darkblue;
|
||||
font-weight: bold;
|
||||
font-family: "Courier New", Courier, monospace
|
||||
}
|
||||
|
||||
/* inline literal: drop the borderbox, padding and red color */
|
||||
|
||||
code, .rst-content tt, .rst-content code {
|
||||
|
@ -55,5 +69,4 @@
|
|||
.rst-content tt.literal,.rst-content tt.literal,.rst-content code.literal {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,165 @@
|
|||
# -*- coding: utf-8; mode: python -*-
|
||||
# pylint: disable=W0141,C0113,C0103,C0325
|
||||
u"""
|
||||
cdomain
|
||||
~~~~~~~
|
||||
|
||||
Replacement for the sphinx c-domain.
|
||||
|
||||
:copyright: Copyright (C) 2016 Markus Heiser
|
||||
:license: GPL Version 2, June 1991 see Linux/COPYING for details.
|
||||
|
||||
List of customizations:
|
||||
|
||||
* Moved the *duplicate C object description* warnings for function
|
||||
declarations in the nitpicky mode. See Sphinx documentation for
|
||||
the config values for ``nitpick`` and ``nitpick_ignore``.
|
||||
|
||||
* Add option 'name' to the "c:function:" directive. With option 'name' the
|
||||
ref-name of a function can be modified. E.g.::
|
||||
|
||||
.. c:function:: int ioctl( int fd, int request )
|
||||
:name: VIDIOC_LOG_STATUS
|
||||
|
||||
The func-name (e.g. ioctl) remains in the output but the ref-name changed
|
||||
from 'ioctl' to 'VIDIOC_LOG_STATUS'. The function is referenced by::
|
||||
|
||||
* :c:func:`VIDIOC_LOG_STATUS` or
|
||||
* :any:`VIDIOC_LOG_STATUS` (``:any:`` needs sphinx 1.3)
|
||||
|
||||
* Handle signatures of function-like macros well. Don't try to deduce
|
||||
arguments types of function-like macros.
|
||||
|
||||
"""
|
||||
|
||||
from docutils import nodes
|
||||
from docutils.parsers.rst import directives
|
||||
|
||||
import sphinx
|
||||
from sphinx import addnodes
|
||||
from sphinx.domains.c import c_funcptr_sig_re, c_sig_re
|
||||
from sphinx.domains.c import CObject as Base_CObject
|
||||
from sphinx.domains.c import CDomain as Base_CDomain
|
||||
|
||||
__version__ = '1.0'
|
||||
|
||||
# Get Sphinx version
|
||||
major, minor, patch = map(int, sphinx.__version__.split("."))
|
||||
|
||||
def setup(app):
|
||||
|
||||
app.override_domain(CDomain)
|
||||
|
||||
return dict(
|
||||
version = __version__,
|
||||
parallel_read_safe = True,
|
||||
parallel_write_safe = True
|
||||
)
|
||||
|
||||
class CObject(Base_CObject):
|
||||
|
||||
"""
|
||||
Description of a C language object.
|
||||
"""
|
||||
option_spec = {
|
||||
"name" : directives.unchanged
|
||||
}
|
||||
|
||||
def handle_func_like_macro(self, sig, signode):
|
||||
u"""Handles signatures of function-like macros.
|
||||
|
||||
If the objtype is 'function' and the the signature ``sig`` is a
|
||||
function-like macro, the name of the macro is returned. Otherwise
|
||||
``False`` is returned. """
|
||||
|
||||
if not self.objtype == 'function':
|
||||
return False
|
||||
|
||||
m = c_funcptr_sig_re.match(sig)
|
||||
if m is None:
|
||||
m = c_sig_re.match(sig)
|
||||
if m is None:
|
||||
raise ValueError('no match')
|
||||
|
||||
rettype, fullname, arglist, _const = m.groups()
|
||||
arglist = arglist.strip()
|
||||
if rettype or not arglist:
|
||||
return False
|
||||
|
||||
arglist = arglist.replace('`', '').replace('\\ ', '') # remove markup
|
||||
arglist = [a.strip() for a in arglist.split(",")]
|
||||
|
||||
# has the first argument a type?
|
||||
if len(arglist[0].split(" ")) > 1:
|
||||
return False
|
||||
|
||||
# This is a function-like macro, it's arguments are typeless!
|
||||
signode += addnodes.desc_name(fullname, fullname)
|
||||
paramlist = addnodes.desc_parameterlist()
|
||||
signode += paramlist
|
||||
|
||||
for argname in arglist:
|
||||
param = addnodes.desc_parameter('', '', noemph=True)
|
||||
# separate by non-breaking space in the output
|
||||
param += nodes.emphasis(argname, argname)
|
||||
paramlist += param
|
||||
|
||||
return fullname
|
||||
|
||||
def handle_signature(self, sig, signode):
|
||||
"""Transform a C signature into RST nodes."""
|
||||
|
||||
fullname = self.handle_func_like_macro(sig, signode)
|
||||
if not fullname:
|
||||
fullname = super(CObject, self).handle_signature(sig, signode)
|
||||
|
||||
if "name" in self.options:
|
||||
if self.objtype == 'function':
|
||||
fullname = self.options["name"]
|
||||
else:
|
||||
# FIXME: handle :name: value of other declaration types?
|
||||
pass
|
||||
return fullname
|
||||
|
||||
def add_target_and_index(self, name, sig, signode):
|
||||
# for C API items we add a prefix since names are usually not qualified
|
||||
# by a module name and so easily clash with e.g. section titles
|
||||
targetname = 'c.' + name
|
||||
if targetname not in self.state.document.ids:
|
||||
signode['names'].append(targetname)
|
||||
signode['ids'].append(targetname)
|
||||
signode['first'] = (not self.names)
|
||||
self.state.document.note_explicit_target(signode)
|
||||
inv = self.env.domaindata['c']['objects']
|
||||
if (name in inv and self.env.config.nitpicky):
|
||||
if self.objtype == 'function':
|
||||
if ('c:func', name) not in self.env.config.nitpick_ignore:
|
||||
self.state_machine.reporter.warning(
|
||||
'duplicate C object description of %s, ' % name +
|
||||
'other instance in ' + self.env.doc2path(inv[name][0]),
|
||||
line=self.lineno)
|
||||
inv[name] = (self.env.docname, self.objtype)
|
||||
|
||||
indextext = self.get_index_text(name)
|
||||
if indextext:
|
||||
if major == 1 and minor < 4:
|
||||
# indexnode's tuple changed in 1.4
|
||||
# https://github.com/sphinx-doc/sphinx/commit/e6a5a3a92e938fcd75866b4227db9e0524d58f7c
|
||||
self.indexnode['entries'].append(
|
||||
('single', indextext, targetname, ''))
|
||||
else:
|
||||
self.indexnode['entries'].append(
|
||||
('single', indextext, targetname, '', None))
|
||||
|
||||
class CDomain(Base_CDomain):
|
||||
|
||||
"""C language domain."""
|
||||
name = 'c'
|
||||
label = 'C'
|
||||
directives = {
|
||||
'function': CObject,
|
||||
'member': CObject,
|
||||
'macro': CObject,
|
||||
'type': CObject,
|
||||
'var': CObject,
|
||||
}
|
|
@ -39,6 +39,8 @@ from docutils.parsers.rst import directives
|
|||
from sphinx.util.compat import Directive
|
||||
from sphinx.ext.autodoc import AutodocReporter
|
||||
|
||||
__version__ = '1.0'
|
||||
|
||||
class KernelDocDirective(Directive):
|
||||
"""Extract kernel-doc comments from the specified file"""
|
||||
required_argument = 1
|
||||
|
@ -139,3 +141,9 @@ def setup(app):
|
|||
app.add_config_value('kerneldoc_verbosity', 1, 'env')
|
||||
|
||||
app.add_directive('kernel-doc', KernelDocDirective)
|
||||
|
||||
return dict(
|
||||
version = __version__,
|
||||
parallel_read_safe = True,
|
||||
parallel_write_safe = True
|
||||
)
|
||||
|
|
|
@ -39,11 +39,18 @@ from docutils.parsers.rst import directives
|
|||
from docutils.parsers.rst.directives.body import CodeBlock, NumberLines
|
||||
from docutils.parsers.rst.directives.misc import Include
|
||||
|
||||
__version__ = '1.0'
|
||||
|
||||
# ==============================================================================
|
||||
def setup(app):
|
||||
# ==============================================================================
|
||||
|
||||
app.add_directive("kernel-include", KernelInclude)
|
||||
return dict(
|
||||
version = __version__,
|
||||
parallel_read_safe = True,
|
||||
parallel_write_safe = True
|
||||
)
|
||||
|
||||
# ==============================================================================
|
||||
class KernelInclude(Include):
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
# -*- coding: utf-8; mode: python -*-
|
||||
# pylint: disable=R0903, C0330, R0914, R0912, E0401
|
||||
|
||||
import os
|
||||
import sys
|
||||
from sphinx.util.pycompat import execfile_
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
def loadConfig(namespace):
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
u"""Load an additional configuration file into *namespace*.
|
||||
|
||||
The name of the configuration file is taken from the environment
|
||||
``SPHINX_CONF``. The external configuration file extends (or overwrites) the
|
||||
configuration values from the origin ``conf.py``. With this you are able to
|
||||
maintain *build themes*. """
|
||||
|
||||
config_file = os.environ.get("SPHINX_CONF", None)
|
||||
if (config_file is not None
|
||||
and os.path.normpath(namespace["__file__"]) != os.path.normpath(config_file) ):
|
||||
config_file = os.path.abspath(config_file)
|
||||
|
||||
if os.path.isfile(config_file):
|
||||
sys.stdout.write("load additional sphinx-config: %s\n" % config_file)
|
||||
config = namespace.copy()
|
||||
config['__file__'] = config_file
|
||||
execfile_(config_file, config)
|
||||
del config['__file__']
|
||||
namespace.update(config)
|
||||
else:
|
||||
sys.stderr.write("WARNING: additional sphinx-config not found: %s\n" % config_file)
|
|
@ -220,7 +220,7 @@ $data =~ s/\n\s+\n/\n\n/g;
|
|||
#
|
||||
# Add escape codes for special characters
|
||||
#
|
||||
$data =~ s,([\_\`\*\<\>\&\\\\:\/\|]),\\$1,g;
|
||||
$data =~ s,([\_\`\*\<\>\&\\\\:\/\|\%\$\#\{\}\~\^]),\\$1,g;
|
||||
|
||||
$data =~ s,DEPRECATED,**DEPRECATED**,g;
|
||||
|
||||
|
|
|
@ -73,6 +73,12 @@ def setup(app):
|
|||
roles.register_local_role('cspan', c_span)
|
||||
roles.register_local_role('rspan', r_span)
|
||||
|
||||
return dict(
|
||||
version = __version__,
|
||||
parallel_read_safe = True,
|
||||
parallel_write_safe = True
|
||||
)
|
||||
|
||||
# ==============================================================================
|
||||
def c_span(name, rawtext, text, lineno, inliner, options=None, content=None):
|
||||
# ==============================================================================
|
||||
|
|
|
@ -1,17 +1,26 @@
|
|||
.. _stable_api_nonsense:
|
||||
|
||||
The Linux Kernel Driver Interface
|
||||
==================================
|
||||
|
||||
(all of your questions answered and then some)
|
||||
|
||||
Greg Kroah-Hartman <greg@kroah.com>
|
||||
|
||||
This is being written to try to explain why Linux does not have a binary
|
||||
kernel interface, nor does it have a stable kernel interface. Please
|
||||
realize that this article describes the _in kernel_ interfaces, not the
|
||||
kernel to userspace interfaces. The kernel to userspace interface is
|
||||
the one that application programs use, the syscall interface. That
|
||||
interface is _very_ stable over time, and will not break. I have old
|
||||
programs that were built on a pre 0.9something kernel that still work
|
||||
just fine on the latest 2.6 kernel release. That interface is the one
|
||||
that users and application programmers can count on being stable.
|
||||
This is being written to try to explain why Linux **does not have a binary
|
||||
kernel interface, nor does it have a stable kernel interface**.
|
||||
|
||||
.. note::
|
||||
|
||||
Please realize that this article describes the **in kernel** interfaces, not
|
||||
the kernel to userspace interfaces.
|
||||
|
||||
The kernel to userspace interface is the one that application programs use,
|
||||
the syscall interface. That interface is **very** stable over time, and
|
||||
will not break. I have old programs that were built on a pre 0.9something
|
||||
kernel that still work just fine on the latest 2.6 kernel release.
|
||||
That interface is the one that users and application programmers can count
|
||||
on being stable.
|
||||
|
||||
|
||||
Executive Summary
|
||||
|
@ -33,7 +42,7 @@ to worry about the in-kernel interfaces changing. For the majority of
|
|||
the world, they neither see this interface, nor do they care about it at
|
||||
all.
|
||||
|
||||
First off, I'm not going to address _any_ legal issues about closed
|
||||
First off, I'm not going to address **any** legal issues about closed
|
||||
source, hidden source, binary blobs, source wrappers, or any other term
|
||||
that describes kernel drivers that do not have their source code
|
||||
released under the GPL. Please consult a lawyer if you have any legal
|
||||
|
@ -51,19 +60,23 @@ Binary Kernel Interface
|
|||
Assuming that we had a stable kernel source interface for the kernel, a
|
||||
binary interface would naturally happen too, right? Wrong. Please
|
||||
consider the following facts about the Linux kernel:
|
||||
|
||||
- Depending on the version of the C compiler you use, different kernel
|
||||
data structures will contain different alignment of structures, and
|
||||
possibly include different functions in different ways (putting
|
||||
functions inline or not.) The individual function organization
|
||||
isn't that important, but the different data structure padding is
|
||||
very important.
|
||||
|
||||
- Depending on what kernel build options you select, a wide range of
|
||||
different things can be assumed by the kernel:
|
||||
|
||||
- different structures can contain different fields
|
||||
- Some functions may not be implemented at all, (i.e. some locks
|
||||
compile away to nothing for non-SMP builds.)
|
||||
- Memory within the kernel can be aligned in different ways,
|
||||
depending on the build options.
|
||||
|
||||
- Linux runs on a wide range of different processor architectures.
|
||||
There is no way that binary drivers from one architecture will run
|
||||
on another architecture properly.
|
||||
|
@ -105,6 +118,7 @@ As a specific examples of this, the in-kernel USB interfaces have
|
|||
undergone at least three different reworks over the lifetime of this
|
||||
subsystem. These reworks were done to address a number of different
|
||||
issues:
|
||||
|
||||
- A change from a synchronous model of data streams to an asynchronous
|
||||
one. This reduced the complexity of a number of drivers and
|
||||
increased the throughput of all USB drivers such that we are now
|
||||
|
@ -166,6 +180,7 @@ very little effort on your part.
|
|||
|
||||
The very good side effects of having your driver in the main kernel tree
|
||||
are:
|
||||
|
||||
- The quality of the driver will rise as the maintenance costs (to the
|
||||
original developer) will decrease.
|
||||
- Other developers will add features to your driver.
|
||||
|
@ -175,7 +190,7 @@ are:
|
|||
changes require it.
|
||||
- The driver automatically gets shipped in all Linux distributions
|
||||
without having to ask the distros to add it.
|
||||
|
||||
|
||||
As Linux supports a larger number of different devices "out of the box"
|
||||
than any other operating system, and it supports these devices on more
|
||||
different processor architectures than any other operating system, this
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
Everything you ever wanted to know about Linux -stable releases.
|
||||
.. _stable_kernel_rules:
|
||||
|
||||
Everything you ever wanted to know about Linux -stable releases
|
||||
===============================================================
|
||||
|
||||
Rules on what kind of patches are accepted, and which ones are not, into the
|
||||
"-stable" tree:
|
||||
|
@ -23,68 +26,94 @@ Rules on what kind of patches are accepted, and which ones are not, into the
|
|||
race can be exploited is also provided.
|
||||
- It cannot contain any "trivial" fixes in it (spelling changes,
|
||||
whitespace cleanups, etc).
|
||||
- It must follow the Documentation/SubmittingPatches rules.
|
||||
- It must follow the
|
||||
:ref:`Documentation/SubmittingPatches <submittingpatches>`
|
||||
rules.
|
||||
- It or an equivalent fix must already exist in Linus' tree (upstream).
|
||||
|
||||
|
||||
Procedure for submitting patches to the -stable tree:
|
||||
Procedure for submitting patches to the -stable tree
|
||||
----------------------------------------------------
|
||||
|
||||
- If the patch covers files in net/ or drivers/net please follow netdev stable
|
||||
submission guidelines as described in
|
||||
Documentation/networking/netdev-FAQ.txt
|
||||
- Security patches should not be handled (solely) by the -stable review
|
||||
process but should follow the procedures in Documentation/SecurityBugs.
|
||||
process but should follow the procedures in
|
||||
:ref:`Documentation/SecurityBugs <securitybugs>`.
|
||||
|
||||
For all other submissions, choose one of the following procedures:
|
||||
For all other submissions, choose one of the following procedures
|
||||
-----------------------------------------------------------------
|
||||
|
||||
--- Option 1 ---
|
||||
.. _option_1:
|
||||
|
||||
Option 1
|
||||
********
|
||||
|
||||
To have the patch automatically included in the stable tree, add the tag
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
To have the patch automatically included in the stable tree, add the tag
|
||||
Cc: stable@vger.kernel.org
|
||||
in the sign-off area. Once the patch is merged it will be applied to
|
||||
the stable tree without anything else needing to be done by the author
|
||||
or subsystem maintainer.
|
||||
|
||||
--- Option 2 ---
|
||||
in the sign-off area. Once the patch is merged it will be applied to
|
||||
the stable tree without anything else needing to be done by the author
|
||||
or subsystem maintainer.
|
||||
|
||||
After the patch has been merged to Linus' tree, send an email to
|
||||
stable@vger.kernel.org containing the subject of the patch, the commit ID,
|
||||
why you think it should be applied, and what kernel version you wish it to
|
||||
be applied to.
|
||||
.. _option_2:
|
||||
|
||||
--- Option 3 ---
|
||||
Option 2
|
||||
********
|
||||
|
||||
Send the patch, after verifying that it follows the above rules, to
|
||||
stable@vger.kernel.org. You must note the upstream commit ID in the
|
||||
changelog of your submission, as well as the kernel version you wish
|
||||
it to be applied to.
|
||||
After the patch has been merged to Linus' tree, send an email to
|
||||
stable@vger.kernel.org containing the subject of the patch, the commit ID,
|
||||
why you think it should be applied, and what kernel version you wish it to
|
||||
be applied to.
|
||||
|
||||
Option 1 is *strongly* preferred, is the easiest and most common. Options 2 and
|
||||
3 are more useful if the patch isn't deemed worthy at the time it is applied to
|
||||
a public git tree (for instance, because it deserves more regression testing
|
||||
first). Option 3 is especially useful if the patch needs some special handling
|
||||
to apply to an older kernel (e.g., if API's have changed in the meantime).
|
||||
.. _option_3:
|
||||
|
||||
Note that for Option 3, if the patch deviates from the original upstream patch
|
||||
(for example because it had to be backported) this must be very clearly
|
||||
documented and justified in the patch description.
|
||||
Option 3
|
||||
********
|
||||
|
||||
Send the patch, after verifying that it follows the above rules, to
|
||||
stable@vger.kernel.org. You must note the upstream commit ID in the
|
||||
changelog of your submission, as well as the kernel version you wish
|
||||
it to be applied to.
|
||||
|
||||
:ref:`option_1` is **strongly** preferred, is the easiest and most common.
|
||||
:ref:`option_2` and :ref:`option_3` are more useful if the patch isn't deemed
|
||||
worthy at the time it is applied to a public git tree (for instance, because
|
||||
it deserves more regression testing first). :ref:`option_3` is especially
|
||||
useful if the patch needs some special handling to apply to an older kernel
|
||||
(e.g., if API's have changed in the meantime).
|
||||
|
||||
Note that for :ref:`option_3`, if the patch deviates from the original
|
||||
upstream patch (for example because it had to be backported) this must be very
|
||||
clearly documented and justified in the patch description.
|
||||
|
||||
The upstream commit ID must be specified with a separate line above the commit
|
||||
text, like this:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
commit <sha1> upstream.
|
||||
|
||||
Additionally, some patches submitted via Option 1 may have additional patch
|
||||
prerequisites which can be cherry-picked. This can be specified in the following
|
||||
format in the sign-off area:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
Cc: <stable@vger.kernel.org> # 3.3.x: a1f84a3: sched: Check for idle
|
||||
Cc: <stable@vger.kernel.org> # 3.3.x: 1b9508f: sched: Rate-limit newidle
|
||||
Cc: <stable@vger.kernel.org> # 3.3.x: fd21073: sched: Fix affinity logic
|
||||
Cc: <stable@vger.kernel.org> # 3.3.x
|
||||
Signed-off-by: Ingo Molnar <mingo@elte.hu>
|
||||
Signed-off-by: Ingo Molnar <mingo@elte.hu>
|
||||
|
||||
The tag sequence has the meaning of:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
The tag sequence has the meaning of:
|
||||
git cherry-pick a1f84a3
|
||||
git cherry-pick 1b9508f
|
||||
git cherry-pick fd21073
|
||||
|
@ -93,12 +122,17 @@ format in the sign-off area:
|
|||
Also, some patches may have kernel version prerequisites. This can be
|
||||
specified in the following format in the sign-off area:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
Cc: <stable@vger.kernel.org> # 3.3.x-
|
||||
|
||||
The tag has the meaning of:
|
||||
The tag has the meaning of:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
git cherry-pick <this commit>
|
||||
|
||||
For each "-stable" tree starting with the specified version.
|
||||
For each "-stable" tree starting with the specified version.
|
||||
|
||||
Following the submission:
|
||||
|
||||
|
@ -109,7 +143,8 @@ Following the submission:
|
|||
other developers and by the relevant subsystem maintainer.
|
||||
|
||||
|
||||
Review cycle:
|
||||
Review cycle
|
||||
------------
|
||||
|
||||
- When the -stable maintainers decide for a review cycle, the patches will be
|
||||
sent to the review committee, and the maintainer of the affected area of
|
||||
|
@ -125,17 +160,22 @@ Review cycle:
|
|||
security kernel team, and not go through the normal review cycle.
|
||||
Contact the kernel security team for more details on this procedure.
|
||||
|
||||
Trees:
|
||||
Trees
|
||||
-----
|
||||
|
||||
- The queues of patches, for both completed versions and in progress
|
||||
versions can be found at:
|
||||
|
||||
http://git.kernel.org/?p=linux/kernel/git/stable/stable-queue.git
|
||||
|
||||
- The finalized and tagged releases of all stable kernels can be found
|
||||
in separate branches per version at:
|
||||
|
||||
http://git.kernel.org/?p=linux/kernel/git/stable/linux-stable.git
|
||||
|
||||
|
||||
Review committee:
|
||||
Review committee
|
||||
----------------
|
||||
|
||||
- This is made up of a number of kernel developers who have volunteered for
|
||||
this task, and a few that haven't.
|
||||
|
|
|
@ -12,13 +12,13 @@ ffffc90000000000 - ffffe8ffffffffff (=45 bits) vmalloc/ioremap space
|
|||
ffffe90000000000 - ffffe9ffffffffff (=40 bits) hole
|
||||
ffffea0000000000 - ffffeaffffffffff (=40 bits) virtual memory map (1TB)
|
||||
... unused hole ...
|
||||
ffffec0000000000 - fffffc0000000000 (=44 bits) kasan shadow memory (16TB)
|
||||
ffffec0000000000 - fffffbffffffffff (=44 bits) kasan shadow memory (16TB)
|
||||
... unused hole ...
|
||||
ffffff0000000000 - ffffff7fffffffff (=39 bits) %esp fixup stacks
|
||||
... unused hole ...
|
||||
ffffffef00000000 - ffffffff00000000 (=64 GB) EFI region mapping space
|
||||
ffffffef00000000 - fffffffeffffffff (=64 GB) EFI region mapping space
|
||||
... unused hole ...
|
||||
ffffffff80000000 - ffffffffa0000000 (=512 MB) kernel text mapping, from phys 0
|
||||
ffffffff80000000 - ffffffff9fffffff (=512 MB) kernel text mapping, from phys 0
|
||||
ffffffffa0000000 - ffffffffff5fffff (=1526 MB) module mapping space
|
||||
ffffffffff600000 - ffffffffffdfffff (=8 MB) vsyscalls
|
||||
ffffffffffe00000 - ffffffffffffffff (=2 MB) unused hole
|
||||
|
|
12
MAINTAINERS
12
MAINTAINERS
|
@ -3139,7 +3139,7 @@ L: cocci@systeme.lip6.fr (moderated for non-subscribers)
|
|||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/mmarek/kbuild.git misc
|
||||
W: http://coccinelle.lip6.fr/
|
||||
S: Supported
|
||||
F: Documentation/coccinelle.txt
|
||||
F: Documentation/dev-tools/coccinelle.rst
|
||||
F: scripts/coccinelle/
|
||||
F: scripts/coccicheck
|
||||
|
||||
|
@ -5148,7 +5148,7 @@ GCOV BASED KERNEL PROFILING
|
|||
M: Peter Oberparleiter <oberpar@linux.vnet.ibm.com>
|
||||
S: Maintained
|
||||
F: kernel/gcov/
|
||||
F: Documentation/gcov.txt
|
||||
F: Documentation/dev-tools/gcov.rst
|
||||
|
||||
GDT SCSI DISK ARRAY CONTROLLER DRIVER
|
||||
M: Achim Leubner <achim_leubner@adaptec.com>
|
||||
|
@ -5636,7 +5636,7 @@ M: Sebastian Reichel <sre@kernel.org>
|
|||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/sre/linux-hsi.git
|
||||
S: Maintained
|
||||
F: Documentation/ABI/testing/sysfs-bus-hsi
|
||||
F: Documentation/hsi.txt
|
||||
F: Documentation/device-drivers/serial-interfaces.rst
|
||||
F: drivers/hsi/
|
||||
F: include/linux/hsi/
|
||||
F: include/uapi/linux/hsi/
|
||||
|
@ -6617,7 +6617,7 @@ L: kasan-dev@googlegroups.com
|
|||
S: Maintained
|
||||
F: arch/*/include/asm/kasan.h
|
||||
F: arch/*/mm/kasan_init*
|
||||
F: Documentation/kasan.txt
|
||||
F: Documentation/dev-tools/kasan.rst
|
||||
F: include/linux/kasan*.h
|
||||
F: lib/test_kasan.c
|
||||
F: mm/kasan/
|
||||
|
@ -6833,7 +6833,7 @@ KMEMCHECK
|
|||
M: Vegard Nossum <vegardno@ifi.uio.no>
|
||||
M: Pekka Enberg <penberg@kernel.org>
|
||||
S: Maintained
|
||||
F: Documentation/kmemcheck.txt
|
||||
F: Documentation/dev-tools/kmemcheck.rst
|
||||
F: arch/x86/include/asm/kmemcheck.h
|
||||
F: arch/x86/mm/kmemcheck/
|
||||
F: include/linux/kmemcheck.h
|
||||
|
@ -6842,7 +6842,7 @@ F: mm/kmemcheck.c
|
|||
KMEMLEAK
|
||||
M: Catalin Marinas <catalin.marinas@arm.com>
|
||||
S: Maintained
|
||||
F: Documentation/kmemleak.txt
|
||||
F: Documentation/dev-tools/kmemleak.rst
|
||||
F: include/linux/kmemleak.h
|
||||
F: mm/kmemleak.c
|
||||
F: mm/kmemleak-test.c
|
||||
|
|
2
Makefile
2
Makefile
|
@ -1425,7 +1425,7 @@ $(help-board-dirs): help-%:
|
|||
|
||||
# Documentation targets
|
||||
# ---------------------------------------------------------------------------
|
||||
DOC_TARGETS := xmldocs sgmldocs psdocs pdfdocs htmldocs mandocs installmandocs epubdocs cleandocs
|
||||
DOC_TARGETS := xmldocs sgmldocs psdocs latexdocs pdfdocs htmldocs mandocs installmandocs epubdocs cleandocs
|
||||
PHONY += $(DOC_TARGETS)
|
||||
$(DOC_TARGETS): scripts_basic FORCE
|
||||
$(Q)$(MAKE) $(build)=scripts build_docproc build_check-lc_ctype
|
||||
|
|
8
README
8
README
|
@ -229,10 +229,6 @@ CONFIGURING the kernel:
|
|||
under some circumstances lead to problems: probing for a
|
||||
nonexistent controller card may confuse your other controllers
|
||||
|
||||
- Compiling the kernel with "Processor type" set higher than 386
|
||||
will result in a kernel that does NOT work on a 386. The
|
||||
kernel will detect this on bootup, and give up.
|
||||
|
||||
- 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,
|
||||
|
@ -289,7 +285,7 @@ COMPILING the kernel:
|
|||
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/i386/boot/bzImage after compilation)
|
||||
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
|
||||
|
@ -391,7 +387,7 @@ IF SOMETHING GOES WRONG:
|
|||
|
||||
- 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/i386/Makefile appropriately, then do a "make
|
||||
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".
|
||||
|
|
|
@ -212,6 +212,7 @@ my $anon_struct_union = 0;
|
|||
my $type_constant = '\%([-_\w]+)';
|
||||
my $type_func = '(\w+)\(\)';
|
||||
my $type_param = '\@(\w+)';
|
||||
my $type_fp_param = '\@(\w+)\(\)'; # Special RST handling for func ptr params
|
||||
my $type_struct = '\&((struct\s*)*[_\w]+)';
|
||||
my $type_struct_xml = '\\&((struct\s*)*[_\w]+)';
|
||||
my $type_env = '(\$\w+)';
|
||||
|
@ -292,6 +293,7 @@ my @highlights_rst = (
|
|||
# Note: need to escape () to avoid func matching later
|
||||
[$type_member_func, "\\:c\\:type\\:`\$1\$2\\\\(\\\\) <\$1>`"],
|
||||
[$type_member, "\\:c\\:type\\:`\$1\$2 <\$1>`"],
|
||||
[$type_fp_param, "**\$1\\\\(\\\\)**"],
|
||||
[$type_func, "\\:c\\:func\\:`\$1()`"],
|
||||
[$type_struct_full, "\\:c\\:type\\:`\$1 \$2 <\$2>`"],
|
||||
[$type_enum_full, "\\:c\\:type\\:`\$1 \$2 <\$2>`"],
|
||||
|
@ -412,7 +414,7 @@ my $doc_com_body = '\s*\* ?';
|
|||
my $doc_decl = $doc_com . '(\w+)';
|
||||
# @params and a strictly limited set of supported section names
|
||||
my $doc_sect = $doc_com .
|
||||
'\s*(\@\w+|description|context|returns?|notes?|examples?)\s*:(.*)';
|
||||
'\s*(\@[.\w]+|\@\.\.\.|description|context|returns?|notes?|examples?)\s*:(.*)';
|
||||
my $doc_content = $doc_com_body . '(.*)';
|
||||
my $doc_block = $doc_com . 'DOC:\s*(.*)?';
|
||||
my $doc_inline_start = '^\s*/\*\*\s*$';
|
||||
|
@ -1831,13 +1833,22 @@ sub output_function_rst(%) {
|
|||
my %args = %{$_[0]};
|
||||
my ($parameter, $section);
|
||||
my $oldprefix = $lineprefix;
|
||||
my $start;
|
||||
my $start = "";
|
||||
|
||||
print ".. c:function:: ";
|
||||
if ($args{'functiontype'} ne "") {
|
||||
$start = $args{'functiontype'} . " " . $args{'function'} . " (";
|
||||
if ($args{'typedef'}) {
|
||||
print ".. c:type:: ". $args{'function'} . "\n\n";
|
||||
print_lineno($declaration_start_line);
|
||||
print " **Typedef**: ";
|
||||
$lineprefix = "";
|
||||
output_highlight_rst($args{'purpose'});
|
||||
$start = "\n\n**Syntax**\n\n ``";
|
||||
} else {
|
||||
$start = $args{'function'} . " (";
|
||||
print ".. c:function:: ";
|
||||
}
|
||||
if ($args{'functiontype'} ne "") {
|
||||
$start .= $args{'functiontype'} . " " . $args{'function'} . " (";
|
||||
} else {
|
||||
$start .= $args{'function'} . " (";
|
||||
}
|
||||
print $start;
|
||||
|
||||
|
@ -1849,9 +1860,6 @@ sub output_function_rst(%) {
|
|||
$count++;
|
||||
$type = $args{'parametertypes'}{$parameter};
|
||||
|
||||
# RST doesn't like address_space tags at function prototypes
|
||||
$type =~ s/__(user|kernel|iomem|percpu|pmem|rcu)\s*//;
|
||||
|
||||
if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) {
|
||||
# pointer-to-function
|
||||
print $1 . $parameter . ") (" . $2;
|
||||
|
@ -1859,11 +1867,15 @@ sub output_function_rst(%) {
|
|||
print $type . " " . $parameter;
|
||||
}
|
||||
}
|
||||
print ")\n\n";
|
||||
print_lineno($declaration_start_line);
|
||||
$lineprefix = " ";
|
||||
output_highlight_rst($args{'purpose'});
|
||||
print "\n";
|
||||
if ($args{'typedef'}) {
|
||||
print ");``\n\n";
|
||||
} else {
|
||||
print ")\n\n";
|
||||
print_lineno($declaration_start_line);
|
||||
$lineprefix = " ";
|
||||
output_highlight_rst($args{'purpose'});
|
||||
print "\n";
|
||||
}
|
||||
|
||||
print "**Parameters**\n\n";
|
||||
$lineprefix = " ";
|
||||
|
@ -2003,7 +2015,7 @@ sub output_struct_rst(%) {
|
|||
($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next;
|
||||
$type = $args{'parametertypes'}{$parameter};
|
||||
print_lineno($parameterdesc_start_lines{$parameter_name});
|
||||
print "``$type $parameter``\n";
|
||||
print "``" . $parameter . "``\n";
|
||||
output_highlight_rst($args{'parameterdescs'}{$parameter_name});
|
||||
print "\n";
|
||||
}
|
||||
|
@ -2193,7 +2205,9 @@ sub dump_typedef($$) {
|
|||
$x =~ s@/\*.*?\*/@@gos; # strip comments.
|
||||
|
||||
# Parse function prototypes
|
||||
if ($x =~ /typedef\s+(\w+)\s*\(\*\s*(\w\S+)\s*\)\s*\((.*)\);/) {
|
||||
if ($x =~ /typedef\s+(\w+)\s*\(\*\s*(\w\S+)\s*\)\s*\((.*)\);/ ||
|
||||
$x =~ /typedef\s+(\w+)\s*(\w\S+)\s*\s*\((.*)\);/) {
|
||||
|
||||
# Function typedefs
|
||||
$return_type = $1;
|
||||
$declaration_name = $2;
|
||||
|
@ -2204,6 +2218,7 @@ sub dump_typedef($$) {
|
|||
output_declaration($declaration_name,
|
||||
'function',
|
||||
{'function' => $declaration_name,
|
||||
'typedef' => 1,
|
||||
'module' => $modulename,
|
||||
'functiontype' => $return_type,
|
||||
'parameterlist' => \@parameterlist,
|
||||
|
@ -2338,6 +2353,7 @@ sub push_parameter($$$) {
|
|||
|
||||
if ($type eq "" && $param =~ /\.\.\.$/)
|
||||
{
|
||||
$param = "...";
|
||||
if (!defined $parameterdescs{$param} || $parameterdescs{$param} eq "") {
|
||||
$parameterdescs{$param} = "variable arguments";
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче