It's been a relatively busy cycle in docsland, though more than usually
well contained to Documentation/ itself. Highlights include: - The Chinese translators have been busy and show no signs of stopping anytime soon. Italian has also caught up. - Aditya Srivastava has been working on improvements to the kernel-doc script. - Thorsten continues his work on reporting-issues.rst and related documentation around regression reporting. - Lots of documentation updates, typo fixes, etc. as usual -----BEGIN PGP SIGNATURE----- iQFDBAABCAAtFiEEIw+MvkEiF49krdp9F0NaE2wMflgFAmCG5moPHGNvcmJldEBs d24ubmV0AAoJEBdDWhNsDH5YCoUH/1q/O+IvS+JNkxneDxbB6OC799BQpabZHi7/ HbYfgfX0nKrV3NAwIhigsIj6WHRE+5p2rKiHOuQxL3daJyfZSqQl0/yI0Ag7Of4g 7y1FKBQrfqS6tJcyNckdtBfxYUQP9yCJY0xfIexkTNiujbmkMKDSJD7lKXd0AaTM styCvTbgTPTzadL5bIHj/GxJ9s8DsxO3y9LGdRc+GrNzPFliMYWlJgbR28zjEKBm UQzy7JGNBX3qTJwgjvv/myqRDy6MligvGrP+wG0KTnAHXKkvDFl3p46kPwzdk1JE +F5sbboUWh20GLYy9t4MZOcq38FUcEPlRPXkxsGNyA8co5ij8+g= =7db3 -----END PGP SIGNATURE----- Merge tag 'docs-5.13' of git://git.lwn.net/linux Pull documentation updates from Jonathan Corbet: "It's been a relatively busy cycle in docsland, though more than usually well contained to Documentation/ itself. Highlights include: - The Chinese translators have been busy and show no signs of stopping anytime soon. Italian has also caught up. - Aditya Srivastava has been working on improvements to the kernel-doc script. - Thorsten continues his work on reporting-issues.rst and related documentation around regression reporting. - Lots of documentation updates, typo fixes, etc. as usual" * tag 'docs-5.13' of git://git.lwn.net/linux: (139 commits) docs/zh_CN: add openrisc translation to zh_CN index docs/zh_CN: add openrisc index.rst translation docs/zh_CN: add openrisc todo.rst translation docs/zh_CN: add openrisc openrisc_port.rst translation docs/zh_CN: add core api translation to zh_CN index docs/zh_CN: add core-api index.rst translation docs/zh_CN: add core-api irq index.rst translation docs/zh_CN: add core-api irq irqflags-tracing.rst translation docs/zh_CN: add core-api irq irq-domain.rst translation docs/zh_CN: add core-api irq irq-affinity.rst translation docs/zh_CN: add core-api irq concepts.rst translation docs: sphinx-pre-install: don't barf on beta Sphinx releases scripts: kernel-doc: improve parsing for kernel-doc comments syntax docs/zh_CN: two minor fixes in zh_CN/doc-guide/ Documentation: dev-tools: Add Testing Overview docs/zh_CN: add translations in zh_CN/dev-tools/gcov docs: reporting-issues: make people CC the regressions list MAINTAINERS: add regressions mailing list doc:it_IT: align Italian documentation docs/zh_CN: sync reporting-issues.rst ...
This commit is contained in:
commit
2f9ef0559e
5
.mailmap
5
.mailmap
|
@ -25,8 +25,9 @@ Alexandre Belloni <alexandre.belloni@bootlin.com> <alexandre.belloni@free-electr
|
|||
Alexei Starovoitov <ast@kernel.org> <alexei.starovoitov@gmail.com>
|
||||
Alexei Starovoitov <ast@kernel.org> <ast@fb.com>
|
||||
Alexei Starovoitov <ast@kernel.org> <ast@plumgrid.com>
|
||||
Alex Shi <alex.shi@linux.alibaba.com> <alex.shi@intel.com>
|
||||
Alex Shi <alex.shi@linux.alibaba.com> <alex.shi@linaro.org>
|
||||
Alex Shi <alexs@kernel.org> <alex.shi@intel.com>
|
||||
Alex Shi <alexs@kernel.org> <alex.shi@linaro.org>
|
||||
Alex Shi <alexs@kernel.org> <alex.shi@linux.alibaba.com>
|
||||
Al Viro <viro@ftp.linux.org.uk>
|
||||
Al Viro <viro@zenIV.linux.org.uk>
|
||||
Andi Kleen <ak@linux.intel.com> <ak@suse.de>
|
||||
|
|
2
CREDITS
2
CREDITS
|
@ -550,7 +550,7 @@ D: gadget layers, SPI subsystem, GPIO subsystem, and more than a few
|
|||
D: device drivers. His encouragement also helped many engineers get
|
||||
D: started working on the Linux kernel. David passed away in early
|
||||
D: 2011, and will be greatly missed.
|
||||
W: https://lkml.org/lkml/2011/4/5/36
|
||||
W: https://lore.kernel.org/lkml/20110405034819.GA7872@kroah.com
|
||||
|
||||
N: Gary Brubaker
|
||||
E: xavyer@ix.netcom.com
|
||||
|
|
|
@ -11,8 +11,8 @@ restrictions without needing to sign the files individually.
|
|||
|
||||
The LSM is selectable at build-time with ``CONFIG_SECURITY_LOADPIN``, and
|
||||
can be controlled at boot-time with the kernel command line option
|
||||
"``loadpin.enabled``". By default, it is enabled, but can be disabled at
|
||||
boot ("``loadpin.enabled=0``").
|
||||
"``loadpin.enforce``". By default, it is enabled, but can be disabled at
|
||||
boot ("``loadpin.enforce=0``").
|
||||
|
||||
LoadPin starts pinning when it sees the first file loaded. If the
|
||||
block device backing the filesystem is not read-only, a sysctl is
|
||||
|
@ -28,4 +28,4 @@ different mechanisms such as ``CONFIG_MODULE_SIG`` and
|
|||
``CONFIG_KEXEC_VERIFY_SIG`` to verify kernel module and kernel image while
|
||||
still use LoadPin to protect the integrity of other files kernel loads. The
|
||||
full list of valid file types can be found in ``kernel_read_file_str``
|
||||
defined in ``include/linux/fs.h``.
|
||||
defined in ``include/linux/kernel_read_file.h``.
|
||||
|
|
|
@ -360,8 +360,8 @@ U != 0, K = unlimited:
|
|||
|
||||
U != 0, K < U:
|
||||
Kernel memory is a subset of the user memory. This setup is useful in
|
||||
deployments where the total amount of memory per-cgroup is overcommited.
|
||||
Overcommiting kernel memory limits is definitely not recommended, since the
|
||||
deployments where the total amount of memory per-cgroup is overcommitted.
|
||||
Overcommitting kernel memory limits is definitely not recommended, since the
|
||||
box can still run out of non-reclaimable memory.
|
||||
In this case, the admin could set up K so that the sum of all groups is
|
||||
never greater than the total memory, and freely set U at the cost of his
|
||||
|
@ -851,6 +851,9 @@ At reading, current status of OOM is shown.
|
|||
(if 1, oom-killer is disabled)
|
||||
- under_oom 0 or 1
|
||||
(if 1, the memory cgroup is under OOM, tasks may be stopped.)
|
||||
- oom_kill integer counter
|
||||
The number of processes belonging to this cgroup killed by any
|
||||
kind of OOM killer.
|
||||
|
||||
11. Memory Pressure
|
||||
===================
|
||||
|
|
|
@ -347,7 +347,7 @@ Examples
|
|||
<debugfs>/dynamic_debug/control
|
||||
|
||||
// enable messages in files of which the paths include string "usb"
|
||||
nullarbor:~ # echo -n '*usb* +p' > <debugfs>/dynamic_debug/control
|
||||
nullarbor:~ # echo -n 'file *usb* +p' > <debugfs>/dynamic_debug/control
|
||||
|
||||
// enable all messages
|
||||
nullarbor:~ # echo -n '+p' > <debugfs>/dynamic_debug/control
|
||||
|
|
|
@ -35,7 +35,6 @@ problems and bugs in particular.
|
|||
:maxdepth: 1
|
||||
|
||||
reporting-issues
|
||||
Reporting bugs (obsolete) <reporting-bugs>
|
||||
security-bugs
|
||||
bug-hunting
|
||||
bug-bisect
|
||||
|
|
|
@ -140,6 +140,7 @@ parameter is applicable::
|
|||
PPT Parallel port support is enabled.
|
||||
PS2 Appropriate PS/2 support is enabled.
|
||||
RAM RAM disk support is enabled.
|
||||
RISCV RISCV architecture is enabled.
|
||||
RDT Intel Resource Director Technology.
|
||||
S390 S390 architecture is enabled.
|
||||
SCSI Appropriate SCSI support is enabled.
|
||||
|
|
|
@ -3471,7 +3471,8 @@
|
|||
|
||||
nr_uarts= [SERIAL] maximum number of UARTs to be registered.
|
||||
|
||||
numa_balancing= [KNL,X86] Enable or disable automatic NUMA balancing.
|
||||
numa_balancing= [KNL,ARM64,PPC,RISCV,S390,X86] Enable or disable automatic
|
||||
NUMA balancing.
|
||||
Allowed values are enable and disable
|
||||
|
||||
numa_zonelist_order= [KNL, BOOT] Select zonelist order for NUMA.
|
||||
|
|
|
@ -332,23 +332,3 @@ To reduce its OS jitter, do at least one of the following:
|
|||
kthreads from being created in the first place. However, please
|
||||
note that this will not eliminate OS jitter, but will instead
|
||||
shift it to RCU_SOFTIRQ.
|
||||
|
||||
Name:
|
||||
watchdog/%u
|
||||
|
||||
Purpose:
|
||||
Detect software lockups on each CPU.
|
||||
|
||||
To reduce its OS jitter, do at least one of the following:
|
||||
|
||||
1. Build with CONFIG_LOCKUP_DETECTOR=n, which will prevent these
|
||||
kthreads from being created in the first place.
|
||||
2. Boot with "nosoftlockup=0", which will also prevent these kthreads
|
||||
from being created. Other related watchdog and softlockup boot
|
||||
parameters may be found in Documentation/admin-guide/kernel-parameters.rst
|
||||
and Documentation/watchdog/watchdog-parameters.rst.
|
||||
3. Echo a zero to /proc/sys/kernel/watchdog to disable the
|
||||
watchdog timer.
|
||||
4. Echo a large number of /proc/sys/kernel/watchdog_thresh in
|
||||
order to reduce the frequency of OS jitter due to the watchdog
|
||||
timer down to a level that is acceptable for your workload.
|
||||
|
|
|
@ -151,7 +151,7 @@ Each cache level's directory provides its attributes. For example, the
|
|||
following shows a single cache level and the attributes available for
|
||||
software to query::
|
||||
|
||||
# tree sys/devices/system/node/node0/memory_side_cache/
|
||||
# tree /sys/devices/system/node/node0/memory_side_cache/
|
||||
/sys/devices/system/node/node0/memory_side_cache/
|
||||
|-- index1
|
||||
| |-- indexing
|
||||
|
|
|
@ -1,187 +0,0 @@
|
|||
.. _reportingbugs:
|
||||
|
||||
.. note::
|
||||
|
||||
This document is obsolete, and will be replaced by
|
||||
'Documentation/admin-guide/reporting-issues.rst' in the near future.
|
||||
|
||||
Reporting bugs
|
||||
++++++++++++++
|
||||
|
||||
Background
|
||||
==========
|
||||
|
||||
The upstream Linux kernel maintainers only fix bugs for specific kernel
|
||||
versions. Those versions include the current "release candidate" (or -rc)
|
||||
kernel, any "stable" kernel versions, and any "long term" kernels.
|
||||
|
||||
Please see https://www.kernel.org/ for a list of supported kernels. Any
|
||||
kernel marked with [EOL] is "end of life" and will not have any fixes
|
||||
backported to it.
|
||||
|
||||
If you've found a bug on a kernel version that isn't listed on kernel.org,
|
||||
contact your Linux distribution or embedded vendor for support.
|
||||
Alternatively, you can attempt to run one of the supported stable or -rc
|
||||
kernels, and see if you can reproduce the bug on that. It's preferable
|
||||
to reproduce the bug on the latest -rc kernel.
|
||||
|
||||
|
||||
How to report Linux kernel bugs
|
||||
===============================
|
||||
|
||||
|
||||
Identify the problematic subsystem
|
||||
----------------------------------
|
||||
|
||||
Identifying which part of the Linux kernel might be causing your issue
|
||||
increases your chances of getting your bug fixed. Simply posting to the
|
||||
generic linux-kernel mailing list (LKML) may cause your bug report to be
|
||||
lost in the noise of a mailing list that gets 1000+ emails a day.
|
||||
|
||||
Instead, try to figure out which kernel subsystem is causing the issue,
|
||||
and email that subsystem's maintainer and mailing list. If the subsystem
|
||||
maintainer doesn't answer, then expand your scope to mailing lists like
|
||||
LKML.
|
||||
|
||||
|
||||
Identify who to notify
|
||||
----------------------
|
||||
|
||||
Once you know the subsystem that is causing the issue, you should send a
|
||||
bug report. Some maintainers prefer bugs to be reported via bugzilla
|
||||
(https://bugzilla.kernel.org), while others prefer that bugs be reported
|
||||
via the subsystem mailing list.
|
||||
|
||||
To find out where to send an emailed bug report, find your subsystem or
|
||||
device driver in the MAINTAINERS file. Search in the file for relevant
|
||||
entries, and send your bug report to the person(s) listed in the "M:"
|
||||
lines, making sure to Cc the mailing list(s) in the "L:" lines. When the
|
||||
maintainer replies to you, make sure to 'Reply-all' in order to keep the
|
||||
public mailing list(s) in the email thread.
|
||||
|
||||
If you know which driver is causing issues, you can pass one of the driver
|
||||
files to the get_maintainer.pl script::
|
||||
|
||||
perl scripts/get_maintainer.pl -f <filename>
|
||||
|
||||
If it is a security bug, please copy the Security Contact listed in the
|
||||
MAINTAINERS file. They can help coordinate bugfix and disclosure. See
|
||||
:ref:`Documentation/admin-guide/security-bugs.rst <securitybugs>` for more information.
|
||||
|
||||
If you can't figure out which subsystem caused the issue, you should file
|
||||
a bug in kernel.org bugzilla and send email to
|
||||
linux-kernel@vger.kernel.org, referencing the bugzilla URL. (For more
|
||||
information on the linux-kernel mailing list see
|
||||
http://vger.kernel.org/lkml/).
|
||||
|
||||
|
||||
Tips for reporting bugs
|
||||
-----------------------
|
||||
|
||||
If you haven't reported a bug before, please read:
|
||||
|
||||
https://www.chiark.greenend.org.uk/~sgtatham/bugs.html
|
||||
|
||||
http://www.catb.org/esr/faqs/smart-questions.html
|
||||
|
||||
It's REALLY important to report bugs that seem unrelated as separate email
|
||||
threads or separate bugzilla entries. If you report several unrelated
|
||||
bugs at once, it's difficult for maintainers to tease apart the relevant
|
||||
data.
|
||||
|
||||
|
||||
Gather information
|
||||
------------------
|
||||
|
||||
The most important information in a bug report is how to reproduce the
|
||||
bug. This includes system information, and (most importantly)
|
||||
step-by-step instructions for how a user can trigger the bug.
|
||||
|
||||
If the failure includes an "OOPS:", take a picture of the screen, capture
|
||||
a netconsole trace, or type the message from your screen into the bug
|
||||
report. Please read "Documentation/admin-guide/bug-hunting.rst" before posting your
|
||||
bug report. This explains what you should do with the "Oops" information
|
||||
to make it useful to the recipient.
|
||||
|
||||
This is a suggested format for a bug report sent via email or bugzilla.
|
||||
Having a standardized bug report form makes it easier for you not to
|
||||
overlook things, and easier for the developers to find the pieces of
|
||||
information they're really interested in. If some information is not
|
||||
relevant to your bug, feel free to exclude it.
|
||||
|
||||
First run the ver_linux script included as scripts/ver_linux, which
|
||||
reports the version of some important subsystems. Run this script with
|
||||
the command ``awk -f scripts/ver_linux``.
|
||||
|
||||
Use that information to fill in all fields of the bug report form, and
|
||||
post it to the mailing list with a subject of "PROBLEM: <one line
|
||||
summary from [1.]>" for easy identification by the developers::
|
||||
|
||||
[1.] One line summary of the problem:
|
||||
[2.] Full description of the problem/report:
|
||||
[3.] Keywords (i.e., modules, networking, kernel):
|
||||
[4.] Kernel information
|
||||
[4.1.] Kernel version (from /proc/version):
|
||||
[4.2.] Kernel .config file:
|
||||
[5.] Most recent kernel version which did not have the bug:
|
||||
[6.] Output of Oops.. message (if applicable) with symbolic information
|
||||
resolved (see Documentation/admin-guide/bug-hunting.rst)
|
||||
[7.] A small shell script or example program which triggers the
|
||||
problem (if possible)
|
||||
[8.] Environment
|
||||
[8.1.] Software (add the output of the ver_linux script here)
|
||||
[8.2.] Processor information (from /proc/cpuinfo):
|
||||
[8.3.] Module information (from /proc/modules):
|
||||
[8.4.] Loaded driver and hardware information (/proc/ioports, /proc/iomem)
|
||||
[8.5.] PCI information ('lspci -vvv' as root)
|
||||
[8.6.] SCSI information (from /proc/scsi/scsi)
|
||||
[8.7.] Other information that might be relevant to the problem
|
||||
(please look in /proc and include all information that you
|
||||
think to be relevant):
|
||||
[X.] Other notes, patches, fixes, workarounds:
|
||||
|
||||
|
||||
Follow up
|
||||
=========
|
||||
|
||||
Expectations for bug reporters
|
||||
------------------------------
|
||||
|
||||
Linux kernel maintainers expect bug reporters to be able to follow up on
|
||||
bug reports. That may include running new tests, applying patches,
|
||||
recompiling your kernel, and/or re-triggering your bug. The most
|
||||
frustrating thing for maintainers is for someone to report a bug, and then
|
||||
never follow up on a request to try out a fix.
|
||||
|
||||
That said, it's still useful for a kernel maintainer to know a bug exists
|
||||
on a supported kernel, even if you can't follow up with retests. Follow
|
||||
up reports, such as replying to the email thread with "I tried the latest
|
||||
kernel and I can't reproduce my bug anymore" are also helpful, because
|
||||
maintainers have to assume silence means things are still broken.
|
||||
|
||||
Expectations for kernel maintainers
|
||||
-----------------------------------
|
||||
|
||||
Linux kernel maintainers are busy, overworked human beings. Some times
|
||||
they may not be able to address your bug in a day, a week, or two weeks.
|
||||
If they don't answer your email, they may be on vacation, or at a Linux
|
||||
conference. Check the conference schedule at https://LWN.net for more info:
|
||||
|
||||
https://lwn.net/Calendar/
|
||||
|
||||
In general, kernel maintainers take 1 to 5 business days to respond to
|
||||
bugs. The majority of kernel maintainers are employed to work on the
|
||||
kernel, and they may not work on the weekends. Maintainers are scattered
|
||||
around the world, and they may not work in your time zone. Unless you
|
||||
have a high priority bug, please wait at least a week after the first bug
|
||||
report before sending the maintainer a reminder email.
|
||||
|
||||
The exceptions to this rule are regressions, kernel crashes, security holes,
|
||||
or userspace breakage caused by new kernel behavior. Those bugs should be
|
||||
addressed by the maintainers ASAP. If you suspect a maintainer is not
|
||||
responding to these types of bugs in a timely manner (especially during a
|
||||
merge window), escalate the bug to LKML and Linus Torvalds.
|
||||
|
||||
Thank you!
|
||||
|
||||
[Some of this is taken from Frohwalt Egerer's original linux-kernel FAQ]
|
File diff suppressed because it is too large
Load Diff
|
@ -90,8 +90,8 @@ Command Function
|
|||
``b`` Will immediately reboot the system without syncing or unmounting
|
||||
your disks.
|
||||
|
||||
``c`` Will perform a system crash by a NULL pointer dereference.
|
||||
A crashdump will be taken if configured.
|
||||
``c`` Will perform a system crash and a crashdump will be taken
|
||||
if configured.
|
||||
|
||||
``d`` Shows all locks that are held.
|
||||
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
CPU Architectures
|
||||
=================
|
||||
|
||||
These books provide programming details about architecture-specific
|
||||
implementation.
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
arm/index
|
||||
arm64/index
|
||||
ia64/index
|
||||
m68k/index
|
||||
mips/index
|
||||
nios2/index
|
||||
openrisc/index
|
||||
parisc/index
|
||||
powerpc/index
|
||||
riscv/index
|
||||
s390/index
|
||||
sh/index
|
||||
sparc/index
|
||||
x86/index
|
||||
xtensa/index
|
|
@ -18,12 +18,12 @@ Orion family
|
|||
- 88F5181L
|
||||
- 88F5182
|
||||
|
||||
- Datasheet: http://www.embeddedarm.com/documentation/third-party/MV88F5182-datasheet.pdf
|
||||
- Programmer's User Guide: http://www.embeddedarm.com/documentation/third-party/MV88F5182-opensource-manual.pdf
|
||||
- User Manual: http://www.embeddedarm.com/documentation/third-party/MV88F5182-usermanual.pdf
|
||||
- Datasheet: https://web.archive.org/web/20210124231420/http://csclub.uwaterloo.ca/~board/ts7800/MV88F5182-datasheet.pdf
|
||||
- Programmer's User Guide: https://web.archive.org/web/20210124231536/http://csclub.uwaterloo.ca/~board/ts7800/MV88F5182-opensource-manual.pdf
|
||||
- User Manual: https://web.archive.org/web/20210124231631/http://csclub.uwaterloo.ca/~board/ts7800/MV88F5182-usermanual.pdf
|
||||
- 88F5281
|
||||
|
||||
- Datasheet: http://www.ocmodshop.com/images/reviews/networking/qnap_ts409u/marvel_88f5281_data_sheet.pdf
|
||||
- Datasheet: https://web.archive.org/web/20131028144728/http://www.ocmodshop.com/images/reviews/networking/qnap_ts409u/marvel_88f5281_data_sheet.pdf
|
||||
- 88F6183
|
||||
Core:
|
||||
Feroceon 88fr331 (88f51xx) or 88fr531-vd (88f52xx) ARMv5 compatible
|
||||
|
@ -38,33 +38,33 @@ Kirkwood family
|
|||
Flavors:
|
||||
- 88F6282 a.k.a Armada 300
|
||||
|
||||
- Product Brief : http://www.marvell.com/embedded-processors/armada-300/assets/armada_310.pdf
|
||||
- Product Brief : https://web.archive.org/web/20111027032509/http://www.marvell.com/embedded-processors/armada-300/assets/armada_310.pdf
|
||||
- 88F6283 a.k.a Armada 310
|
||||
|
||||
- Product Brief : http://www.marvell.com/embedded-processors/armada-300/assets/armada_310.pdf
|
||||
- Product Brief : https://web.archive.org/web/20111027032509/http://www.marvell.com/embedded-processors/armada-300/assets/armada_310.pdf
|
||||
- 88F6190
|
||||
|
||||
- Product Brief : http://www.marvell.com/embedded-processors/kirkwood/assets/88F6190-003_WEB.pdf
|
||||
- Hardware Spec : http://www.marvell.com/embedded-processors/kirkwood/assets/HW_88F619x_OpenSource.pdf
|
||||
- Functional Spec: http://www.marvell.com/embedded-processors/kirkwood/assets/FS_88F6180_9x_6281_OpenSource.pdf
|
||||
- Product Brief : https://web.archive.org/web/20130730072715/http://www.marvell.com/embedded-processors/kirkwood/assets/88F6190-003_WEB.pdf
|
||||
- Hardware Spec : https://web.archive.org/web/20121021182835/http://www.marvell.com/embedded-processors/kirkwood/assets/HW_88F619x_OpenSource.pdf
|
||||
- Functional Spec: https://web.archive.org/web/20130730091033/http://www.marvell.com/embedded-processors/kirkwood/assets/FS_88F6180_9x_6281_OpenSource.pdf
|
||||
- 88F6192
|
||||
|
||||
- Product Brief : http://www.marvell.com/embedded-processors/kirkwood/assets/88F6192-003_ver1.pdf
|
||||
- Hardware Spec : http://www.marvell.com/embedded-processors/kirkwood/assets/HW_88F619x_OpenSource.pdf
|
||||
- Functional Spec: http://www.marvell.com/embedded-processors/kirkwood/assets/FS_88F6180_9x_6281_OpenSource.pdf
|
||||
- Product Brief : https://web.archive.org/web/20131113121446/http://www.marvell.com/embedded-processors/kirkwood/assets/88F6192-003_ver1.pdf
|
||||
- Hardware Spec : https://web.archive.org/web/20121021182835/http://www.marvell.com/embedded-processors/kirkwood/assets/HW_88F619x_OpenSource.pdf
|
||||
- Functional Spec: https://web.archive.org/web/20130730091033/http://www.marvell.com/embedded-processors/kirkwood/assets/FS_88F6180_9x_6281_OpenSource.pdf
|
||||
- 88F6182
|
||||
- 88F6180
|
||||
|
||||
- Product Brief : http://www.marvell.com/embedded-processors/kirkwood/assets/88F6180-003_ver1.pdf
|
||||
- Hardware Spec : http://www.marvell.com/embedded-processors/kirkwood/assets/HW_88F6180_OpenSource.pdf
|
||||
- Functional Spec: http://www.marvell.com/embedded-processors/kirkwood/assets/FS_88F6180_9x_6281_OpenSource.pdf
|
||||
- Product Brief : https://web.archive.org/web/20120616201621/http://www.marvell.com/embedded-processors/kirkwood/assets/88F6180-003_ver1.pdf
|
||||
- Hardware Spec : https://web.archive.org/web/20130730091654/http://www.marvell.com/embedded-processors/kirkwood/assets/HW_88F6180_OpenSource.pdf
|
||||
- Functional Spec: https://web.archive.org/web/20130730091033/http://www.marvell.com/embedded-processors/kirkwood/assets/FS_88F6180_9x_6281_OpenSource.pdf
|
||||
- 88F6281
|
||||
|
||||
- Product Brief : http://www.marvell.com/embedded-processors/kirkwood/assets/88F6281-004_ver1.pdf
|
||||
- Hardware Spec : http://www.marvell.com/embedded-processors/kirkwood/assets/HW_88F6281_OpenSource.pdf
|
||||
- Functional Spec: http://www.marvell.com/embedded-processors/kirkwood/assets/FS_88F6180_9x_6281_OpenSource.pdf
|
||||
- Product Brief : https://web.archive.org/web/20120131133709/http://www.marvell.com/embedded-processors/kirkwood/assets/88F6281-004_ver1.pdf
|
||||
- Hardware Spec : https://web.archive.org/web/20120620073511/http://www.marvell.com/embedded-processors/kirkwood/assets/HW_88F6281_OpenSource.pdf
|
||||
- Functional Spec: https://web.archive.org/web/20130730091033/http://www.marvell.com/embedded-processors/kirkwood/assets/FS_88F6180_9x_6281_OpenSource.pdf
|
||||
Homepage:
|
||||
http://www.marvell.com/embedded-processors/kirkwood/
|
||||
https://web.archive.org/web/20160513194943/http://www.marvell.com/embedded-processors/kirkwood/
|
||||
Core:
|
||||
Feroceon 88fr131 ARMv5 compatible
|
||||
Linux kernel mach directory:
|
||||
|
@ -78,14 +78,15 @@ Discovery family
|
|||
Flavors:
|
||||
- MV78100
|
||||
|
||||
- Product Brief : http://www.marvell.com/embedded-processors/discovery-innovation/assets/MV78100-003_WEB.pdf
|
||||
- Hardware Spec : http://www.marvell.com/embedded-processors/discovery-innovation/assets/HW_MV78100_OpenSource.pdf
|
||||
- Functional Spec: http://www.marvell.com/embedded-processors/discovery-innovation/assets/FS_MV76100_78100_78200_OpenSource.pdf
|
||||
- Product Brief : https://web.archive.org/web/20120616194711/http://www.marvell.com/embedded-processors/discovery-innovation/assets/MV78100-003_WEB.pdf
|
||||
- Hardware Spec : https://web.archive.org/web/20141005120451/http://www.marvell.com/embedded-processors/discovery-innovation/assets/HW_MV78100_OpenSource.pdf
|
||||
- Functional Spec: https://web.archive.org/web/20111110081125/http://www.marvell.com/embedded-processors/discovery-innovation/assets/FS_MV76100_78100_78200_OpenSource.pdf
|
||||
- MV78200
|
||||
|
||||
- Product Brief : http://www.marvell.com/embedded-processors/discovery-innovation/assets/MV78200-002_WEB.pdf
|
||||
- Hardware Spec : http://www.marvell.com/embedded-processors/discovery-innovation/assets/HW_MV78200_OpenSource.pdf
|
||||
- Functional Spec: http://www.marvell.com/embedded-processors/discovery-innovation/assets/FS_MV76100_78100_78200_OpenSource.pdf
|
||||
- Product Brief : https://web.archive.org/web/20140801121623/http://www.marvell.com/embedded-processors/discovery-innovation/assets/MV78200-002_WEB.pdf
|
||||
- Hardware Spec : https://web.archive.org/web/20141005120458/http://www.marvell.com/embedded-processors/discovery-innovation/assets/HW_MV78200_OpenSource.pdf
|
||||
- Functional Spec: https://web.archive.org/web/20111110081125/http://www.marvell.com/embedded-processors/discovery-innovation/assets/FS_MV76100_78100_78200_OpenSource.pdf
|
||||
|
||||
- MV76100
|
||||
|
||||
Not supported by the Linux kernel.
|
||||
|
@ -106,9 +107,9 @@ EBU Armada family
|
|||
- 88F6707
|
||||
- 88F6W11
|
||||
|
||||
- Product Brief: http://www.marvell.com/embedded-processors/armada-300/assets/Marvell_ARMADA_370_SoC.pdf
|
||||
- Hardware Spec: http://www.marvell.com/embedded-processors/armada-300/assets/ARMADA370-datasheet.pdf
|
||||
- Functional Spec: http://www.marvell.com/embedded-processors/armada-300/assets/ARMADA370-FunctionalSpec-datasheet.pdf
|
||||
- Product Brief: https://web.archive.org/web/20121115063038/http://www.marvell.com/embedded-processors/armada-300/assets/Marvell_ARMADA_370_SoC.pdf
|
||||
- Hardware Spec: https://web.archive.org/web/20140617183747/http://www.marvell.com/embedded-processors/armada-300/assets/ARMADA370-datasheet.pdf
|
||||
- Functional Spec: https://web.archive.org/web/20140617183701/http://www.marvell.com/embedded-processors/armada-300/assets/ARMADA370-FunctionalSpec-datasheet.pdf
|
||||
|
||||
Core:
|
||||
Sheeva ARMv7 compatible PJ4B
|
||||
|
@ -116,7 +117,7 @@ EBU Armada family
|
|||
Armada 375 Flavors:
|
||||
- 88F6720
|
||||
|
||||
- Product Brief: http://www.marvell.com/embedded-processors/armada-300/assets/ARMADA_375_SoC-01_product_brief.pdf
|
||||
- Product Brief: https://web.archive.org/web/20131216023516/http://www.marvell.com/embedded-processors/armada-300/assets/ARMADA_375_SoC-01_product_brief.pdf
|
||||
|
||||
Core:
|
||||
ARM Cortex-A9
|
||||
|
@ -126,8 +127,8 @@ EBU Armada family
|
|||
- 88F6820 Armada 385
|
||||
- 88F6828 Armada 388
|
||||
|
||||
- Product infos: http://www.marvell.com/embedded-processors/armada-38x/
|
||||
- Functional Spec: http://www.marvell.com/content/dam/marvell/en/public-collateral/embedded-processors/marvell-embedded-processors-armada-38x-functional-specifications-2015-11.pdf
|
||||
- Product infos: https://web.archive.org/web/20181006144616/http://www.marvell.com/embedded-processors/armada-38x/
|
||||
- Functional Spec: https://web.archive.org/web/20200420191927/https://www.marvell.com/content/dam/marvell/en/public-collateral/embedded-processors/marvell-embedded-processors-armada-38x-functional-specifications-2015-11.pdf
|
||||
|
||||
Core:
|
||||
ARM Cortex-A9
|
||||
|
@ -136,7 +137,7 @@ EBU Armada family
|
|||
- 88F6920 Armada 390
|
||||
- 88F6928 Armada 398
|
||||
|
||||
- Product infos: http://www.marvell.com/embedded-processors/armada-39x/
|
||||
- Product infos: https://web.archive.org/web/20181020222559/http://www.marvell.com/embedded-processors/armada-39x/
|
||||
|
||||
Core:
|
||||
ARM Cortex-A9
|
||||
|
@ -150,16 +151,16 @@ EBU Armada family
|
|||
not to be confused with the non-SMP 78xx0 SoCs
|
||||
|
||||
Product Brief:
|
||||
http://www.marvell.com/embedded-processors/armada-xp/assets/Marvell-ArmadaXP-SoC-product%20brief.pdf
|
||||
https://web.archive.org/web/20121021173528/http://www.marvell.com/embedded-processors/armada-xp/assets/Marvell-ArmadaXP-SoC-product%20brief.pdf
|
||||
|
||||
Functional Spec:
|
||||
http://www.marvell.com/embedded-processors/armada-xp/assets/ARMADA-XP-Functional-SpecDatasheet.pdf
|
||||
https://web.archive.org/web/20180829171131/http://www.marvell.com/embedded-processors/armada-xp/assets/ARMADA-XP-Functional-SpecDatasheet.pdf
|
||||
|
||||
- Hardware Specs:
|
||||
|
||||
- http://www.marvell.com/embedded-processors/armada-xp/assets/HW_MV78230_OS.PDF
|
||||
- http://www.marvell.com/embedded-processors/armada-xp/assets/HW_MV78260_OS.PDF
|
||||
- http://www.marvell.com/embedded-processors/armada-xp/assets/HW_MV78460_OS.PDF
|
||||
- https://web.archive.org/web/20141127013651/http://www.marvell.com/embedded-processors/armada-xp/assets/HW_MV78230_OS.PDF
|
||||
- https://web.archive.org/web/20141222000224/http://www.marvell.com/embedded-processors/armada-xp/assets/HW_MV78260_OS.PDF
|
||||
- https://web.archive.org/web/20141222000230/http://www.marvell.com/embedded-processors/armada-xp/assets/HW_MV78460_OS.PDF
|
||||
|
||||
Core:
|
||||
Sheeva ARMv7 compatible Dual-core or Quad-core PJ4B-MP
|
||||
|
@ -180,13 +181,13 @@ EBU Armada family ARMv8
|
|||
ARM Cortex A53 (ARMv8)
|
||||
|
||||
Homepage:
|
||||
http://www.marvell.com/embedded-processors/armada-3700/
|
||||
https://web.archive.org/web/20181103003602/http://www.marvell.com/embedded-processors/armada-3700/
|
||||
|
||||
Product Brief:
|
||||
http://www.marvell.com/content/dam/marvell/en/public-collateral/embedded-processors/marvell-embedded-processors-armada-37xx-product-brief-2016-01.pdf
|
||||
https://web.archive.org/web/20210121194810/https://www.marvell.com/content/dam/marvell/en/public-collateral/embedded-processors/marvell-embedded-processors-armada-37xx-product-brief-2016-01.pdf
|
||||
|
||||
Hardware Spec:
|
||||
http://www.marvell.com/content/dam/marvell/en/public-collateral/embedded-processors/marvell-embedded-processors-armada-37xx-hardware-specifications-2019-09.pdf
|
||||
https://web.archive.org/web/20210202162011/http://www.marvell.com/content/dam/marvell/en/public-collateral/embedded-processors/marvell-embedded-processors-armada-37xx-hardware-specifications-2019-09.pdf
|
||||
|
||||
Device tree files:
|
||||
arch/arm64/boot/dts/marvell/armada-37*
|
||||
|
@ -198,11 +199,11 @@ EBU Armada family ARMv8
|
|||
Core: ARM Cortex A72
|
||||
|
||||
Homepage:
|
||||
http://www.marvell.com/embedded-processors/armada-70xx/
|
||||
https://web.archive.org/web/20181020222606/http://www.marvell.com/embedded-processors/armada-70xx/
|
||||
|
||||
Product Brief:
|
||||
- http://www.marvell.com/embedded-processors/assets/Armada7020PB-Jan2016.pdf
|
||||
- http://www.marvell.com/embedded-processors/assets/Armada7040PB-Jan2016.pdf
|
||||
- https://web.archive.org/web/20161010105541/http://www.marvell.com/embedded-processors/assets/Armada7020PB-Jan2016.pdf
|
||||
- https://web.archive.org/web/20160928154533/http://www.marvell.com/embedded-processors/assets/Armada7040PB-Jan2016.pdf
|
||||
|
||||
Device tree files:
|
||||
arch/arm64/boot/dts/marvell/armada-70*
|
||||
|
@ -214,11 +215,11 @@ EBU Armada family ARMv8
|
|||
ARM Cortex A72
|
||||
|
||||
Homepage:
|
||||
http://www.marvell.com/embedded-processors/armada-80xx/
|
||||
https://web.archive.org/web/20181022004830/http://www.marvell.com/embedded-processors/armada-80xx/
|
||||
|
||||
Product Brief:
|
||||
- http://www.marvell.com/embedded-processors/assets/Armada8020PB-Jan2016.pdf
|
||||
- http://www.marvell.com/embedded-processors/assets/Armada8040PB-Jan2016.pdf
|
||||
- https://web.archive.org/web/20210124233728/https://www.marvell.com/content/dam/marvell/en/public-collateral/embedded-processors/marvell-embedded-processors-armada-8020-product-brief-2017-12.pdf
|
||||
- https://web.archive.org/web/20161010105532/http://www.marvell.com/embedded-processors/assets/Armada8040PB-Jan2016.pdf
|
||||
|
||||
Device tree files:
|
||||
arch/arm64/boot/dts/marvell/armada-80*
|
||||
|
@ -233,10 +234,10 @@ Avanta family
|
|||
- 88F6560
|
||||
|
||||
Homepage:
|
||||
http://www.marvell.com/broadband/
|
||||
https://web.archive.org/web/20181005145041/http://www.marvell.com/broadband/
|
||||
|
||||
Product Brief:
|
||||
http://www.marvell.com/broadband/assets/Marvell_Avanta_88F6510_305_060-001_product_brief.pdf
|
||||
https://web.archive.org/web/20180829171057/http://www.marvell.com/broadband/assets/Marvell_Avanta_88F6510_305_060-001_product_brief.pdf
|
||||
|
||||
No public datasheet available.
|
||||
|
||||
|
@ -255,7 +256,7 @@ Storage family
|
|||
- 88RC1580
|
||||
|
||||
Product infos:
|
||||
http://www.marvell.com/storage/armada-sp/
|
||||
https://web.archive.org/web/20191129073953/http://www.marvell.com/storage/armada-sp/
|
||||
|
||||
Core:
|
||||
Sheeva ARMv7 comatible Quad-core PJ4C
|
||||
|
@ -269,16 +270,16 @@ Dove family (application processor)
|
|||
- 88AP510 a.k.a Armada 510
|
||||
|
||||
Product Brief:
|
||||
http://www.marvell.com/application-processors/armada-500/assets/Marvell_Armada510_SoC.pdf
|
||||
https://web.archive.org/web/20111102020643/http://www.marvell.com/application-processors/armada-500/assets/Marvell_Armada510_SoC.pdf
|
||||
|
||||
Hardware Spec:
|
||||
http://www.marvell.com/application-processors/armada-500/assets/Armada-510-Hardware-Spec.pdf
|
||||
https://web.archive.org/web/20160428160231/http://www.marvell.com/application-processors/armada-500/assets/Armada-510-Hardware-Spec.pdf
|
||||
|
||||
Functional Spec:
|
||||
http://www.marvell.com/application-processors/armada-500/assets/Armada-510-Functional-Spec.pdf
|
||||
https://web.archive.org/web/20120130172443/http://www.marvell.com/application-processors/armada-500/assets/Armada-510-Functional-Spec.pdf
|
||||
|
||||
Homepage:
|
||||
http://www.marvell.com/application-processors/armada-500/
|
||||
https://web.archive.org/web/20160822232651/http://www.marvell.com/application-processors/armada-500/
|
||||
|
||||
Core:
|
||||
ARMv7 compatible
|
||||
|
@ -295,22 +296,22 @@ PXA 2xx/3xx/93x/95x family
|
|||
- Application processor only
|
||||
- Core: ARMv5 XScale1 core
|
||||
- PXA270, PXA271, PXA272
|
||||
- Product Brief : http://www.marvell.com/application-processors/pxa-family/assets/pxa_27x_pb.pdf
|
||||
- Design guide : http://www.marvell.com/application-processors/pxa-family/assets/pxa_27x_design_guide.pdf
|
||||
- Developers manual : http://www.marvell.com/application-processors/pxa-family/assets/pxa_27x_dev_man.pdf
|
||||
- Specification : http://www.marvell.com/application-processors/pxa-family/assets/pxa_27x_emts.pdf
|
||||
- Specification update : http://www.marvell.com/application-processors/pxa-family/assets/pxa_27x_spec_update.pdf
|
||||
- Product Brief : https://web.archive.org/web/20150927135510/http://www.marvell.com/application-processors/pxa-family/assets/pxa_27x_pb.pdf
|
||||
- Design guide : https://web.archive.org/web/20120111181937/http://www.marvell.com/application-processors/pxa-family/assets/pxa_27x_design_guide.pdf
|
||||
- Developers manual : https://web.archive.org/web/20150927164805/http://www.marvell.com/application-processors/pxa-family/assets/pxa_27x_dev_man.pdf
|
||||
- Specification : https://web.archive.org/web/20140211221535/http://www.marvell.com/application-processors/pxa-family/assets/pxa_27x_emts.pdf
|
||||
- Specification update : https://web.archive.org/web/20120111104906/http://www.marvell.com/application-processors/pxa-family/assets/pxa_27x_spec_update.pdf
|
||||
- Application processor only
|
||||
- Core: ARMv5 XScale2 core
|
||||
- PXA300, PXA310, PXA320
|
||||
- PXA 300 Product Brief : http://www.marvell.com/application-processors/pxa-family/assets/PXA300_PB_R4.pdf
|
||||
- PXA 310 Product Brief : http://www.marvell.com/application-processors/pxa-family/assets/PXA310_PB_R4.pdf
|
||||
- PXA 320 Product Brief : http://www.marvell.com/application-processors/pxa-family/assets/PXA320_PB_R4.pdf
|
||||
- Design guide : http://www.marvell.com/application-processors/pxa-family/assets/PXA3xx_Design_Guide.pdf
|
||||
- Developers manual : http://www.marvell.com/application-processors/pxa-family/assets/PXA3xx_Developers_Manual.zip
|
||||
- Specifications : http://www.marvell.com/application-processors/pxa-family/assets/PXA3xx_EMTS.pdf
|
||||
- Specification Update : http://www.marvell.com/application-processors/pxa-family/assets/PXA3xx_Spec_Update.zip
|
||||
- Reference Manual : http://www.marvell.com/application-processors/pxa-family/assets/PXA3xx_TavorP_BootROM_Ref_Manual.pdf
|
||||
- PXA 300 Product Brief : https://web.archive.org/web/20120111121203/http://www.marvell.com/application-processors/pxa-family/assets/PXA300_PB_R4.pdf
|
||||
- PXA 310 Product Brief : https://web.archive.org/web/20120111104515/http://www.marvell.com/application-processors/pxa-family/assets/PXA310_PB_R4.pdf
|
||||
- PXA 320 Product Brief : https://web.archive.org/web/20121021182826/http://www.marvell.com/application-processors/pxa-family/assets/PXA320_PB_R4.pdf
|
||||
- Design guide : https://web.archive.org/web/20130727144625/http://www.marvell.com/application-processors/pxa-family/assets/PXA3xx_Design_Guide.pdf
|
||||
- Developers manual : https://web.archive.org/web/20130727144605/http://www.marvell.com/application-processors/pxa-family/assets/PXA3xx_Developers_Manual.zip
|
||||
- Specifications : https://web.archive.org/web/20130727144559/http://www.marvell.com/application-processors/pxa-family/assets/PXA3xx_EMTS.pdf
|
||||
- Specification Update : https://web.archive.org/web/20150927183411/http://www.marvell.com/application-processors/pxa-family/assets/PXA3xx_Spec_Update.zip
|
||||
- Reference Manual : https://web.archive.org/web/20120111103844/http://www.marvell.com/application-processors/pxa-family/assets/PXA3xx_TavorP_BootROM_Ref_Manual.pdf
|
||||
- Application processor only
|
||||
- Core: ARMv5 XScale3 core
|
||||
- PXA930, PXA935
|
||||
|
@ -341,26 +342,26 @@ MMP/MMP2/MMP3 family (communication processor)
|
|||
|
||||
Flavors:
|
||||
- PXA168, a.k.a Armada 168
|
||||
- Homepage : http://www.marvell.com/application-processors/armada-100/armada-168.jsp
|
||||
- Product brief : http://www.marvell.com/application-processors/armada-100/assets/pxa_168_pb.pdf
|
||||
- Hardware manual : http://www.marvell.com/application-processors/armada-100/assets/armada_16x_datasheet.pdf
|
||||
- Software manual : http://www.marvell.com/application-processors/armada-100/assets/armada_16x_software_manual.pdf
|
||||
- Specification update : http://www.marvell.com/application-processors/armada-100/assets/ARMADA16x_Spec_update.pdf
|
||||
- Boot ROM manual : http://www.marvell.com/application-processors/armada-100/assets/armada_16x_ref_manual.pdf
|
||||
- App node package : http://www.marvell.com/application-processors/armada-100/assets/armada_16x_app_note_package.pdf
|
||||
- Homepage : https://web.archive.org/web/20110926014256/http://www.marvell.com/application-processors/armada-100/armada-168.jsp
|
||||
- Product brief : https://web.archive.org/web/20111102030100/http://www.marvell.com/application-processors/armada-100/assets/pxa_168_pb.pdf
|
||||
- Hardware manual : https://web.archive.org/web/20160428165359/http://www.marvell.com/application-processors/armada-100/assets/armada_16x_datasheet.pdf
|
||||
- Software manual : https://web.archive.org/web/20160428154454/http://www.marvell.com/application-processors/armada-100/assets/armada_16x_software_manual.pdf
|
||||
- Specification update : https://web.archive.org/web/20150927160338/http://www.marvell.com/application-processors/armada-100/assets/ARMADA16x_Spec_update.pdf
|
||||
- Boot ROM manual : https://web.archive.org/web/20130727205559/http://www.marvell.com/application-processors/armada-100/assets/armada_16x_ref_manual.pdf
|
||||
- App node package : https://web.archive.org/web/20141005090706/http://www.marvell.com/application-processors/armada-100/assets/armada_16x_app_note_package.pdf
|
||||
- Application processor only
|
||||
- Core: ARMv5 compatible Marvell PJ1 88sv331 (Mohawk)
|
||||
- PXA910/PXA920
|
||||
- Homepage : http://www.marvell.com/communication-processors/pxa910/
|
||||
- Product Brief : http://www.marvell.com/communication-processors/pxa910/assets/Marvell_PXA910_Platform-001_PB_final.pdf
|
||||
- Homepage : https://web.archive.org/web/20150928121236/http://www.marvell.com/communication-processors/pxa910/
|
||||
- Product Brief : https://archive.org/download/marvell-pxa910-pb/Marvell_PXA910_Platform-001_PB.pdf
|
||||
- Application processor with Communication processor
|
||||
- Core: ARMv5 compatible Marvell PJ1 88sv331 (Mohawk)
|
||||
- PXA688, a.k.a. MMP2, a.k.a Armada 610
|
||||
- Product Brief : http://www.marvell.com/application-processors/armada-600/assets/armada610_pb.pdf
|
||||
- PXA688, a.k.a. MMP2, a.k.a Armada 610 (OLPC XO-1.75)
|
||||
- Product Brief : https://web.archive.org/web/20111102023255/http://www.marvell.com/application-processors/armada-600/assets/armada610_pb.pdf
|
||||
- Application processor only
|
||||
- Core: ARMv7 compatible Sheeva PJ4 88sv581x core
|
||||
- PXA2128, a.k.a. MMP3 (OLPC XO4, Linux support not upstream)
|
||||
- Product Brief : http://www.marvell.com/application-processors/armada/pxa2128/assets/Marvell-ARMADA-PXA2128-SoC-PB.pdf
|
||||
- PXA2128, a.k.a. MMP3, a.k.a Armada 620 (OLPC XO-4)
|
||||
- Product Brief : https://web.archive.org/web/20120824055155/http://www.marvell.com/application-processors/armada/pxa2128/assets/Marvell-ARMADA-PXA2128-SoC-PB.pdf
|
||||
- Application processor only
|
||||
- Core: Dual-core ARMv7 compatible Sheeva PJ4C core
|
||||
- PXA960/PXA968/PXA978 (Linux support not upstream)
|
||||
|
|
|
@ -64,4 +64,11 @@ linux,uefi-mmap-desc-size 32-bit Size in bytes of each entry in the UEFI
|
|||
memory map.
|
||||
|
||||
linux,uefi-mmap-desc-ver 32-bit Version of the mmap descriptor format.
|
||||
|
||||
linux,initrd-start 64-bit Physical start address of an initrd
|
||||
|
||||
linux,initrd-end 64-bit Physical end address of an initrd
|
||||
|
||||
kaslr-seed 64-bit Entropy used to randomize the kernel image
|
||||
base address location.
|
||||
========================== ====== ===========================================
|
||||
|
|
|
@ -331,27 +331,34 @@ htmlhelp_basename = 'TheLinuxKerneldoc'
|
|||
# -- Options for LaTeX output ---------------------------------------------
|
||||
|
||||
latex_elements = {
|
||||
# The paper size ('letterpaper' or 'a4paper').
|
||||
'papersize': 'a4paper',
|
||||
# The paper size ('letterpaper' or 'a4paper').
|
||||
'papersize': 'a4paper',
|
||||
|
||||
# The font size ('10pt', '11pt' or '12pt').
|
||||
'pointsize': '11pt',
|
||||
# The font size ('10pt', '11pt' or '12pt').
|
||||
'pointsize': '11pt',
|
||||
|
||||
# Latex figure (float) alignment
|
||||
#'figure_align': 'htbp',
|
||||
# Latex figure (float) alignment
|
||||
#'figure_align': 'htbp',
|
||||
|
||||
# Don't mangle with UTF-8 chars
|
||||
'inputenc': '',
|
||||
'utf8extra': '',
|
||||
# Don't mangle with UTF-8 chars
|
||||
'inputenc': '',
|
||||
'utf8extra': '',
|
||||
|
||||
# Additional stuff for the LaTeX preamble.
|
||||
# Set document margins
|
||||
'sphinxsetup': '''
|
||||
hmargin=0.5in, vmargin=1in,
|
||||
parsedliteralwraps=true,
|
||||
verbatimhintsturnover=false,
|
||||
''',
|
||||
|
||||
# Additional stuff for the LaTeX preamble.
|
||||
'preamble': '''
|
||||
% Use some font with UTF-8 support with XeLaTeX
|
||||
% Use some font with UTF-8 support with XeLaTeX
|
||||
\\usepackage{fontspec}
|
||||
\\setsansfont{DejaVu Sans}
|
||||
\\setromanfont{DejaVu Serif}
|
||||
\\setmonofont{DejaVu Sans Mono}
|
||||
'''
|
||||
''',
|
||||
}
|
||||
|
||||
# At least one book (translations) may have Asian characters
|
||||
|
|
|
@ -201,7 +201,7 @@ search trees, such as for traversals or users relying on a the particular
|
|||
order for their own logic. To this end, users can use 'struct rb_root_cached'
|
||||
to optimize O(logN) rb_first() calls to a simple pointer fetch avoiding
|
||||
potentially expensive tree iterations. This is done at negligible runtime
|
||||
overhead for maintanence; albeit larger memory footprint.
|
||||
overhead for maintenance; albeit larger memory footprint.
|
||||
|
||||
Similar to the rb_root structure, cached rbtrees are initialized to be
|
||||
empty via::
|
||||
|
|
|
@ -0,0 +1,755 @@
|
|||
.. SPDX-License-Identifier: GPL-2.0-only
|
||||
|
||||
==========
|
||||
Checkpatch
|
||||
==========
|
||||
|
||||
Checkpatch (scripts/checkpatch.pl) is a perl script which checks for trivial
|
||||
style violations in patches and optionally corrects them. Checkpatch can
|
||||
also be run on file contexts and without the kernel tree.
|
||||
|
||||
Checkpatch is not always right. Your judgement takes precedence over checkpatch
|
||||
messages. If your code looks better with the violations, then its probably
|
||||
best left alone.
|
||||
|
||||
|
||||
Options
|
||||
=======
|
||||
|
||||
This section will describe the options checkpatch can be run with.
|
||||
|
||||
Usage::
|
||||
|
||||
./scripts/checkpatch.pl [OPTION]... [FILE]...
|
||||
|
||||
Available options:
|
||||
|
||||
- -q, --quiet
|
||||
|
||||
Enable quiet mode.
|
||||
|
||||
- -v, --verbose
|
||||
Enable verbose mode. Additional verbose test descriptions are output
|
||||
so as to provide information on why that particular message is shown.
|
||||
|
||||
- --no-tree
|
||||
|
||||
Run checkpatch without the kernel tree.
|
||||
|
||||
- --no-signoff
|
||||
|
||||
Disable the 'Signed-off-by' line check. The sign-off is a simple line at
|
||||
the end of the explanation for the patch, which certifies that you wrote it
|
||||
or otherwise have the right to pass it on as an open-source patch.
|
||||
|
||||
Example::
|
||||
|
||||
Signed-off-by: Random J Developer <random@developer.example.org>
|
||||
|
||||
Setting this flag effectively stops a message for a missing signed-off-by
|
||||
line in a patch context.
|
||||
|
||||
- --patch
|
||||
|
||||
Treat FILE as a patch. This is the default option and need not be
|
||||
explicitly specified.
|
||||
|
||||
- --emacs
|
||||
|
||||
Set output to emacs compile window format. This allows emacs users to jump
|
||||
from the error in the compile window directly to the offending line in the
|
||||
patch.
|
||||
|
||||
- --terse
|
||||
|
||||
Output only one line per report.
|
||||
|
||||
- --showfile
|
||||
|
||||
Show the diffed file position instead of the input file position.
|
||||
|
||||
- -g, --git
|
||||
|
||||
Treat FILE as a single commit or a git revision range.
|
||||
|
||||
Single commit with:
|
||||
|
||||
- <rev>
|
||||
- <rev>^
|
||||
- <rev>~n
|
||||
|
||||
Multiple commits with:
|
||||
|
||||
- <rev1>..<rev2>
|
||||
- <rev1>...<rev2>
|
||||
- <rev>-<count>
|
||||
|
||||
- -f, --file
|
||||
|
||||
Treat FILE as a regular source file. This option must be used when running
|
||||
checkpatch on source files in the kernel.
|
||||
|
||||
- --subjective, --strict
|
||||
|
||||
Enable stricter tests in checkpatch. By default the tests emitted as CHECK
|
||||
do not activate by default. Use this flag to activate the CHECK tests.
|
||||
|
||||
- --list-types
|
||||
|
||||
Every message emitted by checkpatch has an associated TYPE. Add this flag
|
||||
to display all the types in checkpatch.
|
||||
|
||||
Note that when this flag is active, checkpatch does not read the input FILE,
|
||||
and no message is emitted. Only a list of types in checkpatch is output.
|
||||
|
||||
- --types TYPE(,TYPE2...)
|
||||
|
||||
Only display messages with the given types.
|
||||
|
||||
Example::
|
||||
|
||||
./scripts/checkpatch.pl mypatch.patch --types EMAIL_SUBJECT,BRACES
|
||||
|
||||
- --ignore TYPE(,TYPE2...)
|
||||
|
||||
Checkpatch will not emit messages for the specified types.
|
||||
|
||||
Example::
|
||||
|
||||
./scripts/checkpatch.pl mypatch.patch --ignore EMAIL_SUBJECT,BRACES
|
||||
|
||||
- --show-types
|
||||
|
||||
By default checkpatch doesn't display the type associated with the messages.
|
||||
Set this flag to show the message type in the output.
|
||||
|
||||
- --max-line-length=n
|
||||
|
||||
Set the max line length (default 100). If a line exceeds the specified
|
||||
length, a LONG_LINE message is emitted.
|
||||
|
||||
|
||||
The message level is different for patch and file contexts. For patches,
|
||||
a WARNING is emitted. While a milder CHECK is emitted for files. So for
|
||||
file contexts, the --strict flag must also be enabled.
|
||||
|
||||
- --min-conf-desc-length=n
|
||||
|
||||
Set the Kconfig entry minimum description length, if shorter, warn.
|
||||
|
||||
- --tab-size=n
|
||||
|
||||
Set the number of spaces for tab (default 8).
|
||||
|
||||
- --root=PATH
|
||||
|
||||
PATH to the kernel tree root.
|
||||
|
||||
This option must be specified when invoking checkpatch from outside
|
||||
the kernel root.
|
||||
|
||||
- --no-summary
|
||||
|
||||
Suppress the per file summary.
|
||||
|
||||
- --mailback
|
||||
|
||||
Only produce a report in case of Warnings or Errors. Milder Checks are
|
||||
excluded from this.
|
||||
|
||||
- --summary-file
|
||||
|
||||
Include the filename in summary.
|
||||
|
||||
- --debug KEY=[0|1]
|
||||
|
||||
Turn on/off debugging of KEY, where KEY is one of 'values', 'possible',
|
||||
'type', and 'attr' (default is all off).
|
||||
|
||||
- --fix
|
||||
|
||||
This is an EXPERIMENTAL feature. If correctable errors exists, a file
|
||||
<inputfile>.EXPERIMENTAL-checkpatch-fixes is created which has the
|
||||
automatically fixable errors corrected.
|
||||
|
||||
- --fix-inplace
|
||||
|
||||
EXPERIMENTAL - Similar to --fix but input file is overwritten with fixes.
|
||||
|
||||
DO NOT USE this flag unless you are absolutely sure and you have a backup
|
||||
in place.
|
||||
|
||||
- --ignore-perl-version
|
||||
|
||||
Override checking of perl version. Runtime errors maybe encountered after
|
||||
enabling this flag if the perl version does not meet the minimum specified.
|
||||
|
||||
- --codespell
|
||||
|
||||
Use the codespell dictionary for checking spelling errors.
|
||||
|
||||
- --codespellfile
|
||||
|
||||
Use the specified codespell file.
|
||||
Default is '/usr/share/codespell/dictionary.txt'.
|
||||
|
||||
- --typedefsfile
|
||||
|
||||
Read additional types from this file.
|
||||
|
||||
- --color[=WHEN]
|
||||
|
||||
Use colors 'always', 'never', or only when output is a terminal ('auto').
|
||||
Default is 'auto'.
|
||||
|
||||
- --kconfig-prefix=WORD
|
||||
|
||||
Use WORD as a prefix for Kconfig symbols (default is `CONFIG_`).
|
||||
|
||||
- -h, --help, --version
|
||||
|
||||
Display the help text.
|
||||
|
||||
Message Levels
|
||||
==============
|
||||
|
||||
Messages in checkpatch are divided into three levels. The levels of messages
|
||||
in checkpatch denote the severity of the error. They are:
|
||||
|
||||
- ERROR
|
||||
|
||||
This is the most strict level. Messages of type ERROR must be taken
|
||||
seriously as they denote things that are very likely to be wrong.
|
||||
|
||||
- WARNING
|
||||
|
||||
This is the next stricter level. Messages of type WARNING requires a
|
||||
more careful review. But it is milder than an ERROR.
|
||||
|
||||
- CHECK
|
||||
|
||||
This is the mildest level. These are things which may require some thought.
|
||||
|
||||
Type Descriptions
|
||||
=================
|
||||
|
||||
This section contains a description of all the message types in checkpatch.
|
||||
|
||||
.. Types in this section are also parsed by checkpatch.
|
||||
.. The types are grouped into subsections based on use.
|
||||
|
||||
|
||||
Allocation style
|
||||
----------------
|
||||
|
||||
**ALLOC_ARRAY_ARGS**
|
||||
The first argument for kcalloc or kmalloc_array should be the
|
||||
number of elements. sizeof() as the first argument is generally
|
||||
wrong.
|
||||
See: https://www.kernel.org/doc/html/latest/core-api/memory-allocation.html
|
||||
|
||||
**ALLOC_SIZEOF_STRUCT**
|
||||
The allocation style is bad. In general for family of
|
||||
allocation functions using sizeof() to get memory size,
|
||||
constructs like::
|
||||
|
||||
p = alloc(sizeof(struct foo), ...)
|
||||
|
||||
should be::
|
||||
|
||||
p = alloc(sizeof(*p), ...)
|
||||
|
||||
See: https://www.kernel.org/doc/html/latest/process/coding-style.html#allocating-memory
|
||||
|
||||
**ALLOC_WITH_MULTIPLY**
|
||||
Prefer kmalloc_array/kcalloc over kmalloc/kzalloc with a
|
||||
sizeof multiply.
|
||||
See: https://www.kernel.org/doc/html/latest/core-api/memory-allocation.html
|
||||
|
||||
|
||||
API usage
|
||||
---------
|
||||
|
||||
**ARCH_DEFINES**
|
||||
Architecture specific defines should be avoided wherever
|
||||
possible.
|
||||
|
||||
**ARCH_INCLUDE_LINUX**
|
||||
Whenever asm/file.h is included and linux/file.h exists, a
|
||||
conversion can be made when linux/file.h includes asm/file.h.
|
||||
However this is not always the case (See signal.h).
|
||||
This message type is emitted only for includes from arch/.
|
||||
|
||||
**AVOID_BUG**
|
||||
BUG() or BUG_ON() should be avoided totally.
|
||||
Use WARN() and WARN_ON() instead, and handle the "impossible"
|
||||
error condition as gracefully as possible.
|
||||
See: https://www.kernel.org/doc/html/latest/process/deprecated.html#bug-and-bug-on
|
||||
|
||||
**CONSIDER_KSTRTO**
|
||||
The simple_strtol(), simple_strtoll(), simple_strtoul(), and
|
||||
simple_strtoull() functions explicitly ignore overflows, which
|
||||
may lead to unexpected results in callers. The respective kstrtol(),
|
||||
kstrtoll(), kstrtoul(), and kstrtoull() functions tend to be the
|
||||
correct replacements.
|
||||
See: https://www.kernel.org/doc/html/latest/process/deprecated.html#simple-strtol-simple-strtoll-simple-strtoul-simple-strtoull
|
||||
|
||||
**LOCKDEP**
|
||||
The lockdep_no_validate class was added as a temporary measure to
|
||||
prevent warnings on conversion of device->sem to device->mutex.
|
||||
It should not be used for any other purpose.
|
||||
See: https://lore.kernel.org/lkml/1268959062.9440.467.camel@laptop/
|
||||
|
||||
**MALFORMED_INCLUDE**
|
||||
The #include statement has a malformed path. This has happened
|
||||
because the author has included a double slash "//" in the pathname
|
||||
accidentally.
|
||||
|
||||
**USE_LOCKDEP**
|
||||
lockdep_assert_held() annotations should be preferred over
|
||||
assertions based on spin_is_locked()
|
||||
See: https://www.kernel.org/doc/html/latest/locking/lockdep-design.html#annotations
|
||||
|
||||
**UAPI_INCLUDE**
|
||||
No #include statements in include/uapi should use a uapi/ path.
|
||||
|
||||
|
||||
Comment style
|
||||
-------------
|
||||
|
||||
**BLOCK_COMMENT_STYLE**
|
||||
The comment style is incorrect. The preferred style for multi-
|
||||
line comments is::
|
||||
|
||||
/*
|
||||
* This is the preferred style
|
||||
* for multi line comments.
|
||||
*/
|
||||
|
||||
The networking comment style is a bit different, with the first line
|
||||
not empty like the former::
|
||||
|
||||
/* This is the preferred comment style
|
||||
* for files in net/ and drivers/net/
|
||||
*/
|
||||
|
||||
See: https://www.kernel.org/doc/html/latest/process/coding-style.html#commenting
|
||||
|
||||
**C99_COMMENTS**
|
||||
C99 style single line comments (//) should not be used.
|
||||
Prefer the block comment style instead.
|
||||
See: https://www.kernel.org/doc/html/latest/process/coding-style.html#commenting
|
||||
|
||||
|
||||
Commit message
|
||||
--------------
|
||||
|
||||
**BAD_SIGN_OFF**
|
||||
The signed-off-by line does not fall in line with the standards
|
||||
specified by the community.
|
||||
See: https://www.kernel.org/doc/html/latest/process/submitting-patches.html#developer-s-certificate-of-origin-1-1
|
||||
|
||||
**BAD_STABLE_ADDRESS_STYLE**
|
||||
The email format for stable is incorrect.
|
||||
Some valid options for stable address are::
|
||||
|
||||
1. stable@vger.kernel.org
|
||||
2. stable@kernel.org
|
||||
|
||||
For adding version info, the following comment style should be used::
|
||||
|
||||
stable@vger.kernel.org # version info
|
||||
|
||||
**COMMIT_COMMENT_SYMBOL**
|
||||
Commit log lines starting with a '#' are ignored by git as
|
||||
comments. To solve this problem addition of a single space
|
||||
infront of the log line is enough.
|
||||
|
||||
**COMMIT_MESSAGE**
|
||||
The patch is missing a commit description. A brief
|
||||
description of the changes made by the patch should be added.
|
||||
See: https://www.kernel.org/doc/html/latest/process/submitting-patches.html#describe-your-changes
|
||||
|
||||
**MISSING_SIGN_OFF**
|
||||
The patch is missing a Signed-off-by line. A signed-off-by
|
||||
line should be added according to Developer's certificate of
|
||||
Origin.
|
||||
See: https://www.kernel.org/doc/html/latest/process/submitting-patches.html#sign-your-work-the-developer-s-certificate-of-origin
|
||||
|
||||
**NO_AUTHOR_SIGN_OFF**
|
||||
The author of the patch has not signed off the patch. It is
|
||||
required that a simple sign off line should be present at the
|
||||
end of explanation of the patch to denote that the author has
|
||||
written it or otherwise has the rights to pass it on as an open
|
||||
source patch.
|
||||
See: https://www.kernel.org/doc/html/latest/process/submitting-patches.html#sign-your-work-the-developer-s-certificate-of-origin
|
||||
|
||||
**DIFF_IN_COMMIT_MSG**
|
||||
Avoid having diff content in commit message.
|
||||
This causes problems when one tries to apply a file containing both
|
||||
the changelog and the diff because patch(1) tries to apply the diff
|
||||
which it found in the changelog.
|
||||
See: https://lore.kernel.org/lkml/20150611134006.9df79a893e3636019ad2759e@linux-foundation.org/
|
||||
|
||||
**GERRIT_CHANGE_ID**
|
||||
To be picked up by gerrit, the footer of the commit message might
|
||||
have a Change-Id like::
|
||||
|
||||
Change-Id: Ic8aaa0728a43936cd4c6e1ed590e01ba8f0fbf5b
|
||||
Signed-off-by: A. U. Thor <author@example.com>
|
||||
|
||||
The Change-Id line must be removed before submitting.
|
||||
|
||||
**GIT_COMMIT_ID**
|
||||
The proper way to reference a commit id is:
|
||||
commit <12+ chars of sha1> ("<title line>")
|
||||
|
||||
An example may be::
|
||||
|
||||
Commit e21d2170f36602ae2708 ("video: remove unnecessary
|
||||
platform_set_drvdata()") removed the unnecessary
|
||||
platform_set_drvdata(), but left the variable "dev" unused,
|
||||
delete it.
|
||||
|
||||
See: https://www.kernel.org/doc/html/latest/process/submitting-patches.html#describe-your-changes
|
||||
|
||||
|
||||
Comparison style
|
||||
----------------
|
||||
|
||||
**ASSIGN_IN_IF**
|
||||
Do not use assignments in if condition.
|
||||
Example::
|
||||
|
||||
if ((foo = bar(...)) < BAZ) {
|
||||
|
||||
should be written as::
|
||||
|
||||
foo = bar(...);
|
||||
if (foo < BAZ) {
|
||||
|
||||
**BOOL_COMPARISON**
|
||||
Comparisons of A to true and false are better written
|
||||
as A and !A.
|
||||
See: https://lore.kernel.org/lkml/1365563834.27174.12.camel@joe-AO722/
|
||||
|
||||
**COMPARISON_TO_NULL**
|
||||
Comparisons to NULL in the form (foo == NULL) or (foo != NULL)
|
||||
are better written as (!foo) and (foo).
|
||||
|
||||
**CONSTANT_COMPARISON**
|
||||
Comparisons with a constant or upper case identifier on the left
|
||||
side of the test should be avoided.
|
||||
|
||||
|
||||
Macros, Attributes and Symbols
|
||||
------------------------------
|
||||
|
||||
**ARRAY_SIZE**
|
||||
The ARRAY_SIZE(foo) macro should be preferred over
|
||||
sizeof(foo)/sizeof(foo[0]) for finding number of elements in an
|
||||
array.
|
||||
|
||||
The macro is defined in include/linux/kernel.h::
|
||||
|
||||
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
|
||||
|
||||
**AVOID_EXTERNS**
|
||||
Function prototypes don't need to be declared extern in .h
|
||||
files. It's assumed by the compiler and is unnecessary.
|
||||
|
||||
**AVOID_L_PREFIX**
|
||||
Local symbol names that are prefixed with `.L` should be avoided,
|
||||
as this has special meaning for the assembler; a symbol entry will
|
||||
not be emitted into the symbol table. This can prevent `objtool`
|
||||
from generating correct unwind info.
|
||||
|
||||
Symbols with STB_LOCAL binding may still be used, and `.L` prefixed
|
||||
local symbol names are still generally usable within a function,
|
||||
but `.L` prefixed local symbol names should not be used to denote
|
||||
the beginning or end of code regions via
|
||||
`SYM_CODE_START_LOCAL`/`SYM_CODE_END`
|
||||
|
||||
**BIT_MACRO**
|
||||
Defines like: 1 << <digit> could be BIT(digit).
|
||||
The BIT() macro is defined in include/linux/bitops.h::
|
||||
|
||||
#define BIT(nr) (1UL << (nr))
|
||||
|
||||
**CONST_READ_MOSTLY**
|
||||
When a variable is tagged with the __read_mostly annotation, it is a
|
||||
signal to the compiler that accesses to the variable will be mostly
|
||||
reads and rarely(but NOT never) a write.
|
||||
|
||||
const __read_mostly does not make any sense as const data is already
|
||||
read-only. The __read_mostly annotation thus should be removed.
|
||||
|
||||
**DATE_TIME**
|
||||
It is generally desirable that building the same source code with
|
||||
the same set of tools is reproducible, i.e. the output is always
|
||||
exactly the same.
|
||||
|
||||
The kernel does *not* use the ``__DATE__`` and ``__TIME__`` macros,
|
||||
and enables warnings if they are used as they can lead to
|
||||
non-deterministic builds.
|
||||
See: https://www.kernel.org/doc/html/latest/kbuild/reproducible-builds.html#timestamps
|
||||
|
||||
**DEFINE_ARCH_HAS**
|
||||
The ARCH_HAS_xyz and ARCH_HAVE_xyz patterns are wrong.
|
||||
|
||||
For big conceptual features use Kconfig symbols instead. And for
|
||||
smaller things where we have compatibility fallback functions but
|
||||
want architectures able to override them with optimized ones, we
|
||||
should either use weak functions (appropriate for some cases), or
|
||||
the symbol that protects them should be the same symbol we use.
|
||||
See: https://lore.kernel.org/lkml/CA+55aFycQ9XJvEOsiM3txHL5bjUc8CeKWJNR_H+MiicaddB42Q@mail.gmail.com/
|
||||
|
||||
**INIT_ATTRIBUTE**
|
||||
Const init definitions should use __initconst instead of
|
||||
__initdata.
|
||||
|
||||
Similarly init definitions without const require a separate
|
||||
use of const.
|
||||
|
||||
**INLINE_LOCATION**
|
||||
The inline keyword should sit between storage class and type.
|
||||
|
||||
For example, the following segment::
|
||||
|
||||
inline static int example_function(void)
|
||||
{
|
||||
...
|
||||
}
|
||||
|
||||
should be::
|
||||
|
||||
static inline int example_function(void)
|
||||
{
|
||||
...
|
||||
}
|
||||
|
||||
**MULTISTATEMENT_MACRO_USE_DO_WHILE**
|
||||
Macros with multiple statements should be enclosed in a
|
||||
do - while block. Same should also be the case for macros
|
||||
starting with `if` to avoid logic defects::
|
||||
|
||||
#define macrofun(a, b, c) \
|
||||
do { \
|
||||
if (a == 5) \
|
||||
do_this(b, c); \
|
||||
} while (0)
|
||||
|
||||
See: https://www.kernel.org/doc/html/latest/process/coding-style.html#macros-enums-and-rtl
|
||||
|
||||
**WEAK_DECLARATION**
|
||||
Using weak declarations like __attribute__((weak)) or __weak
|
||||
can have unintended link defects. Avoid using them.
|
||||
|
||||
|
||||
Functions and Variables
|
||||
-----------------------
|
||||
|
||||
**CAMELCASE**
|
||||
Avoid CamelCase Identifiers.
|
||||
See: https://www.kernel.org/doc/html/latest/process/coding-style.html#naming
|
||||
|
||||
**FUNCTION_WITHOUT_ARGS**
|
||||
Function declarations without arguments like::
|
||||
|
||||
int foo()
|
||||
|
||||
should be::
|
||||
|
||||
int foo(void)
|
||||
|
||||
**GLOBAL_INITIALISERS**
|
||||
Global variables should not be initialized explicitly to
|
||||
0 (or NULL, false, etc.). Your compiler (or rather your
|
||||
loader, which is responsible for zeroing out the relevant
|
||||
sections) automatically does it for you.
|
||||
|
||||
**INITIALISED_STATIC**
|
||||
Static variables should not be initialized explicitly to zero.
|
||||
Your compiler (or rather your loader) automatically does
|
||||
it for you.
|
||||
|
||||
**RETURN_PARENTHESES**
|
||||
return is not a function and as such doesn't need parentheses::
|
||||
|
||||
return (bar);
|
||||
|
||||
can simply be::
|
||||
|
||||
return bar;
|
||||
|
||||
|
||||
Spacing and Brackets
|
||||
--------------------
|
||||
|
||||
**ASSIGNMENT_CONTINUATIONS**
|
||||
Assignment operators should not be written at the start of a
|
||||
line but should follow the operand at the previous line.
|
||||
|
||||
**BRACES**
|
||||
The placement of braces is stylistically incorrect.
|
||||
The preferred way is to put the opening brace last on the line,
|
||||
and put the closing brace first::
|
||||
|
||||
if (x is true) {
|
||||
we do y
|
||||
}
|
||||
|
||||
This applies for all non-functional blocks.
|
||||
However, there is one special case, namely functions: they have the
|
||||
opening brace at the beginning of the next line, thus::
|
||||
|
||||
int function(int x)
|
||||
{
|
||||
body of function
|
||||
}
|
||||
|
||||
See: https://www.kernel.org/doc/html/latest/process/coding-style.html#placing-braces-and-spaces
|
||||
|
||||
**BRACKET_SPACE**
|
||||
Whitespace before opening bracket '[' is prohibited.
|
||||
There are some exceptions:
|
||||
|
||||
1. With a type on the left::
|
||||
|
||||
;int [] a;
|
||||
|
||||
2. At the beginning of a line for slice initialisers::
|
||||
|
||||
[0...10] = 5,
|
||||
|
||||
3. Inside a curly brace::
|
||||
|
||||
= { [0...10] = 5 }
|
||||
|
||||
**CODE_INDENT**
|
||||
Code indent should use tabs instead of spaces.
|
||||
Outside of comments, documentation and Kconfig,
|
||||
spaces are never used for indentation.
|
||||
See: https://www.kernel.org/doc/html/latest/process/coding-style.html#indentation
|
||||
|
||||
**CONCATENATED_STRING**
|
||||
Concatenated elements should have a space in between.
|
||||
Example::
|
||||
|
||||
printk(KERN_INFO"bar");
|
||||
|
||||
should be::
|
||||
|
||||
printk(KERN_INFO "bar");
|
||||
|
||||
**ELSE_AFTER_BRACE**
|
||||
`else {` should follow the closing block `}` on the same line.
|
||||
See: https://www.kernel.org/doc/html/latest/process/coding-style.html#placing-braces-and-spaces
|
||||
|
||||
**LINE_SPACING**
|
||||
Vertical space is wasted given the limited number of lines an
|
||||
editor window can display when multiple blank lines are used.
|
||||
See: https://www.kernel.org/doc/html/latest/process/coding-style.html#spaces
|
||||
|
||||
**OPEN_BRACE**
|
||||
The opening brace should be following the function definitions on the
|
||||
next line. For any non-functional block it should be on the same line
|
||||
as the last construct.
|
||||
See: https://www.kernel.org/doc/html/latest/process/coding-style.html#placing-braces-and-spaces
|
||||
|
||||
**POINTER_LOCATION**
|
||||
When using 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 adjacent to the type name.
|
||||
Examples::
|
||||
|
||||
char *linux_banner;
|
||||
unsigned long long memparse(char *ptr, char **retptr);
|
||||
char *match_strdup(substring_t *s);
|
||||
|
||||
See: https://www.kernel.org/doc/html/latest/process/coding-style.html#spaces
|
||||
|
||||
**SPACING**
|
||||
Whitespace style used in the kernel sources is described in kernel docs.
|
||||
See: https://www.kernel.org/doc/html/latest/process/coding-style.html#spaces
|
||||
|
||||
**SWITCH_CASE_INDENT_LEVEL**
|
||||
switch should be at the same indent as case.
|
||||
Example::
|
||||
|
||||
switch (suffix) {
|
||||
case 'G':
|
||||
case 'g':
|
||||
mem <<= 30;
|
||||
break;
|
||||
case 'M':
|
||||
case 'm':
|
||||
mem <<= 20;
|
||||
break;
|
||||
case 'K':
|
||||
case 'k':
|
||||
mem <<= 10;
|
||||
/* fall through */
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
See: https://www.kernel.org/doc/html/latest/process/coding-style.html#indentation
|
||||
|
||||
**TRAILING_WHITESPACE**
|
||||
Trailing whitespace should always be removed.
|
||||
Some editors highlight the trailing whitespace and cause visual
|
||||
distractions when editing files.
|
||||
See: https://www.kernel.org/doc/html/latest/process/coding-style.html#spaces
|
||||
|
||||
**WHILE_AFTER_BRACE**
|
||||
while should follow the closing bracket on the same line::
|
||||
|
||||
do {
|
||||
...
|
||||
} while(something);
|
||||
|
||||
See: https://www.kernel.org/doc/html/latest/process/coding-style.html#placing-braces-and-spaces
|
||||
|
||||
|
||||
Others
|
||||
------
|
||||
|
||||
**CONFIG_DESCRIPTION**
|
||||
Kconfig symbols should have a help text which fully describes
|
||||
it.
|
||||
|
||||
**CORRUPTED_PATCH**
|
||||
The patch seems to be corrupted or lines are wrapped.
|
||||
Please regenerate the patch file before sending it to the maintainer.
|
||||
|
||||
**DOS_LINE_ENDINGS**
|
||||
For DOS-formatted patches, there are extra ^M symbols at the end of
|
||||
the line. These should be removed.
|
||||
|
||||
**EXECUTE_PERMISSIONS**
|
||||
There is no reason for source files to be executable. The executable
|
||||
bit can be removed safely.
|
||||
|
||||
**NON_OCTAL_PERMISSIONS**
|
||||
Permission bits should use 4 digit octal permissions (like 0700 or 0444).
|
||||
Avoid using any other base like decimal.
|
||||
|
||||
**NOT_UNIFIED_DIFF**
|
||||
The patch file does not appear to be in unified-diff format. Please
|
||||
regenerate the patch file before sending it to the maintainer.
|
||||
|
||||
**PRINTF_0XDECIMAL**
|
||||
Prefixing 0x with decimal output is defective and should be corrected.
|
||||
|
||||
**TRAILING_STATEMENTS**
|
||||
Trailing statements (for example after any conditional) should be
|
||||
on the next line.
|
||||
Like::
|
||||
|
||||
if (x == y) break;
|
||||
|
||||
should be::
|
||||
|
||||
if (x == y)
|
||||
break;
|
|
@ -124,6 +124,8 @@ 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:
|
||||
|
||||
.. _gcov-test:
|
||||
|
||||
a) gcov is run on the TEST machine
|
||||
|
||||
The gcov tool version on the test machine must be compatible with the
|
||||
|
@ -143,6 +145,8 @@ a) gcov is run on the TEST machine
|
|||
machine. If any of the path components is symbolic link, the actual
|
||||
directory needs to be used instead (due to make's CURDIR handling).
|
||||
|
||||
.. _gcov-build:
|
||||
|
||||
b) gcov is run on the BUILD machine
|
||||
|
||||
The following files need to be copied after each test case from test
|
||||
|
@ -211,7 +215,7 @@ Appendix A: gather_on_build.sh
|
|||
------------------------------
|
||||
|
||||
Sample script to gather coverage meta files on the build machine
|
||||
(see 6a):
|
||||
(see :ref:`Separated build and test machines a. <gcov-test>`):
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
|
@ -244,7 +248,7 @@ Appendix B: gather_on_test.sh
|
|||
-----------------------------
|
||||
|
||||
Sample script to gather coverage data files on the test machine
|
||||
(see 6b):
|
||||
(see :ref:`Separated build and test machines b. <gcov-build>`):
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
|
|
|
@ -7,6 +7,9 @@ be used to work on the kernel. For now, the documents have been pulled
|
|||
together without any significant effort to integrate them into a coherent
|
||||
whole; patches welcome!
|
||||
|
||||
A brief overview of testing-specific tools can be found in
|
||||
Documentation/dev-tools/testing-overview.rst
|
||||
|
||||
.. class:: toc-title
|
||||
|
||||
Table of contents
|
||||
|
@ -14,6 +17,8 @@ whole; patches welcome!
|
|||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
testing-overview
|
||||
checkpatch
|
||||
coccinelle
|
||||
sparse
|
||||
kcov
|
||||
|
|
|
@ -0,0 +1,117 @@
|
|||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
====================
|
||||
Kernel Testing Guide
|
||||
====================
|
||||
|
||||
|
||||
There are a number of different tools for testing the Linux kernel, so knowing
|
||||
when to use each of them can be a challenge. This document provides a rough
|
||||
overview of their differences, and how they fit together.
|
||||
|
||||
|
||||
Writing and Running Tests
|
||||
=========================
|
||||
|
||||
The bulk of kernel tests are written using either the kselftest or KUnit
|
||||
frameworks. These both provide infrastructure to help make running tests and
|
||||
groups of tests easier, as well as providing helpers to aid in writing new
|
||||
tests.
|
||||
|
||||
If you're looking to verify the behaviour of the Kernel — particularly specific
|
||||
parts of the kernel — then you'll want to use KUnit or kselftest.
|
||||
|
||||
|
||||
The Difference Between KUnit and kselftest
|
||||
------------------------------------------
|
||||
|
||||
KUnit (Documentation/dev-tools/kunit/index.rst) is an entirely in-kernel system
|
||||
for "white box" testing: because test code is part of the kernel, it can access
|
||||
internal structures and functions which aren't exposed to userspace.
|
||||
|
||||
KUnit tests therefore are best written against small, self-contained parts
|
||||
of the kernel, which can be tested in isolation. This aligns well with the
|
||||
concept of 'unit' testing.
|
||||
|
||||
For example, a KUnit test might test an individual kernel function (or even a
|
||||
single codepath through a function, such as an error handling case), rather
|
||||
than a feature as a whole.
|
||||
|
||||
This also makes KUnit tests very fast to build and run, allowing them to be
|
||||
run frequently as part of the development process.
|
||||
|
||||
There is a KUnit test style guide which may give further pointers in
|
||||
Documentation/dev-tools/kunit/style.rst
|
||||
|
||||
|
||||
kselftest (Documentation/dev-tools/kselftest.rst), on the other hand, is
|
||||
largely implemented in userspace, and tests are normal userspace scripts or
|
||||
programs.
|
||||
|
||||
This makes it easier to write more complicated tests, or tests which need to
|
||||
manipulate the overall system state more (e.g., spawning processes, etc.).
|
||||
However, it's not possible to call kernel functions directly from kselftest.
|
||||
This means that only kernel functionality which is exposed to userspace somehow
|
||||
(e.g. by a syscall, device, filesystem, etc.) can be tested with kselftest. To
|
||||
work around this, some tests include a companion kernel module which exposes
|
||||
more information or functionality. If a test runs mostly or entirely within the
|
||||
kernel, however, KUnit may be the more appropriate tool.
|
||||
|
||||
kselftest is therefore suited well to tests of whole features, as these will
|
||||
expose an interface to userspace, which can be tested, but not implementation
|
||||
details. This aligns well with 'system' or 'end-to-end' testing.
|
||||
|
||||
For example, all new system calls should be accompanied by kselftest tests.
|
||||
|
||||
Code Coverage Tools
|
||||
===================
|
||||
|
||||
The Linux Kernel supports two different code coverage measurement tools. These
|
||||
can be used to verify that a test is executing particular functions or lines
|
||||
of code. This is useful for determining how much of the kernel is being tested,
|
||||
and for finding corner-cases which are not covered by the appropriate test.
|
||||
|
||||
:doc:`gcov` is GCC's coverage testing tool, which can be used with the kernel
|
||||
to get global or per-module coverage. Unlike KCOV, it does not record per-task
|
||||
coverage. Coverage data can be read from debugfs, and interpreted using the
|
||||
usual gcov tooling.
|
||||
|
||||
:doc:`kcov` is a feature which can be built in to the kernel to allow
|
||||
capturing coverage on a per-task level. It's therefore useful for fuzzing and
|
||||
other situations where information about code executed during, for example, a
|
||||
single syscall is useful.
|
||||
|
||||
|
||||
Dynamic Analysis Tools
|
||||
======================
|
||||
|
||||
The kernel also supports a number of dynamic analysis tools, which attempt to
|
||||
detect classes of issues when they occur in a running kernel. These typically
|
||||
each look for a different class of bugs, such as invalid memory accesses,
|
||||
concurrency issues such as data races, or other undefined behaviour like
|
||||
integer overflows.
|
||||
|
||||
Some of these tools are listed below:
|
||||
|
||||
* kmemleak detects possible memory leaks. See
|
||||
Documentation/dev-tools/kmemleak.rst
|
||||
* KASAN detects invalid memory accesses such as out-of-bounds and
|
||||
use-after-free errors. See Documentation/dev-tools/kasan.rst
|
||||
* UBSAN detects behaviour that is undefined by the C standard, like integer
|
||||
overflows. See Documentation/dev-tools/ubsan.rst
|
||||
* KCSAN detects data races. See Documentation/dev-tools/kcsan.rst
|
||||
* KFENCE is a low-overhead detector of memory issues, which is much faster than
|
||||
KASAN and can be used in production. See Documentation/dev-tools/kfence.rst
|
||||
* lockdep is a locking correctness validator. See
|
||||
Documentation/locking/lockdep-design.rst
|
||||
* There are several other pieces of debug instrumentation in the kernel, many
|
||||
of which can be found in lib/Kconfig.debug
|
||||
|
||||
These tools tend to test the kernel as a whole, and do not "pass" like
|
||||
kselftest or KUnit tests. They can be combined with KUnit or kselftest by
|
||||
running tests on a kernel with these tools enabled: you can then be sure
|
||||
that none of these errors are occurring during the test.
|
||||
|
||||
Some of these tools integrate with KUnit or kselftest and will
|
||||
automatically fail tests if an issue is detected.
|
||||
|
|
@ -75,8 +75,8 @@ II. For kernel maintainers
|
|||
binding, and it hasn't received an Acked-by from the devicetree
|
||||
maintainers after a few weeks, go ahead and take it.
|
||||
|
||||
Subsystem bindings (anything affecting more than a single device)
|
||||
then getting a devicetree maintainer to review it is required.
|
||||
For subsystem bindings (anything affecting more than a single device),
|
||||
getting a devicetree maintainer to review it is required.
|
||||
|
||||
3) For a series going though multiple trees, the binding patch should be
|
||||
kept with the driver using the binding.
|
||||
|
|
|
@ -1,149 +0,0 @@
|
|||
==============
|
||||
Device Classes
|
||||
==============
|
||||
|
||||
Introduction
|
||||
~~~~~~~~~~~~
|
||||
A device class describes a type of device, like an audio or network
|
||||
device. The following device classes have been identified:
|
||||
|
||||
<Insert List of Device Classes Here>
|
||||
|
||||
|
||||
Each device class defines a set of semantics and a programming interface
|
||||
that devices of that class adhere to. Device drivers are the
|
||||
implementation of that programming interface for a particular device on
|
||||
a particular bus.
|
||||
|
||||
Device classes are agnostic with respect to what bus a device resides
|
||||
on.
|
||||
|
||||
|
||||
Programming Interface
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
The device class structure looks like::
|
||||
|
||||
|
||||
typedef int (*devclass_add)(struct device *);
|
||||
typedef void (*devclass_remove)(struct device *);
|
||||
|
||||
See the kerneldoc for the struct class.
|
||||
|
||||
A typical device class definition would look like::
|
||||
|
||||
struct device_class input_devclass = {
|
||||
.name = "input",
|
||||
.add_device = input_add_device,
|
||||
.remove_device = input_remove_device,
|
||||
};
|
||||
|
||||
Each device class structure should be exported in a header file so it
|
||||
can be used by drivers, extensions and interfaces.
|
||||
|
||||
Device classes are registered and unregistered with the core using::
|
||||
|
||||
int devclass_register(struct device_class * cls);
|
||||
void devclass_unregister(struct device_class * cls);
|
||||
|
||||
|
||||
Devices
|
||||
~~~~~~~
|
||||
As devices are bound to drivers, they are added to the device class
|
||||
that the driver belongs to. Before the driver model core, this would
|
||||
typically happen during the driver's probe() callback, once the device
|
||||
has been initialized. It now happens after the probe() callback
|
||||
finishes from the core.
|
||||
|
||||
The device is enumerated in the class. Each time a device is added to
|
||||
the class, the class's devnum field is incremented and assigned to the
|
||||
device. The field is never decremented, so if the device is removed
|
||||
from the class and re-added, it will receive a different enumerated
|
||||
value.
|
||||
|
||||
The class is allowed to create a class-specific structure for the
|
||||
device and store it in the device's class_data pointer.
|
||||
|
||||
There is no list of devices in the device class. Each driver has a
|
||||
list of devices that it supports. The device class has a list of
|
||||
drivers of that particular class. To access all of the devices in the
|
||||
class, iterate over the device lists of each driver in the class.
|
||||
|
||||
|
||||
Device Drivers
|
||||
~~~~~~~~~~~~~~
|
||||
Device drivers are added to device classes when they are registered
|
||||
with the core. A driver specifies the class it belongs to by setting
|
||||
the struct device_driver::devclass field.
|
||||
|
||||
|
||||
sysfs directory structure
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
There is a top-level sysfs directory named 'class'.
|
||||
|
||||
Each class gets a directory in the class directory, along with two
|
||||
default subdirectories::
|
||||
|
||||
class/
|
||||
`-- input
|
||||
|-- devices
|
||||
`-- drivers
|
||||
|
||||
|
||||
Drivers registered with the class get a symlink in the drivers/ directory
|
||||
that points to the driver's directory (under its bus directory)::
|
||||
|
||||
class/
|
||||
`-- input
|
||||
|-- devices
|
||||
`-- drivers
|
||||
`-- usb:usb_mouse -> ../../../bus/drivers/usb_mouse/
|
||||
|
||||
|
||||
Each device gets a symlink in the devices/ directory that points to the
|
||||
device's directory in the physical hierarchy::
|
||||
|
||||
class/
|
||||
`-- input
|
||||
|-- devices
|
||||
| `-- 1 -> ../../../root/pci0/00:1f.0/usb_bus/00:1f.2-1:0/
|
||||
`-- drivers
|
||||
|
||||
|
||||
Exporting Attributes
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
::
|
||||
|
||||
struct devclass_attribute {
|
||||
struct attribute attr;
|
||||
ssize_t (*show)(struct device_class *, char * buf, size_t count, loff_t off);
|
||||
ssize_t (*store)(struct device_class *, const char * buf, size_t count, loff_t off);
|
||||
};
|
||||
|
||||
Class drivers can export attributes using the DEVCLASS_ATTR macro that works
|
||||
similarly to the DEVICE_ATTR macro for devices. For example, a definition
|
||||
like this::
|
||||
|
||||
static DEVCLASS_ATTR(debug,0644,show_debug,store_debug);
|
||||
|
||||
is equivalent to declaring::
|
||||
|
||||
static devclass_attribute devclass_attr_debug;
|
||||
|
||||
The bus driver can add and remove the attribute from the class's
|
||||
sysfs directory using::
|
||||
|
||||
int devclass_create_file(struct device_class *, struct devclass_attribute *);
|
||||
void devclass_remove_file(struct device_class *, struct devclass_attribute *);
|
||||
|
||||
In the example above, the file will be named 'debug' in placed in the
|
||||
class's directory in sysfs.
|
||||
|
||||
|
||||
Interfaces
|
||||
~~~~~~~~~~
|
||||
There may exist multiple mechanisms for accessing the same device of a
|
||||
particular class type. Device interfaces describe these mechanisms.
|
||||
|
||||
When a device is added to a device class, the core attempts to add it
|
||||
to every interface that is registered with the device class.
|
|
@ -63,8 +63,14 @@ Attributes are declared using a macro called DEVICE_ATTR::
|
|||
|
||||
Example:::
|
||||
|
||||
static DEVICE_ATTR(type, 0444, show_type, NULL);
|
||||
static DEVICE_ATTR(power, 0644, show_power, store_power);
|
||||
static DEVICE_ATTR(type, 0444, type_show, NULL);
|
||||
static DEVICE_ATTR(power, 0644, power_show, power_store);
|
||||
|
||||
Helper macros are available for common values of mode, so the above examples
|
||||
can be simplified to:::
|
||||
|
||||
static DEVICE_ATTR_RO(type);
|
||||
static DEVICE_ATTR_RW(power);
|
||||
|
||||
This declares two structures of type struct device_attribute with respective
|
||||
names 'dev_attr_type' and 'dev_attr_power'. These two attributes can be
|
||||
|
@ -76,19 +82,24 @@ organized as follows into a group::
|
|||
NULL,
|
||||
};
|
||||
|
||||
static struct attribute_group dev_attr_group = {
|
||||
static struct attribute_group dev_group = {
|
||||
.attrs = dev_attrs,
|
||||
};
|
||||
|
||||
static const struct attribute_group *dev_attr_groups[] = {
|
||||
&dev_attr_group,
|
||||
static const struct attribute_group *dev_groups[] = {
|
||||
&dev_group,
|
||||
NULL,
|
||||
};
|
||||
|
||||
A helper macro is available for the common case of a single group, so the
|
||||
above two structures can be declared using:::
|
||||
|
||||
ATTRIBUTE_GROUPS(dev);
|
||||
|
||||
This array of groups can then be associated with a device by setting the
|
||||
group pointer in struct device before device_register() is invoked::
|
||||
|
||||
dev->groups = dev_attr_groups;
|
||||
dev->groups = dev_groups;
|
||||
device_register(dev);
|
||||
|
||||
The device_register() function will use the 'groups' pointer to create the
|
||||
|
|
|
@ -7,7 +7,6 @@ Driver Model
|
|||
|
||||
binding
|
||||
bus
|
||||
class
|
||||
design-patterns
|
||||
device
|
||||
devres
|
||||
|
|
|
@ -27,7 +27,7 @@ What is a GPIO?
|
|||
===============
|
||||
|
||||
A "General Purpose Input/Output" (GPIO) is a flexible software-controlled
|
||||
digital signal. They are provided from many kinds of chip, and are familiar
|
||||
digital signal. They are provided from many kinds of chips, and are familiar
|
||||
to Linux developers working with embedded and custom hardware. Each GPIO
|
||||
represents a bit connected to a particular pin, or "ball" on Ball Grid Array
|
||||
(BGA) packages. Board schematics show which external hardware connects to
|
||||
|
|
|
@ -207,9 +207,9 @@ Documentation/driver-api/console.rst. To summarize:
|
|||
Echo a value to the bind file that represents the framebuffer console
|
||||
driver. So assuming vtcon1 represents fbcon, then::
|
||||
|
||||
echo 1 > sys/class/vtconsole/vtcon1/bind - attach framebuffer console to
|
||||
echo 1 > /sys/class/vtconsole/vtcon1/bind - attach framebuffer console to
|
||||
console layer
|
||||
echo 0 > sys/class/vtconsole/vtcon1/bind - detach framebuffer console from
|
||||
echo 0 > /sys/class/vtconsole/vtcon1/bind - detach framebuffer console from
|
||||
console layer
|
||||
|
||||
If fbcon is detached from the console layer, your boot console driver (which is
|
||||
|
|
|
@ -8,4 +8,5 @@ The meaning of entries in the tables is:
|
|||
| ok | # feature supported by the architecture
|
||||
|TODO| # feature not yet supported by the architecture
|
||||
| .. | # feature cannot be supported by the hardware
|
||||
| N/A| # feature doesn't apply to the architecture
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
| alpha: | TODO |
|
||||
| arc: | TODO |
|
||||
| arm: | TODO |
|
||||
| arm64: | TODO |
|
||||
| arm64: | N/A |
|
||||
| csky: | TODO |
|
||||
| h8300: | .. |
|
||||
| hexagon: | TODO |
|
||||
|
|
|
@ -101,6 +101,9 @@ Other Functions
|
|||
.. kernel-doc:: fs/xattr.c
|
||||
:export:
|
||||
|
||||
.. kernel-doc:: fs/namespace.c
|
||||
:export:
|
||||
|
||||
The proc filesystem
|
||||
===================
|
||||
|
||||
|
@ -122,6 +125,12 @@ Events based on file descriptors
|
|||
.. kernel-doc:: fs/eventfd.c
|
||||
:export:
|
||||
|
||||
eventpoll (epoll) interfaces
|
||||
============================
|
||||
|
||||
.. kernel-doc:: fs/eventpoll.c
|
||||
:internal:
|
||||
|
||||
The Filesystem for Exporting Kernel Objects
|
||||
===========================================
|
||||
|
||||
|
|
|
@ -540,7 +540,9 @@ encoded manner. The codes are the following:
|
|||
ac area is accountable
|
||||
nr swap space is not reserved for the area
|
||||
ht area uses huge tlb pages
|
||||
sf synchronous page fault
|
||||
ar architecture specific flag
|
||||
wf wipe on fork
|
||||
dd do not include area into core dump
|
||||
sd soft dirty flag
|
||||
mm mixed map area
|
||||
|
@ -549,6 +551,8 @@ encoded manner. The codes are the following:
|
|||
mg mergable advise flag
|
||||
bt arm64 BTI guarded page
|
||||
mt arm64 MTE allocation tags are enabled
|
||||
um userfaultfd missing tracking
|
||||
uw userfaultfd wr-protect tracking
|
||||
== =======================================
|
||||
|
||||
Note that there is no guarantee that every flag and associated mnemonic will
|
||||
|
|
|
@ -189,7 +189,7 @@ VFAT MOUNT OPTIONS
|
|||
**discard**
|
||||
If set, issues discard/TRIM commands to the block
|
||||
device when blocks are freed. This is useful for SSD devices
|
||||
and sparse/thinly-provisoned LUNs.
|
||||
and sparse/thinly-provisioned LUNs.
|
||||
|
||||
**nfs=stale_rw|nostale_ro**
|
||||
Enable this only if you want to export the FAT filesystem
|
||||
|
|
|
@ -345,7 +345,7 @@ Documentation/ABI/testing/sysfs-bus-iio for IIO ABIs to user space.
|
|||
To debug ISH, event tracing mechanism is used. To enable debug logs::
|
||||
|
||||
echo 1 > /sys/kernel/debug/tracing/events/intel_ish/enable
|
||||
cat sys/kernel/debug/tracing/trace
|
||||
cat /sys/kernel/debug/tracing/trace
|
||||
|
||||
3.8 ISH IIO sysfs Example on Lenovo thinkpad Yoga 260
|
||||
-----------------------------------------------------
|
||||
|
|
|
@ -149,27 +149,11 @@ Architecture-agnostic documentation
|
|||
Architecture-specific documentation
|
||||
-----------------------------------
|
||||
|
||||
These books provide programming details about architecture-specific
|
||||
implementation.
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
arm/index
|
||||
arm64/index
|
||||
ia64/index
|
||||
m68k/index
|
||||
mips/index
|
||||
nios2/index
|
||||
openrisc/index
|
||||
parisc/index
|
||||
powerpc/index
|
||||
riscv/index
|
||||
s390/index
|
||||
sh/index
|
||||
sparc/index
|
||||
x86/index
|
||||
xtensa/index
|
||||
arch
|
||||
|
||||
|
||||
Other documentation
|
||||
-------------------
|
||||
|
|
|
@ -246,9 +246,9 @@ A few EV_ABS codes have special meanings:
|
|||
|
||||
A device should set the resolution of the axis to indicate whether the
|
||||
pressure is in measurable units. If the resolution is zero, the
|
||||
pressure data is in arbitrary units. If the resolution is nonzero, the
|
||||
pressure data is in arbitrary units. If the resolution is non-zero, the
|
||||
pressure data is in units/gram. For example, a value of 10 with a
|
||||
resolution of 1 represents 10 gram, a value of 10 with a resolution on
|
||||
resolution of 1 represents 10 gram, a value of 10 with a resolution of
|
||||
1000 represents 10 microgram.
|
||||
|
||||
EV_SW
|
||||
|
@ -344,7 +344,7 @@ INPUT_PROP_BUTTONPAD
|
|||
|
||||
For touchpads where the button is placed beneath the surface, such that
|
||||
pressing down on the pad causes a button click, this property should be
|
||||
set. Common in clickpad notebooks and macbooks from 2009 and onwards.
|
||||
set. Common in Clickpad notebooks and Macbooks from 2009 and onwards.
|
||||
|
||||
Originally, the buttonpad property was coded into the bcm5974 driver
|
||||
version field under the name integrated button. For backwards
|
||||
|
@ -356,7 +356,7 @@ INPUT_PROP_SEMI_MT
|
|||
Some touchpads, most common between 2008 and 2011, can detect the presence
|
||||
of multiple contacts without resolving the individual positions; only the
|
||||
number of contacts and a rectangular shape is known. For such
|
||||
touchpads, the semi-mt property should be set.
|
||||
touchpads, the SEMI_MT property should be set.
|
||||
|
||||
Depending on the device, the rectangle may enclose all touches, like a
|
||||
bounding box, or just some of them, for instance the two most recent
|
||||
|
@ -394,7 +394,7 @@ Guidelines
|
|||
==========
|
||||
|
||||
The guidelines below ensure proper single-touch and multi-finger functionality.
|
||||
For multi-touch functionality, see the multi-touch-protocol.txt document for
|
||||
For multi-touch functionality, see the multi-touch-protocol.rst document for
|
||||
more information.
|
||||
|
||||
Mice
|
||||
|
|
|
@ -16,8 +16,8 @@ goal is not to support these devices as if they were simple input-only devices
|
|||
(as it is already the case), but to really enable the rendering of force
|
||||
effects.
|
||||
This document only describes the force feedback part of the Linux input
|
||||
interface. Please read joystick.txt and input.txt before reading further this
|
||||
document.
|
||||
interface. Please read joydev/joystick.rst and input.rst before reading further
|
||||
this document.
|
||||
|
||||
Instructions to the user
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
@ -36,7 +36,7 @@ should keep a hand on your device, in order to avoid it to break down if
|
|||
something goes wrong.
|
||||
|
||||
If you have a serial iforce device, you need to start inputattach. See
|
||||
joystick.txt for details.
|
||||
joydev/joystick.rst for details.
|
||||
|
||||
Does it work ?
|
||||
--------------
|
||||
|
|
|
@ -21,7 +21,7 @@ choose which one to program the hardware to, starting from the more exotic
|
|||
addresses is preferred, because the likelihood of clashing with the standard
|
||||
0x201 address is smaller.
|
||||
|
||||
Eg. if your driver supports addresses 0x200, 0x208, 0x210 and 0x218, then
|
||||
E.g. if your driver supports addresses 0x200, 0x208, 0x210 and 0x218, then
|
||||
0x218 would be the address of first choice.
|
||||
|
||||
If your hardware supports a gameport address that is not mapped to ISA io
|
||||
|
@ -78,7 +78,7 @@ the gameport. To register a cooked gameport::
|
|||
|
||||
for (i = 0; i < 4; i++)
|
||||
axes[i] = my_mmio[i];
|
||||
buttons[i] = my_mmio[4];
|
||||
buttons[0] = my_mmio[4];
|
||||
}
|
||||
|
||||
int my_open(struct gameport *gameport, int mode)
|
||||
|
@ -117,25 +117,28 @@ Simple::
|
|||
The gameport structure
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. note::
|
||||
|
||||
This section is outdated. There are several fields here that don't
|
||||
match what's there at include/linux/gameport.h.
|
||||
|
||||
::
|
||||
|
||||
struct gameport {
|
||||
|
||||
void *private;
|
||||
void *port_data;
|
||||
|
||||
A private pointer for free use in the gameport driver. (Not the joystick
|
||||
driver!)
|
||||
|
||||
::
|
||||
|
||||
int number;
|
||||
char name[32];
|
||||
|
||||
Number assigned to the gameport when registered. Informational purpose only.
|
||||
Driver's name as set by driver calling gameport_set_name(). Informational
|
||||
purpose only.
|
||||
|
||||
::
|
||||
|
||||
char phys[32];
|
||||
|
||||
gameport's physical name/description as set by driver calling gameport_set_phys().
|
||||
Informational purpose only.
|
||||
|
||||
::
|
||||
|
||||
|
@ -210,8 +213,16 @@ gameport.
|
|||
|
||||
::
|
||||
|
||||
struct gameport_dev *dev;
|
||||
struct gameport *next;
|
||||
struct timer_list poll_timer;
|
||||
unsigned int poll_interval; /* in msecs */
|
||||
spinlock_t timer_lock;
|
||||
unsigned int poll_cnt;
|
||||
void (*poll_handler)(struct gameport *);
|
||||
struct gameport *parent, *child;
|
||||
struct gameport_driver *drv;
|
||||
struct mutex drv_mutex; /* protects serio->drv so attributes can pin driver */
|
||||
struct device dev;
|
||||
struct list_head node;
|
||||
|
||||
For internal use by the gameport layer.
|
||||
|
||||
|
|
|
@ -120,7 +120,7 @@ Then there is the::
|
|||
|
||||
call to tell those who receive the events that we've sent a complete report.
|
||||
This doesn't seem important in the one button case, but is quite important
|
||||
for for example mouse movement, where you don't want the X and Y values
|
||||
for example for mouse movement, where you don't want the X and Y values
|
||||
to be interpreted separately, because that'd result in a different movement.
|
||||
|
||||
dev->open() and dev->close()
|
||||
|
@ -128,7 +128,7 @@ dev->open() and dev->close()
|
|||
|
||||
In case the driver has to repeatedly poll the device, because it doesn't
|
||||
have an interrupt coming from it and the polling is too expensive to be done
|
||||
all the time, or if the device uses a valuable resource (eg. interrupt), it
|
||||
all the time, or if the device uses a valuable resource (e.g. interrupt), it
|
||||
can use the open and close callback to know when it can stop polling or
|
||||
release the interrupt and when it must resume polling or grab the interrupt
|
||||
again. To do that, we would add this to our example driver::
|
||||
|
@ -161,7 +161,7 @@ makes sure that dev->open() is called only when the first user connects
|
|||
to the device and that dev->close() is called when the very last user
|
||||
disconnects. Calls to both callbacks are serialized.
|
||||
|
||||
The open() callback should return a 0 in case of success or any nonzero value
|
||||
The open() callback should return a 0 in case of success or any non-zero value
|
||||
in case of failure. The close() callback (which is void) must always succeed.
|
||||
|
||||
Inhibiting input devices
|
||||
|
@ -182,8 +182,8 @@ providing events to the input core.
|
|||
|
||||
Calling the device's close() method on inhibit (if there are users) allows the
|
||||
driver to save power. Either by directly powering down the device or by
|
||||
releasing the runtime-pm reference it got in open() when the driver is using
|
||||
runtime-pm.
|
||||
releasing the runtime-PM reference it got in open() when the driver is using
|
||||
runtime-PM.
|
||||
|
||||
Inhibiting and uninhibiting are orthogonal to opening and closing the device by
|
||||
input handlers. Userspace might want to inhibit a device in anticipation before
|
||||
|
@ -219,8 +219,8 @@ It's reported to the input system via::
|
|||
input_report_key(struct input_dev *dev, int code, int value)
|
||||
|
||||
See uapi/linux/input-event-codes.h for the allowable values of code (from 0 to
|
||||
KEY_MAX). Value is interpreted as a truth value, ie any nonzero value means key
|
||||
pressed, zero value means key released. The input code generates events only
|
||||
KEY_MAX). Value is interpreted as a truth value, i.e. any non-zero value means
|
||||
key pressed, zero value means key released. The input code generates events only
|
||||
in case the value is different from before.
|
||||
|
||||
In addition to EV_KEY, there are two more basic event types: EV_REL and
|
||||
|
@ -231,12 +231,12 @@ because it doesn't have any absolute coordinate system to work in. Absolute
|
|||
events are namely for joysticks and digitizers - devices that do work in an
|
||||
absolute coordinate systems.
|
||||
|
||||
Having the device report EV_REL buttons is as simple as with EV_KEY, simply
|
||||
Having the device report EV_REL buttons is as simple as with EV_KEY; simply
|
||||
set the corresponding bits and call the::
|
||||
|
||||
input_report_rel(struct input_dev *dev, int code, int value)
|
||||
|
||||
function. Events are generated only for nonzero value.
|
||||
function. Events are generated only for non-zero values.
|
||||
|
||||
However EV_ABS requires a little special care. Before calling
|
||||
input_register_device, you have to fill additional fields in the input_dev
|
||||
|
@ -280,7 +280,7 @@ device driver. It's a string like 'Generic button device' containing a
|
|||
user friendly name of the device.
|
||||
|
||||
The id* fields contain the bus ID (PCI, USB, ...), vendor ID and device ID
|
||||
of the device. The bus IDs are defined in input.h. The vendor and device ids
|
||||
of the device. The bus IDs are defined in input.h. The vendor and device IDs
|
||||
are defined in pci_ids.h, usb_ids.h and similar include files. These fields
|
||||
should be set by the input device driver before registering it.
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ Introduction
|
|||
Architecture
|
||||
============
|
||||
|
||||
Input subsystem a collection of drivers that is designed to support
|
||||
Input subsystem is a collection of drivers that is designed to support
|
||||
all input devices under Linux. Most of the drivers reside in
|
||||
drivers/input, although quite a few live in drivers/hid and
|
||||
drivers/platform.
|
||||
|
@ -50,7 +50,7 @@ will be available as a character device on major 13, minor 63::
|
|||
|
||||
crw-r--r-- 1 root root 13, 63 Mar 28 22:45 mice
|
||||
|
||||
This device usually created automatically by the system. The commands
|
||||
This device is usually created automatically by the system. The commands
|
||||
to create it by hand are::
|
||||
|
||||
cd /dev
|
||||
|
@ -180,7 +180,7 @@ whole suite. It handles all HID devices, and because there is a very
|
|||
wide variety of them, and because the USB HID specification isn't
|
||||
simple, it needs to be this big.
|
||||
|
||||
Currently, it handles USB mice, joysticks, gamepads, steering wheels
|
||||
Currently, it handles USB mice, joysticks, gamepads, steering wheels,
|
||||
keyboards, trackballs and digitizers.
|
||||
|
||||
However, USB uses HID also for monitor controls, speaker controls, UPSs,
|
||||
|
@ -268,7 +268,7 @@ events on a read. Their layout is::
|
|||
};
|
||||
|
||||
``time`` is the timestamp, it returns the time at which the event happened.
|
||||
Type is for example EV_REL for relative moment, EV_KEY for a keypress or
|
||||
Type is for example EV_REL for relative movement, EV_KEY for a keypress or
|
||||
release. More types are defined in include/uapi/linux/input-event-codes.h.
|
||||
|
||||
``code`` is event code, for example REL_X or KEY_BACKSPACE, again a complete
|
||||
|
|
|
@ -261,7 +261,7 @@ ABS_MT_PRESSURE
|
|||
signal intensity distribution.
|
||||
|
||||
If the resolution is zero, the pressure data is in arbitrary units.
|
||||
If the resolution is nonzero, the pressure data is in units/gram. See
|
||||
If the resolution is non-zero, the pressure data is in units/gram. See
|
||||
:ref:`input-event-codes` for details.
|
||||
|
||||
ABS_MT_DISTANCE
|
||||
|
@ -279,14 +279,14 @@ ABS_MT_ORIENTATION
|
|||
max should be returned; when aligned with the X axis in the negative
|
||||
direction, the range -max should be returned.
|
||||
|
||||
Touch ellipsis are symmetrical by default. For devices capable of true 360
|
||||
Touch ellipses are symmetrical by default. For devices capable of true 360
|
||||
degree orientation, the reported orientation must exceed the range max to
|
||||
indicate more than a quarter of a revolution. For an upside-down finger,
|
||||
range max * 2 should be returned.
|
||||
|
||||
Orientation can be omitted if the touch area is circular, or if the
|
||||
information is not available in the kernel driver. Partial orientation
|
||||
support is possible if the device can distinguish between the two axis, but
|
||||
support is possible if the device can distinguish between the two axes, but
|
||||
not (uniquely) any values in between. In such cases, the range of
|
||||
ABS_MT_ORIENTATION should be [0, 1] [#f4]_.
|
||||
|
||||
|
@ -356,7 +356,7 @@ The range of ABS_MT_ORIENTATION should be set to [0, 1], to indicate that
|
|||
the device can distinguish between a finger along the Y axis (0) and a
|
||||
finger along the X axis (1).
|
||||
|
||||
For win8 devices with both T and C coordinates, the position mapping is::
|
||||
For Win8 devices with both T and C coordinates, the position mapping is::
|
||||
|
||||
ABS_MT_POSITION_X := T_X
|
||||
ABS_MT_POSITION_Y := T_Y
|
||||
|
|
|
@ -4,11 +4,12 @@ Keyboard notifier
|
|||
|
||||
One can use register_keyboard_notifier to get called back on keyboard
|
||||
events (see kbd_keycode() function for details). The passed structure is
|
||||
keyboard_notifier_param:
|
||||
keyboard_notifier_param (see <linux/keyboard.h>):
|
||||
|
||||
- 'vc' always provide the VC for which the keyboard event applies;
|
||||
- 'down' is 1 for a key press event, 0 for a key release;
|
||||
- 'shift' is the current modifier state, mask bit indexes are KG_*;
|
||||
- 'ledstate' is the current LED state;
|
||||
- 'value' depends on the type of event.
|
||||
|
||||
- KBD_KEYCODE events are always sent before other events, value is the keycode.
|
||||
|
|
|
@ -179,7 +179,7 @@ uinput old interface
|
|||
--------------------
|
||||
|
||||
Before uinput version 5, there wasn't a dedicated ioctl to set up a virtual
|
||||
device. Programs supportinf older versions of uinput interface need to fill
|
||||
device. Programs supporting older versions of uinput interface need to fill
|
||||
a uinput_user_dev structure and write it to the uinput file descriptor to
|
||||
configure the new uinput device. New code should not use the old interface
|
||||
but interact with uinput via ioctl calls, or use libevdev.
|
||||
|
|
|
@ -23,7 +23,7 @@ from 93.75 mA to 1500 mA.The Flash currents are adjusted via the CURRENT
|
|||
CONTROL REGISTER(0x09).Flash mode is activated by the ENABLE REGISTER(0x0A),
|
||||
or by pulling the STROBE pin HIGH.
|
||||
|
||||
LM3556 Flash can be controlled through sys/class/leds/flash/brightness file
|
||||
LM3556 Flash can be controlled through /sys/class/leds/flash/brightness file
|
||||
|
||||
* if STROBE pin is enabled, below example control brightness only, and
|
||||
ON / OFF will be controlled by STROBE pin.
|
||||
|
@ -32,17 +32,17 @@ Flash Example:
|
|||
|
||||
OFF::
|
||||
|
||||
#echo 0 > sys/class/leds/flash/brightness
|
||||
#echo 0 > /sys/class/leds/flash/brightness
|
||||
|
||||
93.75 mA::
|
||||
|
||||
#echo 1 > sys/class/leds/flash/brightness
|
||||
#echo 1 > /sys/class/leds/flash/brightness
|
||||
|
||||
...
|
||||
|
||||
1500 mA::
|
||||
|
||||
#echo 16 > sys/class/leds/flash/brightness
|
||||
#echo 16 > /sys/class/leds/flash/brightness
|
||||
|
||||
Torch Mode
|
||||
^^^^^^^^^^
|
||||
|
@ -51,7 +51,7 @@ In Torch Mode, the current source(LED) is programmed via the CURRENT CONTROL
|
|||
REGISTER(0x09).Torch Mode is activated by the ENABLE REGISTER(0x0A) or by the
|
||||
hardware TORCH input.
|
||||
|
||||
LM3556 torch can be controlled through sys/class/leds/torch/brightness file.
|
||||
LM3556 torch can be controlled through /sys/class/leds/torch/brightness file.
|
||||
* if TORCH pin is enabled, below example control brightness only,
|
||||
and ON / OFF will be controlled by TORCH pin.
|
||||
|
||||
|
@ -59,22 +59,22 @@ Torch Example:
|
|||
|
||||
OFF::
|
||||
|
||||
#echo 0 > sys/class/leds/torch/brightness
|
||||
#echo 0 > /sys/class/leds/torch/brightness
|
||||
|
||||
46.88 mA::
|
||||
|
||||
#echo 1 > sys/class/leds/torch/brightness
|
||||
#echo 1 > /sys/class/leds/torch/brightness
|
||||
|
||||
...
|
||||
|
||||
375 mA::
|
||||
|
||||
#echo 8 > sys/class/leds/torch/brightness
|
||||
#echo 8 > /sys/class/leds/torch/brightness
|
||||
|
||||
Indicator Mode
|
||||
^^^^^^^^^^^^^^
|
||||
|
||||
Indicator pattern can be set through sys/class/leds/indicator/pattern file,
|
||||
Indicator pattern can be set through /sys/class/leds/indicator/pattern file,
|
||||
and 4 patterns are pre-defined in indicator_pattern array.
|
||||
|
||||
According to N-lank, Pulse time and N Period values, different pattern wiill
|
||||
|
@ -87,13 +87,13 @@ Indicator pattern example:
|
|||
|
||||
pattern 0::
|
||||
|
||||
#echo 0 > sys/class/leds/indicator/pattern
|
||||
#echo 0 > /sys/class/leds/indicator/pattern
|
||||
|
||||
...
|
||||
|
||||
pattern 3::
|
||||
|
||||
#echo 3 > sys/class/leds/indicator/pattern
|
||||
#echo 3 > /sys/class/leds/indicator/pattern
|
||||
|
||||
Indicator brightness can be controlled through
|
||||
sys/class/leds/indicator/brightness file.
|
||||
|
@ -102,17 +102,17 @@ Example:
|
|||
|
||||
OFF::
|
||||
|
||||
#echo 0 > sys/class/leds/indicator/brightness
|
||||
#echo 0 > /sys/class/leds/indicator/brightness
|
||||
|
||||
5.86 mA::
|
||||
|
||||
#echo 1 > sys/class/leds/indicator/brightness
|
||||
#echo 1 > /sys/class/leds/indicator/brightness
|
||||
|
||||
...
|
||||
|
||||
46.875mA::
|
||||
|
||||
#echo 8 > sys/class/leds/indicator/brightness
|
||||
#echo 8 > /sys/class/leds/indicator/brightness
|
||||
|
||||
Notes
|
||||
-----
|
||||
|
|
|
@ -165,8 +165,8 @@ In-flight parent objects
|
|||
|
||||
Sometimes it may not be convenient or possible to allocate shadow
|
||||
variables alongside their parent objects. Or a livepatch fix may
|
||||
require shadow varibles to only a subset of parent object instances. In
|
||||
these cases, the klp_shadow_get_or_alloc() call can be used to attach
|
||||
require shadow variables for only a subset of parent object instances.
|
||||
In these cases, the klp_shadow_get_or_alloc() call can be used to attach
|
||||
shadow variables to parents already in-flight.
|
||||
|
||||
For commit 1d147bfa6429, a good spot to allocate a shadow spinlock is
|
||||
|
|
|
@ -94,7 +94,7 @@ should:
|
|||
|
||||
a) add your platform support as a _boolean_ option in
|
||||
arch/powerpc/Kconfig, following the example of PPC_PSERIES,
|
||||
PPC_PMAC and PPC_MAPLE. The later is probably a good
|
||||
PPC_PMAC and PPC_MAPLE. The latter is probably a good
|
||||
example of a board support to start from.
|
||||
|
||||
b) create your main platform file as
|
||||
|
|
|
@ -4,7 +4,7 @@ DAWR issues on POWER9
|
|||
|
||||
On POWER9 the Data Address Watchpoint Register (DAWR) can cause a checkstop
|
||||
if it points to cache inhibited (CI) memory. Currently Linux has no way to
|
||||
disinguish CI memory when configuring the DAWR, so (for now) the DAWR is
|
||||
distinguish CI memory when configuring the DAWR, so (for now) the DAWR is
|
||||
disabled by this commit::
|
||||
|
||||
commit 9654153158d3e0684a1bdb76dbababdb7111d5a0
|
||||
|
|
|
@ -73,7 +73,7 @@ return all-ff's (0xff, 0xffff, 0xffffffff for 8/16/32-bit reads).
|
|||
This value was chosen because it is the same value you would
|
||||
get if the device was physically unplugged from the slot.
|
||||
This includes access to PCI memory, I/O space, and PCI config
|
||||
space. Interrupts; however, will continued to be delivered.
|
||||
space. Interrupts; however, will continue to be delivered.
|
||||
|
||||
Detection and recovery are performed with the aid of ppc64
|
||||
firmware. The programming interfaces in the Linux kernel
|
||||
|
|
|
@ -8,7 +8,7 @@ capabilities and information which can be used by a bootloader or userland.
|
|||
Types and Descriptors
|
||||
---------------------
|
||||
|
||||
The types to be used with the "PowerPC" namesapce are defined in [#f1]_.
|
||||
The types to be used with the "PowerPC" namespace are defined in [#f1]_.
|
||||
|
||||
1) PPC_ELFNOTE_CAPABILITIES
|
||||
|
||||
|
|
|
@ -171,7 +171,7 @@ that were present in CMA region::
|
|||
(meta area) |
|
||||
|
|
||||
|
|
||||
Metadata: This area holds a metadata struture whose
|
||||
Metadata: This area holds a metadata structure whose
|
||||
address is registered with f/w and retrieved in the
|
||||
second kernel after crash, on platforms that support
|
||||
tags (OPAL). Having such structure with info needed
|
||||
|
@ -207,7 +207,7 @@ Currently the dump will be copied from /proc/vmcore to a new file upon
|
|||
user intervention. The dump data available through /proc/vmcore will be
|
||||
in ELF format. Hence the existing kdump infrastructure (kdump scripts)
|
||||
to save the dump works fine with minor modifications. KDump scripts on
|
||||
major Distro releases have already been modified to work seemlessly (no
|
||||
major Distro releases have already been modified to work seamlessly (no
|
||||
user intervention in saving the dump) when FADump is used, instead of
|
||||
KDump, as dump mechanism.
|
||||
|
||||
|
|
|
@ -38,5 +38,5 @@ bit of the entropy to decide the index of the 64M zone. Then we chose a
|
|||
|
||||
kernstart_virt_addr
|
||||
|
||||
To enable KASLR, set CONFIG_RANDOMIZE_BASE = y. If KASLR is enable and you
|
||||
To enable KASLR, set CONFIG_RANDOMIZE_BASE = y. If KASLR is enabled and you
|
||||
want to disable it at runtime, add "nokaslr" to the kernel cmdline.
|
||||
|
|
|
@ -34,7 +34,7 @@ To compile/use :
|
|||
Some remarks:
|
||||
|
||||
- The port is named mpc52xxx, and config options are PPC_MPC52xx. The MGT5100
|
||||
is not supported, and I'm not sure anyone is interesting in working on it
|
||||
is not supported, and I'm not sure anyone is interested in working on it
|
||||
so. I didn't took 5xxx because there's apparently a lot of 5xxx that have
|
||||
nothing to do with the MPC5200. I also included the 'MPC' for the same
|
||||
reason.
|
||||
|
|
|
@ -40,7 +40,7 @@ and any in-arguments for the hcall are provided in registers *r4-r12*. If values
|
|||
have to be passed through a memory buffer, the data stored in that buffer should be
|
||||
in Big-endian byte order.
|
||||
|
||||
Once control is returns back to the guest after hypervisor has serviced the
|
||||
Once control returns back to the guest after hypervisor has serviced the
|
||||
'HVCS' instruction the return value of the hcall is available in *r3* and any
|
||||
out values are returned in registers *r4-r12*. Again like in case of in-arguments,
|
||||
any out values stored in a memory buffer will be in Big-endian byte order.
|
||||
|
@ -147,7 +147,7 @@ corresponding opcode values please look into the arch specific header [4]_:
|
|||
| Out: *numBytesRead*
|
||||
| Return Value: *H_Success, H_Parameter, H_P2, H_P3, H_Hardware*
|
||||
|
||||
Given a DRC Index of an NVDIMM, read N-bytes from the the metadata area
|
||||
Given a DRC Index of an NVDIMM, read N-bytes from the metadata area
|
||||
associated with it, at a specified offset and copy it to provided buffer.
|
||||
The metadata area stores configuration information such as label information,
|
||||
bad-blocks etc. The metadata area is located out-of-band of NVDIMM storage
|
||||
|
|
|
@ -189,7 +189,7 @@ kernel aborted a transaction:
|
|||
====================== ================================
|
||||
|
||||
These can be checked by the user program's abort handler as TEXASR[0:7]. If
|
||||
bit 7 is set, it indicates that the error is consider persistent. For example
|
||||
bit 7 is set, it indicates that the error is considered persistent. For example
|
||||
a TM_CAUSE_ALIGNMENT will be persistent while a TM_CAUSE_RESCHED will not.
|
||||
|
||||
GDB
|
||||
|
@ -271,4 +271,4 @@ with these lines:
|
|||
|
||||
hrfid and mtmsrd have the same quirk.
|
||||
|
||||
The Linux kernel uses this quirk in it's early exception handling.
|
||||
The Linux kernel uses this quirk in its early exception handling.
|
||||
|
|
|
@ -341,6 +341,16 @@ that you have sent your patches to the right place. Wait for a minimum of
|
|||
one week before resubmitting or pinging reviewers - possibly longer during
|
||||
busy times like merge windows.
|
||||
|
||||
It's also ok to resend the patch or the patch series after a couple of
|
||||
weeks with the word "RESEND" added to the subject line::
|
||||
|
||||
[PATCH Vx RESEND] sub/sys: Condensed patch summary
|
||||
|
||||
Don't add "RESEND" when you are submitting a modified version of your
|
||||
patch or patch series - "RESEND" only applies to resubmission of a
|
||||
patch or patch series which have not been modified in any way from the
|
||||
previous submission.
|
||||
|
||||
|
||||
Include PATCH in the subject
|
||||
-----------------------------
|
||||
|
@ -625,16 +635,19 @@ not considered part of the summary phrase, but describe how the patch
|
|||
should be treated. Common tags might include a version descriptor if
|
||||
the multiple versions of the patch have been sent out in response to
|
||||
comments (i.e., "v1, v2, v3"), or "RFC" to indicate a request for
|
||||
comments. If there are four patches in a patch series the individual
|
||||
patches may be numbered like this: 1/4, 2/4, 3/4, 4/4. This assures
|
||||
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.
|
||||
comments.
|
||||
|
||||
A couple of example Subjects::
|
||||
If there are four patches in a patch series the individual patches may
|
||||
be numbered like this: 1/4, 2/4, 3/4, 4/4. This assures 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.
|
||||
|
||||
Here are some good example Subjects::
|
||||
|
||||
Subject: [PATCH 2/5] ext2: improve scalability of bitmap searching
|
||||
Subject: [PATCH v2 01/27] x86: fix eflags tracking
|
||||
Subject: [PATCH v2] sub/sys: Condensed patch summary
|
||||
Subject: [PATCH v2 M/N] sub/sys: Condensed patch summary
|
||||
|
||||
The ``from`` line must be the very first line in the message body,
|
||||
and has the form:
|
||||
|
@ -647,34 +660,54 @@ 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
|
||||
changelog, so should make sense to a competent reader who has long
|
||||
since forgotten the immediate details of the discussion that might
|
||||
have led to this patch. Including symptoms of the failure which the
|
||||
patch addresses (kernel log messages, oops messages, etc.) is
|
||||
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
|
||||
well as descriptive.
|
||||
changelog, so should make sense to a competent reader who has long since
|
||||
forgotten the immediate details of the discussion that might have led to
|
||||
this patch. Including symptoms of the failure which the patch addresses
|
||||
(kernel log messages, oops messages, etc.) are especially useful for
|
||||
people who might be searching the commit logs looking for the applicable
|
||||
patch. The text should be written in such detail so that when read
|
||||
weeks, months or even years later, it can give the reader the needed
|
||||
details to grasp the reasoning for **why** the patch was created.
|
||||
|
||||
The ``---`` marker line serves the essential purpose of marking for patch
|
||||
handling tools where the changelog message ends.
|
||||
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 well as descriptive.
|
||||
|
||||
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``
|
||||
which describe what has changed between the v1 and v2 version of the
|
||||
patch.
|
||||
The ``---`` marker line serves the essential purpose of marking for
|
||||
patch handling tools where the changelog message ends.
|
||||
|
||||
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``
|
||||
generates appropriate diffstats by default.)
|
||||
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. 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`` generates appropriate diffstats by default.)
|
||||
|
||||
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`` which describe
|
||||
what has changed between the v1 and v2 version of the patch.
|
||||
|
||||
Please put this information **after** the ``---`` line which separates
|
||||
the changelog from the rest of the patch. The version information is
|
||||
not part of the changelog which gets committed to the git tree. It is
|
||||
additional information for the reviewers. If it's placed above the
|
||||
commit tags, it needs manual interaction to remove it. If it is below
|
||||
the separator line, it gets automatically stripped off when applying the
|
||||
patch::
|
||||
|
||||
<commit message>
|
||||
...
|
||||
Signed-off-by: Author <author@mail>
|
||||
---
|
||||
V2 -> V3: Removed redundant helper function
|
||||
V1 -> V2: Cleaned up coding style and addressed review comments
|
||||
|
||||
path/to/file | 5+++--
|
||||
...
|
||||
|
||||
See more details on the proper patch format in the following
|
||||
references.
|
||||
|
|
|
@ -220,7 +220,7 @@ Older Version : 2.20.4.5 (scsi module), 2.20.2.5 (cmm module)
|
|||
|
||||
4. Use the pre defined DMA mask constants from dma-mapping.h
|
||||
Use the DMA_{64,32}BIT_MASK constants from dma-mapping.h when calling
|
||||
pci_set_dma_mask() or pci_set_consistend_dma_mask(). See
|
||||
pci_set_dma_mask() or pci_set_consistent_dma_mask(). See
|
||||
http://marc.theaimsgroup.com/?t=108001993000001&r=1&w=2 for more
|
||||
details.
|
||||
Signed-off-by: Tobias Klauser <tklauser@nuerscht.ch>
|
||||
|
|
|
@ -22,7 +22,7 @@ u"""
|
|||
|
||||
* *auto span* rightmost cell of a table row over the missing cells on the
|
||||
right side of that table-row. With Option ``:fill-cells:`` this behavior
|
||||
can changed from *auto span* to *auto fill*, which automaticly inserts
|
||||
can be changed from *auto span* to *auto fill*, which automatically inserts
|
||||
(empty) cells instead of spanning the last cell.
|
||||
|
||||
Options:
|
||||
|
@ -161,7 +161,7 @@ class ListTableBuilder(object):
|
|||
for colwidth in colwidths:
|
||||
colspec = nodes.colspec(colwidth=colwidth)
|
||||
# FIXME: It seems, that the stub method only works well in the
|
||||
# absence of rowspan (observed by the html buidler, the docutils-xml
|
||||
# absence of rowspan (observed by the html builder, the docutils-xml
|
||||
# build seems OK). This is not extraordinary, because there exists
|
||||
# no table directive (except *this* flat-table) which allows to
|
||||
# define coexistent of rowspan and stubs (there was no use-case
|
||||
|
|
|
@ -11,7 +11,7 @@ develop firmware for this, and flash it using this adapter cable.
|
|||
|
||||
You can make this adapter from an old printer cable and solder things
|
||||
directly to the Butterfly. Or (if you have the parts and skills) you
|
||||
can come up with something fancier, providing ciruit protection to the
|
||||
can come up with something fancier, providing circuit protection to the
|
||||
Butterfly and the printer port, or with a better power supply than two
|
||||
signal pins from the printer port. Or for that matter, you can use
|
||||
similar cables to talk to many AVR boards, even a breadboard.
|
||||
|
|
|
@ -330,17 +330,17 @@ la lista di celle che compongono la *riga* stessa. Fanno eccezione i *commenti*
|
|||
- head col 3
|
||||
- head col 4
|
||||
|
||||
* - column 1
|
||||
* - row 1
|
||||
- field 1.1
|
||||
- field 1.2 with autospan
|
||||
|
||||
* - column 2
|
||||
* - row 2
|
||||
- field 2.1
|
||||
- :rspan:`1` :cspan:`1` field 2.2 - 3.3
|
||||
|
||||
* .. _`it last row`:
|
||||
|
||||
- column 3
|
||||
- row 3
|
||||
|
||||
Che verrà rappresentata nel seguente modo:
|
||||
|
||||
|
@ -352,37 +352,46 @@ Che verrà rappresentata nel seguente modo:
|
|||
- head col 3
|
||||
- head col 4
|
||||
|
||||
* - column 1
|
||||
* - row 1
|
||||
- field 1.1
|
||||
- field 1.2 with autospan
|
||||
|
||||
* - column 2
|
||||
* - row 2
|
||||
- field 2.1
|
||||
- :rspan:`1` :cspan:`1` field 2.2 - 3.3
|
||||
|
||||
* .. _`it last row`:
|
||||
|
||||
- column 3
|
||||
- row 3
|
||||
|
||||
Riferimenti incrociati
|
||||
----------------------
|
||||
|
||||
Per fare dei riferimenti incrociati da una pagina ad un'altra
|
||||
specificando il percorso a partire dalla cartella *Documentation*.
|
||||
Per esempio, se volete aggiungere un riferimento a questa pagina
|
||||
(l'estensione .rst è opzionale)::
|
||||
Aggiungere un riferimento incrociato da una pagina della
|
||||
documentazione ad un'altra può essere fatto scrivendo il percorso al
|
||||
file corrispondende, non serve alcuna sintassi speciale. Si possono
|
||||
usare sia percorsi assoluti che relativi. Quelli assoluti iniziano con
|
||||
"documentation/". Per esempio, potete fare riferimento a questo
|
||||
documento in uno dei seguenti modi (da notare che l'estensione
|
||||
``.rst`` è necessaria)::
|
||||
|
||||
See Documentation/translations/it_IT/doc-guide/sphinx.rst.
|
||||
Vedere Documentation/doc-guide/sphinx.rst. Questo funziona sempre
|
||||
Guardate pshinx.rst, che si trova nella stessa cartella.
|
||||
Leggete ../sphinx.rst, che si trova nella cartella precedente.
|
||||
|
||||
Se preferite usare un percorso relative allora vi serve la direttiva
|
||||
Sphinx ``doc``. Per esempio, se volete aggiungere un riferimento a
|
||||
questa pagina dalla stessa cartella::
|
||||
Se volete che il collegamento abbia un testo diverso rispetto al
|
||||
titolo del documento, allora dovrete usare la direttiva Sphinx
|
||||
``doc``. Per esempio::
|
||||
|
||||
See :doc:`sphinx`.
|
||||
Vedere :doc:`il mio testo per il collegamento <sphinx>`.
|
||||
|
||||
Per maggiori informazioni su come aggiungere riferimenti incrociati a
|
||||
commenti kernel-doc di funzioni o tipi, leggete
|
||||
Documentation/translations/it_IT/doc-guide/sphinx.rst.
|
||||
Nella maggioranza dei casi si consiglia il primo metodo perché è più
|
||||
pulito ed adatto a chi legge dai sorgenti. Se incontrare un ``:doc:``
|
||||
che non da alcun valore, sentitevi liberi di convertirlo in un
|
||||
percorso al documento.
|
||||
|
||||
Per informazioni riguardo ai riferimenti incrociati ai commenti
|
||||
kernel-doc per funzioni o tipi, consultate
|
||||
|
||||
.. _it_sphinx_kfigure:
|
||||
|
||||
|
@ -391,7 +400,7 @@ Figure ed immagini
|
|||
|
||||
Se volete aggiungere un'immagine, utilizzate le direttive ``kernel-figure``
|
||||
e ``kernel-image``. Per esempio, per inserire una figura di un'immagine in
|
||||
formato SVG::
|
||||
formato SVG (:ref:`it_svg_image_example`)::
|
||||
|
||||
.. kernel-figure:: ../../../doc-guide/svg_image.svg
|
||||
:alt: una semplice immagine SVG
|
||||
|
|
|
@ -369,7 +369,7 @@ all'inizio dell'avvio del sistema è attraverso la procedura
|
|||
Prima di inventare la vostra cache per gli oggetti più usati, considerate
|
||||
l'uso di una cache slab disponibile in ``include/linux/slab.h``.
|
||||
|
||||
:c:func:`current()`
|
||||
:c:macro:`current`
|
||||
-------------------
|
||||
|
||||
Definita in ``include/asm/current.h``
|
||||
|
|
|
@ -127,11 +127,11 @@ il vostro processo si auto-sospenderà; verrà riattivato quando il mutex
|
|||
verrà rilasciato. Questo significa che il processore potrà occuparsi d'altro
|
||||
mentre il vostro processo è in attesa. Esistono molti casi in cui non potete
|
||||
permettervi di sospendere un processo (vedere
|
||||
:ref:`Quali funzioni possono essere chiamate in modo sicuro dalle interruzioni? <it_sleeping-things>`)
|
||||
`Quali funzioni possono essere chiamate in modo sicuro dalle interruzioni?`_)
|
||||
e quindi dovrete utilizzare gli spinlock.
|
||||
|
||||
Nessuno di questi *lock* è ricorsivo: vedere
|
||||
:ref:`Stallo: semplice ed avanzato <it_deadlock>`
|
||||
`Stallo: semplice ed avanzato`_
|
||||
|
||||
I *lock* e i kernel per sistemi monoprocessore
|
||||
----------------------------------------------
|
||||
|
@ -190,7 +190,7 @@ perfetto questa funzione si chiamerebbe 'spin_lock_softirq()').
|
|||
|
||||
Da notare che in questo caso potete utilizzare anche spin_lock_irq()
|
||||
o spin_lock_irqsave(), queste fermano anche le interruzioni hardware:
|
||||
vedere :ref:`Contesto di interruzione hardware <it_hardirq-context>`.
|
||||
vedere `Contesto di interruzione hardware`_.
|
||||
|
||||
Questo funziona alla perfezione anche sui sistemi monoprocessore: gli spinlock
|
||||
svaniscono e questa macro diventa semplicemente local_bh_disable()
|
||||
|
@ -241,7 +241,7 @@ Lo stesso softirq
|
|||
|
||||
Lo stesso softirq può essere eseguito su un diverso processore: allo scopo
|
||||
di migliorare le prestazioni potete utilizzare dati riservati ad ogni
|
||||
processore (vedere :ref:`Dati per processore <it_per-cpu>`). Se siete arrivati
|
||||
processore (vedere `Dati per processore`_). Se siete arrivati
|
||||
fino a questo punto nell'uso dei softirq, probabilmente tenete alla scalabilità
|
||||
delle prestazioni abbastanza da giustificarne la complessità aggiuntiva.
|
||||
|
||||
|
@ -896,8 +896,6 @@ leggendo solamente il codice. E come dice Alan Cox: “Lock data, not code”.
|
|||
Problemi comuni
|
||||
===============
|
||||
|
||||
.. _`it_deadlock`:
|
||||
|
||||
Stallo: semplice ed avanzato
|
||||
----------------------------
|
||||
|
||||
|
@ -1282,7 +1280,6 @@ Il beneficio qui sta nel fatto che il contatore di riferimenti no
|
|||
viene scritto: l'oggetto non viene alterato in alcun modo e quindi diventa
|
||||
molto più veloce su sistemi molti-processore grazie alla loro memoria cache.
|
||||
|
||||
.. _`it_per-cpu`:
|
||||
|
||||
Dati per processore
|
||||
-------------------
|
||||
|
@ -1333,7 +1330,6 @@ Naturalmente, questo è più lento della semplice chiamata
|
|||
spin_lock_irq(), quindi ha senso solo se questo genere di accesso
|
||||
è estremamente raro.
|
||||
|
||||
.. _`it_sleeping-things`:
|
||||
|
||||
Quali funzioni possono essere chiamate in modo sicuro dalle interruzioni?
|
||||
=========================================================================
|
||||
|
|
|
@ -264,11 +264,10 @@ La maggior parte di queste opzioni possono essere attivate per qualsiasi
|
|||
kernel utilizzato per lo sviluppo o a scopo di test. In particolare dovreste
|
||||
attivare:
|
||||
|
||||
- ENABLE_MUST_CHECK e FRAME_WARN per ottenere degli
|
||||
avvertimenti dedicati a problemi come l'uso di interfacce deprecate o
|
||||
l'ignorare un importante valore di ritorno di una funzione. Il risultato
|
||||
generato da questi avvertimenti può risultare verboso, ma non bisogna
|
||||
preoccuparsi per gli avvertimenti provenienti da altre parti del kernel.
|
||||
- FRAME_WARN per ottenere degli avvertimenti su stack frame più
|
||||
grandi di un dato valore. Il risultato generato da questi
|
||||
avvertimenti può risultare verboso, ma non bisogna preoccuparsi per
|
||||
gli avvertimenti provenienti da altre parti del kernel.
|
||||
|
||||
- DEBUG_OBJECTS aggiungerà un codice per tracciare il ciclo di vita di
|
||||
diversi oggetti creati dal kernel e avvisa quando qualcosa viene eseguito
|
||||
|
|
|
@ -562,7 +562,7 @@ kernel. Se la nuova funzionalità è utile all'interno del kernel, per esempio
|
|||
dev'essere condivisa fra una vecchia e una nuova chiamata di sistema o
|
||||
dev'essere utilizzata da una chiamata di sistema e la sua variante compatibile,
|
||||
allora dev'essere implementata come una funzione di supporto
|
||||
(*helper function*) (per esempio ``kern_xyzzy()``). Questa funzione potrà
|
||||
(*helper function*) (per esempio ``ksys_xyzzy()``). Questa funzione potrà
|
||||
essere chiamata dallo *stub* (``sys_xyzzy()``), dalla variante compatibile
|
||||
(``compat_sys_xyzzy()``), e/o da altri parti del kernel.
|
||||
|
||||
|
|
|
@ -75,9 +75,26 @@ stessa riga:
|
|||
if (condition) do_this;
|
||||
do_something_everytime;
|
||||
|
||||
né mettete più assegnamenti sulla stessa riga. Lo stile del kernel
|
||||
Non usate le virgole per evitare le parentesi:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
if (condition)
|
||||
do_this(), do_that();
|
||||
|
||||
Invece, usate sempre le parentesi per racchiudere più istruzioni.
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
if (condition) {
|
||||
do_this();
|
||||
do_that();
|
||||
}
|
||||
|
||||
Non mettete nemmeno più assegnamenti sulla stessa riga. Lo stile del kernel
|
||||
è ultrasemplice. Evitate espressioni intricate.
|
||||
|
||||
|
||||
Al di fuori dei commenti, della documentazione ed escludendo i Kconfig, gli
|
||||
spazi non vengono mai usati per l'indentazione, e l'esempio qui sopra è
|
||||
volutamente errato.
|
||||
|
@ -320,8 +337,7 @@ qualcosa di simile, **non** dovreste chiamarla ``cntusr()``.
|
|||
|
||||
Codificare il tipo di funzione nel suo nome (quella cosa chiamata notazione
|
||||
ungherese) è stupido - il compilatore conosce comunque il tipo e
|
||||
può verificarli, e inoltre confonde i programmatori. Non c'è da
|
||||
sorprendersi che MicroSoft faccia programmi bacati.
|
||||
può verificarli, e inoltre confonde i programmatori.
|
||||
|
||||
Le variabili LOCALI dovrebbero avere nomi corti, e significativi. Se avete
|
||||
un qualsiasi contatore di ciclo, probabilmente sarà chiamato ``i``.
|
||||
|
|
|
@ -357,17 +357,10 @@ benvenuti.
|
|||
Riportare Bug
|
||||
-------------
|
||||
|
||||
https://bugzilla.kernel.org è dove gli sviluppatori del kernel Linux tracciano
|
||||
i bachi del kernel. Gli utenti sono incoraggiati nel riportare tutti i bachi
|
||||
che trovano utilizzando questo strumento.
|
||||
Per maggiori dettagli su come usare il bugzilla del kernel, guardare:
|
||||
|
||||
https://bugzilla.kernel.org/page.cgi?id=faq.html
|
||||
|
||||
Il file admin-guide/reporting-bugs.rst nella cartella principale del kernel
|
||||
fornisce un buon modello sul come segnalare un baco nel kernel, e spiega quali
|
||||
informazioni sono necessarie agli sviluppatori per poter aiutare il
|
||||
rintracciamento del problema.
|
||||
Il file 'Documentation/admin-guide/reporting-issues.rst' nella
|
||||
cartella principale del kernel spiega come segnalare un baco nel
|
||||
kernel, e fornisce dettagli su quali informazioni sono necessarie agli
|
||||
sviluppatori del kernel per poter studiare il problema.
|
||||
|
||||
Gestire i rapporti sui bug
|
||||
--------------------------
|
||||
|
@ -380,8 +373,14 @@ al corrente della vostra presenza. Riparare bachi è una delle migliori vie per
|
|||
acquisire meriti tra gli altri sviluppatori, perchè non a molte persone piace
|
||||
perdere tempo a sistemare i bachi di altri.
|
||||
|
||||
Per lavorare sui rapporti di bachi già riportati, andate su
|
||||
https://bugzilla.kernel.org.
|
||||
Per lavorare sui bachi già segnalati, per prima cosa cercate il
|
||||
sottosistema che vi interessa. Poi, verificate nel file MAINTAINERS
|
||||
dove vengono collezionati solitamente i bachi per quel sottosistema;
|
||||
spesso sarà una lista di discussione, raramente un bugtracker. Cercate
|
||||
bachi nell'archivio e aiutate dove credete di poterlo fare. Potete
|
||||
anche consultare https://bugzilla.kernel.org; però, solo una manciata di
|
||||
sottosistemi lo usano attivamente, ciò nonostante i bachi che
|
||||
coinvolgono l'intero kernel sono sempre riportati lì.
|
||||
|
||||
Liste di discussione
|
||||
--------------------
|
||||
|
|
|
@ -101,7 +101,6 @@ RFCOMM_TTY_MAGIC 0x6d02 ``net/bluetooth/
|
|||
USB_SERIAL_PORT_MAGIC 0x7301 usb_serial_port ``drivers/usb/serial/usb-serial.h``
|
||||
CG_MAGIC 0x00090255 ufs_cylinder_group ``include/linux/ufs_fs.h``
|
||||
LSEMAGIC 0x05091998 lse ``drivers/fc4/fc.c``
|
||||
GDTIOCTL_MAGIC 0x06030f07 gdth_iowr_str ``drivers/scsi/gdth_ioctl.h``
|
||||
RIEBL_MAGIC 0x09051990 ``drivers/net/atarilance.c``
|
||||
NBD_REQUEST_MAGIC 0x12560953 nbd_request ``include/linux/nbd.h``
|
||||
RED_MAGIC2 0x170fc2a5 (any) ``mm/slab.c``
|
||||
|
@ -144,7 +143,6 @@ PWC_MAGIC 0x89DC10AB pwc_device ``drivers/usb/me
|
|||
NBD_REPLY_MAGIC 0x96744668 nbd_reply ``include/linux/nbd.h``
|
||||
ENI155_MAGIC 0xa54b872d midway_eprom ``drivers/atm/eni.h``
|
||||
CODA_MAGIC 0xC0DAC0DA coda_file_info ``fs/coda/coda_fs_i.h``
|
||||
DPMEM_MAGIC 0xc0ffee11 gdt_pci_sram ``drivers/scsi/gdth.h``
|
||||
YAM_MAGIC 0xF10A7654 yam_port ``drivers/net/hamradio/yam.c``
|
||||
CCB_MAGIC 0xf2691ad2 ccb ``drivers/scsi/ncr53c8xx.c``
|
||||
QUEUE_MAGIC_FREE 0xf7e1c9a3 queue_entry ``drivers/scsi/arm/queue.c``
|
||||
|
|
|
@ -28,6 +28,10 @@ sottomissione delle patch, in particolare
|
|||
|
||||
c) quando si usa ``O=builddir``
|
||||
|
||||
d) Qualsiasi modifica in Documentation/ deve compilare con successo senza
|
||||
avvisi o errori. Usare ``make htmldocs`` o ``make pdfdocs`` per verificare
|
||||
e correggere i problemi
|
||||
|
||||
3) Compilare per diverse architetture di processore usando strumenti per
|
||||
la cross-compilazione o altri.
|
||||
|
||||
|
@ -54,8 +58,7 @@ sottomissione delle patch, in particolare
|
|||
|
||||
9) Verificare con sparse.
|
||||
|
||||
10) Usare ``make checkstack`` e ``make namespacecheck`` e correggere tutti i
|
||||
problemi rilevati.
|
||||
10) Usare ``make checkstack`` e correggere tutti i problemi rilevati.
|
||||
|
||||
.. note::
|
||||
|
||||
|
@ -95,31 +98,29 @@ sottomissione delle patch, in particolare
|
|||
informazioni. Le patch che modificano le interfacce utente dovrebbero
|
||||
essere inviate in copia anche a linux-api@vger.kernel.org.
|
||||
|
||||
20) Verifica che il kernel passi con successo ``make headers_check``
|
||||
|
||||
21) La patch è stata verificata con l'iniezione di fallimenti in slab e
|
||||
20) La patch è stata verificata con l'iniezione di fallimenti in slab e
|
||||
nell'allocazione di pagine. Vedere ``Documentation/fault-injection/``.
|
||||
|
||||
Se il nuovo codice è corposo, potrebbe essere opportuno aggiungere
|
||||
l'iniezione di fallimenti specifici per il sottosistema.
|
||||
|
||||
22) Il nuovo codice è stato compilato con ``gcc -W`` (usate
|
||||
21) Il nuovo codice è stato compilato con ``gcc -W`` (usate
|
||||
``make KCFLAGS=-W``). Questo genererà molti avvisi, ma è ottimo
|
||||
per scovare bachi come "warning: comparison between signed and unsigned".
|
||||
|
||||
23) La patch è stata verificata dopo essere stata inclusa nella serie di patch
|
||||
22) La patch è stata verificata dopo essere stata inclusa nella serie di patch
|
||||
-mm; questo al fine di assicurarsi che continui a funzionare assieme a
|
||||
tutte le altre patch in coda e i vari cambiamenti nei sottosistemi VM, VFS
|
||||
e altri.
|
||||
|
||||
24) Tutte le barriere di sincronizzazione {per esempio, ``barrier()``,
|
||||
23) Tutte le barriere di sincronizzazione {per esempio, ``barrier()``,
|
||||
``rmb()``, ``wmb()``} devono essere accompagnate da un commento nei
|
||||
sorgenti che ne spieghi la logica: cosa fanno e perché.
|
||||
|
||||
25) Se la patch aggiunge nuove chiamate ioctl, allora aggiornate
|
||||
24) Se la patch aggiunge nuove chiamate ioctl, allora aggiornate
|
||||
``Documentation/userspace-api/ioctl/ioctl-number.rst``.
|
||||
|
||||
26) Se il codice che avete modificato dipende o usa una qualsiasi interfaccia o
|
||||
25) Se il codice che avete modificato dipende o usa una qualsiasi interfaccia o
|
||||
funzionalità del kernel che è associata a uno dei seguenti simboli
|
||||
``Kconfig``, allora verificate che il kernel compili con diverse
|
||||
configurazioni dove i simboli sono disabilitati e/o ``=m`` (se c'è la
|
||||
|
|
|
@ -433,6 +433,14 @@ Alcune persone aggiungono delle etichette alla fine. Per ora queste verranno
|
|||
ignorate, ma potete farlo per meglio identificare procedure aziendali interne o
|
||||
per aggiungere dettagli circa la firma.
|
||||
|
||||
In seguito al SoB (Signed-off-by:) dell'autore ve ne sono altri da
|
||||
parte di tutte quelle persone che si sono occupate della gestione e
|
||||
del trasporto della patch. Queste però non sono state coinvolte nello
|
||||
sviluppo, ma la loro sequenza d'apparizione ci racconta il percorso
|
||||
**reale** che una patch a intrapreso dallo sviluppatore, fino al
|
||||
manutentore, per poi giungere a Linus.
|
||||
|
||||
|
||||
Quando utilizzare Acked-by:, Cc:, e Co-developed-by:
|
||||
----------------------------------------------------
|
||||
|
||||
|
@ -574,6 +582,10 @@ kernel stabili al fine di capire quale kernel deve ricevere la correzione.
|
|||
Questo è il modo suggerito per indicare che un baco è stato corretto nella
|
||||
patch. Per maggiori dettagli leggete :ref:`it_describe_changes`
|
||||
|
||||
Da notare che aggiungere un tag "Fixes:" non esime dalle regole
|
||||
previste per i kernel stabili, e nemmeno dalla necessità di aggiungere
|
||||
in copia conoscenza stable@vger.kernel.org su tutte le patch per
|
||||
suddetti kernel.
|
||||
|
||||
Il formato canonico delle patch
|
||||
-------------------------------
|
||||
|
@ -642,16 +654,20 @@ Le etichette non verranno considerate come parte della frase riassuntiva, ma
|
|||
indicano come la patch dovrebbe essere trattata. Fra le etichette più comuni
|
||||
ci sono quelle di versione che vengono usate quando una patch è stata inviata
|
||||
più volte (per esempio, "v1, v2, v3"); oppure "RFC" per indicare che si
|
||||
attendono dei commenti (*Request For Comments*). Se ci sono quattro patch
|
||||
nella serie, queste dovrebbero essere enumerate così: 1/4, 2/4, 3/4, 4/4.
|
||||
Questo assicura che gli sviluppatori capiranno l'ordine in cui le patch
|
||||
dovrebbero essere applicate, e per tracciare quelle che hanno revisionate o
|
||||
che hanno applicato.
|
||||
attendono dei commenti (*Request For Comments*).
|
||||
|
||||
Se ci sono quattro patch nella serie, queste dovrebbero essere
|
||||
enumerate così: 1/4, 2/4, 3/4, 4/4. Questo assicura che gli
|
||||
sviluppatori capiranno l'ordine in cui le patch dovrebbero essere
|
||||
applicate, e per tracciare quelle che hanno revisionate o che hanno
|
||||
applicato.
|
||||
|
||||
Un paio di esempi di oggetti::
|
||||
|
||||
Subject: [PATCH 2/5] ext2: improve scalability of bitmap searching
|
||||
Subject: [PATCH v2 01/27] x86: fix eflags tracking
|
||||
Subject: [PATCH v2] sub/sys: Condensed patch summary
|
||||
Subject: [PATCH v2 M/N] sub/sys: Condensed patch summary
|
||||
|
||||
La riga ``from`` dev'essere la prima nel corpo del messaggio ed è nel
|
||||
formato:
|
||||
|
@ -668,30 +684,76 @@ deve aver senso per un lettore esperto che è ha dimenticato i dettagli della
|
|||
discussione che hanno portato alla patch. L'inclusione di informazioni
|
||||
sui problemi oggetto dalla patch (messaggi del kernel, messaggi di oops,
|
||||
eccetera) è particolarmente utile per le persone che potrebbero cercare fra
|
||||
i messaggi di log per la patch che li tratta. Se la patch corregge un errore
|
||||
di compilazione, non sarà necessario includere proprio _tutto_ quello che
|
||||
è uscito dal compilatore; aggiungete solo quello che è necessario per far si
|
||||
che la vostra patch venga trovata. Come nella ``summary phrase``, è importante
|
||||
essere sia brevi che descrittivi.
|
||||
i messaggi di log per la patch che li tratta. Il testo dovrebbe essere scritto
|
||||
con abbastanza dettagli da far capire al lettore **perché** quella
|
||||
patch fu creata, e questo a distanza di settimane, mesi, o addirittura
|
||||
anni.
|
||||
|
||||
Se la patch corregge un errore di compilazione, non sarà necessario
|
||||
includere proprio _tutto_ quello che è uscito dal compilatore;
|
||||
aggiungete solo quello che è necessario per far si che la vostra patch
|
||||
venga trovata. Come nella ``summary phrase``, è importante essere sia
|
||||
brevi che descrittivi.
|
||||
|
||||
La linea di demarcazione ``---`` serve essenzialmente a segnare dove finisce
|
||||
il messaggio di changelog.
|
||||
|
||||
Aggiungere il ``diffstat`` dopo ``---`` è un buon uso di questo spazio, per
|
||||
mostrare i file che sono cambiati, e il numero di file aggiunto o rimossi.
|
||||
Un ``diffstat`` è particolarmente utile per le patch grandi. Altri commenti
|
||||
che sono importanti solo per i manutentori, quindi inadatti al changelog
|
||||
permanente, dovrebbero essere messi qui. Un buon esempio per questo tipo
|
||||
di commenti potrebbe essere quello di descrivere le differenze fra le versioni
|
||||
Un ``diffstat`` è particolarmente utile per le patch grandi. Se
|
||||
includete un ``diffstat`` dopo ``---``, usate le opzioni ``-p 1 -w70``
|
||||
cosicché i nomi dei file elencati non occupino troppo spazio
|
||||
(facilmente rientreranno negli 80 caratteri, magari con qualche
|
||||
indentazione). (``git`` genera di base dei diffstat adatti).
|
||||
|
||||
I commenti che sono importanti solo per i manutentori, quindi
|
||||
inadatti al changelog permanente, dovrebbero essere messi qui. Un
|
||||
buon esempio per questo tipo di commenti potrebbe essere il cosiddetto
|
||||
``patch changelogs`` che descrivere le differenze fra le versioni
|
||||
della patch.
|
||||
|
||||
Se includete un ``diffstat`` dopo ``---``, usate le opzioni ``-p 1 -w70``
|
||||
cosicché i nomi dei file elencati non occupino troppo spazio (facilmente
|
||||
rientreranno negli 80 caratteri, magari con qualche indentazione).
|
||||
(``git`` genera di base dei diffstat adatti).
|
||||
Queste informazioni devono andare **dopo** la linea ``---`` che separa
|
||||
il *changelog* dal resto della patch. Le informazioni riguardanti la
|
||||
versione di una patch non sono parte del *chagelog* che viene incluso
|
||||
in git. Queste sono informazioni utili solo ai revisori. Se venissero
|
||||
messe sopra la riga, qualcuno dovrà fare del lavoro manuale per
|
||||
rimuoverle; cosa che invece viene fatta automaticamente quando vengono
|
||||
messe correttamente oltre la riga.::
|
||||
|
||||
<commit message>
|
||||
...
|
||||
Signed-off-by: Author <author@mail>
|
||||
---
|
||||
V2 -> V3: Removed redundant helper function
|
||||
V1 -> V2: Cleaned up coding style and addressed review comments
|
||||
|
||||
path/to/file | 5+++--
|
||||
...
|
||||
|
||||
Maggiori dettagli sul formato delle patch nei riferimenti qui di seguito.
|
||||
|
||||
Aggiungere i *backtrace* nei messaggi di commit
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
I *backtrace* aiutano a documentare la sequenza di chiamate a funzione
|
||||
che portano ad un problema. Tuttavia, non tutti i *backtrace* sono
|
||||
davvero utili. Per esempio, le sequenze iniziali di avvio sono uniche
|
||||
e ovvie. Copiare integralmente l'output di ``dmesg`` aggiunge tante
|
||||
informazioni che distraggono dal vero problema (per esempio, i
|
||||
marcatori temporali, la lista dei moduli, la lista dei registri, lo
|
||||
stato dello stack).
|
||||
|
||||
Quindi, per rendere utile un *backtrace* dovreste eliminare le
|
||||
informazioni inutili, cosicché ci si possa focalizzare sul
|
||||
problema. Ecco un esempio di un *backtrace* essenziale::
|
||||
|
||||
unchecked MSR access error: WRMSR to 0xd51 (tried to write 0x0000000000000064)
|
||||
at rIP: 0xffffffffae059994 (native_write_msr+0x4/0x20)
|
||||
Call Trace:
|
||||
mba_wrmsr
|
||||
update_domains
|
||||
rdtgroup_mkdir
|
||||
|
||||
.. _it_explicit_in_reply_to:
|
||||
|
||||
Usare esplicitamente In-Reply-To nell'intestazione
|
||||
|
|
|
@ -88,20 +88,18 @@ Linux カーネルパッチ投稿者向けチェックリスト
|
|||
18: 新しいuserspaceインタフェースを作成した場合には、Documentation/ABI/ に
|
||||
Documentation/ABI/README を参考にして必ずドキュメントを追加してください。
|
||||
|
||||
19: 'make headers_check'を実行して全く問題がないことを確認してください。
|
||||
|
||||
20: 少なくともslabアロケーションとpageアロケーションに失敗した場合の
|
||||
19: 少なくともslabアロケーションとpageアロケーションに失敗した場合の
|
||||
挙動について、fault-injectionを利用して確認してください。
|
||||
Documentation/fault-injection/ を参照してください。
|
||||
|
||||
追加したコードがかなりの量であったならば、サブシステム特有の
|
||||
fault-injectionを追加したほうが良いかもしれません。
|
||||
|
||||
21: 新たに追加したコードは、`gcc -W'でコンパイルしてください。
|
||||
20: 新たに追加したコードは、`gcc -W'でコンパイルしてください。
|
||||
このオプションは大量の不要なメッセージを出力しますが、
|
||||
"warning: comparison between signed and unsigned" のようなメッセージは、
|
||||
バグを見つけるのに役に立ちます。
|
||||
|
||||
22: 投稿したパッチが -mm パッチセットにマージされた後、全ての既存のパッチや
|
||||
21: 投稿したパッチが -mm パッチセットにマージされた後、全ての既存のパッチや
|
||||
VM, VFS およびその他のサブシステムに関する様々な変更と、現時点でも共存
|
||||
できることを確認するテストを行ってください。
|
||||
|
|
|
@ -339,14 +339,8 @@ Andrew Morton의 글이 있다.
|
|||
버그 보고
|
||||
---------
|
||||
|
||||
https://bugzilla.kernel.org 는 리눅스 커널 개발자들이 커널의 버그를 추적하는
|
||||
곳이다. 사용자들은 발견한 모든 버그들을 보고하기 위하여 이 툴을 사용할 것을
|
||||
권장한다. kernel bugzilla를 사용하는 자세한 방법은 다음을 참조하라.
|
||||
|
||||
https://bugzilla.kernel.org/page.cgi?id=faq.html
|
||||
|
||||
메인 커널 소스 디렉토리에 있는 'Documentation/admin-guide/reporting-issues.rst'
|
||||
파일은 커널 버그라고 생각되는 것을 보고하는 방법에 관한 좋은 템플릿이며 문제를
|
||||
파일은 커널 버그라고 생각되는 것을 어떻게 보고하면 되는지, 그리고 문제를
|
||||
추적하기 위해서 커널 개발자들이 필요로 하는 정보가 무엇들인지를 상세히 설명하고
|
||||
있다.
|
||||
|
||||
|
@ -362,8 +356,14 @@ https://bugzilla.kernel.org 는 리눅스 커널 개발자들이 커널의 버
|
|||
점수를 얻을 수 있는 가장 좋은 방법중의 하나이다. 왜냐하면 많은 사람들은
|
||||
다른 사람들의 버그들을 수정하기 위하여 시간을 낭비하지 않기 때문이다.
|
||||
|
||||
이미 보고된 버그 리포트들을 가지고 작업하기 위해서 https://bugzilla.kernel.org
|
||||
를 참조하라.
|
||||
이미 보고된 버그 리포트들을 가지고 작업하기 위해서는 여러분이 관심있는
|
||||
서브시스템을 찾아라. 해당 서브시스템의 버그들이 어디로 리포트 되는지
|
||||
MAINTAINERS 파일을 체크하라; 그건 대부분 메일링 리스트이고, 가끔은 버그 추적
|
||||
시스템이다. 그 장소에 있는 최근 버그 리포트 기록들을 검색하고 여러분이 보기에
|
||||
적합하다 싶은 것을 도와라. 여러분은 버그 리포트를 위해
|
||||
https://bugzilla.kernel.org 를 체크하고자 할 수도 있다; 소수의 커널
|
||||
서브시스템들만이 버그 신고와 추적을 위해 해당 시스템을 실제로 사용하고 있지만,
|
||||
전체 커널의 버그들이 그곳에 정리된다.
|
||||
|
||||
|
||||
메일링 리스트들
|
||||
|
|
|
@ -0,0 +1,347 @@
|
|||
.. include:: ../disclaimer-zh_CN.rst
|
||||
|
||||
:Original: Documentation/admin-guide/README.rst
|
||||
|
||||
:译者:
|
||||
|
||||
吴想成 Wu XiangCheng <bobwxc@email.cn>
|
||||
|
||||
Linux内核5.x版本 <http://kernel.org/>
|
||||
=========================================
|
||||
|
||||
以下是Linux版本5的发行注记。仔细阅读它们,
|
||||
它们会告诉你这些都是什么,解释如何安装内核,以及遇到问题时该如何做。
|
||||
|
||||
什么是Linux?
|
||||
---------------
|
||||
|
||||
Linux是Unix操作系统的克隆版本,由Linus Torvalds在一个松散的网络黑客
|
||||
(Hacker,无贬义)团队的帮助下从头开始编写。它旨在实现兼容POSIX和
|
||||
单一UNIX规范。
|
||||
|
||||
它具有在现代成熟的Unix中应当具有的所有功能,包括真正的多任务处理、虚拟内存、
|
||||
共享库、按需加载、共享的写时拷贝(COW)可执行文件、恰当的内存管理以及包括
|
||||
IPv4和IPv6在内的复合网络栈。
|
||||
|
||||
Linux在GNU通用公共许可证,版本2(GNU GPLv2)下分发,详见随附的COPYING文件。
|
||||
|
||||
它能在什么样的硬件上运行?
|
||||
-----------------------------
|
||||
|
||||
虽然Linux最初是为32位的x86 PC机(386或更高版本)开发的,但今天它也能运行在
|
||||
(至少)Compaq Alpha AXP、Sun SPARC与UltraSPARC、Motorola 68000、PowerPC、
|
||||
PowerPC64、ARM、Hitachi SuperH、Cell、IBM S/390、MIPS、HP PA-RISC、Intel
|
||||
IA-64、DEC VAX、AMD x86-64 Xtensa和ARC架构上。
|
||||
|
||||
Linux很容易移植到大多数通用的32位或64位体系架构,只要它们有一个分页内存管理
|
||||
单元(PMMU)和一个移植的GNU C编译器(gcc;GNU Compiler Collection,GCC的一
|
||||
部分)。Linux也被移植到许多没有PMMU的体系架构中,尽管功能显然受到了一定的
|
||||
限制。
|
||||
Linux也被移植到了其自己上。现在可以将内核作为用户空间应用程序运行——这被
|
||||
称为用户模式Linux(UML)。
|
||||
|
||||
文档
|
||||
-----
|
||||
因特网上和书籍上都有大量的电子文档,既有Linux专属文档,也有与一般UNIX问题相关
|
||||
的文档。我建议在任何Linux FTP站点上查找LDP(Linux文档项目)书籍的文档子目录。
|
||||
本自述文件并不是关于系统的文档:有更好的可用资源。
|
||||
|
||||
- 因特网上和书籍上都有大量的(电子)文档,既有Linux专属文档,也有与普通
|
||||
UNIX问题相关的文档。我建议在任何有LDP(Linux文档项目)书籍的Linux FTP
|
||||
站点上查找文档子目录。本自述文件并不是关于系统的文档:有更好的可用资源。
|
||||
|
||||
- 文档/子目录中有各种自述文件:例如,这些文件通常包含一些特定驱动程序的
|
||||
内核安装说明。请阅读
|
||||
:ref:`Documentation/process/changes.rst <changes>` 文件,它包含了升级内核
|
||||
可能会导致的问题的相关信息。
|
||||
|
||||
安装内核源代码
|
||||
---------------
|
||||
|
||||
- 如果您要安装完整的源代码,请把内核tar档案包放在您有权限的目录中(例如您
|
||||
的主目录)并将其解包::
|
||||
|
||||
xz -cd linux-5.x.tar.xz | tar xvf -
|
||||
|
||||
将“X”替换成最新内核的版本号。
|
||||
|
||||
【不要】使用 /usr/src/linux 目录!这里有一组库头文件使用的内核头文件
|
||||
(通常是不完整的)。它们应该与库匹配,而不是被内核的变化搞得一团糟。
|
||||
|
||||
- 您还可以通过打补丁在5.x版本之间升级。补丁以xz格式分发。要通过打补丁进行
|
||||
安装,请获取所有较新的补丁文件,进入内核源代码(linux-5.x)的目录并
|
||||
执行::
|
||||
|
||||
xz -cd ../patch-5.x.xz | patch -p1
|
||||
|
||||
请【按顺序】替换所有大于当前源代码树版本的“x”,这样就可以了。您可能想要
|
||||
删除备份文件(文件名类似xxx~ 或 xxx.orig),并确保没有失败的补丁(文件名
|
||||
类似xxx# 或 xxx.rej)。如果有,不是你就是我犯了错误。
|
||||
|
||||
与5.x内核的补丁不同,5.x.y内核(也称为稳定版内核)的补丁不是增量的,而是
|
||||
直接应用于基本的5.x内核。例如,如果您的基本内核是5.0,并且希望应用5.0.3
|
||||
补丁,则不应先应用5.0.1和5.0.2的补丁。类似地,如果您运行的是5.0.2内核,
|
||||
并且希望跳转到5.0.3,那么在应用5.0.3补丁之前,必须首先撤销5.0.2补丁
|
||||
(即patch -R)。更多关于这方面的内容,请阅读
|
||||
:ref:`Documentation/process/applying-patches.rst <applying_patches>` 。
|
||||
|
||||
或者,脚本 patch-kernel 可以用来自动化这个过程。它能确定当前内核版本并
|
||||
应用找到的所有补丁::
|
||||
|
||||
linux/scripts/patch-kernel linux
|
||||
|
||||
上面命令中的第一个参数是内核源代码的位置。补丁是在当前目录应用的,但是
|
||||
可以将另一个目录指定为第二个参数。
|
||||
|
||||
- 确保没有过时的 .o 文件和依赖项::
|
||||
|
||||
cd linux
|
||||
make mrproper
|
||||
|
||||
现在您应该已经正确安装了源代码。
|
||||
|
||||
软件要求
|
||||
---------
|
||||
|
||||
编译和运行5.x内核需要各种软件包的最新版本。请参考
|
||||
:ref:`Documentation/process/changes.rst <changes>`
|
||||
来了解最低版本要求以及如何升级软件包。请注意,使用过旧版本的这些包可能会
|
||||
导致很难追踪的间接错误,因此不要以为在生成或操作过程中出现明显问题时可以
|
||||
只更新包。
|
||||
|
||||
为内核建立目录
|
||||
---------------
|
||||
|
||||
编译内核时,默认情况下所有输出文件都将与内核源代码放在一起。使用
|
||||
``make O=output/dir`` 选项可以为输出文件(包括 .config)指定备用位置。
|
||||
例如::
|
||||
|
||||
kernel source code: /usr/src/linux-5.x
|
||||
build directory: /home/name/build/kernel
|
||||
|
||||
要配置和构建内核,请使用::
|
||||
|
||||
cd /usr/src/linux-5.x
|
||||
make O=/home/name/build/kernel menuconfig
|
||||
make O=/home/name/build/kernel
|
||||
sudo make O=/home/name/build/kernel modules_install install
|
||||
|
||||
请注意:如果使用了 ``O=output/dir`` 选项,那么它必须用于make的所有调用。
|
||||
|
||||
配置内核
|
||||
---------
|
||||
|
||||
即使只升级一个小版本,也不要跳过此步骤。每个版本中都会添加新的配置选项,
|
||||
如果配置文件没有按预定设置,就会出现奇怪的问题。如果您想以最少的工作量
|
||||
将现有配置升级到新版本,请使用 ``makeoldconfig`` ,它只会询问您新配置
|
||||
选项的答案。
|
||||
|
||||
- 其他配置命令包括::
|
||||
|
||||
"make config" 纯文本界面。
|
||||
|
||||
"make menuconfig" 基于文本的彩色菜单、选项列表和对话框。
|
||||
|
||||
"make nconfig" 增强的基于文本的彩色菜单。
|
||||
|
||||
"make xconfig" 基于Qt的配置工具。
|
||||
|
||||
"make gconfig" 基于GTK+的配置工具。
|
||||
|
||||
"make oldconfig" 基于现有的 ./.config 文件选择所有选项,并询问
|
||||
新配置选项。
|
||||
|
||||
"make olddefconfig"
|
||||
类似上一个,但不询问直接将新选项设置为默认值。
|
||||
|
||||
"make defconfig" 根据体系架构,使用arch/$arch/defconfig或
|
||||
arch/$arch/configs/${PLATFORM}_defconfig中的
|
||||
默认选项值创建./.config文件。
|
||||
|
||||
"make ${PLATFORM}_defconfig"
|
||||
使用arch/$arch/configs/${PLATFORM}_defconfig中
|
||||
的默认选项值创建一个./.config文件。
|
||||
用“makehelp”来获取您体系架构中所有可用平台的列表。
|
||||
|
||||
"make allyesconfig"
|
||||
通过尽可能将选项值设置为“y”,创建一个
|
||||
./.config文件。
|
||||
|
||||
"make allmodconfig"
|
||||
通过尽可能将选项值设置为“m”,创建一个
|
||||
./.config文件。
|
||||
|
||||
"make allnoconfig" 通过尽可能将选项值设置为“n”,创建一个
|
||||
./.config文件。
|
||||
|
||||
"make randconfig" 通过随机设置选项值来创建./.config文件。
|
||||
|
||||
"make localmodconfig" 基于当前配置和加载的模块(lsmod)创建配置。禁用
|
||||
已加载的模块不需要的任何模块选项。
|
||||
|
||||
要为另一台计算机创建localmodconfig,请将该计算机
|
||||
的lsmod存储到一个文件中,并将其作为lsmod参数传入。
|
||||
|
||||
此外,通过在参数LMC_KEEP中指定模块的路径,可以将
|
||||
模块保留在某些文件夹或kconfig文件中。
|
||||
|
||||
target$ lsmod > /tmp/mylsmod
|
||||
target$ scp /tmp/mylsmod host:/tmp
|
||||
|
||||
host$ make LSMOD=/tmp/mylsmod \
|
||||
LMC_KEEP="drivers/usb:drivers/gpu:fs" \
|
||||
localmodconfig
|
||||
|
||||
上述方法在交叉编译时也适用。
|
||||
|
||||
"make localyesconfig" 与localmodconfig类似,只是它会将所有模块选项转换
|
||||
为内置(=y)。你可以同时通过LMC_KEEP保留模块。
|
||||
|
||||
"make kvmconfig" 为kvm客体内核支持启用其他选项。
|
||||
|
||||
"make xenconfig" 为xen dom0客体内核支持启用其他选项。
|
||||
|
||||
"make tinyconfig" 配置尽可能小的内核。
|
||||
|
||||
更多关于使用Linux内核配置工具的信息,见文档
|
||||
Documentation/kbuild/kconfig.rst。
|
||||
|
||||
- ``make config`` 注意事项:
|
||||
|
||||
- 包含不必要的驱动程序会使内核变大,并且在某些情况下会导致问题:
|
||||
探测不存在的控制器卡可能会混淆其他控制器。
|
||||
|
||||
- 如果存在协处理器,则编译了数学仿真的内核仍将使用协处理器:在
|
||||
这种情况下,数学仿真永远不会被使用。内核会稍微大一点,但不管
|
||||
是否有数学协处理器,都可以在不同的机器上工作。
|
||||
|
||||
- “kernel hacking”配置细节通常会导致更大或更慢的内核(或两者
|
||||
兼而有之),甚至可以通过配置一些例程来主动尝试破坏坏代码以发现
|
||||
内核问题,从而降低内核的稳定性(kmalloc())。因此,您可能应该
|
||||
用于研究“开发”、“实验”或“调试”特性相关问题。
|
||||
|
||||
编译内核
|
||||
---------
|
||||
|
||||
- 确保您至少有gcc 4.9可用。
|
||||
有关更多信息,请参阅 :ref:`Documentation/process/changes.rst <changes>` 。
|
||||
|
||||
请注意,您仍然可以使用此内核运行a.out用户程序。
|
||||
|
||||
- 执行 ``make`` 来创建压缩内核映像。如果您安装了lilo以适配内核makefile,
|
||||
那么也可以进行 ``makeinstall`` ,但是您可能需要先检查特定的lilo设置。
|
||||
|
||||
实际安装必须以root身份执行,但任何正常构建都不需要。
|
||||
无须徒然使用root身份。
|
||||
|
||||
- 如果您将内核的任何部分配置为模块,那么还必须执行 ``make modules_install`` 。
|
||||
|
||||
- 详细的内核编译/生成输出:
|
||||
|
||||
通常,内核构建系统在相当安静的模式下运行(但不是完全安静)。但是有时您或
|
||||
其他内核开发人员需要看到编译、链接或其他命令的执行过程。为此,可使用
|
||||
“verbose(详细)”构建模式。
|
||||
向 ``make`` 命令传递 ``V=1`` 来实现,例如::
|
||||
|
||||
make V=1 all
|
||||
|
||||
如需构建系统也给出内个目标重建的愿意,请使用 ``V=2`` 。默认为 ``V=0`` 。
|
||||
|
||||
- 准备一个备份内核以防出错。对于开发版本尤其如此,因为每个新版本都包含
|
||||
尚未调试的新代码。也要确保保留与该内核对应的模块的备份。如果要安装
|
||||
与工作内核版本号相同的新内核,请在进行 ``make modules_install`` 安装
|
||||
之前备份modules目录。
|
||||
|
||||
或者,在编译之前,使用内核配置选项“LOCALVERSION”向常规内核版本附加
|
||||
一个唯一的后缀。LOCALVERSION可以在“General Setup”菜单中设置。
|
||||
|
||||
- 为了引导新内核,您需要将内核映像(例如编译后的
|
||||
.../linux/arch/x86/boot/bzImage)复制到常规可引导内核的位置。
|
||||
|
||||
- 不再支持在没有LILO等启动装载程序帮助的情况下直接从软盘引导内核。
|
||||
|
||||
如果从硬盘引导Linux,很可能使用LILO,它使用/etc/lilo.conf文件中
|
||||
指定的内核映像文件。内核映像文件通常是/vmlinuz、/boot/vmlinuz、
|
||||
/bzImage或/boot/bzImage。使用新内核前,请保存旧映像的副本,并复制
|
||||
新映像覆盖旧映像。然后您【必须重新运行LILO】来更新加载映射!否则,
|
||||
将无法启动新的内核映像。
|
||||
|
||||
重新安装LILO通常需要运行/sbin/LILO。您可能希望编辑/etc/lilo.conf
|
||||
文件为旧内核映像指定一个条目(例如/vmlinux.old)防止新的不能正常
|
||||
工作。有关更多信息,请参阅LILO文档。
|
||||
|
||||
重新安装LILO之后,您应该就已经准备好了。关闭系统,重新启动,尽情
|
||||
享受吧!
|
||||
|
||||
如果需要更改内核映像中的默认根设备、视频模式等,请在适当的地方使用
|
||||
启动装载程序的引导选项。无需重新编译内核即可更改这些参数。
|
||||
|
||||
- 使用新内核重新启动并享受它吧。
|
||||
|
||||
若遇到问题
|
||||
-----------
|
||||
|
||||
- 如果您发现了一些可能由于内核缺陷所导致的问题,请检查MAINTAINERS(维护者)
|
||||
文件看看是否有人与令您遇到麻烦的内核部分相关。如果无人在此列出,那么第二
|
||||
个最好的方案就是把它们发给我(torvalds@linux-foundation.org),也可能发送
|
||||
到任何其他相关的邮件列表或新闻组。
|
||||
|
||||
- 在所有的缺陷报告中,【请】告诉我们您在说什么内核,如何复现问题,以及您的
|
||||
设置是什么的(使用您的常识)。如果问题是新的,请告诉我;如果问题是旧的,
|
||||
请尝试告诉我您什么时候首次注意到它。
|
||||
|
||||
- 如果缺陷导致如下消息::
|
||||
|
||||
unable to handle kernel paging request at address C0000010
|
||||
Oops: 0002
|
||||
EIP: 0010:XXXXXXXX
|
||||
eax: xxxxxxxx ebx: xxxxxxxx ecx: xxxxxxxx edx: xxxxxxxx
|
||||
esi: xxxxxxxx edi: xxxxxxxx ebp: xxxxxxxx
|
||||
ds: xxxx es: xxxx fs: xxxx gs: xxxx
|
||||
Pid: xx, process nr: xx
|
||||
xx xx xx xx xx xx xx xx xx xx
|
||||
|
||||
或者类似的内核调试信息显示在屏幕上或在系统日志里,请【如实】复制它。
|
||||
可能对你来说转储(dump)看起来不可理解,但它确实包含可能有助于调试问题的
|
||||
信息。转储上方的文本也很重要:它说明了内核转储代码的原因(在上面的示例中,
|
||||
是由于内核指针错误)。更多关于如何理解转储的信息,请参见
|
||||
Documentation/admin-guide/bug-hunting.rst。
|
||||
|
||||
- 如果使用 CONFIG_KALLSYMS 编译内核,则可以按原样发送转储,否则必须使用
|
||||
``ksymoops`` 程序来理解转储(但通常首选使用CONFIG_KALLSYMS编译)。
|
||||
此实用程序可从
|
||||
https://www.kernel.org/pub/linux/utils/kernel/ksymoops/ 下载。
|
||||
或者,您可以手动执行转储查找:
|
||||
|
||||
- 在调试像上面这样的转储时,如果您可以查找EIP值的含义,这将非常有帮助。
|
||||
十六进制值本身对我或其他任何人都没有太大帮助:它会取决于特定的内核设置。
|
||||
您应该做的是从EIP行获取十六进制值(忽略 ``0010:`` ),然后在内核名字列表
|
||||
中查找它,以查看哪个内核函数包含有问题的地址。
|
||||
|
||||
要找到内核函数名,您需要找到与显示症状的内核相关联的系统二进制文件。就是
|
||||
文件“linux/vmlinux”。要提取名字列表并将其与内核崩溃中的EIP进行匹配,
|
||||
请执行::
|
||||
|
||||
nm vmlinux | sort | less
|
||||
|
||||
这将为您提供一个按升序排序的内核地址列表,从中很容易找到包含有问题的地址
|
||||
的函数。请注意,内核调试消息提供的地址不一定与函数地址完全匹配(事实上,
|
||||
这是不可能的),因此您不能只“grep”列表:不过列表将为您提供每个内核函数
|
||||
的起点,因此通过查找起始地址低于你正在搜索的地址,但后一个函数的高于的
|
||||
函数,你会找到您想要的。实际上,在您的问题报告中加入一些“上下文”可能是
|
||||
一个好主意,给出相关的上下几行。
|
||||
|
||||
如果您由于某些原因无法完成上述操作(如您使用预编译的内核映像或类似的映像),
|
||||
请尽可能多地告诉我您的相关设置信息,这会有所帮助。有关详细信息请阅读
|
||||
‘Documentation/admin-guide/reporting-issues.rst’。
|
||||
|
||||
- 或者,您可以在正在运行的内核上使用gdb(只读的;即不能更改值或设置断点)。
|
||||
为此,请首先使用-g编译内核;适当地编辑arch/x86/Makefile,然后执行 ``make
|
||||
clean`` 。您还需要启用CONFIG_PROC_FS(通过 ``make config`` )。
|
||||
|
||||
使用新内核重新启动后,执行 ``gdb vmlinux /proc/kcore`` 。现在可以使用所有
|
||||
普通的gdb命令。查找系统崩溃点的命令是 ``l *0xXXXXXXXX`` (将xxx替换为EIP
|
||||
值)。
|
||||
|
||||
用gdb无法调试一个当前未运行的内核是由于gdb(错误地)忽略了编译内核的起始
|
||||
偏移量。
|
|
@ -0,0 +1,81 @@
|
|||
.. include:: ../disclaimer-zh_CN.rst
|
||||
|
||||
:Original: :doc:`../../../admin-guide/bug-bisect`
|
||||
|
||||
:译者:
|
||||
|
||||
吴想成 Wu XiangCheng <bobwxc@email.cn>
|
||||
|
||||
二分(bisect)缺陷
|
||||
+++++++++++++++++++
|
||||
|
||||
(英文版)最后更新:2016年10月28日
|
||||
|
||||
引言
|
||||
=====
|
||||
|
||||
始终尝试由来自kernel.org的源代码构建的最新内核。如果您没有信心这样做,请将
|
||||
错误报告给您的发行版供应商,而不是内核开发人员。
|
||||
|
||||
找到缺陷(bug)并不总是那么容易,不过仍然得去找。如果你找不到它,不要放弃。
|
||||
尽可能多的向相关维护人员报告您发现的信息。请参阅MAINTAINERS文件以了解您所
|
||||
关注的子系统的维护人员。
|
||||
|
||||
在提交错误报告之前,请阅读“Documentation/admin-guide/reporting-issues.rst”。
|
||||
|
||||
设备未出现(Devices not appearing)
|
||||
====================================
|
||||
|
||||
这通常是由udev/systemd引起的。在将其归咎于内核之前先检查一下。
|
||||
|
||||
查找导致缺陷的补丁
|
||||
===================
|
||||
|
||||
使用 ``git`` 提供的工具可以很容易地找到缺陷,只要缺陷是可复现的。
|
||||
|
||||
操作步骤:
|
||||
|
||||
- 从git源代码构建内核
|
||||
- 以此开始二分 [#f1]_::
|
||||
|
||||
$ git bisect start
|
||||
|
||||
- 标记损坏的变更集::
|
||||
|
||||
$ git bisect bad [commit]
|
||||
|
||||
- 标记正常工作的变更集::
|
||||
|
||||
$ git bisect good [commit]
|
||||
|
||||
- 重新构建内核并测试
|
||||
- 使用以下任一与git bisect进行交互::
|
||||
|
||||
$ git bisect good
|
||||
|
||||
或::
|
||||
|
||||
$ git bisect bad
|
||||
|
||||
这取决于您测试的变更集上是否有缺陷
|
||||
- 在一些交互之后,git bisect将给出可能导致缺陷的变更集。
|
||||
|
||||
- 例如,如果您知道当前版本有问题,而4.8版本是正常的,则可以执行以下操作::
|
||||
|
||||
$ git bisect start
|
||||
$ git bisect bad # Current version is bad
|
||||
$ git bisect good v4.8
|
||||
|
||||
|
||||
.. [#f1] 您可以(可选地)在开始git bisect的时候提供good或bad参数
|
||||
``git bisect start [BAD] [GOOD]``
|
||||
|
||||
如需进一步参考,请阅读:
|
||||
|
||||
- ``git-bisect`` 的手册页
|
||||
- `Fighting regressions with git bisect(用git bisect解决回归)
|
||||
<https://www.kernel.org/pub/software/scm/git/docs/git-bisect-lk2009.html>`_
|
||||
- `Fully automated bisecting with "git bisect run"(使用git bisect run
|
||||
来全自动二分) <https://lwn.net/Articles/317154>`_
|
||||
- `Using Git bisect to figure out when brokenness was introduced
|
||||
(使用Git二分来找出何时引入了错误) <http://webchick.net/node/99>`_
|
|
@ -0,0 +1,340 @@
|
|||
.. include:: ../disclaimer-zh_CN.rst
|
||||
|
||||
:Original: :doc:`../../../admin-guide/bug-hunting`
|
||||
|
||||
:译者:
|
||||
|
||||
吴想成 Wu XiangCheng <bobwxc@email.cn>
|
||||
|
||||
追踪缺陷
|
||||
=========
|
||||
|
||||
内核错误报告通常附带如下堆栈转储::
|
||||
|
||||
------------[ cut here ]------------
|
||||
WARNING: CPU: 1 PID: 28102 at kernel/module.c:1108 module_put+0x57/0x70
|
||||
Modules linked in: dvb_usb_gp8psk(-) dvb_usb dvb_core nvidia_drm(PO) nvidia_modeset(PO) snd_hda_codec_hdmi snd_hda_intel snd_hda_codec snd_hwdep snd_hda_core snd_pcm snd_timer snd soundcore nvidia(PO) [last unloaded: rc_core]
|
||||
CPU: 1 PID: 28102 Comm: rmmod Tainted: P WC O 4.8.4-build.1 #1
|
||||
Hardware name: MSI MS-7309/MS-7309, BIOS V1.12 02/23/2009
|
||||
00000000 c12ba080 00000000 00000000 c103ed6a c1616014 00000001 00006dc6
|
||||
c1615862 00000454 c109e8a7 c109e8a7 00000009 ffffffff 00000000 f13f6a10
|
||||
f5f5a600 c103ee33 00000009 00000000 00000000 c109e8a7 f80ca4d0 c109f617
|
||||
Call Trace:
|
||||
[<c12ba080>] ? dump_stack+0x44/0x64
|
||||
[<c103ed6a>] ? __warn+0xfa/0x120
|
||||
[<c109e8a7>] ? module_put+0x57/0x70
|
||||
[<c109e8a7>] ? module_put+0x57/0x70
|
||||
[<c103ee33>] ? warn_slowpath_null+0x23/0x30
|
||||
[<c109e8a7>] ? module_put+0x57/0x70
|
||||
[<f80ca4d0>] ? gp8psk_fe_set_frontend+0x460/0x460 [dvb_usb_gp8psk]
|
||||
[<c109f617>] ? symbol_put_addr+0x27/0x50
|
||||
[<f80bc9ca>] ? dvb_usb_adapter_frontend_exit+0x3a/0x70 [dvb_usb]
|
||||
[<f80bb3bf>] ? dvb_usb_exit+0x2f/0xd0 [dvb_usb]
|
||||
[<c13d03bc>] ? usb_disable_endpoint+0x7c/0xb0
|
||||
[<f80bb48a>] ? dvb_usb_device_exit+0x2a/0x50 [dvb_usb]
|
||||
[<c13d2882>] ? usb_unbind_interface+0x62/0x250
|
||||
[<c136b514>] ? __pm_runtime_idle+0x44/0x70
|
||||
[<c13620d8>] ? __device_release_driver+0x78/0x120
|
||||
[<c1362907>] ? driver_detach+0x87/0x90
|
||||
[<c1361c48>] ? bus_remove_driver+0x38/0x90
|
||||
[<c13d1c18>] ? usb_deregister+0x58/0xb0
|
||||
[<c109fbb0>] ? SyS_delete_module+0x130/0x1f0
|
||||
[<c1055654>] ? task_work_run+0x64/0x80
|
||||
[<c1000fa5>] ? exit_to_usermode_loop+0x85/0x90
|
||||
[<c10013f0>] ? do_fast_syscall_32+0x80/0x130
|
||||
[<c1549f43>] ? sysenter_past_esp+0x40/0x6a
|
||||
---[ end trace 6ebc60ef3981792f ]---
|
||||
|
||||
这样的堆栈跟踪提供了足够的信息来识别内核源代码中发生错误的那一行。根据问题的
|
||||
严重性,它还可能包含 **“Oops”** 一词,比如::
|
||||
|
||||
BUG: unable to handle kernel NULL pointer dereference at (null)
|
||||
IP: [<c06969d4>] iret_exc+0x7d0/0xa59
|
||||
*pdpt = 000000002258a001 *pde = 0000000000000000
|
||||
Oops: 0002 [#1] PREEMPT SMP
|
||||
...
|
||||
|
||||
尽管有 **Oops** 或其他类型的堆栈跟踪,但通常需要找到出问题的行来识别和处理缺
|
||||
陷。在本章中,我们将参考“Oops”来了解需要分析的各种堆栈跟踪。
|
||||
|
||||
如果内核是用 ``CONFIG_DEBUG_INFO`` 编译的,那么可以使用文件:
|
||||
`scripts/decode_stacktrace.sh` 。
|
||||
|
||||
链接的模块
|
||||
-----------
|
||||
|
||||
受到污染或正在加载/卸载的模块用“(…)”标记,污染标志在
|
||||
`Documentation/admin-guide/tainted-kernels.rst` 文件中进行了描述,“正在被加
|
||||
载”用“+”标注,“正在被卸载”用“-”标注。
|
||||
|
||||
|
||||
Oops消息在哪?
|
||||
---------------
|
||||
|
||||
通常,Oops文本由klogd从内核缓冲区读取,然后交给 ``syslogd`` ,后者将其写入
|
||||
syslog文件,通常是 ``/var/log/messages`` (取决于 ``/etc/syslog.conf`` )。
|
||||
在使用systemd的系统上,它也可以由 ``journald`` 守护进程存储,并通过运行
|
||||
``journalctl`` 命令进行访问。
|
||||
|
||||
有时 ``klogd`` 会挂掉,这种情况下您可以运行 ``dmesg > file`` 从内核缓冲区
|
||||
读取数据并保存它。或者您可以 ``cat /proc/kmsg > file`` ,但是您必须适时
|
||||
中断以停止传输,因为 ``kmsg`` 是一个“永无止境的文件”。
|
||||
|
||||
如果机器严重崩溃,无法输入命令或磁盘不可用,那还有三个选项:
|
||||
|
||||
(1) 手动复制屏幕上的文本,并在机器重新启动后输入。很难受,但这是突然崩溃下
|
||||
唯一的选择。或者你可以用数码相机拍下屏幕——虽然不那么好,但总比什么都没
|
||||
有好。如果消息滚动超出控制台顶部,使用更高分辨率(例如 ``vga=791`` )
|
||||
引导启动将允许您阅读更多文本。(警告:这需要 ``vesafb`` ,因此对“早期”
|
||||
的Oppses没有帮助)
|
||||
|
||||
(2) 从串口终端启动(参见
|
||||
:ref:`Documentation/admin-guide/serial-console.rst <serial_console>` ),
|
||||
在另一台机器上运行调制解调器然后用你喜欢的通信程序捕获输出。
|
||||
Minicom运行良好。
|
||||
|
||||
(3) 使用Kdump(参阅 Documentation/admin-guide/kdump/kdump.rst ),使用
|
||||
Documentation/admin-guide/kdump/gdbmacros.txt 中的dmesg gdbmacro从旧内存
|
||||
中提取内核环形缓冲区。
|
||||
|
||||
找到缺陷位置
|
||||
-------------
|
||||
|
||||
如果你能指出缺陷在内核源代码中的位置,则报告缺陷的效果会非常好。这有两种方法。
|
||||
通常来说使用 ``gdb`` 会比较容易,不过内核需要用调试信息来预编译。
|
||||
|
||||
gdb
|
||||
^^^^
|
||||
|
||||
GNU 调试器(GNU debugger, ``gdb`` )是从 ``vmlinux`` 文件中找出OOPS的确切
|
||||
文件和行号的最佳方法。
|
||||
|
||||
在使用 ``CONFIG_DEBUG_INFO`` 编译的内核上使用gdb效果最好。可通过运行以下命令
|
||||
进行设置::
|
||||
|
||||
$ ./scripts/config -d COMPILE_TEST -e DEBUG_KERNEL -e DEBUG_INFO
|
||||
|
||||
在用 ``CONFIG_DEBUG_INFO`` 编译的内核上,你可以直接从OOPS复制EIP值::
|
||||
|
||||
EIP: 0060:[<c021e50e>] Not tainted VLI
|
||||
|
||||
并使用GDB来将其翻译成可读形式::
|
||||
|
||||
$ gdb vmlinux
|
||||
(gdb) l *0xc021e50e
|
||||
|
||||
如果没有启用 ``CONFIG_DEBUG_INFO`` ,则使用OOPS的函数偏移::
|
||||
|
||||
EIP is at vt_ioctl+0xda8/0x1482
|
||||
|
||||
并在启用 ``CONFIG_DEBUG_INFO`` 的情况下重新编译内核::
|
||||
|
||||
$ ./scripts/config -d COMPILE_TEST -e DEBUG_KERNEL -e DEBUG_INFO
|
||||
$ make vmlinux
|
||||
$ gdb vmlinux
|
||||
(gdb) l *vt_ioctl+0xda8
|
||||
0x1888 is in vt_ioctl (drivers/tty/vt/vt_ioctl.c:293).
|
||||
288 {
|
||||
289 struct vc_data *vc = NULL;
|
||||
290 int ret = 0;
|
||||
291
|
||||
292 console_lock();
|
||||
293 if (VT_BUSY(vc_num))
|
||||
294 ret = -EBUSY;
|
||||
295 else if (vc_num)
|
||||
296 vc = vc_deallocate(vc_num);
|
||||
297 console_unlock();
|
||||
|
||||
或者若您想要更详细的显示::
|
||||
|
||||
(gdb) p vt_ioctl
|
||||
$1 = {int (struct tty_struct *, unsigned int, unsigned long)} 0xae0 <vt_ioctl>
|
||||
(gdb) l *0xae0+0xda8
|
||||
|
||||
您也可以使用对象文件作为替代::
|
||||
|
||||
$ make drivers/tty/
|
||||
$ gdb drivers/tty/vt/vt_ioctl.o
|
||||
(gdb) l *vt_ioctl+0xda8
|
||||
|
||||
如果你有调用跟踪,类似::
|
||||
|
||||
Call Trace:
|
||||
[<ffffffff8802c8e9>] :jbd:log_wait_commit+0xa3/0xf5
|
||||
[<ffffffff810482d9>] autoremove_wake_function+0x0/0x2e
|
||||
[<ffffffff8802770b>] :jbd:journal_stop+0x1be/0x1ee
|
||||
...
|
||||
|
||||
这表明问题可能在 :jbd: 模块中。您可以在gdb中加载该模块并列出相关代码::
|
||||
|
||||
$ gdb fs/jbd/jbd.ko
|
||||
(gdb) l *log_wait_commit+0xa3
|
||||
|
||||
.. note::
|
||||
|
||||
您还可以对堆栈跟踪处的任何函数调用执行相同的操作,例如::
|
||||
|
||||
[<f80bc9ca>] ? dvb_usb_adapter_frontend_exit+0x3a/0x70 [dvb_usb]
|
||||
|
||||
上述调用发生的位置可以通过以下方式看到::
|
||||
|
||||
$ gdb drivers/media/usb/dvb-usb/dvb-usb.o
|
||||
(gdb) l *dvb_usb_adapter_frontend_exit+0x3a
|
||||
|
||||
objdump
|
||||
^^^^^^^^
|
||||
|
||||
要调试内核,请使用objdump并从崩溃输出中查找十六进制偏移,以找到有效的代码/汇
|
||||
编行。如果没有调试符号,您将看到所示例程的汇编程序代码,但是如果内核有调试
|
||||
符号,C代码也将可见(调试符号可以在内核配置菜单的hacking项中启用)。例如::
|
||||
|
||||
$ objdump -r -S -l --disassemble net/dccp/ipv4.o
|
||||
|
||||
.. note::
|
||||
|
||||
您需要处于内核树的顶层以便此获得您的C文件。
|
||||
|
||||
如果您无法访问源代码,仍然可以使用以下方法调试一些崩溃转储(如Dave Miller的
|
||||
示例崩溃转储输出所示)::
|
||||
|
||||
EIP is at +0x14/0x4c0
|
||||
...
|
||||
Code: 44 24 04 e8 6f 05 00 00 e9 e8 fe ff ff 8d 76 00 8d bc 27 00 00
|
||||
00 00 55 57 56 53 81 ec bc 00 00 00 8b ac 24 d0 00 00 00 8b 5d 08
|
||||
<8b> 83 3c 01 00 00 89 44 24 14 8b 45 28 85 c0 89 44 24 18 0f 85
|
||||
|
||||
Put the bytes into a "foo.s" file like this:
|
||||
|
||||
.text
|
||||
.globl foo
|
||||
foo:
|
||||
.byte .... /* bytes from Code: part of OOPS dump */
|
||||
|
||||
Compile it with "gcc -c -o foo.o foo.s" then look at the output of
|
||||
"objdump --disassemble foo.o".
|
||||
|
||||
Output:
|
||||
|
||||
ip_queue_xmit:
|
||||
push %ebp
|
||||
push %edi
|
||||
push %esi
|
||||
push %ebx
|
||||
sub $0xbc, %esp
|
||||
mov 0xd0(%esp), %ebp ! %ebp = arg0 (skb)
|
||||
mov 0x8(%ebp), %ebx ! %ebx = skb->sk
|
||||
mov 0x13c(%ebx), %eax ! %eax = inet_sk(sk)->opt
|
||||
|
||||
`scripts/decodecode` 文件可以用来自动完成大部分工作,这取决于正在调试的CPU
|
||||
体系结构。
|
||||
|
||||
报告缺陷
|
||||
---------
|
||||
|
||||
一旦你通过定位缺陷找到了其发生的地方,你可以尝试自己修复它或者向上游报告它。
|
||||
|
||||
为了向上游报告,您应该找出用于开发受影响代码的邮件列表。这可以使用 ``get_maintainer.pl`` 。
|
||||
|
||||
|
||||
例如,您在gspca的sonixj.c文件中发现一个缺陷,则可以通过以下方法找到它的维护者::
|
||||
|
||||
$ ./scripts/get_maintainer.pl -f drivers/media/usb/gspca/sonixj.c
|
||||
Hans Verkuil <hverkuil@xs4all.nl> (odd fixer:GSPCA USB WEBCAM DRIVER,commit_signer:1/1=100%)
|
||||
Mauro Carvalho Chehab <mchehab@kernel.org> (maintainer:MEDIA INPUT INFRASTRUCTURE (V4L/DVB),commit_signer:1/1=100%)
|
||||
Tejun Heo <tj@kernel.org> (commit_signer:1/1=100%)
|
||||
Bhaktipriya Shridhar <bhaktipriya96@gmail.com> (commit_signer:1/1=100%,authored:1/1=100%,added_lines:4/4=100%,removed_lines:9/9=100%)
|
||||
linux-media@vger.kernel.org (open list:GSPCA USB WEBCAM DRIVER)
|
||||
linux-kernel@vger.kernel.org (open list)
|
||||
|
||||
请注意它将指出:
|
||||
|
||||
- 最后接触源代码的开发人员(如果这是在git树中完成的)。在上面的例子中是Tejun
|
||||
和Bhaktipriya(在这个特定的案例中,没有人真正参与这个文件的开发);
|
||||
- 驱动维护人员(Hans Verkuil);
|
||||
- 子系统维护人员(Mauro Carvalho Chehab);
|
||||
- 驱动程序和/或子系统邮件列表(linux-media@vger.kernel.org);
|
||||
- Linux内核邮件列表(linux-kernel@vger.kernel.org)。
|
||||
|
||||
通常,修复缺陷的最快方法是将它报告给用于开发相关代码的邮件列表(linux-media
|
||||
ML),抄送驱动程序维护者(Hans)。
|
||||
|
||||
如果你完全不知道该把报告寄给谁,且 ``get_maintainer.pl`` 也没有提供任何有用
|
||||
的信息,请发送到linux-kernel@vger.kernel.org。
|
||||
|
||||
感谢您的帮助,这使Linux尽可能稳定:-)
|
||||
|
||||
修复缺陷
|
||||
---------
|
||||
|
||||
如果你懂得编程,你不仅可以通过报告错误来帮助我们,还可以提供一个解决方案。
|
||||
毕竟,开源就是分享你的工作,你不想因为你的天才而被认可吗?
|
||||
|
||||
如果你决定这样做,请在制定解决方案后将其提交到上游。
|
||||
|
||||
请务必阅读
|
||||
:ref:`Documentation/process/submitting-patches.rst <submittingpatches>` ,
|
||||
以帮助您的代码被接受。
|
||||
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
用 ``klogd`` 进行Oops跟踪的注意事项
|
||||
------------------------------------
|
||||
|
||||
为了帮助Linus和其他内核开发人员, ``klogd`` 对保护故障的处理提供了大量支持。
|
||||
为了完整支持地址解析,至少应该使用 ``sysklogd`` 包的1.3-pl3版本。
|
||||
|
||||
当发生保护故障时, ``klogd`` 守护进程会自动将内核日志消息中的重要地址转换为
|
||||
它们的等效符号。然后通过 ``klogd`` 使用的任何报告机制来转发这个已翻译的内核
|
||||
消息。保护错误消息可以直接从消息文件中剪切出来并转发给内核开发人员。
|
||||
|
||||
``klogd`` 执行两种类型的地址解析,静态翻译和动态翻译。静态翻译使用System.map
|
||||
文件。为了进行静态转换, ``klogd`` 守护进程必须能够在守护进程初始化时找到系
|
||||
统映射文件。有关 ``klogd`` 如何搜索映射文件的信息,请参见klogd手册页。
|
||||
|
||||
当使用内核可加载模块时,动态地址转换非常重要。由于内核模块的内存是从内核的
|
||||
动态内存池中分配的,因此无论是模块的开头还是模块中的函数和符号都没有固定的
|
||||
位置。
|
||||
|
||||
内核支持系统调用,允许程序确定加载哪些模块及其在内存中的位置。klogd守护进程
|
||||
使用这些系统调用构建了一个符号表,可用于调试可加载内核模块中发生的保护错误。
|
||||
|
||||
klogd至少会提供产生保护故障的模块的名称。如果可加载模块的开发人员选择从模块
|
||||
导出符号信息,则可能会有其他可用的符号信息。
|
||||
|
||||
由于内核模块环境可以是动态的,因此当模块环境发生变化时,必须有一种通知
|
||||
``klogd`` 守护进程的机制。有一些可用的命令行选项允许klogd向当前正在执行的守
|
||||
护进程发出信号示意应该刷新符号信息。有关更多信息,请参阅 ``klogd`` 手册页。
|
||||
|
||||
sysklogd发行版附带了一个补丁,它修改了 ``modules-2.0.0`` 包,以便在加载或
|
||||
卸载模块时自动向klogd发送信号。应用此补丁基本上可无缝支持调试内核可加载模块
|
||||
发生的保护故障。
|
||||
|
||||
以下是 ``klogd`` 处理的可加载模块中的保护故障示例::
|
||||
|
||||
Aug 29 09:51:01 blizard kernel: Unable to handle kernel paging request at virtual address f15e97cc
|
||||
Aug 29 09:51:01 blizard kernel: current->tss.cr3 = 0062d000, %cr3 = 0062d000
|
||||
Aug 29 09:51:01 blizard kernel: *pde = 00000000
|
||||
Aug 29 09:51:01 blizard kernel: Oops: 0002
|
||||
Aug 29 09:51:01 blizard kernel: CPU: 0
|
||||
Aug 29 09:51:01 blizard kernel: EIP: 0010:[oops:_oops+16/3868]
|
||||
Aug 29 09:51:01 blizard kernel: EFLAGS: 00010212
|
||||
Aug 29 09:51:01 blizard kernel: eax: 315e97cc ebx: 003a6f80 ecx: 001be77b edx: 00237c0c
|
||||
Aug 29 09:51:01 blizard kernel: esi: 00000000 edi: bffffdb3 ebp: 00589f90 esp: 00589f8c
|
||||
Aug 29 09:51:01 blizard kernel: ds: 0018 es: 0018 fs: 002b gs: 002b ss: 0018
|
||||
Aug 29 09:51:01 blizard kernel: Process oops_test (pid: 3374, process nr: 21, stackpage=00589000)
|
||||
Aug 29 09:51:01 blizard kernel: Stack: 315e97cc 00589f98 0100b0b4 bffffed4 0012e38e 00240c64 003a6f80 00000001
|
||||
Aug 29 09:51:01 blizard kernel: 00000000 00237810 bfffff00 0010a7fa 00000003 00000001 00000000 bfffff00
|
||||
Aug 29 09:51:01 blizard kernel: bffffdb3 bffffed4 ffffffda 0000002b 0007002b 0000002b 0000002b 00000036
|
||||
Aug 29 09:51:01 blizard kernel: Call Trace: [oops:_oops_ioctl+48/80] [_sys_ioctl+254/272] [_system_call+82/128]
|
||||
Aug 29 09:51:01 blizard kernel: Code: c7 00 05 00 00 00 eb 08 90 90 90 90 90 90 90 90 89 ec 5d c3
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
::
|
||||
|
||||
Dr. G.W. Wettstein Oncology Research Div. Computing Facility
|
||||
Roger Maris Cancer Center INTERNET: greg@wind.rmcc.com
|
||||
820 4th St. N.
|
||||
Fargo, ND 58122
|
||||
Phone: 701-234-7556
|
|
@ -13,9 +13,13 @@ Linux 内核用户和管理员指南
|
|||
|
||||
这个初始部分包含总体信息,包括描述内核的README, 关于内核参数的文档等。
|
||||
|
||||
Todolist:
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
README
|
||||
|
||||
Todolist:
|
||||
|
||||
kernel-parameters
|
||||
devices
|
||||
sysctl/index
|
||||
|
@ -28,16 +32,21 @@ Todolist:
|
|||
|
||||
下面的一组文档,针对的是试图跟踪问题和bug的用户。
|
||||
|
||||
Todolist:
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
reporting-bugs
|
||||
reporting-issues
|
||||
security-bugs
|
||||
bug-hunting
|
||||
bug-bisect
|
||||
tainted-kernels
|
||||
init
|
||||
|
||||
Todolist:
|
||||
|
||||
reporting-bugs
|
||||
ramoops
|
||||
dynamic-debug-howto
|
||||
init
|
||||
kdump/index
|
||||
perf/index
|
||||
|
||||
|
@ -56,6 +65,7 @@ Todolist:
|
|||
|
||||
clearing-warn-once
|
||||
cpu-load
|
||||
unicode
|
||||
|
||||
Todolist:
|
||||
|
||||
|
@ -111,7 +121,6 @@ Todolist:
|
|||
sysrq
|
||||
thunderbolt
|
||||
ufs
|
||||
unicode
|
||||
vga-softcursor
|
||||
video-output
|
||||
xfs
|
||||
|
|
|
@ -0,0 +1,54 @@
|
|||
.. include:: ../disclaimer-zh_CN.rst
|
||||
|
||||
:Original: :doc:`../../../admin-guide/init`
|
||||
|
||||
:译者:
|
||||
|
||||
吴想成 Wu XiangCheng <bobwxc@email.cn>
|
||||
|
||||
解释“No working init found.”启动挂起消息
|
||||
=========================================
|
||||
|
||||
:作者:
|
||||
|
||||
Andreas Mohr <andi at lisas period de>
|
||||
|
||||
Cristian Souza <cristianmsbr at gmail period com>
|
||||
|
||||
本文档提供了加载初始化二进制(init binary)失败的一些高层级原因(大致按执行
|
||||
顺序列出)。
|
||||
|
||||
1) **无法挂载根文件系统Unable to mount root FS** :请设置“debug”内核参数(在
|
||||
引导加载程序bootloader配置文件或CONFIG_CMDLINE)以获取更详细的内核消息。
|
||||
|
||||
2) **初始化二进制不存在于根文件系统上init binary doesn't exist on rootfs** :
|
||||
确保您的根文件系统类型正确(并且 ``root=`` 内核参数指向正确的分区);拥有
|
||||
所需的驱动程序,例如SCSI或USB等存储硬件;文件系统(ext3、jffs2等)是内建的
|
||||
(或者作为模块由initrd预加载)。
|
||||
|
||||
3) **控制台设备损坏Broken console device** : ``console= setup`` 中可能存在
|
||||
冲突 --> 初始控制台不可用(initial console unavailable)。例如,由于串行
|
||||
IRQ问题(如缺少基于中断的配置)导致的某些串行控制台不可靠。尝试使用不同的
|
||||
``console= device`` 或像 ``netconsole=`` 。
|
||||
|
||||
4) **二进制存在但依赖项不可用Binary exists but dependencies not available** :
|
||||
例如初始化二进制的必需库依赖项,像 ``/lib/ld-linux.so.2`` 丢失或损坏。使用
|
||||
``readelf -d <INIT>|grep NEEDED`` 找出需要哪些库。
|
||||
|
||||
5) **无法加载二进制Binary cannot be loaded** :请确保二进制的体系结构与您的
|
||||
硬件匹配。例如i386不匹配x86_64,或者尝试在ARM硬件上加载x86。如果您尝试在
|
||||
此处加载非二进制文件(shell脚本?),您应该确保脚本在其工作头(shebang
|
||||
header)行 ``#!/...`` 中指定能正常工作的解释器(包括其库依赖项)。在处理
|
||||
脚本之前,最好先测试一个简单的非脚本二进制文件,比如 ``/bin/sh`` ,并确认
|
||||
它能成功执行。要了解更多信息,请将代码添加到 ``init/main.c`` 以显示
|
||||
kernel_execve()的返回值。
|
||||
|
||||
当您发现新的失败原因时,请扩展本解释(毕竟加载初始化二进制是一个 **关键** 且
|
||||
艰难的过渡步骤,需要尽可能无痛地进行),然后向LKML提交一个补丁。
|
||||
|
||||
待办事项:
|
||||
|
||||
- 通过一个可以存储 ``kernel_execve()`` 结果值的结构体数组实现各种
|
||||
``run_init_process()`` 调用,并在失败时通过迭代 **所有** 结果来记录一切
|
||||
(非常重要的可用性修复)。
|
||||
- 试着使实现本身在一般情况下更有帮助,例如在受影响的地方提供额外的错误消息。
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,74 @@
|
|||
.. include:: ../disclaimer-zh_CN.rst
|
||||
|
||||
:Original: :doc:`../../../admin-guide/security-bugs`
|
||||
|
||||
:译者:
|
||||
|
||||
吴想成 Wu XiangCheng <bobwxc@email.cn>
|
||||
|
||||
安全缺陷
|
||||
=========
|
||||
|
||||
Linux内核开发人员非常重视安全性。因此我们想知道何时发现了安全漏洞,以便尽快
|
||||
修复和披露。请向Linux内核安全团队报告安全漏洞。
|
||||
|
||||
联络
|
||||
-----
|
||||
|
||||
可以通过电子邮件<security@kernel.org>联系Linux内核安全团队。这是一个安全人员
|
||||
的私有列表,他们将帮助验证错误报告并开发和发布修复程序。如果您已经有了一个
|
||||
修复,请将其包含在您的报告中,这样可以大大加快进程。安全团队可能会从区域维护
|
||||
人员那里获得额外的帮助,以理解和修复安全漏洞。
|
||||
|
||||
与任何缺陷一样,提供的信息越多,诊断和修复就越容易。如果您不清楚哪些信息有用,
|
||||
请查看“Documentation/translations/zh_CN/admin-guide/reporting-issues.rst”中
|
||||
概述的步骤。任何利用漏洞的攻击代码都非常有用,未经报告者同意不会对外发布,除
|
||||
非已经公开。
|
||||
|
||||
请尽可能发送无附件的纯文本电子邮件。如果所有的细节都藏在附件里,那么就很难对
|
||||
一个复杂的问题进行上下文引用的讨论。把它想象成一个
|
||||
:doc:`常规的补丁提交 <../process/submitting-patches>` (即使你还没有补丁):
|
||||
描述问题和影响,列出复现步骤,然后给出一个建议的解决方案,所有这些都是纯文本的。
|
||||
|
||||
披露和限制信息
|
||||
---------------
|
||||
|
||||
安全列表不是公开渠道。为此,请参见下面的协作。
|
||||
|
||||
一旦开发出了健壮的补丁,发布过程就开始了。对公开的缺陷的修复会立即发布。
|
||||
|
||||
尽管我们倾向于在未公开缺陷的修复可用时即发布补丁,但应报告者或受影响方的请求,
|
||||
这可能会被推迟到发布过程开始后的7日内,如果根据缺陷的严重性需要更多的时间,
|
||||
则可额外延长到14天。推迟发布修复的唯一有效原因是为了适应QA的逻辑和需要发布
|
||||
协调的大规模部署。
|
||||
|
||||
虽然可能与受信任的个人共享受限信息以开发修复,但未经报告者许可,此类信息不会
|
||||
与修复程序一起发布或发布在任何其他披露渠道上。这包括但不限于原始错误报告和
|
||||
后续讨论(如有)、漏洞、CVE信息或报告者的身份。
|
||||
|
||||
换句话说,我们唯一感兴趣的是修复缺陷。提交给安全列表的所有其他资料以及对报告
|
||||
的任何后续讨论,即使在解除限制之后,也将永久保密。
|
||||
|
||||
协调
|
||||
------
|
||||
|
||||
对敏感缺陷(例如那些可能导致权限提升的缺陷)的修复可能需要与私有邮件列表
|
||||
<linux-distros@vs.openwall.org>进行协调,以便分发供应商做好准备,在公开披露
|
||||
上游补丁时发布一个已修复的内核。发行版将需要一些时间来测试建议的补丁,通常
|
||||
会要求至少几天的限制,而供应商更新发布更倾向于周二至周四。若合适,安全团队
|
||||
可以协助这种协调,或者报告者可以从一开始就包括linux发行版。在这种情况下,请
|
||||
记住在电子邮件主题行前面加上“[vs]”,如linux发行版wiki中所述:
|
||||
<http://oss-security.openwall.org/wiki/mailing-lists/distros#how-to-use-the-lists>。
|
||||
|
||||
CVE分配
|
||||
--------
|
||||
|
||||
安全团队通常不分配CVE,我们也不需要它们来进行报告或修复,因为这会使过程不必
|
||||
要的复杂化,并可能耽误缺陷处理。如果报告者希望在公开披露之前分配一个CVE编号,
|
||||
他们需要联系上述的私有linux-distros列表。当在提供补丁之前已有这样的CVE编号时,
|
||||
如报告者愿意,最好在提交消息中提及它。
|
||||
|
||||
保密协议
|
||||
---------
|
||||
|
||||
Linux内核安全团队不是一个正式的机构实体,因此无法签订任何保密协议。
|
|
@ -0,0 +1,157 @@
|
|||
.. include:: ../disclaimer-zh_CN.rst
|
||||
|
||||
:Original: :doc:`../../../admin-guide/tainted-kernels`
|
||||
|
||||
:译者:
|
||||
|
||||
吴想成 Wu XiangCheng <bobwxc@email.cn>
|
||||
|
||||
受污染的内核
|
||||
-------------
|
||||
|
||||
当发生一些在稍后调查问题时可能相关的事件时,内核会将自己标记为“受污染
|
||||
(tainted)”的。不用太过担心,大多数情况下运行受污染的内核没有问题;这些信息
|
||||
主要在有人想调查某个问题时才有意义的,因为问题的真正原因可能是导致内核受污染
|
||||
的事件。这就是为什么来自受污染内核的缺陷报告常常被开发人员忽略,因此请尝试用
|
||||
未受污染的内核重现问题。
|
||||
|
||||
请注意,即使在您消除导致污染的原因(亦即卸载专有内核模块)之后,内核仍将保持
|
||||
污染状态,以表示内核仍然不可信。这也是为什么内核在注意到内部问题(“kernel
|
||||
bug”)、可恢复错误(“kernel oops”)或不可恢复错误(“kernel panic”)时会打印
|
||||
受污染状态,并将有关此的调试信息写入日志 ``dmesg`` 输出。也可以通过
|
||||
``/proc/`` 中的文件在运行时检查受污染的状态。
|
||||
|
||||
|
||||
BUG、Oops或Panics消息中的污染标志
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
在顶部以“CPU:”开头的一行中可以找到受污染的状态;内核是否受到污染和原因会显示
|
||||
在进程ID(“PID:”)和触发事件命令的缩写名称(“Comm:”)之后::
|
||||
|
||||
BUG: unable to handle kernel NULL pointer dereference at 0000000000000000
|
||||
Oops: 0002 [#1] SMP PTI
|
||||
CPU: 0 PID: 4424 Comm: insmod Tainted: P W O 4.20.0-0.rc6.fc30 #1
|
||||
Hardware name: Red Hat KVM, BIOS 0.5.1 01/01/2011
|
||||
RIP: 0010:my_oops_init+0x13/0x1000 [kpanic]
|
||||
[...]
|
||||
|
||||
如果内核在事件发生时没有被污染,您将在那里看到“Not-tainted:”;如果被污染,那
|
||||
么它将是“Tainted:”以及字母或空格。在上面的例子中,它看起来是这样的::
|
||||
|
||||
Tainted: P W O
|
||||
|
||||
下表解释了这些字符的含义。在本例中,由于加载了专有模块( ``P`` ),出现了
|
||||
警告( ``W`` ),并且加载了外部构建的模块( ``O`` ),所以内核早些时候受到
|
||||
了污染。要解码其他字符,请使用下表。
|
||||
|
||||
|
||||
解码运行时的污染状态
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
在运行时,您可以通过读取 ``cat /proc/sys/kernel/tainted`` 来查询受污染状态。
|
||||
如果返回 ``0`` ,则内核没有受到污染;任何其他数字都表示受到污染的原因。解码
|
||||
这个数字的最简单方法是使用脚本 ``tools/debugging/kernel-chktaint`` ,您的
|
||||
发行版可能会将其作为名为 ``linux-tools`` 或 ``kernel-tools`` 的包的一部分提
|
||||
供;如果没有,您可以从
|
||||
`git.kernel.org <https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/plain/tools/debugging/kernel-chktaint>`_
|
||||
网站下载此脚本并用 ``sh kernel-chktaint`` 执行,它会在上面引用的日志中有类似
|
||||
语句的机器上打印这样的内容::
|
||||
|
||||
Kernel is Tainted for following reasons:
|
||||
* Proprietary module was loaded (#0)
|
||||
* Kernel issued warning (#9)
|
||||
* Externally-built ('out-of-tree') module was loaded (#12)
|
||||
See Documentation/admin-guide/tainted-kernels.rst in the Linux kernel or
|
||||
https://www.kernel.org/doc/html/latest/admin-guide/tainted-kernels.html for
|
||||
a more details explanation of the various taint flags.
|
||||
Raw taint value as int/string: 4609/'P W O '
|
||||
|
||||
你也可以试着自己解码这个数字。如果内核被污染的原因只有一个,那么这很简单,
|
||||
在本例中您可以通过下表找到数字。如果你需要解码有多个原因的数字,因为它是一
|
||||
个位域(bitfield),其中每个位表示一个特定类型的污染的存在或不存在,最好让
|
||||
前面提到的脚本来处理。但是如果您需要快速看一下,可以使用这个shell命令来检查
|
||||
设置了哪些位::
|
||||
|
||||
$ for i in $(seq 18); do echo $(($i-1)) $(($(cat /proc/sys/kernel/tainted)>>($i-1)&1));done
|
||||
|
||||
污染状态代码表
|
||||
~~~~~~~~~~~~~~~
|
||||
|
||||
=== ===== ====== ========================================================
|
||||
位 日志 数字 内核被污染的原因
|
||||
=== ===== ====== ========================================================
|
||||
0 G/P 1 已加载专用模块
|
||||
1 _/F 2 模块被强制加载
|
||||
2 _/S 4 内核运行在不合规范的系统上
|
||||
3 _/R 8 模块被强制卸载
|
||||
4 _/M 16 处理器报告了机器检测异常(MCE)
|
||||
5 _/B 32 引用了错误的页或某些意外的页标志
|
||||
6 _/U 64 用户空间应用程序请求的污染
|
||||
7 _/D 128 内核最近死机了,即曾出现OOPS或BUG
|
||||
8 _/A 256 ACPI表被用户覆盖
|
||||
9 _/W 512 内核发出警告
|
||||
10 _/C 1024 已加载staging驱动程序
|
||||
11 _/I 2048 已应用平台固件缺陷的解决方案
|
||||
12 _/O 4096 已加载外部构建(“树外”)模块
|
||||
13 _/E 8192 已加载未签名的模块
|
||||
14 _/L 16384 发生软锁定
|
||||
15 _/K 32768 内核已实时打补丁
|
||||
16 _/X 65536 备用污染,为发行版定义并使用
|
||||
17 _/T 131072 内核是用结构随机化插件构建的
|
||||
=== ===== ====== ========================================================
|
||||
|
||||
注:字符 ``_`` 表示空白,以便于阅读表。
|
||||
|
||||
污染的更详细解释
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
||||
0) ``G`` 加载的所有模块都有GPL或兼容许可证, ``P`` 加载了任何专有模块。
|
||||
没有MODULE_LICENSE(模块许可证)或MODULE_LICENSE未被insmod认可为GPL
|
||||
兼容的模块被认为是专有的。
|
||||
|
||||
|
||||
1) ``F`` 任何模块被 ``insmod -f`` 强制加载, ``' '`` 所有模块正常加载。
|
||||
|
||||
2) ``S`` 内核运行在不合规范的处理器或系统上:硬件已运行在不受支持的配置中,
|
||||
因此无法保证正确执行。内核将被污染,例如:
|
||||
|
||||
- 在x86上:PAE是通过intel CPU(如Pentium M)上的forcepae强制执行的,这些
|
||||
CPU不报告PAE,但可能有功能实现,SMP内核在非官方支持的SMP Athlon CPU上
|
||||
运行,MSR被暴露到用户空间中。
|
||||
- 在arm上:在某些CPU(如Keystone 2)上运行的内核,没有启用某些内核特性。
|
||||
- 在arm64上:CPU之间存在不匹配的硬件特性,引导加载程序以不同的模式引导CPU。
|
||||
- 某些驱动程序正在被用在不受支持的体系结构上(例如x86_64以外的其他系统
|
||||
上的scsi/snic,非x86/x86_64/itanium上的scsi/ips,已经损坏了arm64上
|
||||
irqchip/irq-gic的固件设置…)。
|
||||
|
||||
3) ``R`` 模块被 ``rmmod -f`` 强制卸载, ``' '`` 所有模块都正常卸载。
|
||||
|
||||
4) ``M`` 任何处理器报告了机器检测异常, ``' '`` 未发生机器检测异常。
|
||||
|
||||
5) ``B`` 页面释放函数发现错误的页面引用或某些意外的页面标志。这表示硬件问题
|
||||
或内核错误;日志中应该有其他信息指示发生此污染的原因。
|
||||
|
||||
6) ``U`` 用户或用户应用程序特意请求设置受污染标志,否则应为 ``' '`` 。
|
||||
|
||||
7) ``D`` 内核最近死机了,即出现了OOPS或BUG。
|
||||
|
||||
8) ``A`` ACPI表被重写。
|
||||
|
||||
9) ``W`` 内核之前已发出过警告(尽管有些警告可能会设置更具体的污染标志)。
|
||||
|
||||
10) ``C`` 已加载staging驱动程序。
|
||||
|
||||
11) ``I`` 内核正在处理平台固件(BIOS或类似软件)中的严重错误。
|
||||
|
||||
12) ``O`` 已加载外部构建(“树外”)模块。
|
||||
|
||||
13) ``E`` 在支持模块签名的内核中加载了未签名的模块。
|
||||
|
||||
14) ``L`` 系统上先前发生过软锁定。
|
||||
|
||||
15) ``K`` 内核已经实时打了补丁。
|
||||
|
||||
16) ``X`` 备用污染,由Linux发行版定义和使用。
|
||||
|
||||
17) ``T`` 内核构建时使用了randstruct插件,它可以有意生成非常不寻常的内核结构
|
||||
布局(甚至是性能病态的布局),这在调试时非常有用。于构建时设置。
|
|
@ -0,0 +1,170 @@
|
|||
.. include:: ../disclaimer-zh_CN.rst
|
||||
|
||||
:Original: Documentation/admin-guide/unicode.rst
|
||||
|
||||
:译者:
|
||||
|
||||
吴想成 Wu XiangCheng <bobwxc@email.cn>
|
||||
|
||||
Unicode(统一码)支持
|
||||
======================
|
||||
|
||||
(英文版)上次更新:2005-01-17,版本号 1.4
|
||||
|
||||
此文档由H. Peter Anvin <unicode@lanana.org>管理,是Linux注册名称与编号管理局
|
||||
(Linux Assigned Names And Numbers Authority,LANANA)项目的一部分。
|
||||
现行版本请见:
|
||||
|
||||
http://www.lanana.org/docs/unicode/admin-guide/unicode.rst
|
||||
|
||||
简介
|
||||
-----
|
||||
|
||||
Linux内核代码已被重写以使用Unicode来将字符映射到字体。下载一个Unicode到字体
|
||||
(Unicode-to-font)表,八位字符集与UTF-8模式都将改用此字体来显示。
|
||||
|
||||
这微妙地改变了八位字符表的语义。现在的四个字符表是:
|
||||
|
||||
=============== =============================== ================
|
||||
映射代号 映射名称 Escape代码 (G0)
|
||||
=============== =============================== ================
|
||||
LAT1_MAP Latin-1 (ISO 8859-1) ESC ( B
|
||||
GRAF_MAP DEC VT100 pseudographics ESC ( 0
|
||||
IBMPC_MAP IBM code page 437 ESC ( U
|
||||
USER_MAP User defined ESC ( K
|
||||
=============== =============================== ================
|
||||
|
||||
特别是 ESC ( U 不再是“直通字体”,因为字体可能与IBM字符集完全不同。
|
||||
例如,即使加载了一个Latin-1字体,也允许使用块图形(block graphics)。
|
||||
|
||||
请注意,尽管这些代码与ISO 2022类似,但这些代码及其用途都与ISO 2022不匹配;
|
||||
Linux有两个八位代码(G0和G1),而ISO 2022有四个七位代码(G0-G3)。
|
||||
|
||||
根据Unicode标准/ISO 10646,U+F000到U+F8FF被保留用于操作系统范围内的分配
|
||||
(Unicode标准将其称为“团体区域(Corporate Zone)”,因为这对于Linux是不准确
|
||||
的,所以我们称之为“Linux区域”)。选择U+F000作为起点,因为它允许直接映射
|
||||
区域以2的大倍数开始(以防需要1024或2048个字符的字体)。这就留下U+E000到
|
||||
U+EFFF作为最终用户区。
|
||||
|
||||
[v1.2]:Unicodes范围从U+F000到U+F7FF已经被硬编码为直接映射到加载的字体,
|
||||
绕过了翻译表。用户定义的映射现在默认为U+F000到U+F0FF,模拟前述行为。实际上,
|
||||
此范围可能较短;例如,vgacon只能处理256字符(U+F000..U+F0FF)或512字符
|
||||
(U+F000..U+F1FF)字体。
|
||||
|
||||
Linux 区域中定义的实际字符
|
||||
---------------------------
|
||||
|
||||
此外,还定义了Unicode 1.1.4中不存在的以下字符;这些字符由DEC VT图形映射使用。
|
||||
[v1.2]此用法已过时,不应再使用;请参见下文。
|
||||
|
||||
====== ======================================
|
||||
U+F800 DEC VT GRAPHICS HORIZONTAL LINE SCAN 1
|
||||
U+F801 DEC VT GRAPHICS HORIZONTAL LINE SCAN 3
|
||||
U+F803 DEC VT GRAPHICS HORIZONTAL LINE SCAN 7
|
||||
U+F804 DEC VT GRAPHICS HORIZONTAL LINE SCAN 9
|
||||
====== ======================================
|
||||
|
||||
DEC VT220使用6x10字符矩阵,这些字符在DEC VT图形字符集中形成一个平滑的过渡。
|
||||
我省略了扫描5行,因为它也被用作块图形字符,因此被编码为U+2500 FORMS LIGHT
|
||||
HORIZONTAL。
|
||||
|
||||
[v1.3]:这些字符已正式添加到Unicode 3.2.0中;它们在U+23BA、U+23BB、U+23BC、
|
||||
U+23BD处添加。Linux现在使用新值。
|
||||
|
||||
[v1.2]:添加了以下字符来表示常见的键盘符号,这些符号不太可能被添加到Unicode
|
||||
中,因为它们非常讨厌地取决于特定供应商。当然,这是糟糕设计的一个好例子。
|
||||
|
||||
====== ======================================
|
||||
U+F810 KEYBOARD SYMBOL FLYING FLAG
|
||||
U+F811 KEYBOARD SYMBOL PULLDOWN MENU
|
||||
U+F812 KEYBOARD SYMBOL OPEN APPLE
|
||||
U+F813 KEYBOARD SYMBOL SOLID APPLE
|
||||
====== ======================================
|
||||
|
||||
克林贡(Klingon)语支持
|
||||
------------------------
|
||||
|
||||
1996年,Linux是世界上第一个添加对人工语言克林贡支持的操作系统,克林贡是由
|
||||
Marc Okrand为《星际迷航》电视连续剧创造的。这种编码后来被征募Unicode注册表
|
||||
(ConScript Unicode Registry,CSUR)采用,并建议(但最终被拒绝)纳入Unicode
|
||||
平面一。不过,它仍然是Linux区域中的Linux/CSUR私有分配。
|
||||
|
||||
这种编码已经得到克林贡语言研究所(Klingon Language Institute)的认可。
|
||||
有关更多信息,请联系他们:
|
||||
|
||||
http://www.kli.org/
|
||||
|
||||
由于Linux CZ开头部分的字符大多是dingbats/symbols/forms类型,而且这是一种
|
||||
语言,因此根据标准Unicode惯例,我将它放置在16单元的边界上。
|
||||
|
||||
.. note::
|
||||
|
||||
这个范围现在由征募Unicode注册表正式管理。规范性引用文件为:
|
||||
|
||||
https://www.evertype.com/standards/csur/klingon.html
|
||||
|
||||
克林贡语有一个26个字符的字母表,一个10位数的位置数字书写系统,从左到右
|
||||
,从上到下书写。
|
||||
|
||||
克林贡字母的几种字形已经被提出。但是由于这组符号看起来始终是一致的,只有实际
|
||||
的形状不同,因此按照标准Unicode惯例,这些差异被认为是字体变体。
|
||||
|
||||
====== =======================================================
|
||||
U+F8D0 KLINGON LETTER A
|
||||
U+F8D1 KLINGON LETTER B
|
||||
U+F8D2 KLINGON LETTER CH
|
||||
U+F8D3 KLINGON LETTER D
|
||||
U+F8D4 KLINGON LETTER E
|
||||
U+F8D5 KLINGON LETTER GH
|
||||
U+F8D6 KLINGON LETTER H
|
||||
U+F8D7 KLINGON LETTER I
|
||||
U+F8D8 KLINGON LETTER J
|
||||
U+F8D9 KLINGON LETTER L
|
||||
U+F8DA KLINGON LETTER M
|
||||
U+F8DB KLINGON LETTER N
|
||||
U+F8DC KLINGON LETTER NG
|
||||
U+F8DD KLINGON LETTER O
|
||||
U+F8DE KLINGON LETTER P
|
||||
U+F8DF KLINGON LETTER Q
|
||||
- Written <q> in standard Okrand Latin transliteration
|
||||
U+F8E0 KLINGON LETTER QH
|
||||
- Written <Q> in standard Okrand Latin transliteration
|
||||
U+F8E1 KLINGON LETTER R
|
||||
U+F8E2 KLINGON LETTER S
|
||||
U+F8E3 KLINGON LETTER T
|
||||
U+F8E4 KLINGON LETTER TLH
|
||||
U+F8E5 KLINGON LETTER U
|
||||
U+F8E6 KLINGON LETTER V
|
||||
U+F8E7 KLINGON LETTER W
|
||||
U+F8E8 KLINGON LETTER Y
|
||||
U+F8E9 KLINGON LETTER GLOTTAL STOP
|
||||
|
||||
U+F8F0 KLINGON DIGIT ZERO
|
||||
U+F8F1 KLINGON DIGIT ONE
|
||||
U+F8F2 KLINGON DIGIT TWO
|
||||
U+F8F3 KLINGON DIGIT THREE
|
||||
U+F8F4 KLINGON DIGIT FOUR
|
||||
U+F8F5 KLINGON DIGIT FIVE
|
||||
U+F8F6 KLINGON DIGIT SIX
|
||||
U+F8F7 KLINGON DIGIT SEVEN
|
||||
U+F8F8 KLINGON DIGIT EIGHT
|
||||
U+F8F9 KLINGON DIGIT NINE
|
||||
|
||||
U+F8FD KLINGON COMMA
|
||||
U+F8FE KLINGON FULL STOP
|
||||
U+F8FF KLINGON SYMBOL FOR EMPIRE
|
||||
====== =======================================================
|
||||
|
||||
其他虚构和人工字母
|
||||
-------------------
|
||||
|
||||
自从分配了克林贡Linux Unicode块之后,John Cowan <jcowan@reutershealth.com>
|
||||
和 Michael Everson <everson@evertype.com> 建立了一个虚构和人工字母的注册表。
|
||||
征募Unicode注册表请访问:
|
||||
|
||||
https://www.evertype.com/standards/csur/
|
||||
|
||||
所使用的范围位于最终用户区域的低端,因此无法进行规范化分配,但建议希望对虚构
|
||||
字母进行编码的人员使用这些代码,以实现互操作性。对于克林贡语,CSUR采用了Linux
|
||||
编码。CSUR的人正在推动将Tengwar和Cirth添加到Unicode平面一;将克林贡添加到
|
||||
Unicode平面一被拒绝,因此上述编码仍然是官方的。
|
|
@ -0,0 +1,126 @@
|
|||
.. include:: ../disclaimer-zh_CN.rst
|
||||
|
||||
:Original: :doc:`../../../core-api/irq/index`
|
||||
:Translator: Yanteng Si <siyanteng@loongson.cn>
|
||||
|
||||
.. _cn_core-api_index.rst:
|
||||
|
||||
|
||||
===========
|
||||
核心API文档
|
||||
===========
|
||||
|
||||
这是核心内核API手册的首页。 非常感谢为本手册转换(和编写!)的文档!
|
||||
|
||||
核心实用程序
|
||||
============
|
||||
|
||||
本节包含通用的和“核心中的核心”文档。 第一部分是 docbook 时期遗留下
|
||||
来的大量 kerneldoc 信息;有朝一日,若有人有动力的话,应当把它们拆分
|
||||
出来。
|
||||
|
||||
Todolist:
|
||||
|
||||
kernel-api
|
||||
workqueue
|
||||
printk-basics
|
||||
printk-formats
|
||||
symbol-namespaces
|
||||
|
||||
数据结构和低级实用程序
|
||||
======================
|
||||
|
||||
在整个内核中使用的函数库。
|
||||
|
||||
Todolist:
|
||||
|
||||
kobject
|
||||
kref
|
||||
assoc_array
|
||||
xarray
|
||||
idr
|
||||
circular-buffers
|
||||
rbtree
|
||||
generic-radix-tree
|
||||
packing
|
||||
bus-virt-phys-mapping
|
||||
this_cpu_ops
|
||||
timekeeping
|
||||
errseq
|
||||
|
||||
并发原语
|
||||
========
|
||||
|
||||
Linux如何让一切同时发生。 详情请参阅
|
||||
:doc:`/locking/index`
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
irq/index
|
||||
|
||||
Todolist:
|
||||
|
||||
refcount-vs-atomic
|
||||
local_ops
|
||||
padata
|
||||
../RCU/index
|
||||
|
||||
低级硬件管理
|
||||
============
|
||||
|
||||
缓存管理,CPU热插拔管理等。
|
||||
|
||||
Todolist:
|
||||
|
||||
cachetlb
|
||||
cpu_hotplug
|
||||
memory-hotplug
|
||||
genericirq
|
||||
protection-keys
|
||||
|
||||
|
||||
内存管理
|
||||
========
|
||||
|
||||
如何在内核中分配和使用内存。请注意,在
|
||||
:doc:`/vm/index` 中有更多的内存管理文档。
|
||||
|
||||
Todolist:
|
||||
|
||||
memory-allocation
|
||||
unaligned-memory-access
|
||||
dma-api
|
||||
dma-api-howto
|
||||
dma-attributes
|
||||
dma-isa-lpc
|
||||
mm-api
|
||||
genalloc
|
||||
pin_user_pages
|
||||
boot-time-mm
|
||||
gfp_mask-from-fs-io
|
||||
|
||||
内核调试的接口
|
||||
==============
|
||||
|
||||
Todolist:
|
||||
|
||||
debug-objects
|
||||
tracepoint
|
||||
debugging-via-ohci1394
|
||||
|
||||
其它文档
|
||||
========
|
||||
|
||||
不适合放在其它地方或尚未归类的文件;
|
||||
|
||||
Todolist:
|
||||
|
||||
librs
|
||||
|
||||
.. only:: subproject and html
|
||||
|
||||
Indices
|
||||
=======
|
||||
|
||||
* :ref:`genindex`
|
|
@ -0,0 +1,24 @@
|
|||
.. include:: ../../disclaimer-zh_CN.rst
|
||||
|
||||
:Original: :doc:`../../../../core-api/irq/concepts`
|
||||
:Translator: Yanteng Si <siyanteng@loongson.cn>
|
||||
|
||||
.. _cn_concepts.rst:
|
||||
|
||||
|
||||
===========
|
||||
什么是IRQ?
|
||||
===========
|
||||
|
||||
IRQ (Interrupt ReQuest) 指来自设备的中断请求。
|
||||
目前,它们可以通过一个引脚或通过一个数据包进入。
|
||||
多个设备可以连接到同一个引脚,从而共享一个IRQ。
|
||||
|
||||
IRQ编号是用来描述硬件中断源的内核标识符。通常它是一个到全局irq_desc数组的索引,
|
||||
但是除了在linux/interrupt.h中实现的之外,其它细节是体系结构特征相关的。
|
||||
|
||||
IRQ编号是对机器上可能的中断源的枚举。通常枚举的是系统中所有中断控制器的输入引脚
|
||||
编号。在ISA(工业标准体系结构)的情况下所枚举的是两个i8259中断控制器的16个输入引脚。
|
||||
|
||||
体系结构可以给IRQ号赋予额外的含义,在涉及到硬件手动配置的情况下,我们鼓励这样做。
|
||||
ISA IRQ是赋予这种额外含义的一个典型例子。
|
|
@ -0,0 +1,19 @@
|
|||
.. include:: ../../disclaimer-zh_CN.rst
|
||||
|
||||
:Original: :doc:`../../../../core-api/irq/index`
|
||||
:Translator: Yanteng Si <siyanteng@loongson.cn>
|
||||
|
||||
.. _cn_irq_index.rst:
|
||||
|
||||
|
||||
====
|
||||
IRQs
|
||||
====
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
concepts
|
||||
irq-affinity
|
||||
irq-domain
|
||||
irqflags-tracing
|
|
@ -0,0 +1,76 @@
|
|||
.. include:: ../../disclaimer-zh_CN.rst
|
||||
|
||||
:Original: :doc:`../../../../core-api/irq/irq-affinity`
|
||||
:Translator: Yanteng Si <siyanteng@loongson.cn>
|
||||
|
||||
.. _cn_irq-affinity.rst:
|
||||
|
||||
|
||||
==============
|
||||
SMP IRQ 亲和性
|
||||
==============
|
||||
|
||||
变更记录:
|
||||
- 作者:最初由Ingo Molnar <mingo@redhat.com>开始撰写
|
||||
- 后期更新维护: Max Krasnyansky <maxk@qualcomm.com>
|
||||
|
||||
|
||||
/proc/irq/IRQ#/smp_affinity和/proc/irq/IRQ#/smp_affinity_list指定了哪些CPU能
|
||||
够关联到一个给定的IRQ源,这两个文件包含了这些指定cpu的cpu位掩码(smp_affinity)和cpu列
|
||||
表(smp_affinity_list)。它不允许关闭所有CPU, 同时如果IRQ控制器不支持中断请求亲和
|
||||
(IRQ affinity),那么所有cpu的默认值将保持不变(即关联到所有CPU).
|
||||
|
||||
/proc/irq/default_smp_affinity指明了适用于所有非激活IRQ的默认亲和性掩码。一旦IRQ被
|
||||
分配/激活,它的亲和位掩码将被设置为默认掩码。然后可以如上所述改变它。默认掩码是0xffffffff。
|
||||
|
||||
下面是一个先将IRQ44(eth1)限制在CPU0-3上,然后限制在CPU4-7上的例子(这是一个8CPU的SMP box)
|
||||
|
||||
::
|
||||
|
||||
[root@moon 44]# cd /proc/irq/44
|
||||
[root@moon 44]# cat smp_affinity
|
||||
ffffffff
|
||||
|
||||
[root@moon 44]# echo 0f > smp_affinity
|
||||
[root@moon 44]# cat smp_affinity
|
||||
0000000f
|
||||
[root@moon 44]# ping -f h
|
||||
PING hell (195.4.7.3): 56 data bytes
|
||||
...
|
||||
--- hell ping statistics ---
|
||||
6029 packets transmitted, 6027 packets received, 0% packet loss
|
||||
round-trip min/avg/max = 0.1/0.1/0.4 ms
|
||||
[root@moon 44]# cat /proc/interrupts | grep 'CPU\|44:'
|
||||
CPU0 CPU1 CPU2 CPU3 CPU4 CPU5 CPU6 CPU7
|
||||
44: 1068 1785 1785 1783 0 0 0 0 IO-APIC-level eth1
|
||||
|
||||
从上面一行可以看出,IRQ44只传递给前四个处理器(0-3)。
|
||||
现在让我们把这个IRQ限制在CPU(4-7)。
|
||||
|
||||
::
|
||||
|
||||
[root@moon 44]# echo f0 > smp_affinity
|
||||
[root@moon 44]# cat smp_affinity
|
||||
000000f0
|
||||
[root@moon 44]# ping -f h
|
||||
PING hell (195.4.7.3): 56 data bytes
|
||||
..
|
||||
--- hell ping statistics ---
|
||||
2779 packets transmitted, 2777 packets received, 0% packet loss
|
||||
round-trip min/avg/max = 0.1/0.5/585.4 ms
|
||||
[root@moon 44]# cat /proc/interrupts | 'CPU\|44:'
|
||||
CPU0 CPU1 CPU2 CPU3 CPU4 CPU5 CPU6 CPU7
|
||||
44: 1068 1785 1785 1783 1784 1069 1070 1069 IO-APIC-level eth1
|
||||
|
||||
这次IRQ44只传递给最后四个处理器。
|
||||
即CPU0-3的计数器没有变化。
|
||||
|
||||
下面是一个将相同的irq(44)限制在cpus 1024到1031的例子
|
||||
|
||||
::
|
||||
|
||||
[root@moon 44]# echo 1024-1031 > smp_affinity_list
|
||||
[root@moon 44]# cat smp_affinity_list
|
||||
1024-1031
|
||||
|
||||
需要注意的是,如果要用位掩码来做这件事,就需要32个为0的位掩码来追踪其相关的一个。
|
|
@ -0,0 +1,227 @@
|
|||
.. include:: ../../disclaimer-zh_CN.rst
|
||||
|
||||
:Original: :doc:`../../../../core-api/irq/irq-domain`
|
||||
:Translator: Yanteng Si <siyanteng@loongson.cn>
|
||||
|
||||
.. _cn_irq-domain.rst:
|
||||
|
||||
|
||||
=======================
|
||||
irq_domain 中断号映射库
|
||||
=======================
|
||||
|
||||
目前Linux内核的设计使用了一个巨大的数字空间,每个独立的IRQ源都被分配了一个不
|
||||
同的数字。
|
||||
当只有一个中断控制器时,这很简单,但在有多个中断控制器的系统中,内核必须确保每
|
||||
个中断控制器都能得到非重复的Linux IRQ号(数字)分配。
|
||||
|
||||
注册为唯一的irqchips的中断控制器编号呈现出上升的趋势:例如GPIO控制器等不同
|
||||
种类的子驱动程序通过将其中断处理程序建模为irqchips,即实际上是级联中断控制器,
|
||||
避免了重新实现与IRQ核心系统相同的回调机制。
|
||||
|
||||
在这里,中断号与硬件中断号离散了所有种类的对应关系:而在过去,IRQ号可以选择,
|
||||
使它们与硬件IRQ线进入根中断控制器(即实际向CPU发射中断线的组件)相匹配,现
|
||||
在这个编号仅仅是一个数字。
|
||||
|
||||
出于这个原因,我们需要一种机制将控制器本地中断号(即硬件irq编号)与Linux IRQ
|
||||
号分开。
|
||||
|
||||
irq_alloc_desc*() 和 irq_free_desc*() API 提供了对irq号的分配,但它们不
|
||||
提供任何对控制器本地IRQ(hwirq)号到Linux IRQ号空间的反向映射的支持。
|
||||
|
||||
irq_domain 库在 irq_alloc_desc*() API 的基础上增加了 hwirq 和 IRQ 号码
|
||||
之间的映射。 相比于中断控制器驱动开放编码自己的反向映射方案,我们更喜欢用
|
||||
irq_domain来管理映射。
|
||||
|
||||
irq_domain还实现了从抽象的irq_fwspec结构体到hwirq号的转换(到目前为止是
|
||||
Device Tree和ACPI GSI),并且可以很容易地扩展以支持其它IRQ拓扑数据源。
|
||||
|
||||
irq_domain的用法
|
||||
================
|
||||
|
||||
中断控制器驱动程序通过以下方式创建并注册一个irq_domain。调用
|
||||
irq_domain_add_*() 或 irq_domain_create_*()函数之一(每个映射方法都有不
|
||||
同的分配器函数,后面会详细介绍)。 函数成功后会返回一个指向irq_domain的指针。
|
||||
调用者必须向分配器函数提供一个irq_domain_ops结构体。
|
||||
|
||||
在大多数情况下,irq_domain在开始时是空的,没有任何hwirq和IRQ号之间的映射。
|
||||
通过调用irq_create_mapping()将映射添加到irq_domain中,该函数接受
|
||||
irq_domain和一个hwirq号作为参数。 如果hwirq的映射还不存在,那么它将分配
|
||||
一个新的Linux irq_desc,将其与hwirq关联起来,并调用.map()回调,这样驱动
|
||||
程序就可以执行任何必要的硬件设置。
|
||||
|
||||
当接收到一个中断时,应该使用irq_find_mapping()函数从hwirq号中找到
|
||||
Linux IRQ号。
|
||||
|
||||
在调用irq_find_mapping()之前,至少要调用一次irq_create_mapping()函数,
|
||||
以免描述符不能被分配。
|
||||
|
||||
如果驱动程序有Linux的IRQ号或irq_data指针,并且需要知道相关的hwirq号(比
|
||||
如在irq_chip回调中),那么可以直接从irq_data->hwirq中获得。
|
||||
|
||||
irq_domain映射的类型
|
||||
====================
|
||||
|
||||
从hwirq到Linux irq的反向映射有几种机制,每种机制使用不同的分配函数。应该
|
||||
使用哪种反向映射类型取决于用例。 下面介绍每一种反向映射类型:
|
||||
|
||||
线性映射
|
||||
--------
|
||||
|
||||
::
|
||||
|
||||
irq_domain_add_linear()
|
||||
irq_domain_create_linear()
|
||||
|
||||
线性反向映射维护了一个固定大小的表,该表以hwirq号为索引。 当一个hwirq被映射
|
||||
时,会给hwirq分配一个irq_desc,并将irq号存储在表中。
|
||||
|
||||
当最大的hwirq号固定且数量相对较少时,线性图是一个很好的选择(~<256)。 这种
|
||||
映射的优点是固定时间查找IRQ号,而且irq_descs只分配给在用的IRQ。 缺点是该表
|
||||
必须尽可能大的hwirq号。
|
||||
|
||||
irq_domain_add_linear()和irq_domain_create_linear()在功能上是等价的,
|
||||
除了第一个参数不同--前者接受一个Open Firmware特定的 'struct device_node' 而
|
||||
后者接受一个更通用的抽象 'struct fwnode_handle' 。
|
||||
|
||||
大多数驱动应该使用线性映射
|
||||
|
||||
树状映射
|
||||
--------
|
||||
|
||||
::
|
||||
|
||||
irq_domain_add_tree()
|
||||
irq_domain_create_tree()
|
||||
|
||||
irq_domain维护着从hwirq号到Linux IRQ的radix的树状映射。 当一个hwirq被映射时,
|
||||
一个irq_desc被分配,hwirq被用作radix树的查找键。
|
||||
|
||||
如果hwirq号可以非常大,树状映射是一个很好的选择,因为它不需要分配一个和最大hwirq
|
||||
号一样大的表。 缺点是,hwirq到IRQ号的查找取决于表中有多少条目。
|
||||
|
||||
irq_domain_add_tree()和irq_domain_create_tree()在功能上是等价的,除了第一
|
||||
个参数不同——前者接受一个Open Firmware特定的 'struct device_node' ,而后者接受
|
||||
一个更通用的抽象 'struct fwnode_handle' 。
|
||||
|
||||
很少有驱动应该需要这个映射。
|
||||
|
||||
无映射
|
||||
------
|
||||
|
||||
::
|
||||
|
||||
irq_domain_add_nomap()
|
||||
|
||||
当硬件中的hwirq号是可编程的时候,就可以采用无映射类型。 在这种情况下,最好将
|
||||
Linux IRQ号编入硬件本身,这样就不需要映射了。 调用irq_create_direct_mapping()
|
||||
会分配一个Linux IRQ号,并调用.map()回调,这样驱动就可以将Linux IRQ号编入硬件中。
|
||||
|
||||
大多数驱动程序不能使用这个映射。
|
||||
|
||||
传统映射类型
|
||||
------------
|
||||
|
||||
::
|
||||
|
||||
irq_domain_add_simple()
|
||||
irq_domain_add_legacy()
|
||||
irq_domain_add_legacy_isa()
|
||||
irq_domain_create_simple()
|
||||
irq_domain_create_legacy()
|
||||
|
||||
传统映射是已经为 hwirqs 分配了一系列 irq_descs 的驱动程序的特殊情况。 当驱动程
|
||||
序不能立即转换为使用线性映射时,就会使用它。 例如,许多嵌入式系统板卡支持文件使用
|
||||
一组用于IRQ号的定义(#define),这些定义被传递给struct设备注册。 在这种情况下,
|
||||
不能动态分配Linux IRQ号,应该使用传统映射。
|
||||
|
||||
传统映射假设已经为控制器分配了一个连续的IRQ号范围,并且可以通过向hwirq号添加一
|
||||
个固定的偏移来计算IRQ号,反之亦然。 缺点是需要中断控制器管理IRQ分配,并且需要为每
|
||||
个hwirq分配一个irq_desc,即使它没有被使用。
|
||||
|
||||
只有在必须支持固定的IRQ映射时,才应使用传统映射。 例如,ISA控制器将使用传统映射来
|
||||
映射Linux IRQ 0-15,这样现有的ISA驱动程序就能得到正确的IRQ号。
|
||||
|
||||
大多数使用传统映射的用户应该使用irq_domain_add_simple()或
|
||||
irq_domain_create_simple(),只有在系统提供IRQ范围时才会使用传统域,否则将使用
|
||||
线性域映射。这个调用的语义是这样的:如果指定了一个IRQ范围,那么 描述符将被即时分配
|
||||
给它,如果没有范围被分配,它将不会执行 irq_domain_add_linear() 或
|
||||
irq_domain_create_linear(),这意味着 *no* irq 描述符将被分配。
|
||||
|
||||
一个简单域的典型用例是,irqchip供应商同时支持动态和静态IRQ分配。
|
||||
|
||||
为了避免最终出现使用线性域而没有描述符被分配的情况,确保使用简单域的驱动程序在任何
|
||||
irq_find_mapping()之前调用irq_create_mapping()是非常重要的,因为后者实际上
|
||||
将用于静态IRQ分配情况。
|
||||
|
||||
irq_domain_add_simple()和irq_domain_create_simple()以及
|
||||
irq_domain_add_legacy()和irq_domain_create_legacy()在功能上是等价的,只
|
||||
是第一个参数不同--前者接受Open Firmware特定的 'struct device_node' ,而后者
|
||||
接受一个更通用的抽象 'struct fwnode_handle' 。
|
||||
|
||||
IRQ域层级结构
|
||||
-------------
|
||||
|
||||
在某些架构上,可能有多个中断控制器参与将一个中断从设备传送到目标CPU。
|
||||
让我们来看看x86平台上典型的中断传递路径吧
|
||||
::
|
||||
|
||||
Device --> IOAPIC -> Interrupt remapping Controller -> Local APIC -> CPU
|
||||
|
||||
涉及到的中断控制器有三个:
|
||||
|
||||
1) IOAPIC 控制器
|
||||
2) 中断重映射控制器
|
||||
3) Local APIC 控制器
|
||||
|
||||
为了支持这样的硬件拓扑结构,使软件架构与硬件架构相匹配,为每个中断控制器建立一
|
||||
个irq_domain数据结构,并将这些irq_domain组织成层次结构。
|
||||
|
||||
在建立irq_domain层次结构时,靠近设备的irq_domain为子域,靠近CPU的
|
||||
irq_domain为父域。所以在上面的例子中,将建立如下的层次结构。
|
||||
::
|
||||
|
||||
CPU Vector irq_domain (root irq_domain to manage CPU vectors)
|
||||
^
|
||||
|
|
||||
Interrupt Remapping irq_domain (manage irq_remapping entries)
|
||||
^
|
||||
|
|
||||
IOAPIC irq_domain (manage IOAPIC delivery entries/pins)
|
||||
|
||||
使用irq_domain层次结构的主要接口有四个:
|
||||
|
||||
1) irq_domain_alloc_irqs(): 分配IRQ描述符和与中断控制器相关的资源来传递这些中断。
|
||||
2) irq_domain_free_irqs(): 释放IRQ描述符和与这些中断相关的中断控制器资源。
|
||||
3) irq_domain_activate_irq(): 激活中断控制器硬件以传递中断。
|
||||
4) irq_domain_deactivate_irq(): 停用中断控制器硬件,停止传递中断。
|
||||
|
||||
为了支持irq_domain层次结构,需要做如下修改:
|
||||
|
||||
1) 一个新的字段 'parent' 被添加到irq_domain结构中;它用于维护irq_domain的层次信息。
|
||||
2) 一个新的字段 'parent_data' 被添加到irq_data结构中;它用于建立层次结构irq_data以
|
||||
匹配irq_domain层次结构。irq_data用于存储irq_domain指针和硬件irq号。
|
||||
3) 新的回调被添加到irq_domain_ops结构中,以支持层次结构的irq_domain操作。
|
||||
|
||||
在支持分层irq_domain和分层irq_data准备就绪后,为每个中断控制器建立一个irq_domain结
|
||||
构,并为每个与IRQ相关联的irq_domain分配一个irq_data结构。现在我们可以再进一步支持堆
|
||||
栈式(层次结构)的irq_chip。也就是说,一个irq_chip与层次结构中的每个irq_data相关联。
|
||||
一个子irq_chip可以自己或通过与它的父irq_chip合作来实现一个所需的操作。
|
||||
|
||||
通过堆栈式的irq_chip,中断控制器驱动只需要处理自己管理的硬件,在需要的时候可以向其父
|
||||
irq_chip请求服务。所以我们可以实现更简洁的软件架构。
|
||||
|
||||
为了让中断控制器驱动程序支持irq_domain层次结构,它需要做到以下几点:
|
||||
|
||||
1) 实现 irq_domain_ops.alloc 和 irq_domain_ops.free
|
||||
2) 可选择地实现 irq_domain_ops.activate 和 irq_domain_ops.deactivate.
|
||||
3) 可选择地实现一个irq_chip来管理中断控制器硬件。
|
||||
4) 不需要实现irq_domain_ops.map和irq_domain_ops.unmap,它们在层次结构
|
||||
irq_domain中是不用的。
|
||||
|
||||
irq_domain层次结构绝不是x86特有的,大量用于支持其他架构,如ARM、ARM64等。
|
||||
|
||||
调试功能
|
||||
========
|
||||
|
||||
打开CONFIG_GENERIC_IRQ_DEBUGFS,可让IRQ子系统的大部分内部结构都在debugfs中暴露出来。
|
|
@ -0,0 +1,45 @@
|
|||
.. include:: ../../disclaimer-zh_CN.rst
|
||||
|
||||
:Original: :doc:`../../../../core-api/irq/irqflags-tracing`
|
||||
:Translator: Yanteng Si <siyanteng@loongson.cn>
|
||||
|
||||
.. _cn_irqflags-tracing.rst:
|
||||
|
||||
|
||||
=================
|
||||
IRQ-flags状态追踪
|
||||
=================
|
||||
|
||||
:Author: 最初由Ingo Molnar <mingo@redhat.com>开始撰写
|
||||
|
||||
“irq-flags tracing”(中断标志追踪)功能可以 “追踪” hardirq和softirq的状态,它让
|
||||
感兴趣的子系统有机会了解到到内核中发生的每一个
|
||||
hardirqs-off/hardirqs-on、softirqs-off/softirqs-on事件。
|
||||
|
||||
CONFIG_TRACE_IRQFLAGS_SUPPORT是通用锁调试代码提供的CONFIG_PROVE_SPIN_LOCKING
|
||||
和CONFIG_PROVE_RW_LOCKING所需要的。否则将只有CONFIG_PROVE_MUTEX_LOCKING和
|
||||
CONFIG_PROVE_RWSEM_LOCKING在一个架构上被提供--这些都是不在IRQ上下文中使用的
|
||||
锁API。(rwsems的一个异常是可以解决的)
|
||||
|
||||
架构对这一点的支持当然不属于“微不足道”的范畴,因为很多低级的汇编代码都要处理irq-flags
|
||||
的状态变化。但是一个架构可以以一种相当直接且无风险的方式启用irq-flags-tracing。
|
||||
|
||||
架构如果想支持这个,需要先做一些代码组织上的改变:
|
||||
|
||||
- 在他们的arch级Kconfig文件中添加并启用TRACE_IRQFLAGS_SUPPORT。
|
||||
|
||||
然后还需要做一些功能上的改变来实现对irq-flags-tracing的支持:
|
||||
|
||||
- 在低级入口代码中增加(构建条件)对trace_hardirqs_off()/trace_hardirqs_on()
|
||||
函数的调用。锁验证器会密切关注 “real”的irq-flags是否与 “virtual”的irq-flags
|
||||
状态相匹配,如果两者不匹配,则会发出警告(并关闭自己)。通常维护arch中
|
||||
irq-flags-track的大部分时间都是在这种状态下度过的:看看lockdep的警告,试着
|
||||
找出我们还没有搞定的汇编代码。修复并重复。一旦系统启动,并且在irq-flags跟踪功
|
||||
能中没有出现lockdep警告的情况下,arch支持就完成了。
|
||||
|
||||
- 如果该架构有不可屏蔽的中断,那么需要通过lockdep_off()/lockdep_on()将这些中
|
||||
断从irq跟踪[和锁验证]机制中排除。
|
||||
|
||||
一般来说,在一个架构中,不完整的irq-flags-tracing实现是没有风险的:lockdep
|
||||
会检测到这一点,并将自己关闭。即锁验证器仍然可靠。应该不会因为irq-tracing的错
|
||||
误而崩溃。(除非通过修改不该修改的条件来更改汇编或寄存器而破坏其他代码)
|
|
@ -0,0 +1,105 @@
|
|||
.. SPDX-License-Identifier: GPL-2.0
|
||||
.. include:: ../disclaimer-zh_CN.rst
|
||||
|
||||
:Original: :doc:`../../../cpu-freq/core`
|
||||
:Translator: Yanteng Si <siyanteng@loongson.cn>
|
||||
|
||||
.. _cn_core.rst:
|
||||
|
||||
|
||||
====================================
|
||||
CPUFreq核心和CPUFreq通知器的通用说明
|
||||
====================================
|
||||
|
||||
作者:
|
||||
- Dominik Brodowski <linux@brodo.de>
|
||||
- David Kimdon <dwhedon@debian.org>
|
||||
- Rafael J. Wysocki <rafael.j.wysocki@intel.com>
|
||||
- Viresh Kumar <viresh.kumar@linaro.org>
|
||||
|
||||
.. 目录:
|
||||
|
||||
1. CPUFreq核心和接口
|
||||
2. CPUFreq通知器
|
||||
3. 含有Operating Performance Point (OPP)的CPUFreq表的生成
|
||||
|
||||
1. CPUFreq核心和接口
|
||||
======================
|
||||
|
||||
cpufreq核心代码位于drivers/cpufreq/cpufreq.c中。这些cpufreq代码为CPUFreq架构的驱
|
||||
动程序(那些操作硬件切换频率的代码)以及 "通知器 "提供了一个标准化的接口。
|
||||
这些是设备驱动程序或需要了解策略变化的其它内核部分(如 ACPI 热量管理)或所有频率更改(除
|
||||
计时代码外),甚至需要强制确定速度限制的通知器(如 ARM 架构上的 LCD 驱动程序)。
|
||||
此外, 内核 "常数" loops_per_jiffy会根据频率变化而更新。
|
||||
|
||||
cpufreq策略的引用计数由 cpufreq_cpu_get 和 cpufreq_cpu_put 来完成,以确保 cpufreq 驱
|
||||
动程序被正确地注册到核心中,并且驱动程序在 cpufreq_put_cpu 被调用之前不会被卸载。这也保证
|
||||
了每个CPU核的cpufreq 策略在使用期间不会被释放。
|
||||
|
||||
2. CPUFreq 通知器
|
||||
====================
|
||||
|
||||
CPUFreq通知器符合标准的内核通知器接口。
|
||||
关于通知器的细节请参阅 linux/include/linux/notifier.h。
|
||||
|
||||
这里有两个不同的CPUfreq通知器 - 策略通知器和转换通知器。
|
||||
|
||||
|
||||
2.1 CPUFreq策略通知器
|
||||
----------------------------
|
||||
|
||||
当创建或移除策略时,这些都会被通知。
|
||||
|
||||
阶段是在通知器的第二个参数中指定的。当第一次创建策略时,阶段是CPUFREQ_CREATE_POLICY,当
|
||||
策略被移除时,阶段是CPUFREQ_REMOVE_POLICY。
|
||||
|
||||
第三个参数 ``void *pointer`` 指向一个结构体cpufreq_policy,其包括min,max(新策略的下限和
|
||||
上限(单位为kHz))这几个值。
|
||||
|
||||
|
||||
2.2 CPUFreq转换通知器
|
||||
--------------------------------
|
||||
|
||||
当CPUfreq驱动切换CPU核心频率时,策略中的每个在线CPU都会收到两次通知,这些变化没有任何外部干
|
||||
预。
|
||||
|
||||
第二个参数指定阶段 - CPUFREQ_PRECHANGE or CPUFREQ_POSTCHANGE.
|
||||
|
||||
第三个参数是一个包含如下值的结构体cpufreq_freqs:
|
||||
|
||||
===== ====================
|
||||
cpu 受影响cpu的编号
|
||||
old 旧频率
|
||||
new 新频率
|
||||
flags cpufreq驱动的标志
|
||||
===== ====================
|
||||
|
||||
3. 含有Operating Performance Point (OPP)的CPUFreq表的生成
|
||||
==================================================================
|
||||
关于OPP的细节请参阅 Documentation/power/opp.rst
|
||||
|
||||
dev_pm_opp_init_cpufreq_table -
|
||||
这个功能提供了一个随时可用的转换程序,用来将OPP层关于可用频率的内部信息翻译成一种容易提供给
|
||||
cpufreq的格式。
|
||||
|
||||
.. Warning::
|
||||
|
||||
不要在中断上下文中使用此函数。
|
||||
|
||||
例如::
|
||||
|
||||
soc_pm_init()
|
||||
{
|
||||
/* Do things */
|
||||
r = dev_pm_opp_init_cpufreq_table(dev, &freq_table);
|
||||
if (!r)
|
||||
policy->freq_table = freq_table;
|
||||
/* Do other things */
|
||||
}
|
||||
|
||||
.. note::
|
||||
|
||||
该函数只有在CONFIG_PM_OPP之外还启用了CONFIG_CPU_FREQ时才可用。
|
||||
|
||||
dev_pm_opp_free_cpufreq_table
|
||||
释放dev_pm_opp_init_cpufreq_table分配的表。
|
|
@ -0,0 +1,259 @@
|
|||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
.. include:: ../disclaimer-zh_CN.rst
|
||||
|
||||
:Original: :doc:`../../../cpu-freq/cpu-drivers`
|
||||
:Translator: Yanteng Si <siyanteng@loongson.cn>
|
||||
|
||||
.. _cn_cpu-drivers.rst:
|
||||
|
||||
|
||||
=======================================
|
||||
如何实现一个新的CPUFreq处理器驱动程序?
|
||||
=======================================
|
||||
|
||||
作者:
|
||||
|
||||
|
||||
- Dominik Brodowski <linux@brodo.de>
|
||||
- Rafael J. Wysocki <rafael.j.wysocki@intel.com>
|
||||
- Viresh Kumar <viresh.kumar@linaro.org>
|
||||
|
||||
.. Contents
|
||||
|
||||
1. 怎么做?
|
||||
1.1 初始化
|
||||
1.2 Per-CPU 初始化
|
||||
1.3 验证
|
||||
1.4 target/target_index 或 setpolicy?
|
||||
1.5 target/target_index
|
||||
1.6 setpolicy
|
||||
1.7 get_intermediate 与 target_intermediate
|
||||
2. 频率表助手
|
||||
|
||||
|
||||
|
||||
1. 怎么做?
|
||||
===========
|
||||
|
||||
如此,你刚刚得到了一个全新的CPU/芯片组及其数据手册,并希望为这个CPU/芯片组添加cpufreq
|
||||
支持?很好,这里有一些至关重要的提示:
|
||||
|
||||
|
||||
1.1 初始化
|
||||
----------
|
||||
|
||||
首先,在__initcall_level_7 (module_init())或更靠后的函数中检查这个内核是否
|
||||
运行在正确的CPU和正确的芯片组上。如果是,则使用cpufreq_register_driver()向
|
||||
CPUfreq核心层注册一个cpufreq_driver结构体。
|
||||
|
||||
结构体cpufreq_driver应该包含什么成员?
|
||||
|
||||
.name - 驱动的名字。
|
||||
|
||||
.init - 一个指向per-policy初始化函数的指针。
|
||||
|
||||
.verify - 一个指向"verification"函数的指针。
|
||||
|
||||
.setpolicy 或 .fast_switch 或 .target 或 .target_index - 差异见
|
||||
下文。
|
||||
|
||||
并且可选择
|
||||
|
||||
.flags - cpufreq核的提示。
|
||||
|
||||
.driver_data - cpufreq驱动程序的特定数据。
|
||||
|
||||
.resolve_freq - 返回最适合目标频率的频率。不过并不能改变频率。
|
||||
|
||||
.get_intermediate 和 target_intermediate - 用于在改变CPU频率时切换到稳定
|
||||
的频率。
|
||||
|
||||
.get - 返回CPU的当前频率。
|
||||
|
||||
.bios_limit - 返回HW/BIOS对CPU的最大频率限制值。
|
||||
|
||||
.exit - 一个指向per-policy清理函数的指针,该函数在cpu热插拔过程的CPU_POST_DEAD
|
||||
阶段被调用。
|
||||
|
||||
.stop_cpu - 一个指向per-policy停止函数的指针,该函数在cpu热插拔过程的CPU_DOWN_PREPARE
|
||||
阶段被调用。
|
||||
|
||||
.suspend - 一个指向per-policy暂停函数的指针,该函数在关中断且在该策略的调节器停止
|
||||
后被调用。
|
||||
|
||||
.resume - 一个指向per-policy恢复函数的指针,该函数在关中断且在调节器再一次开始前被
|
||||
调用。
|
||||
|
||||
.ready - 一个指向per-policy准备函数的指针,该函数在策略完全初始化之后被调用。
|
||||
|
||||
.attr - 一个指向NULL结尾的"struct freq_attr"列表的指针,该函数允许导出值到
|
||||
sysfs。
|
||||
|
||||
.boost_enabled - 如果设置,则启用提升(boost)频率。
|
||||
|
||||
.set_boost - 一个指向per-policy函数的指针,该函数用来开启/关闭提升(boost)频率功能。
|
||||
|
||||
|
||||
1.2 Per-CPU 初始化
|
||||
------------------
|
||||
|
||||
每当一个新的CPU被注册到设备模型中,或者在cpufreq驱动注册自己之后,如果此CPU的cpufreq策
|
||||
略不存在,则会调用per-policy的初始化函数cpufreq_driver.init。请注意,.init()和.exit()程序
|
||||
只对策略调用一次,而不是对策略管理的每个CPU调用一次。它需要一个 ``struct cpufreq_policy
|
||||
*policy`` 作为参数。现在该怎么做呢?
|
||||
|
||||
如果有必要,请在你的CPU上激活CPUfreq功能支持。
|
||||
|
||||
然后,驱动程序必须填写以下数值:
|
||||
|
||||
+-----------------------------------+--------------------------------------+
|
||||
|policy->cpuinfo.min_freq 和 | |
|
||||
|policy->cpuinfo.max_freq | 该CPU支持的最低和最高频率(kHz) |
|
||||
| | |
|
||||
| | |
|
||||
+-----------------------------------+--------------------------------------+
|
||||
|policy->cpuinfo.transition_latency | |
|
||||
| | CPU在两个频率之间切换所需的时间,以 |
|
||||
| | 纳秒为单位(如适用,否则指定 |
|
||||
| | CPUFREQ_ETERNAL) |
|
||||
+-----------------------------------+--------------------------------------+
|
||||
|policy->cur | 该CPU当前的工作频率(如适用) |
|
||||
| | |
|
||||
+-----------------------------------+--------------------------------------+
|
||||
|policy->min, | |
|
||||
|policy->max, | |
|
||||
|policy->policy and, if necessary, | |
|
||||
|policy->governor | 必须包含该cpu的 “默认策略”。稍后 |
|
||||
| | 会用这些值调用 |
|
||||
| | cpufreq_driver.verify and either |
|
||||
| | cpufreq_driver.setpolicy or |
|
||||
| | cpufreq_driver.target/target_index |
|
||||
| | |
|
||||
+-----------------------------------+--------------------------------------+
|
||||
|policy->cpus | 用与这个CPU一起做DVFS的(在线+离线) |
|
||||
| | CPU(即与它共享时钟/电压轨)的掩码更新 |
|
||||
| | 这个 |
|
||||
| | |
|
||||
+-----------------------------------+--------------------------------------+
|
||||
|
||||
对于设置其中的一些值(cpuinfo.min[max]_freq, policy->min[max]),频率表助手可能会有帮
|
||||
助。关于它们的更多信息,请参见第2节。
|
||||
|
||||
|
||||
1.3 验证
|
||||
--------
|
||||
|
||||
当用户决定设置一个新的策略(由 “policy,governor,min,max组成”)时,必须对这个策略进行验证,
|
||||
以便纠正不兼容的值。为了验证这些值,cpufreq_verify_within_limits(``struct cpufreq_policy
|
||||
*policy``, ``unsigned int min_freq``, ``unsigned int max_freq``)函数可能会有帮助。
|
||||
关于频率表助手的详细内容请参见第2节。
|
||||
|
||||
您需要确保至少有一个有效频率(或工作范围)在 policy->min 和 policy->max 范围内。如果有必
|
||||
要,先增加policy->max,只有在没有办法的情况下,才减少policy->min。
|
||||
|
||||
|
||||
1.4 target 或 target_index 或 setpolicy 或 fast_switch?
|
||||
-------------------------------------------------------
|
||||
|
||||
大多数cpufreq驱动甚至大多数cpu频率升降算法只允许将CPU频率设置为预定义的固定值。对于这些,你
|
||||
可以使用->target(),->target_index()或->fast_switch()回调。
|
||||
|
||||
有些cpufreq功能的处理器可以自己在某些限制之间切换频率。这些应使用->setpolicy()回调。
|
||||
|
||||
|
||||
1.5. target/target_index
|
||||
------------------------
|
||||
|
||||
target_index调用有两个参数:``struct cpufreq_policy * policy``和``unsigned int``
|
||||
索引(于列出的频率表)。
|
||||
|
||||
当调用这里时,CPUfreq驱动必须设置新的频率。实际频率必须由freq_table[index].frequency决定。
|
||||
|
||||
它应该总是在错误的情况下恢复到之前的频率(即policy->restore_freq),即使我们之前切换到中间频率。
|
||||
|
||||
已弃用
|
||||
----------
|
||||
目标调用有三个参数。``struct cpufreq_policy * policy``, unsigned int target_frequency,
|
||||
unsigned int relation.
|
||||
|
||||
CPUfreq驱动在调用这里时必须设置新的频率。实际的频率必须使用以下规则来确定。
|
||||
|
||||
- 紧跟 "目标频率"。
|
||||
- policy->min <= new_freq <= policy->max (这必须是有效的!!!)
|
||||
- 如果 relation==CPUFREQ_REL_L,尝试选择一个高于或等于 target_freq 的 new_freq。("L代表
|
||||
最低,但不能低于")
|
||||
- 如果 relation==CPUFREQ_REL_H,尝试选择一个低于或等于 target_freq 的 new_freq。("H代表
|
||||
最高,但不能高于")
|
||||
|
||||
这里,频率表助手可能会帮助你--详见第2节。
|
||||
|
||||
1.6. fast_switch
|
||||
----------------
|
||||
|
||||
这个函数用于从调度器的上下文进行频率切换。并非所有的驱动都要实现它,因为不允许在这个回调中睡眠。这
|
||||
个回调必须经过高度优化,以尽可能快地进行切换。
|
||||
|
||||
这个函数有两个参数: ``struct cpufreq_policy *policy`` 和 ``unsigned int target_frequency``。
|
||||
|
||||
|
||||
1.7 setpolicy
|
||||
-------------
|
||||
|
||||
setpolicy调用只需要一个``struct cpufreq_policy * policy``作为参数。需要将处理器内或芯片组内动态频
|
||||
率切换的下限设置为policy->min,上限设置为policy->max,如果支持的话,当policy->policy为
|
||||
CPUFREQ_POLICY_PERFORMANCE时选择面向性能的设置,当CPUFREQ_POLICY_POWERSAVE时选择面向省电的设置。
|
||||
也可以查看drivers/cpufreq/longrun.c中的参考实现。
|
||||
|
||||
1.8 get_intermediate 和 target_intermediate
|
||||
--------------------------------------------
|
||||
|
||||
仅适用于 target_index() 和 CPUFREQ_ASYNC_NOTIFICATION 未设置的驱动。
|
||||
|
||||
get_intermediate应该返回一个平台想要切换到的稳定的中间频率,target_intermediate()应该将CPU设置为
|
||||
该频率,然后再跳转到'index'对应的频率。核心会负责发送通知,驱动不必在target_intermediate()或
|
||||
target_index()中处理。
|
||||
|
||||
在驱动程序不想因为某个目标频率切换到中间频率的情况下,它们可以从get_intermediate()中返回'0'。在这种情况
|
||||
下,核心将直接调用->target_index()。
|
||||
|
||||
注意:->target_index()应该在失败的情况下恢复到policy->restore_freq,因为core会为此发送通知。
|
||||
|
||||
|
||||
2. 频率表助手
|
||||
=============
|
||||
|
||||
由于大多数cpufreq处理器只允许被设置为几个特定的频率,因此,一个带有一些函数的 “频率表”可能会辅助处理器驱动
|
||||
程序的一些工作。这样的 "频率表" 由一个cpufreq_frequency_table条目构成的数组组成,"driver_data" 中包
|
||||
含了驱动程序的具体数值,"frequency" 中包含了相应的频率,并设置了标志。在表的最后,需要添加一个
|
||||
cpufreq_frequency_table条目,频率设置为CPUFREQ_TABLE_END。而如果想跳过表中的一个条目,则将频率设置为
|
||||
CPUFREQ_ENTRY_INVALID。这些条目不需要按照任何特定的顺序排序,但如果它们是cpufreq 核心会对它们进行快速的DVFS,
|
||||
因为搜索最佳匹配会更快。
|
||||
|
||||
如果策略在其policy->freq_table字段中包含一个有效的指针,cpufreq表就会被核心自动验证。
|
||||
|
||||
cpufreq_frequency_table_verify()保证至少有一个有效的频率在policy->min和policy->max范围内,并且所有其他
|
||||
标准都被满足。这对->verify调用很有帮助。
|
||||
|
||||
cpufreq_frequency_table_target()是对应于->target阶段的频率表助手。只要把数值传递给这个函数,这个函数就会返
|
||||
回包含CPU要设置的频率的频率表条目。
|
||||
|
||||
以下宏可以作为cpufreq_frequency_table的迭代器。
|
||||
|
||||
cpufreq_for_each_entry(pos, table) - 遍历频率表的所有条目。
|
||||
|
||||
cpufreq_for_each_valid_entry(pos, table) - 该函数遍历所有条目,不包括CPUFREQ_ENTRY_INVALID频率。
|
||||
使用参数 "pos"-一个``cpufreq_frequency_table * `` 作为循环变量,使用参数 "table"-作为你想迭代
|
||||
的``cpufreq_frequency_table * `` 。
|
||||
|
||||
例如::
|
||||
|
||||
struct cpufreq_frequency_table *pos, *driver_freq_table;
|
||||
|
||||
cpufreq_for_each_entry(pos, driver_freq_table) {
|
||||
/* Do something with pos */
|
||||
pos->frequency = ...
|
||||
}
|
||||
|
||||
如果你需要在driver_freq_table中处理pos的位置,不要减去指针,因为它的代价相当高。相反,使用宏
|
||||
cpufreq_for_each_entry_idx() 和 cpufreq_for_each_valid_entry_idx() 。
|
|
@ -0,0 +1,130 @@
|
|||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
.. include:: ../disclaimer-zh_CN.rst
|
||||
|
||||
:Original: :doc:`../../../cpu-freq/cpufreq-stats`
|
||||
:Translator: Yanteng Si <siyanteng@loongson.cn>
|
||||
|
||||
.. _cn_cpufreq-stats.rst:
|
||||
|
||||
|
||||
==========================================
|
||||
sysfs CPUFreq Stats的一般说明
|
||||
==========================================
|
||||
|
||||
用户信息
|
||||
|
||||
|
||||
作者: Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
|
||||
|
||||
.. Contents
|
||||
|
||||
1. 简介
|
||||
2. 提供的统计数据(举例说明)
|
||||
3. 配置cpufreq-stats
|
||||
|
||||
|
||||
1. 简介
|
||||
===============
|
||||
|
||||
cpufreq-stats是一个为每个CPU提供CPU频率统计的驱动。
|
||||
这些统计数据在/sysfs中以一堆只读接口的形式提供。这个接口(在配置好后)将出现在
|
||||
/sysfs(<sysfs root>/devices/system/cpu/cpuX/cpufreq/stats/)中cpufreq下的一个单
|
||||
独的目录中,提供给每个CPU。
|
||||
各种统计数据将在此目录下形成只读文件。
|
||||
|
||||
此驱动是独立于任何可能运行在你所用CPU上的特定cpufreq_driver而设计的。因此,它将与所有
|
||||
cpufreq_driver一起工作。
|
||||
|
||||
|
||||
2. 提供的统计数据(举例说明)
|
||||
=====================================
|
||||
|
||||
cpufreq stats提供了以下统计数据(在下面详细解释)。
|
||||
|
||||
- time_in_state
|
||||
- total_trans
|
||||
- trans_table
|
||||
|
||||
所有的统计数据将从统计驱动被载入的时间(或统计被重置的时间)开始,到某一统计数据被读取的时间为止。
|
||||
显然,统计驱动不会有任何关于统计驱动载入之前的频率转换信息。
|
||||
|
||||
::
|
||||
|
||||
<mysystem>:/sys/devices/system/cpu/cpu0/cpufreq/stats # ls -l
|
||||
total 0
|
||||
drwxr-xr-x 2 root root 0 May 14 16:06 .
|
||||
drwxr-xr-x 3 root root 0 May 14 15:58 ..
|
||||
--w------- 1 root root 4096 May 14 16:06 reset
|
||||
-r--r--r-- 1 root root 4096 May 14 16:06 time_in_state
|
||||
-r--r--r-- 1 root root 4096 May 14 16:06 total_trans
|
||||
-r--r--r-- 1 root root 4096 May 14 16:06 trans_table
|
||||
|
||||
- **reset**
|
||||
|
||||
只写属性,可用于重置统计计数器。这对于评估不同调节器下的系统行为非常有用,且无需重启。
|
||||
|
||||
|
||||
- **time_in_state**
|
||||
|
||||
此项给出了这个CPU所支持的每个频率所花费的时间。cat输出的每一行都会有"<frequency>
|
||||
<time>"对,表示这个CPU在<frequency>上花费了<time>个usertime单位的时间。这里的
|
||||
usertime单位是10mS(类似于/proc中输出的其他时间)。
|
||||
|
||||
::
|
||||
|
||||
<mysystem>:/sys/devices/system/cpu/cpu0/cpufreq/stats # cat time_in_state
|
||||
3600000 2089
|
||||
3400000 136
|
||||
3200000 34
|
||||
3000000 67
|
||||
2800000 172488
|
||||
|
||||
|
||||
- **total_trans**
|
||||
|
||||
给出了这个CPU上频率转换的总次数。cat的输出将有一个单一的计数,这就是频率转换的总数。
|
||||
|
||||
::
|
||||
|
||||
<mysystem>:/sys/devices/system/cpu/cpu0/cpufreq/stats # cat total_trans
|
||||
20
|
||||
|
||||
- **trans_table**
|
||||
|
||||
这将提供所有CPU频率转换的细粒度信息。这里的cat输出是一个二维矩阵,其中一个条目<i, j>(第
|
||||
i行,第j列)代表从Freq_i到Freq_j的转换次数。Freq_i行和Freq_j列遵循驱动最初提供给cpufreq
|
||||
核的频率表的排序顺序,因此可以排序(升序或降序)或不排序。 这里的输出也包含了每行每列的实际
|
||||
频率值,以便更好地阅读。
|
||||
|
||||
如果转换表大于PAGE_SIZE,读取时将返回一个-EFBIG错误。
|
||||
|
||||
::
|
||||
|
||||
<mysystem>:/sys/devices/system/cpu/cpu0/cpufreq/stats # cat trans_table
|
||||
From : To
|
||||
: 3600000 3400000 3200000 3000000 2800000
|
||||
3600000: 0 5 0 0 0
|
||||
3400000: 4 0 2 0 0
|
||||
3200000: 0 1 0 2 0
|
||||
3000000: 0 0 1 0 3
|
||||
2800000: 0 0 0 2 0
|
||||
|
||||
3. 配置cpufreq-stats
|
||||
============================
|
||||
|
||||
要在你的内核中配置cpufreq-stats::
|
||||
|
||||
Config Main Menu
|
||||
Power management options (ACPI, APM) --->
|
||||
CPU Frequency scaling --->
|
||||
[*] CPU Frequency scaling
|
||||
[*] CPU frequency translation statistics
|
||||
|
||||
|
||||
"CPU Frequency scaling" (CONFIG_CPU_FREQ) 应该被启用以配置cpufreq-stats。
|
||||
|
||||
"CPU frequency translation statistics" (CONFIG_CPU_FREQ_STAT)提供了包括
|
||||
time_in_state、total_trans和trans_table的统计数据。
|
||||
|
||||
一旦启用了这个选项,并且你的CPU支持cpufrequency,你就可以在/sysfs中看到CPU频率统计。
|
|
@ -0,0 +1,45 @@
|
|||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
.. include:: ../disclaimer-zh_CN.rst
|
||||
|
||||
:Original: :doc:`../../../cpu-freq/index`
|
||||
:Translator: Yanteng Si <siyanteng@loongson.cn>
|
||||
|
||||
.. _cn_index.rst:
|
||||
|
||||
|
||||
=======================================================
|
||||
Linux CPUFreq - Linux(TM)内核中的CPU频率和电压升降代码
|
||||
=======================================================
|
||||
|
||||
Author: Dominik Brodowski <linux@brodo.de>
|
||||
|
||||
时钟升降允许你在运行中改变CPU的时钟速度。这是一个很好的节省电池电量的方法,因为时
|
||||
钟速度越低,CPU消耗的电量越少。
|
||||
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
core
|
||||
cpu-drivers
|
||||
cpufreq-stats
|
||||
|
||||
邮件列表
|
||||
------------
|
||||
这里有一个 CPU 频率变化的 CVS 提交和通用列表,您可以在这里报告bug、问题或提交补丁。要发
|
||||
布消息,请发送电子邮件到 linux-pm@vger.kernel.org。
|
||||
|
||||
链接
|
||||
-----
|
||||
FTP档案:
|
||||
* ftp://ftp.linux.org.uk/pub/linux/cpufreq/
|
||||
|
||||
如何访问CVS仓库:
|
||||
* http://cvs.arm.linux.org.uk/
|
||||
|
||||
CPUFreq邮件列表:
|
||||
* http://vger.kernel.org/vger-lists.html#linux-pm
|
||||
|
||||
SA-1100的时钟和电压标度:
|
||||
* http://www.lartmaker.nl/projects/scaling
|
|
@ -0,0 +1,264 @@
|
|||
.. include:: ../disclaimer-zh_CN.rst
|
||||
|
||||
:Original: Documentation/dev-tools/gcov.rst
|
||||
:Translator: 赵军奎 Bernard Zhao <bernard@vivo.com>
|
||||
|
||||
在Linux内核里使用gcov做代码覆盖率检查
|
||||
=====================================
|
||||
|
||||
gcov分析核心支持在Linux内核中启用GCC的覆盖率测试工具 gcov_ ,Linux内核
|
||||
运行时的代码覆盖率数据会以gcov兼容的格式导出到“gcov”debugfs目录中,可
|
||||
以通过gcov的 ``-o`` 选项(如下示例)获得指定文件的代码运行覆盖率统计数据
|
||||
(需要跳转到内核编译路径下并且要有root权限)::
|
||||
|
||||
# cd /tmp/linux-out
|
||||
# gcov -o /sys/kernel/debug/gcov/tmp/linux-out/kernel spinlock.c
|
||||
|
||||
这将在当前目录中创建带有执行计数注释的源代码文件。
|
||||
在获得这些统计文件后,可以使用图形化的gcov前端工具(比如 lcov_ ),来实现
|
||||
自动化处理Linux内核的覆盖率运行数据,同时生成易于阅读的HTML格式文件。
|
||||
|
||||
可能的用途:
|
||||
|
||||
* 调试(用来判断每一行的代码是否已经运行过)
|
||||
* 测试改进(如何修改测试代码,尽可能地覆盖到没有运行过的代码)
|
||||
* 内核最小化配置(对于某一个选项配置,如果关联的代码从来没有运行过,
|
||||
是否还需要这个配置)
|
||||
|
||||
.. _gcov: https://gcc.gnu.org/onlinedocs/gcc/Gcov.html
|
||||
.. _lcov: http://ltp.sourceforge.net/coverage/lcov.php
|
||||
|
||||
|
||||
准备
|
||||
----
|
||||
|
||||
内核打开如下配置::
|
||||
|
||||
CONFIG_DEBUG_FS=y
|
||||
CONFIG_GCOV_KERNEL=y
|
||||
|
||||
获取整个内核的覆盖率数据,还需要打开::
|
||||
|
||||
CONFIG_GCOV_PROFILE_ALL=y
|
||||
|
||||
需要注意的是,整个内核开启覆盖率统计会造成内核镜像文件尺寸的增大,
|
||||
同时内核运行也会变慢一些。
|
||||
另外,并不是所有的架构都支持整个内核开启覆盖率统计。
|
||||
|
||||
代码运行覆盖率数据只在debugfs挂载完成后才可以访问::
|
||||
|
||||
mount -t debugfs none /sys/kernel/debug
|
||||
|
||||
|
||||
定制化
|
||||
------
|
||||
|
||||
如果要单独针对某一个路径或者文件进行代码覆盖率统计,可以在内核相应路
|
||||
径的Makefile中增加如下的配置:
|
||||
|
||||
- 单独统计单个文件(例如main.o)::
|
||||
|
||||
GCOV_PROFILE_main.o := y
|
||||
|
||||
- 单独统计某一个路径::
|
||||
|
||||
GCOV_PROFILE := y
|
||||
|
||||
如果要在整个内核的覆盖率统计(开启CONFIG_GCOV_PROFILE_ALL)中单独排除
|
||||
某一个文件或者路径,可以使用如下的方法::
|
||||
|
||||
GCOV_PROFILE_main.o := n
|
||||
|
||||
和::
|
||||
|
||||
GCOV_PROFILE := n
|
||||
|
||||
此机制仅支持链接到内核镜像或编译为内核模块的文件。
|
||||
|
||||
|
||||
相关文件
|
||||
--------
|
||||
|
||||
gcov功能需要在debugfs中创建如下文件:
|
||||
|
||||
``/sys/kernel/debug/gcov``
|
||||
gcov相关功能的根路径
|
||||
|
||||
``/sys/kernel/debug/gcov/reset``
|
||||
全局复位文件:向该文件写入数据后会将所有的gcov统计数据清0
|
||||
|
||||
``/sys/kernel/debug/gcov/path/to/compile/dir/file.gcda``
|
||||
gcov工具可以识别的覆盖率统计数据文件,向该文件写入数据后
|
||||
会将本文件的gcov统计数据清0
|
||||
|
||||
``/sys/kernel/debug/gcov/path/to/compile/dir/file.gcno``
|
||||
gcov工具需要的软连接文件(指向编译时生成的信息统计文件),这个文件是
|
||||
在gcc编译时如果配置了选项 ``-ftest-coverage`` 时生成的。
|
||||
|
||||
|
||||
针对模块的统计
|
||||
--------------
|
||||
|
||||
内核中的模块会动态的加载和卸载,模块卸载时对应的数据会被清除掉。
|
||||
gcov提供了一种机制,通过保留相关数据的副本来收集这部分卸载模块的覆盖率数据。
|
||||
模块卸载后这些备份数据在debugfs中会继续存在。
|
||||
一旦这个模块重新加载,模块关联的运行统计会被初始化成debugfs中备份的数据。
|
||||
|
||||
可以通过对内核参数gcov_persist的修改来停用gcov对模块的备份机制::
|
||||
|
||||
gcov_persist = 0
|
||||
|
||||
在运行时,用户还可以通过写入模块的数据文件或者写入gcov复位文件来丢弃已卸
|
||||
载模块的数据。
|
||||
|
||||
|
||||
编译机和测试机分离
|
||||
------------------
|
||||
|
||||
gcov的内核分析插桩支持内核的编译和运行是在同一台机器上,也可以编译和运
|
||||
行是在不同的机器上。
|
||||
如果内核编译和运行是不同的机器,那么需要额外的准备工作,这取决于gcov工具
|
||||
是在哪里使用的:
|
||||
|
||||
.. _gcov-test_zh:
|
||||
|
||||
a) 若gcov运行在测试机上
|
||||
|
||||
测试机上面gcov工具的版本必须要跟内核编译机器使用的gcc版本相兼容,
|
||||
同时下面的文件要从编译机拷贝到测试机上:
|
||||
|
||||
从源代码中:
|
||||
- 所有的C文件和头文件
|
||||
|
||||
从编译目录中:
|
||||
- 所有的C文件和头文件
|
||||
- 所有的.gcda文件和.gcno文件
|
||||
- 所有目录的链接
|
||||
|
||||
特别需要注意,测试机器上面的目录结构跟编译机器上面的目录机构必须
|
||||
完全一致。
|
||||
如果文件是软链接,需要替换成真正的目录文件(这是由make的当前工作
|
||||
目录变量CURDIR引起的)。
|
||||
|
||||
.. _gcov-build_zh:
|
||||
|
||||
b) 若gcov运行在编译机上
|
||||
|
||||
测试用例运行结束后,如下的文件需要从测试机中拷贝到编译机上:
|
||||
|
||||
从sysfs中的gcov目录中:
|
||||
- 所有的.gcda文件
|
||||
- 所有的.gcno文件软链接
|
||||
|
||||
这些文件可以拷贝到编译机的任意目录下,gcov使用-o选项指定拷贝的
|
||||
目录。
|
||||
|
||||
比如一个是示例的目录结构如下::
|
||||
|
||||
/tmp/linux: 内核源码目录
|
||||
/tmp/out: 内核编译文件路径(make O=指定)
|
||||
/tmp/coverage: 从测试机器上面拷贝的数据文件路径
|
||||
|
||||
[user@build] cd /tmp/out
|
||||
[user@build] gcov -o /tmp/coverage/tmp/out/init main.c
|
||||
|
||||
|
||||
关于编译器的注意事项
|
||||
--------------------
|
||||
|
||||
GCC和LLVM gcov工具不一定兼容。
|
||||
如果编译器是GCC,使用 gcov_ 来处理.gcno和.gcda文件,如果是Clang编译器,
|
||||
则使用 llvm-cov_ 。
|
||||
|
||||
.. _gcov: https://gcc.gnu.org/onlinedocs/gcc/Gcov.html
|
||||
.. _llvm-cov: https://llvm.org/docs/CommandGuide/llvm-cov.html
|
||||
|
||||
GCC和Clang gcov之间的版本差异由Kconfig处理的。
|
||||
kconfig会根据编译工具链的检查自动选择合适的gcov格式。
|
||||
|
||||
问题定位
|
||||
--------
|
||||
|
||||
可能出现的问题1
|
||||
编译到链接阶段报错终止
|
||||
|
||||
问题原因
|
||||
分析标志指定在了源文件但是没有链接到主内核,或者客制化了链接程序
|
||||
|
||||
解决方法
|
||||
通过在相应的Makefile中使用 ``GCOV_PROFILE := n``
|
||||
或者 ``GCOV_PROFILE_basename.o := n`` 来将链接报错的文件排除掉
|
||||
|
||||
可能出现的问题2
|
||||
从sysfs复制的文件显示为空或不完整
|
||||
|
||||
问题原因
|
||||
由于seq_file的工作方式,某些工具(例如cp或tar)可能无法正确地从
|
||||
sysfs复制文件。
|
||||
|
||||
解决方法
|
||||
使用 ``cat`` 读取 ``.gcda`` 文件,使用 ``cp -d`` 复制链接,或者使用附录B
|
||||
中所示的机制。
|
||||
|
||||
|
||||
附录A:collect_on_build.sh
|
||||
--------------------------
|
||||
|
||||
用于在编译机上收集覆盖率元文件的示例脚本
|
||||
(见 :ref:`编译机和测试机分离 a. <gcov-test_zh>` )
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
#!/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
|
||||
|
||||
|
||||
附录B:collect_on_test.sh
|
||||
-------------------------
|
||||
|
||||
用于在测试机上收集覆盖率数据文件的示例脚本
|
||||
(见 :ref:`编译机和测试机分离 b. <gcov-build_zh>` )
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
#!/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,35 @@
|
|||
.. include:: ../disclaimer-zh_CN.rst
|
||||
|
||||
:Original: Documentation/dev-tools/index.rst
|
||||
:Translator: 赵军奎 Bernard Zhao <bernard@vivo.com>
|
||||
|
||||
============
|
||||
内核开发工具
|
||||
============
|
||||
|
||||
本文档是有关内核开发工具文档的合集。
|
||||
目前这些文档已经整理在一起,不需要再花费额外的精力。
|
||||
欢迎任何补丁。
|
||||
|
||||
.. class:: toc-title
|
||||
|
||||
目录
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
gcov
|
||||
|
||||
Todolist:
|
||||
|
||||
- coccinelle
|
||||
- sparse
|
||||
- kcov
|
||||
- kasan
|
||||
- ubsan
|
||||
- kmemleak
|
||||
- kcsan
|
||||
- gdb-kernel-debugging
|
||||
- kgdb
|
||||
- kselftest
|
||||
- kunit/index
|
|
@ -6,4 +6,4 @@
|
|||
|
||||
.. note::
|
||||
如果您发现本文档与原始文件有任何不同或者有翻译问题,请联系该文件的译者,
|
||||
或者请求时奎亮的帮助:<alex.shi@linux.alibaba.com>。
|
||||
或者请求时奎亮的帮助:<alexs@kernel.org>。
|
||||
|
|
|
@ -0,0 +1,238 @@
|
|||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
.. include:: ../disclaimer-zh_CN.rst
|
||||
|
||||
:Original: Documentation/doc-guide/contributing.rst
|
||||
|
||||
:译者: 吴想成 Wu XiangCheng <bobwxc@email.cn>
|
||||
|
||||
如何帮助改进内核文档
|
||||
====================
|
||||
|
||||
在任何软件开发项目中,文档都是重要组成部分。好的文档有助于引入新的开发人员,
|
||||
并帮助已有的开发人员更有效地工作。如果缺少高质量的文档,大量的时间就会浪费在
|
||||
代码的逆向工程和犯本可避免的错误上。
|
||||
|
||||
不幸的是,内核的文档目前远远不能满足支持如此规模和重要性的项目的需要。
|
||||
|
||||
本指南适用于希望帮助改善这种状况的贡献者。内核文档的改进可以由开发者在不同的
|
||||
技能层级上进行;这也是一条相对简单可以帮助您了解内核过程并在社区中找到一席之
|
||||
地的路径。下面的大部分内容是文档维护人员列出的最迫切需要完成的任务。
|
||||
|
||||
文档待办事项列表
|
||||
----------------
|
||||
|
||||
为了使我们的文档达到应有的水平,需要完成的任务数不胜数。此列表包含许多重要的
|
||||
项目,但还远远不够详尽;如果您知道改进文档的其他方法,请不要羞于启齿。
|
||||
|
||||
消除警告(WARNING)
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
文档构建目前出现了数量惊人的警告。虱子多了不痒,债多了不愁;大伙儿忽略了它们,
|
||||
他们永远不会注意到他们的工作增加了新的警告。因此,消除警告是文档待办事项列表
|
||||
中优先级最高的任务之一。这项任务本身相当简单,但必须以正确的方式进行,才能取
|
||||
得成功。
|
||||
|
||||
C代码编译器发出的警告常常会被视为误报,从而导致出现了旨在让编译器闭嘴的补丁。
|
||||
文档构建中的警告几乎总是指向真正的问题;要消除这些警告,需要理解问题并从源头上
|
||||
解决问题。因此,修复文档警告的补丁不应在标题中直接写“修复警告”;它们应该指明
|
||||
真正修复的问题。
|
||||
|
||||
另一个重点是,文档警告常常由C代码里kernel-doc注释中的问题引起。虽然文档维护
|
||||
人员对收到这些修复补丁的副本表示感谢,但是文档树实际上通常并不适合接受这些
|
||||
补丁;它们应该被交给相关子系统的维护人员。
|
||||
|
||||
例如,在一次文档构建中,我几乎是随意选取了一对警告::
|
||||
|
||||
./drivers/devfreq/devfreq.c:1818: warning: bad line:
|
||||
- Resource-managed devfreq_register_notifier()
|
||||
./drivers/devfreq/devfreq.c:1854: warning: bad line:
|
||||
- Resource-managed devfreq_unregister_notifier()
|
||||
|
||||
(作了断行以便于阅读)
|
||||
|
||||
简单看一下上面给出的源文件,会发现几个kernel-doc注释,如下所示::
|
||||
|
||||
/**
|
||||
* devm_devfreq_register_notifier()
|
||||
- Resource-managed devfreq_register_notifier()
|
||||
* @dev: The devfreq user device. (parent of devfreq)
|
||||
* @devfreq: The devfreq object.
|
||||
* @nb: The notifier block to be unregistered.
|
||||
* @list: DEVFREQ_TRANSITION_NOTIFIER.
|
||||
*/
|
||||
|
||||
问题在于缺了一个“*”,这不符合构建系统对C注释块的格式要求。此问题自2016年注释
|
||||
被添加以来一直存在——整整四年之久。修复它只需要添加丢失的星号。看一眼该文件的
|
||||
历史记录以了解主题行的常规格式是什么样,再使用 ``scripts/get_maintainer.pl``
|
||||
来搞清谁应当收到此补丁。生成的补丁如下所示::
|
||||
|
||||
[PATCH] PM / devfreq: Fix two malformed kerneldoc comments
|
||||
|
||||
Two kerneldoc comments in devfreq.c fail to adhere to the required format,
|
||||
resulting in these doc-build warnings:
|
||||
|
||||
./drivers/devfreq/devfreq.c:1818: warning: bad line:
|
||||
- Resource-managed devfreq_register_notifier()
|
||||
./drivers/devfreq/devfreq.c:1854: warning: bad line:
|
||||
- Resource-managed devfreq_unregister_notifier()
|
||||
|
||||
Add a couple of missing asterisks and make kerneldoc a little happier.
|
||||
|
||||
Signed-off-by: Jonathan Corbet <corbet@lwn.net>
|
||||
---
|
||||
drivers/devfreq/devfreq.c | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c
|
||||
index 57f6944d65a6..00c9b80b3d33 100644
|
||||
--- a/drivers/devfreq/devfreq.c
|
||||
+++ b/drivers/devfreq/devfreq.c
|
||||
@@ -1814,7 +1814,7 @@ static void devm_devfreq_notifier_release(struct device *dev, void *res)
|
||||
|
||||
/**
|
||||
* devm_devfreq_register_notifier()
|
||||
- - Resource-managed devfreq_register_notifier()
|
||||
+ * - Resource-managed devfreq_register_notifier()
|
||||
* @dev: The devfreq user device. (parent of devfreq)
|
||||
* @devfreq: The devfreq object.
|
||||
* @nb: The notifier block to be unregistered.
|
||||
@@ -1850,7 +1850,7 @@ EXPORT_SYMBOL(devm_devfreq_register_notifier);
|
||||
|
||||
/**
|
||||
* devm_devfreq_unregister_notifier()
|
||||
- - Resource-managed devfreq_unregister_notifier()
|
||||
+ * - Resource-managed devfreq_unregister_notifier()
|
||||
* @dev: The devfreq user device. (parent of devfreq)
|
||||
* @devfreq: The devfreq object.
|
||||
* @nb: The notifier block to be unregistered.
|
||||
--
|
||||
2.24.1
|
||||
|
||||
整个过程只花了几分钟。当然,我后来发现有人在另一个树中修复了它,这亮出了另一
|
||||
个教训:在深入研究问题之前,一定要检查linux-next树,看看问题是否已经修复。
|
||||
|
||||
其他修复可能需要更长的时间,尤其是那些与缺少文档的结构体成员或函数参数相关的
|
||||
修复。这种情况下,需要找出这些成员或参数的作用,并正确描述它们。总之,这种
|
||||
任务有时会有点乏味,但它非常重要。如果我们真的可以从文档构建中消除警告,那么
|
||||
我们就可以开始期望开发人员开始注意避免添加新的警告了。
|
||||
|
||||
“迷失的”kernel-doc注释
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
开发者被鼓励去为他们的代码写kernel-doc注释,但是许多注释从未被引入文档构建。
|
||||
这使得这些信息更难找到,例如使Sphinx无法生成指向该文档的链接。将 ``kernel-doc``
|
||||
指令添加到文档中以引入这些注释可以帮助社区获得为编写注释所做工作的全部价值。
|
||||
|
||||
``scripts/find-unused-docs.sh`` 工具可以用来找到这些被忽略的评论。
|
||||
|
||||
请注意,将导出的函数和数据结构引入文档是最有价值的。许多子系统还具有供内部
|
||||
使用的kernel-doc注释;除非这些注释放在专门针对相关子系统开发人员的文档中,
|
||||
否则不应将其引入文档构建中。
|
||||
|
||||
|
||||
修正错字
|
||||
~~~~~~~~
|
||||
|
||||
|
||||
修复文档中的排版或格式错误是一种快速学习如何创建和发送修补程序的方法,也是
|
||||
一项有用的服务。我总是愿意接受这样的补丁。这也意味着,一旦你修复了一些这种
|
||||
错误,请考虑转移到更高级的任务,留下一些拼写错误给下一个初学者解决。
|
||||
|
||||
请注意,有些并 **不是** 拼写错误,不应该被“修复”:
|
||||
|
||||
- 内核文档中用美式和英式英语拼写皆可,没有必要互相倒换。
|
||||
|
||||
- 在内核文档中,没必要讨论句点后面应该跟一个还是两个空格的问题。其他一些有
|
||||
合理分歧的地方,比如“牛津逗号”,在这也是跑题的。
|
||||
|
||||
与对任何项目的任何补丁一样,请考虑您的更改是否真的让事情变得更好。
|
||||
|
||||
“上古”文档
|
||||
~~~~~~~~~~
|
||||
|
||||
一些内核文档是最新的、被维护的,并且非常有用,有些文件确并非如此。尘封、陈旧
|
||||
和不准确的文档可能会误导读者,并对我们的整个文档产生怀疑。任何解决这些问题的
|
||||
事情都是非常受欢迎的。
|
||||
|
||||
无论何时处理文档,请考虑它是否是最新的,是否需要更新,或者是否应该完全删除。
|
||||
您可以注意以下几个警告标志:
|
||||
|
||||
- 对2.x内核的引用
|
||||
- 指向SourceForge存储库
|
||||
- 历史记录除了拼写错误啥也没有持续几年
|
||||
- 讨论Git之前时代的工作流
|
||||
|
||||
当然,最好的办法是更新文档,添加所需的任何信息。这样的工作通常需要与熟悉相关
|
||||
子系统的开发人员合作。当有人善意地询问开发人员,并听取他们的回答然后采取
|
||||
行动时,开发人员通常更愿意与这些致力于改进文档的人员合作。
|
||||
|
||||
有些文档已经没希望了;例如,我们偶尔会发现引用了很久以前从内核中删除的代码的
|
||||
文档。删除过时的文档会碰见令人惊讶的阻力,但我们无论如何都应该这样做。文档中
|
||||
多余的粗枝大叶对任何人都没有帮助。
|
||||
|
||||
如果一个严重过时的文档中可能有一些有用的信息,而您又无法更新它,那么最好在
|
||||
开头添加一个警告。建议使用以下文本::
|
||||
|
||||
.. warning ::
|
||||
This document is outdated and in need of attention. Please use
|
||||
this information with caution, and please consider sending patches
|
||||
to update it.
|
||||
|
||||
这样的话,至少我们长期受苦的读者会得到文件可能会把他们引入歧途的警告。
|
||||
|
||||
文档一致性
|
||||
~~~~~~~~~~
|
||||
|
||||
这里的老前辈们会记得上世纪90年代出现在书架上的Linux书籍,它们只是从网上不同
|
||||
位置搜来的文档文件的集合。在此之后,(大部分)这些书都得到了改进,但是内核的
|
||||
文档仍然主要是建立在这种模型上。它有数千个文件,几乎每个文件都是与其他文件相
|
||||
独立编写的。我们没有一个连贯的内核文档;只有数千个独立的文档。
|
||||
|
||||
我们一直试图通过编篡一套“书籍”来改善这种情况,以为特定读者提供成套文档。这
|
||||
包括:
|
||||
|
||||
- Documentation/translations/zh_CN/admin-guide/index.rst
|
||||
- Documentation/core-api/index.rst
|
||||
- Documentation/driver-api/index.rst
|
||||
- Documentation/userspace-api/index.rst
|
||||
|
||||
以及文档本身这本“书”。
|
||||
|
||||
将文档移到适当的书中是一项重要的任务,需要继续进行。不过这项工作还是有一些
|
||||
挑战性。移动文档会给处理这些文档的人带来短期的痛苦;他们对这些更改无甚热情
|
||||
也是可以理解的。通常情况下,可以将一个文档移动一下;不过我们真的不想一直移动
|
||||
它们。
|
||||
|
||||
即使所有文件都在正确的位置,我们也只是把一大堆文件变成一群小堆文件。试图将
|
||||
所有这些文件组合成一个整体的工作尚未开始。如果你对如何在这方面取得进展有好的
|
||||
想法,我们将很高兴了解。
|
||||
|
||||
样式表(Stylesheet)改进
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
随着Sphinx的采用,我们得到了比以前更好的HTML输出。但它仍然需要很大的改进;
|
||||
Donald Knuth和Edward Tufte可能是映像平平的。这需要调整我们的样式表,以创建
|
||||
更具排版效果、可访问性和可读性的输出。
|
||||
|
||||
请注意:如果你承担这个任务,你将进入经典的两难领域。即使是相对明显的变化,
|
||||
也会有很多意见和讨论。唉,这就是我们生活的世界的本质。
|
||||
|
||||
无LaTeX的PDF构建
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
对于拥有大量时间和Python技能的人来说,这绝对是一项不平凡的任务。Sphinx工具链
|
||||
相对较小且包含良好;很容易添加到开发系统中。但是构建PDF或EPUB输出需要安装
|
||||
LaTeX,它绝对称不上小或包含良好的。消除Latex将是一件很好的事情。
|
||||
|
||||
最初是希望使用 `rst2pdf <https://rst2pdf.org/>`_ 工具来生成PDF,但结果发现
|
||||
无法胜任这项任务。不过rst2pdf的开发工作最近似乎又有了起色,这是个充满希望的
|
||||
迹象。如果有开发人员愿意与该项目合作,使rst2pdf可与内核文档构建一起工作,
|
||||
大家会非常感激。
|
||||
|
||||
编写更多文档
|
||||
~~~~~~~~~~~~
|
||||
|
||||
当然,内核中许多部分的文档严重不足。如果您有编写一个特定内核子系统文档的相应
|
||||
知识并愿意这样做,请不要犹豫,编写并向内核贡献结果吧!数不清的内核开发人员和
|
||||
用户会感谢你。
|
|
@ -0,0 +1,27 @@
|
|||
.. include:: ../disclaimer-zh_CN.rst
|
||||
|
||||
:Original: Documentation/doc-guide/index.rst
|
||||
|
||||
:译者: 吴想成 Wu XiangCheng <bobwxc@email.cn>
|
||||
|
||||
.. _doc_guide_zh:
|
||||
|
||||
================
|
||||
如何编写内核文档
|
||||
================
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
sphinx
|
||||
kernel-doc
|
||||
parse-headers
|
||||
contributing
|
||||
maintainer-profile
|
||||
|
||||
.. only:: 子项目与HTML
|
||||
|
||||
目录
|
||||
====
|
||||
|
||||
* :ref:`genindex`
|
|
@ -0,0 +1,499 @@
|
|||
.. include:: ../disclaimer-zh_CN.rst
|
||||
|
||||
:Original: Documentation/doc-guide/kernel-doc.rst
|
||||
|
||||
:译者: 吴想成 Wu XiangCheng <bobwxc@email.cn>
|
||||
|
||||
编写kernel-doc注释
|
||||
==================
|
||||
|
||||
Linux内核源文件可以包含kernel-doc格式的结构化文档注释,用以描述代码的函数、
|
||||
类型和设计。将文档嵌入源文件更容易保持文档最新。
|
||||
|
||||
.. note:: 内核文档格式与javadoc、gtk-doc或Doxygen看似很相似,但由于历史原因,
|
||||
实际有着明显的不同。内核源包含成千上万个kernel-doc注释。请坚持遵循
|
||||
此处描述的风格。
|
||||
|
||||
.. note:: kernel-doc无法包含Rust代码:请参考 Documentation/rust/docs.rst 。
|
||||
|
||||
从注释中提取kernel-doc结构,并从中生成适当的 `Sphinx C 域`_ 函数和带有锚点的
|
||||
类型描述。这些注释将被过滤以生成特殊kernel-doc高亮和交叉引用。详见下文。
|
||||
|
||||
.. _Sphinx C 域: http://www.sphinx-doc.org/en/stable/domains.html
|
||||
|
||||
使用 ``EXPORT_SYMBOL`` 或 ``EXPORT_SYMBOL_GPL`` 导出到可加载模块的每个函数都
|
||||
应该有一个kernel-doc注释。模块使用的头文件中的函数和数据结构也应该有
|
||||
kernel-doc注释。
|
||||
|
||||
对于其他内核文件(未标记为 ``static`` )中外部可见的函数,提供kernel-doc格式
|
||||
的文档是一个很好的实践。我们也建议为私有(文件 ``static`` )程序提供kernel-doc
|
||||
格式的文档,以确保内核源代码布局的一致性。此建议优先级较低,由内核源文件的
|
||||
维护者自行决定。
|
||||
|
||||
如何格式化kernel-doc注释
|
||||
------------------------
|
||||
|
||||
kernel-doc注释用 ``/**`` 作为开始标记。 ``kernel-doc`` 工具将提取以这种方式
|
||||
标记的注释。注释其余部分的格式类似于一个普通的多行注释,左侧有一列星号,以
|
||||
``*/`` 行结束。
|
||||
|
||||
函数和类型的kernel-doc注释应该放在所描述的函数或类型之前,以便最大限度地提高
|
||||
更改代码的人同时更改文档的可能性。概述kernel-doc注释可以放在最顶部的任何地方。
|
||||
|
||||
用详细模式和不生成实际输出来运行 ``kernel-doc`` 工具,可以验证文档注释的格式
|
||||
是否正确。例如::
|
||||
|
||||
scripts/kernel-doc -v -none drivers/foo/bar.c
|
||||
|
||||
当请求执行额外的gcc检查时,内核构建将验证文档格式::
|
||||
|
||||
make W=n
|
||||
|
||||
函数文档
|
||||
--------
|
||||
|
||||
函数和函数式宏的kernel-doc注释的一般格式是::
|
||||
|
||||
/**
|
||||
* 函数名() - 函数简要说明.
|
||||
* @参数1: 描述第一个参数.
|
||||
* @参数2: 描述第二个参数.
|
||||
* 可以为参数提供一段
|
||||
* 多行描述.
|
||||
*
|
||||
* 更详细的描述,进一步讨论函数 函数名(), 这可能对使用或修改它的人有用.
|
||||
* 以空注释行开始, 内部可以包含空注释行.
|
||||
*
|
||||
* 详细描述可以有多个段落.
|
||||
*
|
||||
* Context: 描述函数是否可以休眠, 它需要、释放或期望持有什么锁.
|
||||
* 可以写多行.
|
||||
* Return: 描述函数返回值.
|
||||
*
|
||||
* 返回值描述也可以有多个段落,
|
||||
* 并且应该放在注释块的末尾.
|
||||
*/
|
||||
|
||||
函数名后面的简短描述可以跨多行,并以参数描述、空注释行或注释块结尾结束。
|
||||
|
||||
函数参数
|
||||
~~~~~~~~
|
||||
|
||||
每个函数参数都应该按照顺序描述,紧跟在函数简要说明之后。不要在函数描述和参数
|
||||
之间,也不要在参数之间留空。
|
||||
|
||||
每个 ``@参数:`` 描述可以跨多行。
|
||||
|
||||
.. note::
|
||||
|
||||
如果 ``@参数`` 描述有多行,则说明的续行应该从上一行的同一列开始::
|
||||
|
||||
* @参数: 较长说明
|
||||
* 的续行
|
||||
|
||||
或::
|
||||
|
||||
* @参数:
|
||||
* 较长说明
|
||||
* 的续行
|
||||
|
||||
如果函数的参数数目可变,则需用kernel-doc格式对其进行描述::
|
||||
|
||||
* @...: 描述
|
||||
|
||||
函数上下文
|
||||
~~~~~~~~~~
|
||||
|
||||
可调用函数的上下文应该在 ``Context`` 节中描述。此节应该包括函数是休眠的还是
|
||||
可以从中断上下文调用的,以及它需要什么锁、释放什么锁和期望它的调用者持有什么
|
||||
锁。
|
||||
|
||||
例如::
|
||||
|
||||
* Context: Any context.
|
||||
* Context: Any context. Takes and releases the RCU lock.
|
||||
* Context: Any context. Expects <lock> to be held by caller.
|
||||
* Context: Process context. May sleep if @gfp flags permit.
|
||||
* Context: Process context. Takes and releases <mutex>.
|
||||
* Context: Softirq or process context. Takes and releases <lock>, BH-safe.
|
||||
* Context: Interrupt context.
|
||||
|
||||
返回值
|
||||
~~~~~~
|
||||
|
||||
如有返回值,应在 ``Return`` 节中描述。
|
||||
|
||||
.. note::
|
||||
|
||||
#) 您提供的多行描述文本 *不会* 识别换行符,因此如果您想将某些文本预格式化,
|
||||
如::
|
||||
|
||||
* Return:
|
||||
* 0 - OK
|
||||
* -EINVAL - invalid argument
|
||||
* -ENOMEM - out of memory
|
||||
|
||||
它们在最终文档中变成一行::
|
||||
|
||||
Return: 0 - OK -EINVAL - invalid argument -ENOMEM - out of memory
|
||||
|
||||
因此,为了在需要的地方换行,您需要使用ReST列表,例如::
|
||||
|
||||
* Return:
|
||||
* * 0 - OK to runtime suspend the device
|
||||
* * -EBUSY - Device should not be runtime suspended
|
||||
|
||||
#) 如果您提供的描述性文本中的行以某个后跟冒号的短语开头,则每一个这种短语
|
||||
都将被视为新的节标题,可能会产生意料不到的效果。
|
||||
|
||||
结构体、共用体、枚举类型文档
|
||||
----------------------------
|
||||
|
||||
结构体(struct)、共用体(union)、枚举(enum)类型kernel-doc注释的一般格式为::
|
||||
|
||||
/**
|
||||
* struct 结构体名 - 简要描述.
|
||||
* @成员1: 成员1描述.
|
||||
* @成员2: 成员2描述.
|
||||
* 可以为成员提供
|
||||
* 多行描述.
|
||||
*
|
||||
* 结构体的描述.
|
||||
*/
|
||||
|
||||
可以用 ``union`` 或 ``enum`` 替换上面示例中的 ``struct`` ,以描述共用体或枚举。
|
||||
``成员`` 用于表示枚举中的元素或共用体成员。
|
||||
|
||||
结构体名称后面的简要说明可以跨多行,并以成员说明、空白注释行或注释块结尾结束。
|
||||
|
||||
成员
|
||||
~~~~
|
||||
|
||||
结构体、共用体和枚举的成员应以与函数参数相同的方式记录;它们后紧跟简短的描述,
|
||||
并且为多行。
|
||||
|
||||
在结构体或共用体描述中,可以使用 ``private:`` 和 ``public:`` 注释标签。
|
||||
``private:`` 域内的字段不会列在生成的文档中。
|
||||
|
||||
``private:`` 和 ``public:`` 标签必须紧跟在 ``/*`` 注释标记之后。可以选择是否
|
||||
在 ``:`` 和 ``*/`` 结束标记之间包含注释。
|
||||
|
||||
例子::
|
||||
|
||||
/**
|
||||
* struct 张三 - 简短描述
|
||||
* @a: 第一个成员
|
||||
* @b: 第二个成员
|
||||
* @d: 第三个成员
|
||||
*
|
||||
* 详细描述
|
||||
*/
|
||||
struct 张三 {
|
||||
int a;
|
||||
int b;
|
||||
/* private: 仅内部使用 */
|
||||
int c;
|
||||
/* public: 下一个是公有的 */
|
||||
int d;
|
||||
};
|
||||
|
||||
嵌套的结构体/共用体
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
嵌套的结构体/共用体可像这样记录::
|
||||
|
||||
/**
|
||||
* struct nested_foobar - a struct with nested unions and structs
|
||||
* @memb1: first member of anonymous union/anonymous struct
|
||||
* @memb2: second member of anonymous union/anonymous struct
|
||||
* @memb3: third member of anonymous union/anonymous struct
|
||||
* @memb4: fourth member of anonymous union/anonymous struct
|
||||
* @bar: non-anonymous union
|
||||
* @bar.st1: struct st1 inside @bar
|
||||
* @bar.st2: struct st2 inside @bar
|
||||
* @bar.st1.memb1: first member of struct st1 on union bar
|
||||
* @bar.st1.memb2: second member of struct st1 on union bar
|
||||
* @bar.st2.memb1: first member of struct st2 on union bar
|
||||
* @bar.st2.memb2: second member of struct st2 on union bar
|
||||
*/
|
||||
struct nested_foobar {
|
||||
/* Anonymous union/struct*/
|
||||
union {
|
||||
struct {
|
||||
int memb1;
|
||||
int memb2;
|
||||
};
|
||||
struct {
|
||||
void *memb3;
|
||||
int memb4;
|
||||
};
|
||||
};
|
||||
union {
|
||||
struct {
|
||||
int memb1;
|
||||
int memb2;
|
||||
} st1;
|
||||
struct {
|
||||
void *memb1;
|
||||
int memb2;
|
||||
} st2;
|
||||
} bar;
|
||||
};
|
||||
|
||||
.. note::
|
||||
|
||||
#) 在记录嵌套结构体或共用体时,如果结构体/共用体 ``张三`` 已命名,则其中
|
||||
的成员 ``李四`` 应记录为 ``@张三.李四:``
|
||||
|
||||
#) 当嵌套结构体/共用体是匿名的时,其中的成员 ``李四`` 应记录为 ``@李四:``
|
||||
|
||||
行间注释文档
|
||||
~~~~~~~~~~~~
|
||||
|
||||
结构成员也可在定义时以行间注释形式记录。有两种样式,一种是单行注释,其中开始
|
||||
``/**`` 和结束 ``*/`` 位于同一行;另一种是多行注释,开头结尾各自位于一行,就
|
||||
像所有其他核心文档注释一样::
|
||||
|
||||
/**
|
||||
* struct 张三 - 简短描述.
|
||||
* @张三: 成员张三.
|
||||
*/
|
||||
struct 张三 {
|
||||
int 张三;
|
||||
/**
|
||||
* @李四: 成员李四.
|
||||
*/
|
||||
int 李四;
|
||||
/**
|
||||
* @王五: 成员王五.
|
||||
*
|
||||
* 此处,成员描述可以为好几段.
|
||||
*/
|
||||
int 王五;
|
||||
union {
|
||||
/** @儿子: 单行描述. */
|
||||
int 儿子;
|
||||
};
|
||||
/** @赵六: 描述@张三里面的结构体@赵六 */
|
||||
struct {
|
||||
/**
|
||||
* @赵六.女儿: 描述@张三.赵六里面的@女儿
|
||||
*/
|
||||
int 女儿;
|
||||
} 赵六;
|
||||
};
|
||||
|
||||
Typedef文档
|
||||
-----------
|
||||
|
||||
Typedef的kernel-doc文档注释的一般格式为::
|
||||
|
||||
/**
|
||||
* typedef 类型名称 - 简短描述.
|
||||
*
|
||||
* 类型描述.
|
||||
*/
|
||||
|
||||
还可以记录带有函数原型的typedef::
|
||||
|
||||
/**
|
||||
* typedef 类型名称 - 简短描述.
|
||||
* @参数1: 参数1的描述
|
||||
* @参数2: 参数2的描述
|
||||
*
|
||||
* 类型描述.
|
||||
*
|
||||
* Context: 锁(Locking)上下文.
|
||||
* Return: 返回值的意义.
|
||||
*/
|
||||
typedef void (*类型名称)(struct v4l2_ctrl *参数1, void *参数2);
|
||||
|
||||
高亮与交叉引用
|
||||
--------------
|
||||
|
||||
在kernel-doc注释的描述文本中可以识别以下特殊模式,并将其转换为正确的
|
||||
reStructuredText标记和 `Sphinx C 域`_ 引用。
|
||||
|
||||
.. attention:: 以下内容 **仅** 在kernel-doc注释中识别, **不会** 在普通的
|
||||
reStructuredText文档中识别。
|
||||
|
||||
``funcname()``
|
||||
函数引用。
|
||||
|
||||
``@parameter``
|
||||
函数参数的名称(未交叉引用,仅格式化)。
|
||||
|
||||
``%CONST``
|
||||
常量的名称(未交叉引用,仅格式化)。
|
||||
|
||||
````literal````
|
||||
预格式化文本块。输出将使用等距字体。
|
||||
|
||||
若你需要使用在kernel-doc脚本或reStructuredText中有特殊含义的字符,则此功能
|
||||
非常有用。
|
||||
|
||||
若你需要在函数描述中使用类似于 ``%ph`` 的东西,这特别有用。
|
||||
|
||||
``$ENVVAR``
|
||||
环境变量名称(未交叉引用,仅格式化)。
|
||||
|
||||
``&struct name``
|
||||
结构体引用。
|
||||
|
||||
``&enum name``
|
||||
枚举引用。
|
||||
|
||||
``&typedef name``
|
||||
Typedef引用。
|
||||
|
||||
``&struct_name->member`` or ``&struct_name.member``
|
||||
结构体或共用体成员引用。交叉引用将链接到结构体或共用体定义,而不是直接到成员。
|
||||
|
||||
``&name``
|
||||
泛类型引用。请首选上面描述的完整引用方式。此法主要是为了可能未描述的注释。
|
||||
|
||||
从reStructuredText交叉引用
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
无需额外的语法来从reStructuredText文档交叉引用kernel-do注释中定义的函数和类型。
|
||||
只需以 ``()`` 结束函数名,并在类型之前写上 ``struct`` , ``union`` , ``enum``
|
||||
或 ``typedef`` 。
|
||||
例如::
|
||||
|
||||
See foo().
|
||||
See struct foo.
|
||||
See union bar.
|
||||
See enum baz.
|
||||
See typedef meh.
|
||||
|
||||
若要在交叉引用链接中使用自定义文本,可以通过以下语法进行::
|
||||
|
||||
See :c:func:`my custom link text for function foo <foo>`.
|
||||
See :c:type:`my custom link text for struct bar <bar>`.
|
||||
|
||||
有关更多详细信息,请参阅 `Sphinx C 域`_ 文档。
|
||||
|
||||
总述性文档注释
|
||||
--------------
|
||||
|
||||
为了促进源代码和注释紧密联合,可以将kernel-doc文档块作为自由形式的注释,而
|
||||
不是函数、结构、联合、枚举或typedef的绑定kernel-doc。例如,这可以用于解释
|
||||
驱动程序或库代码的操作理论。
|
||||
|
||||
这是通过使用带有节标题的 ``DOC:`` 节关键字来实现的。
|
||||
|
||||
总述或高层级文档注释的一般格式为::
|
||||
|
||||
/**
|
||||
* DOC: Theory of Operation
|
||||
*
|
||||
* The whizbang foobar is a dilly of a gizmo. It can do whatever you
|
||||
* want it to do, at any time. It reads your mind. Here's how it works.
|
||||
*
|
||||
* foo bar splat
|
||||
*
|
||||
* The only drawback to this gizmo is that is can sometimes damage
|
||||
* hardware, software, or its subject(s).
|
||||
*/
|
||||
|
||||
``DOC:`` 后面的标题用作源文件中的标题,但也用作提取文档注释的标识符。因此,
|
||||
文件中的标题必须是唯一的。
|
||||
|
||||
包含kernel-doc注释
|
||||
==================
|
||||
|
||||
文档注释可以被包含在任何使用专用kernel-doc Sphinx指令扩展的reStructuredText
|
||||
文档中。
|
||||
|
||||
kernel-doc指令的格式如下::
|
||||
|
||||
.. kernel-doc:: source
|
||||
:option:
|
||||
|
||||
*source* 是相对于内核源代码树的源文件路径。
|
||||
支持以下指令选项:
|
||||
|
||||
export: *[source-pattern ...]*
|
||||
包括 *source* 中使用 ``EXPORT_SYMBOL`` 或 ``EXPORT_SYMBOL_GPL`` 导出的所有
|
||||
函数的文档,无论是在 *source* 中还是在 *source-pattern* 指定的任何文件中。
|
||||
|
||||
当kernel-doc注释被放置在头文件中,而 ``EXPORT_SYMBOL`` 和 ``EXPORT_SYMBOL_GPL``
|
||||
位于函数定义旁边时, *source-pattern* 非常有用。
|
||||
|
||||
例子::
|
||||
|
||||
.. kernel-doc:: lib/bitmap.c
|
||||
:export:
|
||||
|
||||
.. kernel-doc:: include/net/mac80211.h
|
||||
:export: net/mac80211/*.c
|
||||
|
||||
internal: *[source-pattern ...]*
|
||||
包括 *source* 中所有在 *source* 或 *source-pattern* 的任何文件中都没有使用
|
||||
``EXPORT_SYMBOL`` 或 ``EXPORT_SYMBOL_GPL`` 导出的函数和类型的文档。
|
||||
|
||||
例子::
|
||||
|
||||
.. kernel-doc:: drivers/gpu/drm/i915/intel_audio.c
|
||||
:internal:
|
||||
|
||||
identifiers: *[ function/type ...]*
|
||||
在 *source* 中包含每个 *function* 和 *type* 的文档。如果没有指定 *function* ,
|
||||
则 *source* 中所有函数和类型的文档都将包含在内。
|
||||
|
||||
例子::
|
||||
|
||||
.. kernel-doc:: lib/bitmap.c
|
||||
:identifiers: bitmap_parselist bitmap_parselist_user
|
||||
|
||||
.. kernel-doc:: lib/idr.c
|
||||
:identifiers:
|
||||
|
||||
no-identifiers: *[ function/type ...]*
|
||||
排除 *source* 中所有 *function* 和 *type* 的文档。
|
||||
|
||||
例子::
|
||||
|
||||
.. kernel-doc:: lib/bitmap.c
|
||||
:no-identifiers: bitmap_parselist
|
||||
|
||||
functions: *[ function/type ...]*
|
||||
这是“identifiers”指令的别名,已弃用。
|
||||
|
||||
doc: *title*
|
||||
包含 *source* 中由 *title* 标题标识的 ``DOC:`` 文档段落。 *title* 中允许
|
||||
空格;不要在 *title* 上加引号。 *title* 仅用作段落的标识符,不包含在输出中。
|
||||
请确保在所附的reStructuredText文档中有适当的标题。
|
||||
|
||||
例子::
|
||||
|
||||
.. kernel-doc:: drivers/gpu/drm/i915/intel_audio.c
|
||||
:doc: High Definition Audio over HDMI and Display Port
|
||||
|
||||
如果没有选项,kernel-doc指令将包含源文件中的所有文档注释。
|
||||
|
||||
kernel-doc扩展包含在内核源代码树中,位于 ``Documentation/sphinx/kerneldoc.py`` 。
|
||||
在内部,它使用 ``scripts/kernel-doc`` 脚本从源代码中提取文档注释。
|
||||
|
||||
.. _kernel_doc_zh:
|
||||
|
||||
如何使用kernel-doc生成手册(man)页
|
||||
-----------------------------------
|
||||
|
||||
如果您只想使用kernel-doc生成手册页,可以从内核git树这样做::
|
||||
|
||||
$ scripts/kernel-doc -man \
|
||||
$(git grep -l '/\*\*' -- :^Documentation :^tools) \
|
||||
| scripts/split-man.pl /tmp/man
|
||||
|
||||
一些旧版本的git不支持路径排除语法的某些变体。
|
||||
以下命令之一可能适用于这些版本::
|
||||
|
||||
$ scripts/kernel-doc -man \
|
||||
$(git grep -l '/\*\*' -- . ':!Documentation' ':!tools') \
|
||||
| scripts/split-man.pl /tmp/man
|
||||
|
||||
$ scripts/kernel-doc -man \
|
||||
$(git grep -l '/\*\*' -- . ":(exclude)Documentation" ":(exclude)tools") \
|
||||
| scripts/split-man.pl /tmp/man
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
.. include:: ../disclaimer-zh_CN.rst
|
||||
|
||||
:Original: Documentation/doc-guide/maintainer-profile.rst
|
||||
|
||||
:译者: 吴想成 Wu XiangCheng <bobwxc@email.cn>
|
||||
|
||||
文档子系统维护人员条目概述
|
||||
==========================
|
||||
|
||||
文档“子系统”是内核文档和相关基础设施的中心协调点。它涵盖了 Documentation/ 下
|
||||
的文件层级(Documentation/devicetree 除外)、scripts/ 下的各种实用程序,并且
|
||||
在某些情况下的也包括 LICENSES/ 。
|
||||
|
||||
不过值得注意的是,这个子系统的边界比通常更加模糊。许多其他子系统维护人员需要
|
||||
保持对 Documentation/ 某些部分的控制,以便于可以更自由地做更改。除此之外,
|
||||
许多内核文档都以kernel-doc注释的形式出现在源代码中;这些注释通常(但不总是)
|
||||
由相关的子系统维护人员维护。
|
||||
|
||||
文档子系统的邮件列表是<linux-doc@vger.kernel.org>。
|
||||
补丁应尽量针对docs-next树。
|
||||
|
||||
提交检查单补遗
|
||||
--------------
|
||||
|
||||
在进行文档更改时,您应当构建文档以测试,并确保没有引入新的错误或警告。生成
|
||||
HTML文档并查看结果将有助于避免对文档渲染结果的不必要争执。
|
||||
|
||||
开发周期的关键节点
|
||||
------------------
|
||||
|
||||
补丁可以随时发送,但在合并窗口期间,响应将比通常慢。文档树往往在合并窗口打开
|
||||
之前关闭得比较晚,因为文档补丁导致回归的风险很小。
|
||||
|
||||
审阅节奏
|
||||
--------
|
||||
|
||||
我(译注:指Jonathan Corbet <corbet@lwn.net>)是文档子系统的唯一维护者,我在
|
||||
自己的时间里完成这项工作,所以对补丁的响应有时会很慢。当补丁被合并时(或当我
|
||||
决定拒绝合并补丁时),我都会发送通知。如果您在发送补丁后一周内没有收到回复,
|
||||
请不要犹豫,发送提醒就好。
|
||||
|
|
@ -0,0 +1,187 @@
|
|||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
.. include:: ../disclaimer-zh_CN.rst
|
||||
|
||||
:Original: Documentation/doc-guide/parse-headers.rst
|
||||
|
||||
:译者: 吴想成 Wu XiangCheng <bobwxc@email.cn>
|
||||
|
||||
=====================
|
||||
包含用户空间API头文件
|
||||
=====================
|
||||
|
||||
有时,为了描述用户空间API并在代码和文档之间生成交叉引用,需要包含头文件和示例
|
||||
C代码。为用户空间API文件添加交叉引用还有一个好处:如果在文档中找不到相应符号,
|
||||
Sphinx将生成警告。这有助于保持用户空间API文档与内核更改同步。
|
||||
:ref:`parse_headers.pl <parse_headers_zh>` 提供了生成此类交叉引用的一种方法。
|
||||
在构建文档时,必须通过Makefile调用它。有关如何在内核树中使用它的示例,请参阅
|
||||
``Documentation/userspace-api/media/Makefile`` 。
|
||||
|
||||
.. _parse_headers_zh:
|
||||
|
||||
parse_headers.pl
|
||||
----------------
|
||||
|
||||
脚本名称
|
||||
~~~~~~~~
|
||||
|
||||
|
||||
parse_headers.pl——解析一个C文件,识别函数、结构体、枚举、定义并对Sphinx文档
|
||||
创建交叉引用。
|
||||
|
||||
|
||||
用法概要
|
||||
~~~~~~~~
|
||||
|
||||
|
||||
\ **parse_headers.pl**\ [<选项>] <C文件> <输出文件> [<例外文件>]
|
||||
|
||||
<选项> 可以是: --debug, --help 或 --usage 。
|
||||
|
||||
|
||||
选项
|
||||
~~~~
|
||||
|
||||
|
||||
|
||||
\ **--debug**\
|
||||
|
||||
开启脚本详细模式,在调试时很有用。
|
||||
|
||||
|
||||
\ **--usage**\
|
||||
|
||||
打印简短的帮助信息并退出。
|
||||
|
||||
|
||||
|
||||
\ **--help**\
|
||||
|
||||
打印更详细的帮助信息并退出。
|
||||
|
||||
|
||||
说明
|
||||
~~~~
|
||||
|
||||
通过C头文件或源文件(<C文件>)中为描述API的文档编写的带交叉引用的 ..预格式化
|
||||
文本 块将文件转换成重构文本(RST)。它接受一个可选的<例外文件>,其中描述了
|
||||
哪些元素将被忽略或指向非默认引用。
|
||||
|
||||
输出被写入到<输出文件>。
|
||||
|
||||
它能够识别定义、函数、结构体、typedef、枚举和枚举符号,并为它们创建交叉引用。
|
||||
它还能够区分用于指定Linux ioctl的 ``#define`` 。
|
||||
|
||||
<例外文件> 包含两种类型的语句: \ **ignore**\ 或 \ **replace**\ .
|
||||
|
||||
ignore标记的语法为:
|
||||
|
||||
|
||||
ignore \ **type**\ \ **name**\
|
||||
|
||||
The \ **ignore**\ 意味着它不会为类型为 \ **type**\ 的 \ **name**\ 符号生成
|
||||
交叉引用。
|
||||
|
||||
|
||||
replace标记的语法为:
|
||||
|
||||
|
||||
replace \ **type**\ \ **name**\ \ **new_value**\
|
||||
|
||||
The \ **replace**\ 味着它将为 \ **type**\ 类型的 \ **name**\ 符号生成交叉引
|
||||
用,但是它将使用 \ **new_value**\ 来取代默认的替换规则。
|
||||
|
||||
|
||||
这两种语句中, \ **type**\ 可以是以下任一项:
|
||||
|
||||
|
||||
\ **ioctl**\
|
||||
|
||||
ignore 或 replace 语句应用于ioctl定义,如:
|
||||
|
||||
#define VIDIOC_DBG_S_REGISTER _IOW('V', 79, struct v4l2_dbg_register)
|
||||
|
||||
|
||||
|
||||
\ **define**\
|
||||
|
||||
ignore 或 replace 语句应用于在<C文件>中找到的任何其他 ``#define`` 。
|
||||
|
||||
|
||||
|
||||
\ **typedef**\
|
||||
|
||||
ignore 和 replace 语句应用于<C文件>中的typedef语句。
|
||||
|
||||
|
||||
|
||||
\ **struct**\
|
||||
|
||||
ignore 和 replace 语句应用于<C文件>中的结构体名称语句。
|
||||
|
||||
|
||||
|
||||
\ **enum**\
|
||||
|
||||
ignore 和 replace 语句应用于<C文件>中的枚举名称语句。
|
||||
|
||||
|
||||
|
||||
\ **symbol**\
|
||||
|
||||
ignore 和 replace 语句应用于<C文件>中的枚举值名称语句。
|
||||
|
||||
replace语句中, \ **new_value**\ 会自动使用 \ **typedef**\ , \ **enum**\
|
||||
和 \ **struct**\ 类型的 :c:type: 引用;以及 \ **ioctl**\ , \ **define**\ 和
|
||||
\ **symbol**\ 类型的 :ref: 。引用的类型也可以在replace语句中显式定义。
|
||||
|
||||
|
||||
示例
|
||||
~~~~
|
||||
|
||||
|
||||
ignore define _VIDEODEV2_H
|
||||
|
||||
|
||||
忽略<C文件>中的 #define _VIDEODEV2_H 。
|
||||
|
||||
ignore symbol PRIVATE
|
||||
|
||||
|
||||
如下结构体:
|
||||
|
||||
enum foo { BAR1, BAR2, PRIVATE };
|
||||
|
||||
不会为 \ **PRIVATE**\ 生成交叉引用。
|
||||
|
||||
replace symbol BAR1 :c:type:\`foo\`
|
||||
replace symbol BAR2 :c:type:\`foo\`
|
||||
|
||||
|
||||
如下结构体:
|
||||
|
||||
enum foo { BAR1, BAR2, PRIVATE };
|
||||
|
||||
它会让BAR1和BAR2枚举符号交叉引用C域中的foo符号。
|
||||
|
||||
|
||||
|
||||
缺陷
|
||||
~~~~
|
||||
|
||||
|
||||
请向Mauro Carvalho Chehab <mchehab@kernel.org>报告有关缺陷。
|
||||
|
||||
中文翻译问题请找中文翻译维护者。
|
||||
|
||||
|
||||
版权
|
||||
~~~~
|
||||
|
||||
|
||||
版权所有 (c) 2016 Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
|
||||
|
||||
许可证 GPLv2:GNU GPL version 2 <https://gnu.org/licenses/gpl.html>
|
||||
|
||||
这是自由软件:你可以自由地修改和重新发布它。
|
||||
在法律允许的范围内,**不提供任何保证**。
|
|
@ -0,0 +1,415 @@
|
|||
.. include:: ../disclaimer-zh_CN.rst
|
||||
|
||||
:Original: Documentation/doc-guide/sphinx.rst
|
||||
|
||||
:译者: 吴想成 Wu XiangCheng <bobwxc@email.cn>
|
||||
|
||||
.. _sphinxdoc_zh:
|
||||
|
||||
简介
|
||||
====
|
||||
|
||||
Linux内核使用 `Sphinx <http://www.sphinx-doc.org/>`_ 来把 ``Documentation``
|
||||
下的 `reStructuredText <http://docutils.sourceforge.net/rst.html>`_ 文件转
|
||||
换成漂亮的文档。使用 ``make htmldocs`` 或 ``make pdfdocs`` 命令即可构建HTML
|
||||
或PDF格式的文档。生成的文档放在 ``Documentation/output`` 文件夹中。
|
||||
|
||||
reStructuredText文件可能包含包含来自源文件的结构化文档注释或kernel-doc注释。
|
||||
通常它们用于描述代码的功能、类型和设计。kernel-doc注释有一些特殊的结构和
|
||||
格式,但除此之外,它们还被作为reStructuredText处理。
|
||||
|
||||
最后,有成千上万的纯文本文档文件散布在 ``Documentation`` 里。随着时间推移,
|
||||
其中一些可能会转换为reStructuredText,但其中大部分仍保持纯文本。
|
||||
|
||||
.. _sphinx_install_zh:
|
||||
|
||||
安装Sphinx
|
||||
==========
|
||||
|
||||
Documentation/ 下的ReST文件现在使用sphinx1.3或更高版本构建。
|
||||
|
||||
这有一个脚本可以检查Sphinx的依赖项。更多详细信息见
|
||||
:ref:`sphinx-pre-install_zh` 。
|
||||
|
||||
大多数发行版都附带了Sphinx,但是它的工具链比较脆弱,而且在您的机器上升级它
|
||||
或其他一些Python包导致文档构建中断的情况并不少见。
|
||||
|
||||
避免此情况的一种方法是使用与发行版附带的不同的版本。因此,建议使用
|
||||
``virtualenv-3`` 或 ``virtualenv`` 在虚拟环境中安装Sphinx,具体取决于发行版
|
||||
如何打包Python3。
|
||||
|
||||
.. note::
|
||||
|
||||
#) 低于1.5版本的Sphinx无法与Python的0.13.1或更高版本docutils一起正常工作。
|
||||
如果您想使用这些版本,那么应该运行 ``pip install 'docutils==0.12'`` 。
|
||||
|
||||
#) html输出建议使用RTD主题。根据Sphinx版本的不同,它应该用
|
||||
``pip install sphinx_rtd_theme`` 单独安装。
|
||||
|
||||
#) 一些ReST页面包含数学表达式。由于Sphinx的工作方式,这些表达式是使用 LaTeX
|
||||
编写的。它需要安装amsfonts和amsmath宏包,以便显示。
|
||||
|
||||
总之,如您要安装Sphinx 1.7.9版本,应执行::
|
||||
|
||||
$ virtualenv sphinx_1.7.9
|
||||
$ . sphinx_1.7.9/bin/activate
|
||||
(sphinx_1.7.9) $ pip install -r Documentation/sphinx/requirements.txt
|
||||
|
||||
在运行 ``. sphinx_1.7.9/bin/activate`` 之后,提示符将变化,以指示您正在使用新
|
||||
环境。如果您打开了一个新的shell,那么在构建文档之前,您需要重新运行此命令以再
|
||||
次进入虚拟环境中。
|
||||
|
||||
图片输出
|
||||
--------
|
||||
|
||||
内核文档构建系统包含一个扩展,可以处理GraphViz和SVG格式的图像(参见
|
||||
:ref:`sphinx_kfigure_zh` )。
|
||||
|
||||
为了让它工作,您需要同时安装GraphViz和ImageMagick包。如果没有安装这些软件包,
|
||||
构建系统仍将构建文档,但不会在输出中包含任何图像。
|
||||
|
||||
PDF和LaTeX构建
|
||||
--------------
|
||||
|
||||
目前只有Sphinx 1.4及更高版本才支持这种构建。
|
||||
|
||||
对于PDF和LaTeX输出,还需要 ``XeLaTeX`` 3.14159265版本。(译注:此版本号真实
|
||||
存在)
|
||||
|
||||
根据发行版的不同,您可能还需要安装一系列 ``texlive`` 软件包,这些软件包提供了
|
||||
``XeLaTeX`` 工作所需的最小功能集。
|
||||
|
||||
.. _sphinx-pre-install_zh:
|
||||
|
||||
检查Sphinx依赖项
|
||||
----------------
|
||||
|
||||
这有一个脚本可以自动检查Sphinx依赖项。如果它认得您的发行版,还会提示您所用发行
|
||||
版的安装命令::
|
||||
|
||||
$ ./scripts/sphinx-pre-install
|
||||
Checking if the needed tools for Fedora release 26 (Twenty Six) are available
|
||||
Warning: better to also install "texlive-luatex85".
|
||||
You should run:
|
||||
|
||||
sudo dnf install -y texlive-luatex85
|
||||
/usr/bin/virtualenv sphinx_1.7.9
|
||||
. sphinx_1.7.9/bin/activate
|
||||
pip install -r Documentation/sphinx/requirements.txt
|
||||
|
||||
Can't build as 1 mandatory dependency is missing at ./scripts/sphinx-pre-install line 468.
|
||||
|
||||
默认情况下,它会检查html和PDF的所有依赖项,包括图像、数学表达式和LaTeX构建的
|
||||
需求,并假设将使用虚拟Python环境。html构建所需的依赖项被认为是必需的,其他依
|
||||
赖项则是可选的。
|
||||
|
||||
它支持两个可选参数:
|
||||
|
||||
``--no-pdf``
|
||||
|
||||
禁用PDF检查;
|
||||
|
||||
``--no-virtualenv``
|
||||
|
||||
使用Sphinx的系统打包,而不是Python虚拟环境。
|
||||
|
||||
Sphinx构建
|
||||
==========
|
||||
|
||||
生成文档的常用方法是运行 ``make htmldocs`` 或 ``make pdfdocs`` 。还有其它可用
|
||||
的格式:请参阅 ``make help`` 的文档部分。生成的文档放在 ``Documentation/output``
|
||||
下相应格式的子目录中。
|
||||
|
||||
要生成文档,显然必须安装Sphinx( ``sphinx-build`` )。要让HTML输出更漂亮,可以
|
||||
使用Read the Docs Sphinx主题( ``sphinx_rtd_theme`` )。对于PDF输出,您还需要
|
||||
``XeLaTeX`` 和来自ImageMagick(https://www.imagemagick.org)的 ``convert(1)`` 。
|
||||
所有这些软件在大多发行版中都可用或已打包。
|
||||
|
||||
要传递额外的选项给Sphinx,可以使用make变量 ``SPHINXOPTS`` 。例如,使用
|
||||
``make SPHINXOPTS=-v htmldocs`` 获得更详细的输出。
|
||||
|
||||
|
||||
要删除生成的文档,请运行 ``make cleandocs`` 。
|
||||
|
||||
编写文档
|
||||
========
|
||||
|
||||
添加新文档很容易,只需:
|
||||
|
||||
1. 在 ``Documentation`` 下某处添加一个新的 ``.rst`` 文件。
|
||||
2. 从 ``Documentation/index.rst`` 中的Sphinx `主目录树`_ 链接到它。
|
||||
|
||||
.. _主目录树: http://www.sphinx-doc.org/en/stable/markup/toctree.html
|
||||
|
||||
对于简单的文档(比如您现在正在阅读的文档),这通常已经足够好了,但是对于较大
|
||||
的文档,最好创建一个子目录(或者使用现有的子目录)。例如,图形子系统文档位于
|
||||
``Documentation/gpu`` 下,拆分为多个 ``.rst`` 文件,并具有从主目录链接来的单
|
||||
独索引 ``index.rst`` (有自己的目录树 ``toctree`` )。
|
||||
|
||||
请参阅 `Sphinx <http://www.sphinx-doc.org/>`_ 和 `reStructuredText
|
||||
<http://docutils.sourceforge.net/rst.html>`_ 的文档,以了解如何使用它们。
|
||||
特别是Sphinx `reStructuredText 基础`_ 这是开始学习使用reStructuredText的
|
||||
好地方。还有一些 `Sphinx 特殊标记结构`_ 。
|
||||
|
||||
.. _reStructuredText 基础: http://www.sphinx-doc.org/en/stable/rest.html
|
||||
.. _Sphinx 特殊标记结构: http://www.sphinx-doc.org/en/stable/markup/index.html
|
||||
|
||||
内核文档的具体指南
|
||||
------------------
|
||||
|
||||
这是一些内核文档的具体指南:
|
||||
|
||||
* 请不要过于痴迷转换格式到reStructuredText。保持简单。在大多数情况下,文档
|
||||
应该是纯文本,格式应足够一致,以便可以转换为其他格式。
|
||||
|
||||
* 将现有文档转换为reStructuredText时,请尽量减少格式更改。
|
||||
|
||||
* 在转换文档时,还要更新内容,而不仅仅是格式。
|
||||
|
||||
* 请遵循标题修饰符的顺序:
|
||||
|
||||
1. ``=`` 文档标题,要有上线::
|
||||
|
||||
========
|
||||
文档标题
|
||||
========
|
||||
|
||||
2. ``=`` 章::
|
||||
|
||||
章标题
|
||||
======
|
||||
|
||||
3. ``-`` 节::
|
||||
|
||||
节标题
|
||||
------
|
||||
|
||||
4. ``~`` 小节::
|
||||
|
||||
小节标题
|
||||
~~~~~~~~
|
||||
|
||||
尽管RST没有规定具体的顺序(“没有强加一个固定数量和顺序的节标题装饰风格,最终
|
||||
按照的顺序将是实际遇到的顺序。”),但是拥有一个通用级别的文档更容易遵循。
|
||||
|
||||
* 对于插入固定宽度的文本块(用于代码样例、用例等): ``::`` 用于语法高亮意义不
|
||||
大的内容,尤其是短代码段; ``.. code-block:: <language>`` 用于需要语法高亮的
|
||||
较长代码块。对于嵌入到文本中的简短代码片段,请使用 \`\` 。
|
||||
|
||||
|
||||
C域
|
||||
---
|
||||
|
||||
**Sphinx C域(Domain)** (name c)适用于C API文档。例如,函数原型:
|
||||
|
||||
.. code-block:: rst
|
||||
|
||||
.. c:function:: int ioctl( int fd, int request )
|
||||
|
||||
内核文档的C域有一些附加特性。例如,您可以使用诸如 ``open`` 或 ``ioctl`` 这样的
|
||||
通用名称重命名函数的引用名称:
|
||||
|
||||
.. code-block:: rst
|
||||
|
||||
.. c:function:: int ioctl( int fd, int request )
|
||||
:name: VIDIOC_LOG_STATUS
|
||||
|
||||
函数名称(例如ioctl)仍保留在输出中,但引用名称从 ``ioctl`` 变为
|
||||
``VIDIOC_LOG_STATUS`` 。此函数的索引项也变为 ``VIDIOC_LOG_STATUS`` 。
|
||||
|
||||
请注意,不需要使用 ``c:func:`` 生成函数文档的交叉引用。由于一些Sphinx扩展的
|
||||
神奇力量,如果给定函数名的索引项存在,文档构建系统会自动将对 ``function()``
|
||||
的引用转换为交叉引用。如果在内核文档中看到 ``c:func:`` 的用法,请删除它。
|
||||
|
||||
|
||||
列表
|
||||
----
|
||||
|
||||
我们建议使用 *列式表* 格式。 *列式表* 格式是二级列表。与ASCII艺术相比,它们对
|
||||
文本文件的读者来说可能没有那么舒适。但其优点是易于创建或修改,而且修改的差异
|
||||
(diff)更有意义,因为差异仅限于修改的内容。
|
||||
|
||||
*平铺表* 也是一个二级列表,类似于 *列式表* ,但具有一些额外特性:
|
||||
|
||||
* 列范围:使用 ``cspan`` 修饰,可以通过其他列扩展单元格
|
||||
|
||||
* 行范围:使用 ``rspan`` 修饰,可以通过其他行扩展单元格
|
||||
|
||||
* 自动将表格行最右边的单元格扩展到该行右侧空缺的单元格上。若使用
|
||||
``:fill-cells:`` 选项,此行为可以从 *自动合并* 更改为 *自动插入* ,自动
|
||||
插入(空)单元格,而不是扩展合并到最后一个单元格。
|
||||
|
||||
选项:
|
||||
|
||||
* ``:header-rows:`` [int] 标题行计数
|
||||
* ``:stub-columns:`` [int] 标题列计数
|
||||
* ``:widths:`` [[int] [int] ... ] 列宽
|
||||
* ``:fill-cells:`` 插入缺少的单元格,而不是自动合并缺少的单元格
|
||||
|
||||
修饰:
|
||||
|
||||
* ``:cspan:`` [int] 扩展列
|
||||
* ``:rspan:`` [int] 扩展行
|
||||
|
||||
下面的例子演示了如何使用这些标记。分级列表的第一级是 *表格行* 。 *表格行* 中
|
||||
只允许一个标记,即该 *表格行* 中的单元格列表。 *comments* ( ``..`` )和
|
||||
*targets* 例外(例如引用 ``:ref:`最后一行 <last row_zh>``` / :ref:`最后一行
|
||||
<last row_zh>` )。
|
||||
|
||||
.. code-block:: rst
|
||||
|
||||
.. flat-table:: 表格标题
|
||||
:widths: 2 1 1 3
|
||||
|
||||
* - 表头 列1
|
||||
- 表头 列2
|
||||
- 表头 列3
|
||||
- 表头 列4
|
||||
|
||||
* - 行1
|
||||
- 字段1.1
|
||||
- 字段1.2(自动扩展)
|
||||
|
||||
* - 行2
|
||||
- 字段2.1
|
||||
- :rspan:`1` :cspan:`1` 字段2.2~3.3
|
||||
|
||||
* .. _`last row_zh`:
|
||||
|
||||
- 行3
|
||||
|
||||
渲染效果:
|
||||
|
||||
.. flat-table:: 表格标题
|
||||
:widths: 2 1 1 3
|
||||
|
||||
* - 表头 列1
|
||||
- 表头 列2
|
||||
- 表头 列3
|
||||
- 表头 列4
|
||||
|
||||
* - 行1
|
||||
- 字段1.1
|
||||
- 字段1.2(自动扩展)
|
||||
|
||||
* - 行2
|
||||
- 字段2.1
|
||||
- :rspan:`1` :cspan:`1` 字段2.2~3.3
|
||||
|
||||
* .. _`last row_zh`:
|
||||
|
||||
- 行3
|
||||
|
||||
交叉引用
|
||||
--------
|
||||
|
||||
从一页文档到另一页文档的交叉引用可以通过简单地写出文件路径来完成,无特殊格式
|
||||
要求。路径可以是绝对路径或相对路径。绝对路径从“Documentation/”开始。例如,要
|
||||
交叉引用此页,以下写法皆可,取决于具体的文档目录(注意 ``.rst`` 扩展名是可选
|
||||
的)::
|
||||
|
||||
参见 Documentation/doc-guide/sphinx.rst 。此法始终可用。
|
||||
请查看 sphinx.rst ,仅在同级目录中有效。
|
||||
请阅读 ../sphinx.rst ,上级目录中的文件。
|
||||
|
||||
如果要使用相对路径,则需要使用Sphinx的 ``doc`` 修饰。例如,从同一目录引用此页
|
||||
的操作如下::
|
||||
|
||||
参见 :doc:`sphinx文档的自定义链接文本 <sphinx>`.
|
||||
|
||||
对于大多数用例,前者是首选,因为它更干净,更适合阅读源文件的人。如果您遇到一
|
||||
个没有任何特殊作用的 ``:doc:`` 用法,请将其转换为文档路径。
|
||||
|
||||
有关交叉引用kernel-doc函数或类型的信息,请参阅
|
||||
Documentation/doc-guide/kernel-doc.rst 。
|
||||
|
||||
.. _sphinx_kfigure_zh:
|
||||
|
||||
图形图片
|
||||
========
|
||||
|
||||
如果要添加图片,应该使用 ``kernel-figure`` 和 ``kernel-image`` 指令。例如,
|
||||
要插入具有可缩放图像格式的图形,请使用SVG(:ref:`svg_image_example_zh` )::
|
||||
|
||||
.. kernel-figure:: ../../../doc-guide/svg_image.svg
|
||||
:alt: 简易 SVG 图片
|
||||
|
||||
SVG 图片示例
|
||||
|
||||
.. _svg_image_example_zh:
|
||||
|
||||
.. kernel-figure:: ../../../doc-guide/svg_image.svg
|
||||
:alt: 简易 SVG 图片
|
||||
|
||||
SVG 图片示例
|
||||
|
||||
内核figure(和image)指令支持 DOT 格式文件,请参阅
|
||||
|
||||
* DOT:http://graphviz.org/pdf/dotguide.pdf
|
||||
* Graphviz:http://www.graphviz.org/content/dot-language
|
||||
|
||||
一个简单的例子(:ref:`hello_dot_file_zh` )::
|
||||
|
||||
.. kernel-figure:: ../../../doc-guide/hello.dot
|
||||
:alt: 你好,世界
|
||||
|
||||
DOT 示例
|
||||
|
||||
.. _hello_dot_file_zh:
|
||||
|
||||
.. kernel-figure:: ../../../doc-guide/hello.dot
|
||||
:alt: 你好,世界
|
||||
|
||||
DOT 示例
|
||||
|
||||
嵌入的渲染标记(或语言),如Graphviz的 **DOT** 由 ``kernel-render`` 指令提供::
|
||||
|
||||
.. kernel-render:: DOT
|
||||
:alt: 有向图
|
||||
:caption: 嵌入式 **DOT** (Graphviz) 代码
|
||||
|
||||
digraph foo {
|
||||
"五棵松" -> "国贸";
|
||||
}
|
||||
|
||||
如何渲染取决于安装的工具。如果安装了Graphviz,您将看到一个矢量图像。否则,原始
|
||||
标记将作为 *文字块* 插入(:ref:`hello_dot_render_zh` )。
|
||||
|
||||
.. _hello_dot_render_zh:
|
||||
|
||||
.. kernel-render:: DOT
|
||||
:alt: 有向图
|
||||
:caption: 嵌入式 **DOT** (Graphviz) 代码
|
||||
|
||||
digraph foo {
|
||||
"五棵松" -> "国贸";
|
||||
}
|
||||
|
||||
*render* 指令包含 *figure* 指令中已知的所有选项,以及选项 ``caption`` 。如果
|
||||
``caption`` 有值,则插入一个 *figure* 节点,若无,则插入一个 *image* 节点。
|
||||
如果您想引用它,还需要一个 ``caption`` (:ref:`hello_svg_render_zh` )。
|
||||
|
||||
嵌入式 **SVG**::
|
||||
|
||||
.. kernel-render:: SVG
|
||||
:caption: 嵌入式 **SVG** 标记
|
||||
:alt: 右上箭头
|
||||
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" ...>
|
||||
...
|
||||
</svg>
|
||||
|
||||
.. _hello_svg_render_zh:
|
||||
|
||||
.. kernel-render:: SVG
|
||||
:caption: 嵌入式 **SVG** 标记
|
||||
:alt: 右上箭头
|
||||
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg"
|
||||
version="1.1" baseProfile="full" width="70px" height="40px" viewBox="0 0 700 400">
|
||||
<line x1="180" y1="370" x2="500" y2="50" stroke="black" stroke-width="15px"/>
|
||||
<polygon points="585 0 525 25 585 50" transform="rotate(135 525 25)"/>
|
||||
</svg>
|
||||
|
|
@ -18,8 +18,18 @@
|
|||
|
||||
admin-guide/index
|
||||
process/index
|
||||
dev-tools/index
|
||||
doc-guide/index
|
||||
kernel-hacking/index
|
||||
filesystems/index
|
||||
arm64/index
|
||||
sound/index
|
||||
cpu-freq/index
|
||||
mips/index
|
||||
iio/index
|
||||
riscv/index
|
||||
core-api/index
|
||||
openrisc/index
|
||||
|
||||
目录和表格
|
||||
----------
|
||||
|
|
|
@ -0,0 +1,708 @@
|
|||
.. include:: ../disclaimer-zh_CN.rst
|
||||
|
||||
:Original: Documentation/kernel-hacking/hacking.rst
|
||||
|
||||
:译者:
|
||||
|
||||
吴想成 Wu XiangCheng <bobwxc@email.cn>
|
||||
|
||||
==============
|
||||
内核骇客指北
|
||||
==============
|
||||
|
||||
:作者: Rusty Russell
|
||||
|
||||
引言
|
||||
=====
|
||||
|
||||
欢迎咱优雅的读者们来阅读Rusty的非常不靠谱的Linux内核骇客(Hacking)指南。本文
|
||||
描述了内核代码的常见例程和一般要求:其目标是引导有经验的C程序员入门Linux内核
|
||||
开发。我回避了实现细节:这是代码要做的,也忽略了很多有用的例程。
|
||||
|
||||
在你读这篇文章之前,请理解我从来没有想过要写这篇文章,因为我的资历太低了;
|
||||
但我一直想读这样的文章,自己写是唯一的方法。我希望它能成长为一个最佳实践、
|
||||
通用起点和其他信息的汇编。
|
||||
|
||||
玩家
|
||||
=======
|
||||
|
||||
在任何时候,系统中的每个CPU都可以:
|
||||
|
||||
- 与任何进程无关,服务于硬件中断;
|
||||
|
||||
- 与任何进程无关,服务于软件中断(softirq)或子任务(tasklet);
|
||||
|
||||
- 运行于内核空间中,与进程(用户上下文)相关联;
|
||||
|
||||
- 在用户空间中运行进程。
|
||||
|
||||
它们之间有优先级顺序。最下面的两个可以互相抢占,但上面为严格的层次结构:
|
||||
每个层级只能被上方的抢占。例如,当一个软中断在CPU上运行时,没有其他软中断
|
||||
会抢占它,但是硬件中断可以抢占它。不过,系统中的任何其他CPU都是独立执行的。
|
||||
|
||||
我们将会看到许多方法,用户上下文可以阻止中断,从而成为真正的不可抢占。
|
||||
|
||||
用户上下文
|
||||
------------
|
||||
|
||||
用户上下文是指当您从系统调用或其他陷阱进入时:就像用户空间一样,您可以被更
|
||||
重要的任务和中断抢占。您可以通过调用 :c:func:`schedule()` 进行睡眠。
|
||||
|
||||
.. note::
|
||||
|
||||
在模块加载和卸载以及块设备层上的操作时,你始终处于用户上下文中。
|
||||
|
||||
在用户上下文中,当前 ``current`` 指针(指示我们当前正在执行的任务)是有效的,
|
||||
且 :c:func:`in_interrupt()` ( ``include/linux/preempt.h`` )值为非(false)。
|
||||
|
||||
.. warning::
|
||||
|
||||
请注意,如果您禁用了抢占或软中断(见下文),:c:func:`in_interrupt()` 会
|
||||
返回假阳性。
|
||||
|
||||
硬件中断(Hard IRQs)
|
||||
----------------------
|
||||
|
||||
像定时器、网卡和键盘等都是可能在任意时刻产生中断的真实硬件。内核运行中断
|
||||
处理程序,为硬件提供服务。内核确保处理程序永远不会重入:如果相同的中断到达,
|
||||
它将被排队(或丢弃)。因为它会关闭中断,所以处理程序必须很快:通常它只是
|
||||
确认中断,标记一个“软件中断”以执行并退出。
|
||||
|
||||
您可以通过 :c:func:`in_irq()` 返回真来判断您处于硬件中断状态。
|
||||
|
||||
.. warning::
|
||||
|
||||
请注意,如果中断被禁用,这将返回假阳性(见下文)。
|
||||
|
||||
软件中断上下文:软中断(Softirqs)与子任务(Tasklets)
|
||||
-------------------------------------------------------
|
||||
|
||||
当系统调用即将返回用户空间或硬件中断处理程序退出时,任何标记为挂起(通常通
|
||||
过硬件中断)的“软件中断”将运行( ``kernel/softirq.c`` )。
|
||||
|
||||
此处完成了许多真正的中断处理工作。在向SMP过渡的早期,只有“bottom halves下半
|
||||
部”(BHs)机制,无法利用多个CPU的优势。在从那些一团糟的就电脑切换过来后不久,
|
||||
我们放弃了这个限制,转而使用“软中断”。
|
||||
|
||||
``include/linux/interrupt.h`` 列出了不同的软中断。定时器软中断是一个非常重要
|
||||
的软中断( ``include/linux/timer.h`` ):您可以注册它以在给定时间后为您调用
|
||||
函数。
|
||||
|
||||
软中断通常是一个很难处理的问题,因为同一个软中断将同时在多个CPU上运行。因此,
|
||||
子任务( ``include/linux/interrupt.h`` )更常用:它们是动态可注册的(意味着
|
||||
您可以拥有任意数量),并且它们还保证任何子任务都只能在一个CPU上运行,不同的
|
||||
子任务也可以同时运行。
|
||||
|
||||
.. warning::
|
||||
|
||||
“tasklet”这个名字是误导性的:它们与“任务”无关,可能更多与当时
|
||||
阿列克谢·库兹涅佐夫享用的糟糕伏特加有关。
|
||||
|
||||
你可以使用 :c:func:`in_softirq()` 宏( ``include/linux/preempt.h`` )来确认
|
||||
是否处于软中断(或子任务)中。
|
||||
|
||||
.. warning::
|
||||
|
||||
注意,如果持有 :ref:`bottom half lock <local_bh_disable_zh>` 锁,这将返回
|
||||
假阳性。
|
||||
|
||||
一些基本规则
|
||||
================
|
||||
|
||||
缺少内存保护
|
||||
如果你损坏了内存,无论是在用户上下文还是中断上下文中,整个机器都会崩溃。
|
||||
你确定你不能在用户空间里做你想做的事吗?
|
||||
|
||||
缺少浮点或MMX
|
||||
FPU上下文不会被保存;即使在用户上下文中,FPU状态也可能与当前进程不一致:
|
||||
您会弄乱某些用户进程的FPU状态。如果真的要这样做,就必须显式地保存/恢复
|
||||
完整的FPU状态(并避免上下文切换)。这通常不是个好主意;请优先用定点算法。
|
||||
|
||||
严格的堆栈限制
|
||||
对于大多数32位体系结构,根据配置选项的不同内核堆栈大约为3K到6K;对于大
|
||||
多数64位机器,内核堆栈大约为14K,并且经常与中断共享,因此你无法使用全部。
|
||||
应避免深度递归和栈上的巨型本地数组(用动态分配它们来代替)。
|
||||
|
||||
Linux内核是可移植的
|
||||
就这样吧。您的代码应该是纯64位的,并且不依赖于字节序(endian)。您还应该
|
||||
尽量减少CPU特定的东西,例如内联汇编(inline assembly)应该被干净地封装和
|
||||
最小化以便于移植。一般来说,它应该局限于内核树中有体系结构依赖的部分。
|
||||
|
||||
输入输出控制(ioctls):避免编写新的系统调用
|
||||
==============================================
|
||||
|
||||
系统调用(system call)通常看起来像这样::
|
||||
|
||||
asmlinkage long sys_mycall(int arg)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
首先,在大多数情况下,您无需创建新的系统调用。创建一个字符设备并为其实现适当
|
||||
的输入输出控制(ioctls)。这比系统调用灵活得多,不必写进每个体系结构的
|
||||
``include/asm/unistd.h`` 和 ``arch/kernel/entry.S`` 文件里,而且更容易被Linus
|
||||
接受。
|
||||
|
||||
如果您的程序所做的只是读取或写入一些参数,请考虑实现 :c:func:`sysfs()` 接口。
|
||||
|
||||
在输入输出控制中,您处于进程的用户上下文。出现错误时,返回一个负的错误参数
|
||||
(errno,请参阅 ``include/uapi/asm-generic/errno-base.h`` 、
|
||||
``include/uapi/asm-generic/errno.h`` 和 ``include/linux/errno.h`` ),否则返
|
||||
回0。
|
||||
|
||||
在睡眠之后,您应该检查是否出现了信号:Unix/Linux处理信号的方法是暂时退出系统
|
||||
调用,并返回 ``-ERESTARTSYS`` 错误。系统调用入口代码将切换回用户上下文,处理
|
||||
信号处理程序,然后系统调用将重新启动(除非用户禁用了该功能)。因此,您应该准
|
||||
备好处理重新启动,例如若您处理某些数据结构到一半。
|
||||
|
||||
::
|
||||
|
||||
if (signal_pending(current))
|
||||
return -ERESTARTSYS;
|
||||
|
||||
|
||||
如果你要做更长时间的计算:优先考虑用户空间。如果你真的想在内核中做这件事,你
|
||||
应该定期检查你是否需要让出CPU(请记得每个CPU都有协作多任务)。
|
||||
习惯用法::
|
||||
|
||||
cond_resched(); /* Will sleep */
|
||||
|
||||
|
||||
接口设计的小注释:UNIX系统调用的格言是“提供机制而不是策略
|
||||
Provide mechanism not policy”。
|
||||
|
||||
死锁的“配方”
|
||||
====================
|
||||
|
||||
您不能调用任何可能睡眠的程序,除非:
|
||||
|
||||
- 您处于用户上下文中。
|
||||
|
||||
- 你未拥有任何自旋锁。
|
||||
|
||||
- 您已经启用中断(实际上,Andi Kleen说调度代码将为您启用它们,但这可能不是
|
||||
您想要的)。
|
||||
|
||||
注意,有些函数可能隐式地睡眠:常见的是用户空间访问函数(\*_user)和没有
|
||||
``GFP_ATOMIC`` 的内存分配函数。
|
||||
|
||||
您应该始终打开 ``CONFIG_DEBUG_ATOMIC_SLEEP`` 项来编译内核,如果您违反这些
|
||||
规则,它将警告您。如果你 **真的** 违反了规则,你最终会锁住你的电脑。
|
||||
|
||||
真的会这样。
|
||||
|
||||
|
||||
常用函数/程序
|
||||
===============
|
||||
|
||||
:c:func:`printk()`
|
||||
------------------
|
||||
|
||||
定义于 ``include/linux/printk.h``
|
||||
|
||||
:c:func:`printk()` 将内核消息提供给控制台、dmesg和syslog守护进程。它对于调
|
||||
试和报告错误很有用,并且可以在中断上下文中使用,但是使用时要小心:如果机器
|
||||
的控制台中充斥着printk消息则会无法使用。它使用与ANSI C printf基本兼容的格式
|
||||
字符串,并通过C字符串串联为其提供第一个“优先”参数::
|
||||
|
||||
printk(KERN_INFO "i = %u\n", i);
|
||||
|
||||
|
||||
参见 ``include/linux/kern_levels.h`` ;了解其他 ``KERN_`` 值;syslog将这些值
|
||||
解释为级别。特殊用法:打印IP地址使用::
|
||||
|
||||
__be32 ipaddress;
|
||||
printk(KERN_INFO "my ip: %pI4\n", &ipaddress);
|
||||
|
||||
|
||||
:c:func:`printk()` 内部使用的1K缓冲区,不捕获溢出。请确保足够使用。
|
||||
|
||||
.. note::
|
||||
|
||||
当您开始在用户程序中将printf打成printk时,就知道自己是真正的内核程序员了
|
||||
:)
|
||||
|
||||
.. note::
|
||||
|
||||
另一个注释:最初的unix第六版源代码在其printf函数的顶部有一个注释:“printf
|
||||
不应该用于叽叽喳喳”。你也应该遵循此建议。
|
||||
|
||||
:c:func:`copy_to_user()` / :c:func:`copy_from_user()` / :c:func:`get_user()` / :c:func:`put_user()`
|
||||
---------------------------------------------------------------------------------------------------
|
||||
|
||||
定义于 ``include/linux/uaccess.h`` / ``asm/uaccess.h``
|
||||
|
||||
**[睡眠]**
|
||||
|
||||
:c:func:`put_user()` 和 :c:func:`get_user()` 用于从用户空间中获取和向用户空
|
||||
间中传出单个值(如int、char或long)。指向用户空间的指针永远不应该直接取消
|
||||
引用:应该使用这些程序复制数据。两者都返回 ``-EFAULT`` 或 0。
|
||||
|
||||
:c:func:`copy_to_user()` 和 :c:func:`copy_from_user()` 更通用:它们从/向用户
|
||||
空间复制任意数量的数据。
|
||||
|
||||
.. warning::
|
||||
|
||||
与 :c:func:`put_user()` 和 :c:func:`get_user()` 不同,它们返回未复制的
|
||||
数据量(即0仍然意味着成功)。
|
||||
|
||||
【是的,这个愚蠢的接口真心让我尴尬。火爆的口水仗大概每年都会发生。
|
||||
—— Rusty Russell】
|
||||
|
||||
这些函数可以隐式睡眠。它不应该在用户上下文之外调用(没有意义)、调用时禁用中断
|
||||
或获得自旋锁。
|
||||
|
||||
:c:func:`kmalloc()`/:c:func:`kfree()`
|
||||
-------------------------------------
|
||||
|
||||
定义于 ``include/linux/slab.h``
|
||||
|
||||
**[可能睡眠:见下]**
|
||||
|
||||
这些函数用于动态请求指针对齐的内存块,类似用户空间中的malloc和free,但
|
||||
:c:func:`kmalloc()` 需要额外的标志词。重要的值:
|
||||
|
||||
``GFP_KERNEL``
|
||||
可以睡眠和交换以释放内存。只允许在用户上下文中使用,但这是分配内存最可靠
|
||||
的方法。
|
||||
|
||||
``GFP_ATOMIC``
|
||||
不会睡眠。较 ``GFP_KERNEL`` 更不可靠,但可以从中断上下文调用。你 **应该**
|
||||
有一个很好的内存不足错误处理策略。
|
||||
|
||||
``GFP_DMA``
|
||||
分配低于16MB的ISA DMA。如果你不知道那是什么,那你就不需要了。非常不可靠。
|
||||
|
||||
如果您看到一个从无效上下文警告消息调用的睡眠的函数,那么您可能在没有
|
||||
``GFP_ATOMIC`` 的情况下从中断上下文调用了一个睡眠的分配函数。你必须立即修复,
|
||||
快点!
|
||||
|
||||
如果你要分配至少 ``PAGE_SIZE`` ( ``asm/page.h`` 或 ``asm/page_types.h`` )
|
||||
字节,请考虑使用 :c:func:`__get_free_pages()` ( ``include/linux/gfp.h`` )。
|
||||
它采用顺序参数(0表示页面大小,1表示双页,2表示四页……)和与上述相同的内存
|
||||
优先级标志字。
|
||||
|
||||
如果分配的字节数超过一页,可以使用 :c:func:`vmalloc()` 。它将在内核映射中分
|
||||
配虚拟内存。此块在物理内存中不是连续的,但是MMU(内存管理单元)使它看起来像
|
||||
是为您准备好的连续空间(因此它只是看起来对cpu连续,对外部设备驱动程序则不然)。
|
||||
如果您真的需要为一些奇怪的设备提供大量物理上连续的内存,那么您就会遇到问题:
|
||||
Linux对此支持很差,因为正在运行的内核中的内存碎片化会使它变得很困难。最好的
|
||||
方法是在引导过程的早期通过 :c:func:`alloc_bootmem()` 函数分配。
|
||||
|
||||
在创建自己的常用对象缓存之前,请考虑使用 ``include/linux/slab.h`` 中的slab
|
||||
缓存。
|
||||
|
||||
:c:macro:`current`
|
||||
------------------
|
||||
|
||||
定义于 ``include/asm/current.h``
|
||||
|
||||
此全局变量(其实是宏)包含指向当前任务结构(task structure)的指针,因此仅在
|
||||
用户上下文中有效。例如,当进程进行系统调用时,这将指向调用进程的任务结构。
|
||||
在中断上下文中不为空(**not NULL**)。
|
||||
|
||||
:c:func:`mdelay()`/:c:func:`udelay()`
|
||||
-------------------------------------
|
||||
|
||||
定义于 ``include/asm/delay.h`` / ``include/linux/delay.h``
|
||||
|
||||
:c:func:`udelay()` 和 :c:func:`ndelay()` 函数可被用于小暂停。不要对它们使用
|
||||
大的值,因为这样会导致溢出——帮助函数 :c:func:`mdelay()` 在这里很有用,或者
|
||||
考虑 :c:func:`msleep()`。
|
||||
|
||||
:c:func:`cpu_to_be32()`/:c:func:`be32_to_cpu()`/:c:func:`cpu_to_le32()`/:c:func:`le32_to_cpu()`
|
||||
-----------------------------------------------------------------------------------------------
|
||||
|
||||
定义于 ``include/asm/byteorder.h``
|
||||
|
||||
:c:func:`cpu_to_be32()` 系列函数(其中“32”可以替换为64或16,“be”可以替换为
|
||||
“le”)是在内核中进行字节序转换的常用方法:它们返回转换后的值。所有的变体也
|
||||
提供反向转换函数:
|
||||
:c:func:`be32_to_cpu()` 等。
|
||||
|
||||
这些函数有两个主要的变体:指针变体,例如 :c:func:`cpu_to_be32p()` ,它获取
|
||||
指向给定类型的指针,并返回转换后的值。另一个变体是“in-situ”系列,例如
|
||||
:c:func:`cpu_to_be32s()` ,它转换指针引用的值,并返回void。
|
||||
|
||||
:c:func:`local_irq_save()`/:c:func:`local_irq_restore()`
|
||||
--------------------------------------------------------
|
||||
|
||||
定义于 ``include/linux/irqflags.h``
|
||||
|
||||
|
||||
这些程序禁用本地CPU上的硬中断,并还原它们。它们是可重入的;在其一个
|
||||
``unsigned long flags`` 参数中保存以前的状态。如果您知道中断已启用,那么可
|
||||
直接使用 :c:func:`local_irq_disable()` 和 :c:func:`local_irq_enable()`。
|
||||
|
||||
.. _local_bh_disable_zh:
|
||||
|
||||
:c:func:`local_bh_disable()`/:c:func:`local_bh_enable()`
|
||||
--------------------------------------------------------
|
||||
|
||||
定义于 ``include/linux/bottom_half.h``
|
||||
|
||||
|
||||
这些程序禁用本地CPU上的软中断,并还原它们。它们是可重入的;如果之前禁用了
|
||||
软中断,那么在调用这对函数之后仍然会禁用它们。它们阻止软中断和子任务在当前
|
||||
CPU上运行。
|
||||
|
||||
:c:func:`smp_processor_id()`
|
||||
----------------------------
|
||||
|
||||
定义于 ``include/linux/smp.h``
|
||||
|
||||
:c:func:`get_cpu()` 禁用抢占(这样您就不会突然移动到另一个cpu)并返回当前
|
||||
处理器号,介于0和 ``NR_CPUS`` 之间。请注意,CPU编号不一定是连续的。完成后,
|
||||
使用 :c:func:`put_cpu()` 再次返回。
|
||||
|
||||
如果您知道您不能被另一个任务抢占(即您处于中断上下文中,或已禁用抢占),您
|
||||
可以使用 :c:func:`smp_processor_id()`。
|
||||
|
||||
``__init``/``__exit``/``__initdata``
|
||||
------------------------------------
|
||||
|
||||
定义于 ``include/linux/init.h``
|
||||
|
||||
引导之后,内核释放一个特殊的部分;用 ``__init`` 标记的函数和用 ``__initdata``
|
||||
标记的数据结构在引导完成后被丢弃:同样地,模块在初始化后丢弃此内存。
|
||||
``__exit`` 用于声明只在退出时需要的函数:如果此文件未编译为模块,则该函数将
|
||||
被删除。请参阅头文件以使用。请注意,使用 :c:func:`EXPORT_SYMBOL()` 或
|
||||
:c:func:`EXPORT_SYMBOL_GPL()` 将标记为 ``__init`` 的函数导出到模块是没有意义
|
||||
的——这将出问题。
|
||||
|
||||
|
||||
:c:func:`__initcall()`/:c:func:`module_init()`
|
||||
----------------------------------------------
|
||||
|
||||
定义于 ``include/linux/init.h`` / ``include/linux/module.h``
|
||||
|
||||
内核的许多部分都作为模块(内核的可动态加载部分)良好服务。使用
|
||||
:c:func:`module_init()` 和 :c:func:`module_exit()` 宏可以简化代码编写,无需
|
||||
``#ifdef`` ,即可以作为模块运行或内置在内核中。
|
||||
|
||||
:c:func:`module_init()` 宏定义在模块插入时(如果文件编译为模块)或在引导时
|
||||
调用哪个函数:如果文件未编译为模块,:c:func:`module_init()` 宏将等效于
|
||||
:c:func:`__initcall()` ,它通过链接器的魔力确保在引导时调用该函数。
|
||||
|
||||
该函数可以返回一个错误值,以导致模块加载失败(不幸的是,如果将模块编译到内核
|
||||
中,则此操作无效)。此函数在启用中断的用户上下文中调用,因此可以睡眠。
|
||||
|
||||
:c:func:`module_exit()`
|
||||
-----------------------
|
||||
|
||||
|
||||
定义于 ``include/linux/module.h``
|
||||
|
||||
这个宏定义了在模块删除时要调用的函数(如果是编译到内核中的文件,则无用武之地)。
|
||||
只有在模块使用计数到零时才会调用它。这个函数也可以睡眠,但不能失败:当它返回
|
||||
时,所有的东西都必须清理干净。
|
||||
|
||||
注意,这个宏是可选的:如果它不存在,您的模块将不可移除(除非 ``rmmod -f`` )。
|
||||
|
||||
:c:func:`try_module_get()`/:c:func:`module_put()`
|
||||
-------------------------------------------------
|
||||
|
||||
定义于 ``include/linux/module.h``
|
||||
|
||||
这些函数会操作模块使用计数,以防止删除(如果另一个模块使用其导出的符号之一,
|
||||
则无法删除模块,参见下文)。在调用模块代码之前,您应该在该模块上调用
|
||||
:c:func:`try_module_get()` :若失败,那么该模块将被删除,您应该将其视为不存在。
|
||||
若成功,您就可以安全地进入模块,并在完成后调用模块 :c:func:`module_put()` 。
|
||||
|
||||
大多数可注册结构体都有所有者字段,例如在
|
||||
:c:type:`struct file_operations <file_operations>` 结构体中,此字段应设置为
|
||||
宏 ``THIS_MODULE`` 。
|
||||
|
||||
等待队列 ``include/linux/wait.h``
|
||||
====================================
|
||||
|
||||
**[睡眠]**
|
||||
|
||||
等待队列用于等待某程序在条件为真时唤醒另一程序。必须小心使用,以确保没有竞争
|
||||
条件。先声明一个 :c:type:`wait_queue_head_t` ,然后对希望等待该条件的进程声明
|
||||
一个关于它们自己的 :c:type:`wait_queue_entry_t` ,并将其放入队列中。
|
||||
|
||||
声明
|
||||
-----
|
||||
|
||||
使用 :c:func:`DECLARE_WAIT_QUEUE_HEAD()` 宏声明一个 ``wait_queue_head_t`` ,
|
||||
或者在初始化代码中使用 :c:func:`init_waitqueue_head()` 程序。
|
||||
|
||||
排队
|
||||
-----
|
||||
|
||||
将自己放在等待队列中相当复杂,因为你必须在检查条件之前将自己放入队列中。有一
|
||||
个宏可以来执行此操作: :c:func:`wait_event_interruptible()`
|
||||
( ``include/linux/wait.h`` )第一个参数是等待队列头,第二个参数是计算的表达
|
||||
式;当该表达式为true时宏返回0,或者在接收到信号时返回 ``-ERESTARTSYS`` 。
|
||||
:c:func:`wait_event()` 版本会忽略信号。
|
||||
|
||||
唤醒排队任务
|
||||
-------------
|
||||
|
||||
调用 :c:func:`wake_up()` ( ``include/linux/wait.h`` ),它将唤醒队列中的所有
|
||||
进程。例外情况:如果有一个进程设置了 ``TASK_EXCLUSIVE`` ,队列的其余部分将不
|
||||
会被唤醒。这个基本函数的其他变体也可以在同一个头文件中使用。
|
||||
|
||||
原子操作
|
||||
=========
|
||||
|
||||
某些操作在所有平台上都有保证。第一类为操作 :c:type:`atomic_t`
|
||||
( ``include/asm/atomic.h`` )的函数;它包含一个有符号整数(至少32位长),
|
||||
您必须使用这些函数来操作或读取 :c:type:`atomic_t` 变量。
|
||||
:c:func:`atomic_read()` 和 :c:func:`atomic_set()` 获取并设置计数器,还有
|
||||
:c:func:`atomic_add()` ,:c:func:`atomic_sub()` ,:c:func:`atomic_inc()` ,
|
||||
:c:func:`atomic_dec()` 和 :c:func:`atomic_dec_and_test()` (如果递减为零,
|
||||
则返回true)。
|
||||
|
||||
是的。它在原子变量为零时返回true(即!=0)。
|
||||
|
||||
请注意,这些函数比普通的算术运算速度慢,因此不应过度使用。
|
||||
|
||||
第二类原子操作是在 ``unsigned long`` ( ``include/linux/bitops.h`` )上的
|
||||
原子位操作。这些操作通常采用指向位模式(bit pattern)的指针,第0位是最低有效
|
||||
位。:c:func:`set_bit()`,:c:func:`clear_bit()` 和 :c:func:`change_bit()` 设置、
|
||||
清除和更改给定位。:c:func:`test_and_set_bit()` ,:c:func:`test_and_clear_bit()`
|
||||
和 :c:func:`test_and_change_bit()` 执行相同的操作,但如果之前设置了位,则返回
|
||||
true;这些对于原子设置标志特别有用。
|
||||
|
||||
可以使用大于 ``BITS_PER_LONG`` 位的位索引调用这些操作。但结果在大端序平台上
|
||||
不太正常,所以最好不要这样做。
|
||||
|
||||
符号
|
||||
=====
|
||||
|
||||
在内核内部,正常的链接规则仍然适用(即除非用static关键字将符号声明为文件范围,
|
||||
否则它可以在内核中的任何位置使用)。但是对于模块,会保留一个特殊可导出符号表,
|
||||
该表将入口点限制为内核内部。模块也可以导出符号。
|
||||
|
||||
:c:func:`EXPORT_SYMBOL()`
|
||||
-------------------------
|
||||
|
||||
定义于 ``include/linux/export.h``
|
||||
|
||||
这是导出符号的经典方法:动态加载的模块将能够正常使用符号。
|
||||
|
||||
:c:func:`EXPORT_SYMBOL_GPL()`
|
||||
-----------------------------
|
||||
|
||||
定义于 ``include/linux/export.h``
|
||||
|
||||
|
||||
类似于 :c:func:`EXPORT_SYMBOL()`,只是 :c:func:`EXPORT_SYMBOL_GPL()` 导出的
|
||||
符号只能由具有由 :c:func:`MODULE_LICENSE()` 指定GPL兼容许可证的模块看到。这
|
||||
意味着此函数被认为是一个内部实现问题,而不是一个真正的接口。一些维护人员和
|
||||
开发人员在添加一些新的API或功能时可能却需要导出 EXPORT_SYMBOL_GPL()。
|
||||
|
||||
:c:func:`EXPORT_SYMBOL_NS()`
|
||||
----------------------------
|
||||
|
||||
定义于 ``include/linux/export.h``
|
||||
|
||||
这是 ``EXPORT_SYMBOL()`` 的变体,允许指定符号命名空间。符号名称空间记录于
|
||||
Documentation/core-api/symbol-namespaces.rst 。
|
||||
|
||||
:c:func:`EXPORT_SYMBOL_NS_GPL()`
|
||||
--------------------------------
|
||||
|
||||
定义于 ``include/linux/export.h``
|
||||
|
||||
这是 ``EXPORT_SYMBOL_GPL()`` 的变体,允许指定符号命名空间。符号名称空间记录于
|
||||
Documentation/core-api/symbol-namespaces.rst 。
|
||||
|
||||
程序与惯例
|
||||
===========
|
||||
|
||||
双向链表 ``include/linux/list.h``
|
||||
-----------------------------------
|
||||
|
||||
内核头文件中曾经有三组链表程序,但这一组是赢家。如果你对一个单链表没有特别迫切的
|
||||
需求,那么这是一个不错的选择。
|
||||
|
||||
通常 :c:func:`list_for_each_entry()` 很有用。
|
||||
|
||||
返回值惯例
|
||||
------------
|
||||
|
||||
对于在用户上下文中调用的代码,违背C语言惯例是很常见的,即返回0表示成功,返回
|
||||
负错误值(例如 ``-EFAULT`` )表示失败。这在一开始可能是不直观的,但在内核中
|
||||
相当普遍。
|
||||
|
||||
使用 :c:func:`ERR_PTR()` ( ``include/linux/err.h`` )将负错误值编码到指针中,
|
||||
然后使用 :c:func:`IS_ERR()` 和 :c:func:`PTR_ERR()` 将其再取出:避免为错误值
|
||||
使用单独的指针参数。挺讨厌的,但的确是个好方式。
|
||||
|
||||
破坏编译
|
||||
----------
|
||||
|
||||
Linus和其他开发人员有时会更改开发内核中的函数或结构体名称;这样做不仅是为了
|
||||
让每个人都保持警惕,还反映了一个重大的更改(例如,不能再在打开中断的情况下
|
||||
调用,或者执行额外的检查,或者不执行以前捕获的检查)。通常这会附带一个linux
|
||||
内核邮件列表中相当全面的注释;请搜索存档以查看。简单地对文件进行全局替换通常
|
||||
会让事情变得 **更糟** 。
|
||||
|
||||
初始化结构体成员
|
||||
------------------
|
||||
|
||||
初始化结构体的首选方法是使用指定的初始化器,如ISO C99所述。
|
||||
例如::
|
||||
|
||||
static struct block_device_operations opt_fops = {
|
||||
.open = opt_open,
|
||||
.release = opt_release,
|
||||
.ioctl = opt_ioctl,
|
||||
.check_media_change = opt_media_change,
|
||||
};
|
||||
|
||||
|
||||
这使得很容易查找(grep),并且可以清楚地看到设置了哪些结构字段。你应该这样做,
|
||||
因为它看起来很酷。
|
||||
|
||||
GNU 扩展
|
||||
----------
|
||||
|
||||
Linux内核中明确允许GNU扩展。请注意,由于缺乏通用性,一些更复杂的版本并没有
|
||||
得到很好的支持,但以下内容被认为是标准的(有关更多详细信息,请参阅GCC info页
|
||||
的“C 扩展”部分——是的,实际上是info页,手册页只是info中内容的简短摘要)。
|
||||
|
||||
- 内联函数
|
||||
|
||||
- 语句表达式(Statement expressions)(即({ 和 })结构)。
|
||||
|
||||
|
||||
- 声明函数/变量/类型的属性(__attribute__)
|
||||
|
||||
- typeof
|
||||
|
||||
- 零长度数组
|
||||
|
||||
- 宏变量
|
||||
|
||||
- 空指针运算
|
||||
|
||||
- 非常量(Non-Constant)初始化程序
|
||||
|
||||
- 汇编程序指令(在 arch/ 和 include/asm/ 之内)
|
||||
|
||||
- 字符串函数名(__func__)。
|
||||
|
||||
- __builtin_constant_p()
|
||||
|
||||
在内核中使用long long时要小心,gcc为其生成的代码非常糟糕:除法和乘法在i386上
|
||||
不能工作,因为内核环境中缺少用于它的gcc运行时函数。
|
||||
|
||||
C++
|
||||
---
|
||||
|
||||
在内核中使用C++通常是个坏主意,因为内核不提供必要的运行时环境,并且不为其
|
||||
测试包含文件。不过这仍然是可能的,但不建议。如果你真的想这么做,至少别用
|
||||
异常处理(exceptions)。
|
||||
|
||||
#if
|
||||
---
|
||||
|
||||
通常认为,在头文件(或.c文件顶部)中使用宏来抽象函数比在源代码中使用“if”预
|
||||
处理器语句更干净。
|
||||
|
||||
把你的东西放进内核里
|
||||
======================
|
||||
|
||||
为了让你的东西更正式、补丁更整洁,还有一些工作要做:
|
||||
|
||||
- 搞清楚你在谁的地界儿上干活。查看源文件的顶部、 ``MAINTAINERS`` 文件以及
|
||||
``CREDITS`` 文件的最后一部分。你应该和此人协调,确保你没有重新发明轮子,
|
||||
或者尝试一些已经被拒绝的东西。
|
||||
|
||||
确保你把你的名字和电子邮件地址放在你创建或修改的任何文件的顶部。当人们发
|
||||
现一个缺陷,或者想要做出修改时,这是他们首先会看的地方。
|
||||
|
||||
- 通常你需要一个配置选项来支持你的内核编程。在适当的目录中编辑 ``Kconfig`` 。
|
||||
配置语言很容易通过剪切和粘贴来使用,在
|
||||
Documentation/kbuild/kconfig-language.rst 中有完整的文档。
|
||||
|
||||
在您对选项的描述中,请确保同时照顾到了专家用户和对此功能一无所知的用户。
|
||||
在此说明任何不兼容和问题。结尾一定要写上“如有疑问,就选N”(或者是“Y”);
|
||||
这是针对那些看不懂你在说什么的人的。
|
||||
|
||||
- 编辑 ``Makefile`` :配置变量在这里导出,因此通常你只需添加一行
|
||||
“obj-$(CONFIG_xxx) += xxx.o”。语法记录在
|
||||
Documentation/kbuild/makefiles.rst 。
|
||||
|
||||
- 如果你做了一些有意义的事情,那可以把自己放进 ``CREDITS`` ,通常不止一个
|
||||
文件(无论如何你的名字都应该在源文件的顶部)。维护人员意味着您希望在对
|
||||
子系统进行更改时得到询问,并了解缺陷;这意味着对某部分代码做出更多承诺。
|
||||
|
||||
- 最后,别忘记去阅读 Documentation/process/submitting-patches.rst ,
|
||||
也许还有 Documentation/process/submitting-drivers.rst 。
|
||||
|
||||
Kernel 仙女棒
|
||||
===============
|
||||
|
||||
浏览源代码时的一些收藏。请随意添加到此列表。
|
||||
|
||||
``arch/x86/include/asm/delay.h``::
|
||||
|
||||
#define ndelay(n) (__builtin_constant_p(n) ? \
|
||||
((n) > 20000 ? __bad_ndelay() : __const_udelay((n) * 5ul)) : \
|
||||
__ndelay(n))
|
||||
|
||||
|
||||
``include/linux/fs.h``::
|
||||
|
||||
/*
|
||||
* Kernel pointers have redundant information, so we can use a
|
||||
* scheme where we can return either an error code or a dentry
|
||||
* pointer with the same return value.
|
||||
*
|
||||
* This should be a per-architecture thing, to allow different
|
||||
* error and pointer decisions.
|
||||
*/
|
||||
#define ERR_PTR(err) ((void *)((long)(err)))
|
||||
#define PTR_ERR(ptr) ((long)(ptr))
|
||||
#define IS_ERR(ptr) ((unsigned long)(ptr) > (unsigned long)(-1000))
|
||||
|
||||
``arch/x86/include/asm/uaccess_32.h:``::
|
||||
|
||||
#define copy_to_user(to,from,n) \
|
||||
(__builtin_constant_p(n) ? \
|
||||
__constant_copy_to_user((to),(from),(n)) : \
|
||||
__generic_copy_to_user((to),(from),(n)))
|
||||
|
||||
|
||||
``arch/sparc/kernel/head.S:``::
|
||||
|
||||
/*
|
||||
* Sun people can't spell worth damn. "compatibility" indeed.
|
||||
* At least we *know* we can't spell, and use a spell-checker.
|
||||
*/
|
||||
|
||||
/* Uh, actually Linus it is I who cannot spell. Too much murky
|
||||
* Sparc assembly will do this to ya.
|
||||
*/
|
||||
C_LABEL(cputypvar):
|
||||
.asciz "compatibility"
|
||||
|
||||
/* Tested on SS-5, SS-10. Probably someone at Sun applied a spell-checker. */
|
||||
.align 4
|
||||
C_LABEL(cputypvar_sun4m):
|
||||
.asciz "compatible"
|
||||
|
||||
|
||||
``arch/sparc/lib/checksum.S:``::
|
||||
|
||||
/* Sun, you just can't beat me, you just can't. Stop trying,
|
||||
* give up. I'm serious, I am going to kick the living shit
|
||||
* out of you, game over, lights out.
|
||||
*/
|
||||
|
||||
|
||||
致谢
|
||||
=====
|
||||
|
||||
感谢Andi Kleen提出点子,回答我的问题,纠正我的错误,充实内容等帮助。
|
||||
感谢Philipp Rumpf做了许多拼写和清晰度修复,以及一些优秀的不明显的点。
|
||||
感谢Werner Almesberger对 :c:func:`disable_irq()` 做了一个很好的总结,
|
||||
Jes Sorensen和Andrea Arcangeli补充了一些注意事项。
|
||||
感谢Michael Elizabeth Chastain检查并补充了配置部分。
|
||||
感谢Telsa Gwynne教我DocBook。
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue