mirror of
https://github.com/torvalds/linux.git
synced 2024-11-23 12:42:02 +00:00
Another moderately busy cycle in docsland:
- Work on Chinese translations has picked up again. Happily, they are maintaining the existing translations and not just adding new ones. - Some maintenance of the Japanese and Italian translations as well. - The removal of the venerable "dontdiff" file. It has long outlived its usefulness and contained entries ("parse.*") that would actively mask actual source change. - The addition of enforcement information to the code-of-conduct documentation. Along with some build-system fixes and a lot of typo and language fixes. -----BEGIN PGP SIGNATURE----- iQFDBAABCAAtFiEEIw+MvkEiF49krdp9F0NaE2wMflgFAmc7eD4PHGNvcmJldEBs d24ubmV0AAoJEBdDWhNsDH5YSp4H/2zknNZNhxAtWbF1L/MprjVgh5OtS0xEI8SR Klks8pHm9Dg5sg3EciJ9Jt7C3ZdPANOb7K4ykL2w2TKLgZbIMUa6FIqKbASqbryX 0t3nTn0gvkVMEtLlNLw4M1QIUox55fxLKUMV0MxcTAkvmFnG6XJl2gzGoL/SrI/h 19QDAKZZn2+S7Yow8MAdfef+ILu1Y9ms/4pumeUXHgVPJO7HDMCS85zQGU3tAB2n HgR4RRSXNsfXvW/rxx2YvGtJ3SZWnZM7NVbWcb25i8Wu/uBDOzoSW7uFRRad67cP d0MiHrB9RqltHGaJpEUisKLpTExd/GEZlTL+ILbXDROT+BHdLDQ= =ndvR -----END PGP SIGNATURE----- Merge tag 'docs-6.13' of git://git.lwn.net/linux Pull documentation updates from Jonathan Corbet: "Another moderately busy cycle in docsland: - Work on Chinese translations has picked up again. Happily, they are maintaining the existing translations and not just adding new ones. - Some maintenance of the Japanese and Italian translations as well. - The removal of the venerable "dontdiff" file. It has long outlived its usefulness and contained entries ("parse.*") that would actively mask actual source change. - The addition of enforcement information to the code-of-conduct documentation. Along with some build-system fixes and a lot of typo and language fixes" * tag 'docs-6.13' of git://git.lwn.net/linux: (52 commits) Documentation/CoC: spell out enforcement for unacceptable behaviors docs: fix typos and whitespace in Documentation/process/backporting.rst docs/zh_CN: fix one sentence in llvm.rst docs: bug-bisect: add a note about bisecting -next docs/zh_CN: add the translation of kbuild/llvm.rst Documentation: Fix incorrect paths/magic in magic numbers rst Documentation/maintainer-tip: Fix typos Documentation: Improve crash_kexec_post_notifiers description Docs/zh_CN: Translate physical_memory.rst to Simplified Chinese Documentation: admin: reorganize kernel-parameters intro docs/zh_CN: update the translation of process/programming-language.rst docs/zh_CN: update the translation of mm/page_owner.rst docs/zh_CN: update the translation of mm/page_table_check.rst docs/zh_CN: update the translation of mm/overcommit-accounting.rst docs/zh_CN: update the translation of mm/admon/faq.rst docs/zh_CN: update the translation of mm/active_mm.rst docs/zh_CN: update the translation of mm/hmm.rst docs: remove Documentation/dontdiff docs/zh_CN: Add a entry in Chinese glossary Docs/zh_CN: Fix the pfn calculation error in page_tables.rst ...
This commit is contained in:
commit
c3cda60e83
1
.mailmap
1
.mailmap
@ -730,6 +730,7 @@ Will Deacon <will@kernel.org> <will.deacon@arm.com>
|
||||
Wolfram Sang <wsa@kernel.org> <w.sang@pengutronix.de>
|
||||
Wolfram Sang <wsa@kernel.org> <wsa@the-dreams.de>
|
||||
Yakir Yang <kuankuan.y@gmail.com> <ykk@rock-chips.com>
|
||||
Yanteng Si <si.yanteng@linux.dev> <siyanteng@loongson.cn>
|
||||
Yusuke Goda <goda.yusuke@renesas.com>
|
||||
Zack Rusin <zack.rusin@broadcom.com> <zackr@vmware.com>
|
||||
Zhu Yanjun <zyjzyj2000@gmail.com> <yanjunz@nvidia.com>
|
||||
|
@ -108,6 +108,27 @@ a fully reliable and straight-forward way to reproduce the regression, too.*
|
||||
With that the process is complete. Now report the regression as described by
|
||||
Documentation/admin-guide/reporting-issues.rst.
|
||||
|
||||
Bisecting linux-next
|
||||
--------------------
|
||||
|
||||
If you face a problem only happening in linux-next, bisect between the
|
||||
linux-next branches 'stable' and 'master'. The following commands will start
|
||||
the process for a linux-next tree you added as a remote called 'next'::
|
||||
|
||||
git bisect start
|
||||
git bisect good next/stable
|
||||
git bisect bad next/master
|
||||
|
||||
The 'stable' branch refers to the state of linux-mainline that the current
|
||||
linux-next release (found in the 'master' branch) is based on -- the former
|
||||
thus should be free of any problems that show up in -next, but not in Linus'
|
||||
tree.
|
||||
|
||||
This will bisect across a wide range of changes, some of which you might have
|
||||
used in earlier linux-next releases without problems. Sadly there is no simple
|
||||
way to avoid checking them: bisecting from one linux-next release to a later
|
||||
one (say between 'next-20241020' and 'next-20241021') is impossible, as they
|
||||
share no common history.
|
||||
|
||||
Additional reading material
|
||||
---------------------------
|
||||
|
@ -27,6 +27,16 @@ kernel command line (/proc/cmdline) and collects module parameters
|
||||
when it loads a module, so the kernel command line can be used for
|
||||
loadable modules too.
|
||||
|
||||
This document may not be entirely up to date and comprehensive. The command
|
||||
"modinfo -p ${modulename}" shows a current list of all parameters of a loadable
|
||||
module. Loadable modules, after being loaded into the running kernel, also
|
||||
reveal their parameters in /sys/module/${modulename}/parameters/. Some of these
|
||||
parameters may be changed at runtime by the command
|
||||
``echo -n ${value} > /sys/module/${modulename}/parameters/${parm}``.
|
||||
|
||||
Special handling
|
||||
----------------
|
||||
|
||||
Hyphens (dashes) and underscores are equivalent in parameter names, so::
|
||||
|
||||
log_buf_len=1M print-fatal-signals=1
|
||||
@ -39,8 +49,8 @@ Double-quotes can be used to protect spaces in values, e.g.::
|
||||
|
||||
param="spaces in here"
|
||||
|
||||
cpu lists:
|
||||
----------
|
||||
cpu lists
|
||||
~~~~~~~~~
|
||||
|
||||
Some kernel parameters take a list of CPUs as a value, e.g. isolcpus,
|
||||
nohz_full, irqaffinity, rcu_nocbs. The format of this list is:
|
||||
@ -82,12 +92,17 @@ so that "nohz_full=all" is the equivalent of "nohz_full=0-N".
|
||||
The semantics of "N" and "all" is supported on a level of bitmaps and holds for
|
||||
all users of bitmap_parselist().
|
||||
|
||||
This document may not be entirely up to date and comprehensive. The command
|
||||
"modinfo -p ${modulename}" shows a current list of all parameters of a loadable
|
||||
module. Loadable modules, after being loaded into the running kernel, also
|
||||
reveal their parameters in /sys/module/${modulename}/parameters/. Some of these
|
||||
parameters may be changed at runtime by the command
|
||||
``echo -n ${value} > /sys/module/${modulename}/parameters/${parm}``.
|
||||
Metric suffixes
|
||||
~~~~~~~~~~~~~~~
|
||||
|
||||
The [KMG] suffix is commonly described after a number of kernel
|
||||
parameter values. 'K', 'M', 'G', 'T', 'P', and 'E' suffixes are allowed.
|
||||
These letters represent the _binary_ multipliers 'Kilo', 'Mega', 'Giga',
|
||||
'Tera', 'Peta', and 'Exa', equaling 2^10, 2^20, 2^30, 2^40, 2^50, and
|
||||
2^60 bytes respectively. Such letter suffixes can also be entirely omitted.
|
||||
|
||||
Kernel Build Options
|
||||
--------------------
|
||||
|
||||
The parameters listed below are only valid if certain kernel build options
|
||||
were enabled and if respective hardware is present. This list should be kept
|
||||
@ -211,10 +226,5 @@ a fixed number of characters. This limit depends on the architecture
|
||||
and is between 256 and 4096 characters. It is defined in the file
|
||||
./include/uapi/asm-generic/setup.h as COMMAND_LINE_SIZE.
|
||||
|
||||
Finally, the [KMG] suffix is commonly described after a number of kernel
|
||||
parameter values. These 'K', 'M', and 'G' letters represent the _binary_
|
||||
multipliers 'Kilo', 'Mega', and 'Giga', equaling 2^10, 2^20, and 2^30
|
||||
bytes respectively. Such letter suffixes can also be entirely omitted:
|
||||
|
||||
.. include:: kernel-parameters.txt
|
||||
:literal:
|
||||
|
@ -921,12 +921,16 @@
|
||||
the parameter has no effect.
|
||||
|
||||
crash_kexec_post_notifiers
|
||||
Run kdump after running panic-notifiers and dumping
|
||||
kmsg. This only for the users who doubt kdump always
|
||||
succeeds in any situation.
|
||||
Note that this also increases risks of kdump failure,
|
||||
because some panic notifiers can make the crashed
|
||||
kernel more unstable.
|
||||
Only jump to kdump kernel after running the panic
|
||||
notifiers and dumping kmsg. This option increases
|
||||
the risks of a kdump failure, since some panic
|
||||
notifiers can make the crashed kernel more unstable.
|
||||
In configurations where kdump may not be reliable,
|
||||
running the panic notifiers could allow collecting
|
||||
more data on dmesg, like stack traces from other CPUS
|
||||
or extra data dumped by panic_print. Note that some
|
||||
configurations enable this option unconditionally,
|
||||
like Hyper-V, PowerPC (fadump) and AMD SEV-SNP.
|
||||
|
||||
crashkernel=size[KMG][@offset[KMG]]
|
||||
[KNL,EARLY] Using kexec, Linux can switch to a 'crash kernel'
|
||||
@ -6882,6 +6886,12 @@
|
||||
|
||||
reserve_mem=12M:4096:trace trace_instance=boot_map^traceoff^traceprintk@trace,sched,irq
|
||||
|
||||
Note, saving the trace buffer across reboots does require that the system
|
||||
is set up to not wipe memory. For instance, CONFIG_RESET_ATTACK_MITIGATION
|
||||
can force a memory reset on boot which will clear any trace that was stored.
|
||||
This is just one of many ways that can clear memory. Make sure your system
|
||||
keeps the content of memory across reboots before relying on this option.
|
||||
|
||||
See also Documentation/trace/debugging.rst
|
||||
|
||||
|
||||
|
@ -616,7 +616,7 @@ ONLINE section for notifications on online and offline operation::
|
||||
....
|
||||
cpuhp_remove_instance(state, &inst2->node);
|
||||
....
|
||||
remove_multi_state(state);
|
||||
cpuhp_remove_multi_state(state);
|
||||
|
||||
|
||||
Testing of hotplug states
|
||||
|
@ -295,9 +295,9 @@ slot set.
|
||||
|
||||
Fourth, the io_tlb_slot array keeps track of any "padding slots" allocated to
|
||||
meet alloc_align_mask requirements described above. When
|
||||
swiotlb_tlb_map_single() allocates bounce buffer space to meet alloc_align_mask
|
||||
swiotlb_tbl_map_single() allocates bounce buffer space to meet alloc_align_mask
|
||||
requirements, it may allocate pre-padding space across zero or more slots. But
|
||||
when swiotbl_tlb_unmap_single() is called with the bounce buffer address, the
|
||||
when swiotlb_tbl_unmap_single() is called with the bounce buffer address, the
|
||||
alloc_align_mask value that governed the allocation, and therefore the
|
||||
allocation of any padding slots, is not known. The "pad_slots" field records
|
||||
the number of padding slots so that swiotlb_tbl_unmap_single() can free them.
|
||||
|
@ -23,7 +23,7 @@ Possible uses:
|
||||
associated code is never run?)
|
||||
|
||||
.. _gcov: https://gcc.gnu.org/onlinedocs/gcc/Gcov.html
|
||||
.. _lcov: http://ltp.sourceforge.net/coverage/lcov.php
|
||||
.. _lcov: https://github.com/linux-test-project/lcov
|
||||
|
||||
|
||||
Preparation
|
||||
|
@ -75,11 +75,11 @@ supports it for the architecture you are using, you can use hardware
|
||||
breakpoints if you desire to run with the ``CONFIG_STRICT_KERNEL_RWX``
|
||||
option turned on, else you need to turn off this option.
|
||||
|
||||
Next you should choose one of more I/O drivers to interconnect debugging
|
||||
Next you should choose one or more I/O drivers to interconnect the debugging
|
||||
host and debugged target. Early boot debugging requires a KGDB I/O
|
||||
driver that supports early debugging and the driver must be built into
|
||||
the kernel directly. Kgdb I/O driver configuration takes place via
|
||||
kernel or module parameters which you can learn more about in the in the
|
||||
kernel or module parameters which you can learn more about in the
|
||||
section that describes the parameter kgdboc.
|
||||
|
||||
Here is an example set of ``.config`` symbols to enable or disable for kgdb::
|
||||
@ -201,8 +201,8 @@ Using loadable module or built-in
|
||||
Configure kgdboc at runtime with sysfs
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
At run time you can enable or disable kgdboc by echoing a parameters
|
||||
into the sysfs. Here are two examples:
|
||||
At run time you can enable or disable kgdboc by writing parameters
|
||||
into sysfs. Here are two examples:
|
||||
|
||||
1. Enable kgdboc on ttyS0::
|
||||
|
||||
@ -329,7 +329,7 @@ ways to activate this feature.
|
||||
|
||||
2. Use sysfs before configuring an I/O driver::
|
||||
|
||||
echo 1 > /sys/module/kgdb/parameters/kgdb_use_con
|
||||
echo 1 > /sys/module/debug_core/parameters/kgdb_use_con
|
||||
|
||||
.. note::
|
||||
|
||||
@ -374,10 +374,10 @@ default behavior is always set to 0.
|
||||
Kernel parameter: ``nokaslr``
|
||||
-----------------------------
|
||||
|
||||
If the architecture that you are using enable KASLR by default,
|
||||
If the architecture that you are using enables KASLR by default,
|
||||
you should consider turning it off. KASLR randomizes the
|
||||
virtual address where the kernel image is mapped and confuse
|
||||
gdb which resolve kernel symbol address from symbol table
|
||||
virtual address where the kernel image is mapped and confuses
|
||||
gdb which resolves addresses of kernel symbols from the symbol table
|
||||
of vmlinux.
|
||||
|
||||
Using kdb
|
||||
@ -631,8 +631,6 @@ automatically changes into kgdb mode.
|
||||
|
||||
kgdb
|
||||
|
||||
Now disconnect your terminal program and connect gdb in its place
|
||||
|
||||
2. At the kdb prompt, disconnect the terminal program and connect gdb in
|
||||
its place.
|
||||
|
||||
@ -749,7 +747,7 @@ The kernel debugger is organized into a number of components:
|
||||
helper functions in some of the other kernel components to make it
|
||||
possible for kdb to examine and report information about the kernel
|
||||
without taking locks that could cause a kernel deadlock. The kdb core
|
||||
contains implements the following functionality.
|
||||
implements the following functionality.
|
||||
|
||||
- A simple shell
|
||||
|
||||
|
@ -133,7 +133,7 @@ KMSAN shadow memory
|
||||
-------------------
|
||||
|
||||
KMSAN associates a metadata byte (also called shadow byte) with every byte of
|
||||
kernel memory. A bit in the shadow byte is set iff the corresponding bit of the
|
||||
kernel memory. A bit in the shadow byte is set if the corresponding bit of the
|
||||
kernel memory byte is uninitialized. Marking the memory uninitialized (i.e.
|
||||
setting its shadow bytes to ``0xff``) is called poisoning, marking it
|
||||
initialized (setting the shadow bytes to ``0x00``) is called unpoisoning.
|
||||
|
@ -1,271 +0,0 @@
|
||||
*.a
|
||||
*.aux
|
||||
*.bc
|
||||
*.bin
|
||||
*.bz2
|
||||
*.c.[012]*.*
|
||||
*.cis
|
||||
*.cpio
|
||||
*.csp
|
||||
*.dsp
|
||||
*.dvi
|
||||
*.elf
|
||||
*.eps
|
||||
*.fw
|
||||
*.gcno
|
||||
*.gcov
|
||||
*.gen.S
|
||||
*.gif
|
||||
*.grep
|
||||
*.grp
|
||||
*.gz
|
||||
*.html
|
||||
*.i
|
||||
*.jpeg
|
||||
*.ko
|
||||
*.ll
|
||||
*.log
|
||||
*.lst
|
||||
*.lzma
|
||||
*.lzo
|
||||
*.mo
|
||||
*.moc
|
||||
*.mod
|
||||
*.mod.c
|
||||
*.o
|
||||
*.o.*
|
||||
*.order
|
||||
*.orig
|
||||
*.out
|
||||
*.patch
|
||||
*.pdf
|
||||
*.plist
|
||||
*.png
|
||||
*.pot
|
||||
*.ps
|
||||
*.rej
|
||||
*.s
|
||||
*.sgml
|
||||
*.so
|
||||
*.so.dbg
|
||||
*.symtypes
|
||||
*.tab.c
|
||||
*.tab.h
|
||||
*.tex
|
||||
*.ver
|
||||
*.xml
|
||||
*.xz
|
||||
*.zst
|
||||
*_MODULES
|
||||
*_vga16.c
|
||||
*~
|
||||
\#*#
|
||||
*.9
|
||||
.*
|
||||
.*.d
|
||||
.mm
|
||||
53c700_d.h
|
||||
CVS
|
||||
ChangeSet
|
||||
GPATH
|
||||
GRTAGS
|
||||
GSYMS
|
||||
GTAGS
|
||||
Image
|
||||
Module.markers
|
||||
Module.symvers
|
||||
PENDING
|
||||
SCCS
|
||||
System.map*
|
||||
TAGS
|
||||
aconf
|
||||
af_names.h
|
||||
aic7*reg.h*
|
||||
aic7*reg_print.c*
|
||||
aic7*seq.h*
|
||||
aicasm
|
||||
aicdb.h*
|
||||
altivec*.c
|
||||
asm-offsets.h
|
||||
asm_offsets.h
|
||||
autoconf.h*
|
||||
av_permissions.h
|
||||
bbootsect
|
||||
binkernel.spec
|
||||
bootsect
|
||||
bounds.h
|
||||
bsetup
|
||||
btfixupprep
|
||||
build
|
||||
bvmlinux
|
||||
bzImage*
|
||||
capability_names.h
|
||||
capflags.c
|
||||
classlist.h*
|
||||
comp*.log
|
||||
compile.h*
|
||||
conf
|
||||
config
|
||||
config-*
|
||||
config.mak
|
||||
config.mak.autogen
|
||||
conmakehash
|
||||
consolemap_deftbl.c*
|
||||
cpustr.h
|
||||
crc32table.h*
|
||||
cscope.*
|
||||
defkeymap.c
|
||||
devlist.h*
|
||||
devicetable-offsets.h
|
||||
dnotify_test
|
||||
dslm
|
||||
dtc
|
||||
elf2ecoff
|
||||
elfconfig.h*
|
||||
evergreen_reg_safe.h
|
||||
fixdep
|
||||
flask.h
|
||||
fore200e_mkfirm
|
||||
fore200e_pca_fw.c*
|
||||
gconf
|
||||
gconf-cfg
|
||||
gen-devlist
|
||||
gen_crc32table
|
||||
gen_init_cpio
|
||||
generated
|
||||
genheaders
|
||||
genksyms
|
||||
*_gray256.c
|
||||
hpet_example
|
||||
hugepage-mmap
|
||||
hugepage-shm
|
||||
ihex2fw
|
||||
inat-tables.c
|
||||
initramfs_list
|
||||
int16.c
|
||||
int1.c
|
||||
int2.c
|
||||
int32.c
|
||||
int4.c
|
||||
int8.c
|
||||
kallsyms
|
||||
keywords.c
|
||||
ksym.c*
|
||||
ksym.h*
|
||||
*lex.c
|
||||
*lex.*.c
|
||||
linux
|
||||
logo_*.c
|
||||
logo_*_clut224.c
|
||||
logo_*_mono.c
|
||||
mach-types
|
||||
mach-types.h
|
||||
machtypes.h
|
||||
map
|
||||
map_hugetlb
|
||||
mconf
|
||||
mconf-cfg
|
||||
miboot*
|
||||
mk_elfconfig
|
||||
mkboot
|
||||
mkbugboot
|
||||
mkcpustr
|
||||
mkdep
|
||||
mkprep
|
||||
mkregtable
|
||||
mktables
|
||||
mktree
|
||||
mkutf8data
|
||||
modpost
|
||||
modules-only.symvers
|
||||
modules.builtin
|
||||
modules.builtin.modinfo
|
||||
modules.builtin.ranges
|
||||
modules.nsdeps
|
||||
modules.order
|
||||
modversions.h*
|
||||
nconf
|
||||
nconf-cfg
|
||||
ncscope.*
|
||||
offset.h
|
||||
oui.c*
|
||||
page-types
|
||||
parse.c
|
||||
parse.h
|
||||
patches*
|
||||
pca200e.bin
|
||||
pca200e_ecd.bin2
|
||||
perf.data
|
||||
perf.data.old
|
||||
perf-archive
|
||||
piggyback
|
||||
piggy.gzip
|
||||
piggy.S
|
||||
pnmtologo
|
||||
ppc_defs.h*
|
||||
pss_boot.h
|
||||
qconf
|
||||
qconf-cfg
|
||||
r100_reg_safe.h
|
||||
r200_reg_safe.h
|
||||
r300_reg_safe.h
|
||||
r420_reg_safe.h
|
||||
r600_reg_safe.h
|
||||
randstruct.seed
|
||||
randomize_layout_hash.h
|
||||
randomize_layout_seed.h
|
||||
recordmcount
|
||||
relocs
|
||||
rlim_names.h
|
||||
rn50_reg_safe.h
|
||||
rs600_reg_safe.h
|
||||
rv515_reg_safe.h
|
||||
series
|
||||
setup
|
||||
setup.bin
|
||||
setup.elf
|
||||
sortextable
|
||||
sImage
|
||||
sm_tbl*
|
||||
split-include
|
||||
syscalltab.h
|
||||
tables.c
|
||||
tags
|
||||
test_get_len
|
||||
tftpboot.img
|
||||
timeconst.h
|
||||
times.h*
|
||||
trix_boot.h
|
||||
utsrelease.h*
|
||||
vdso-syms.lds
|
||||
vdso.lds
|
||||
vdso32-int80-syms.lds
|
||||
vdso32-syms.lds
|
||||
vdso32-syscall-syms.lds
|
||||
vdso32-sysenter-syms.lds
|
||||
vdso32.lds
|
||||
vdso32.so.dbg
|
||||
vdso64.lds
|
||||
vdso64.so.dbg
|
||||
version.h*
|
||||
vmImage
|
||||
vmlinux
|
||||
vmlinux-*
|
||||
vmlinux.aout
|
||||
vmlinux.bin.all
|
||||
vmlinux.lds
|
||||
vmlinux.map
|
||||
vmlinux.symvers
|
||||
vmlinuz
|
||||
voffset.h
|
||||
vsyscall.lds
|
||||
vsyscall_32.lds
|
||||
wanxlfw.inc
|
||||
uImage
|
||||
unifdef
|
||||
utf8data.c
|
||||
wakeup.bin
|
||||
wakeup.elf
|
||||
wakeup.lds
|
||||
zImage*
|
||||
zoffset.h
|
@ -196,9 +196,9 @@ the hotspot switches to a new place.
|
||||
|
||||
Miscellaneous
|
||||
=============
|
||||
One open issue is that kernel has an optional data structure
|
||||
One open issue is that the kernel has an optional data structure
|
||||
randomization mechanism, which also randomizes the situation of cache
|
||||
line sharing of data members.
|
||||
line sharing among data members.
|
||||
|
||||
|
||||
.. [1] https://en.wikipedia.org/wiki/False_sharing
|
||||
|
@ -50,7 +50,7 @@ so outline what is contained here, why it should be merged, and what, if
|
||||
any, testing has been done. All of this information will end up in the tag
|
||||
itself, and then in the merge commit that the maintainer makes if/when they
|
||||
merge the pull request. So write it up well, as it will be in the kernel
|
||||
tree for forever.
|
||||
tree forever.
|
||||
|
||||
As said by Linus::
|
||||
|
||||
|
@ -29,7 +29,7 @@ address.
|
||||
With a page granularity of 4KB and a address range of 32 bits, pfn 0 is at
|
||||
address 0x00000000, pfn 1 is at address 0x00001000, pfn 2 is at 0x00002000
|
||||
and so on until we reach pfn 0xfffff at 0xfffff000. With 16KB pages pfs are
|
||||
at 0x00004000, 0x00008000 ... 0xffffc000 and pfn goes from 0 to 0x3fffff.
|
||||
at 0x00004000, 0x00008000 ... 0xffffc000 and pfn goes from 0 to 0x3ffff.
|
||||
|
||||
As you can see, with 4KB pages the page base address uses bits 12-31 of the
|
||||
address, and this is why `PAGE_SHIFT` in this case is defined as 12 and
|
||||
|
@ -191,11 +191,6 @@ change to a revision control system. It will be followed by:
|
||||
option to diff will associate function names with changes, making the
|
||||
resulting patch easier for others to read.
|
||||
|
||||
You should avoid including changes to irrelevant files (those generated by
|
||||
the build process, for example, or editor backup files) in the patch. The
|
||||
file "dontdiff" in the Documentation directory can help in this regard;
|
||||
pass it to diff with the "-X" option.
|
||||
|
||||
The tags already briefly mentioned above are used to provide insights how
|
||||
the patch came into being. They are described in detail in the
|
||||
:ref:`Documentation/process/submitting-patches.rst <submittingpatches>`
|
||||
|
@ -74,7 +74,7 @@ your source tree. Don't forget to cherry-pick with ``-x`` if you want a
|
||||
written record of where the patch came from!
|
||||
|
||||
Note that if you are submitting a patch for stable, the format is
|
||||
slightly different; the first line after the subject line needs tobe
|
||||
slightly different; the first line after the subject line needs to be
|
||||
either::
|
||||
|
||||
commit <upstream commit> upstream
|
||||
@ -553,7 +553,7 @@ Submitting backports to stable
|
||||
==============================
|
||||
|
||||
As the stable maintainers try to cherry-pick mainline fixes onto their
|
||||
stable kernels, they may send out emails asking for backports when when
|
||||
stable kernels, they may send out emails asking for backports when
|
||||
encountering conflicts, see e.g.
|
||||
<https://lore.kernel.org/stable/2023101528-jawed-shelving-071a@gregkh/>.
|
||||
These emails typically include the exact steps you need to cherry-pick
|
||||
@ -563,9 +563,9 @@ One thing to make sure is that your changelog conforms to the expected
|
||||
format::
|
||||
|
||||
<original patch title>
|
||||
|
||||
|
||||
[ Upstream commit <mainline rev> ]
|
||||
|
||||
|
||||
<rest of the original changelog>
|
||||
[ <summary of the conflicts and their resolutions> ]
|
||||
Signed-off-by: <your name and email>
|
||||
|
@ -46,7 +46,7 @@ jfsutils 1.1.3 fsck.jfs -V
|
||||
reiserfsprogs 3.6.3 reiserfsck -V
|
||||
xfsprogs 2.6.0 xfs_db -V
|
||||
squashfs-tools 4.0 mksquashfs -version
|
||||
btrfs-progs 0.18 btrfsck
|
||||
btrfs-progs 0.18 btrfs --version
|
||||
pcmciautils 004 pccardctl -V
|
||||
quota-tools 3.09 quota -V
|
||||
PPP 2.4.0 pppd --version
|
||||
|
@ -156,3 +156,90 @@ overridden decisions including complete and identifiable voting details.
|
||||
Because how we interpret and enforce the Code of Conduct will evolve over
|
||||
time, this document will be updated when necessary to reflect any
|
||||
changes.
|
||||
|
||||
Enforcement for Unacceptable Behavior Code of Conduct Violations
|
||||
----------------------------------------------------------------
|
||||
|
||||
The Code of Conduct committee works to ensure that our community continues
|
||||
to be inclusive and fosters diverse discussions and viewpoints, and works
|
||||
to improve those characteristics over time. A majority of the reports the
|
||||
Code of Conduct Committee receives stem from incorrect understanding regarding
|
||||
the development process and maintainers' roles, responsibilities, and their
|
||||
right to make decisions on code acceptance. These are resolved through
|
||||
clarification of the development process and the scope of the Code of Conduct.
|
||||
|
||||
Unacceptable behaviors could interrupt respectful collaboration for a short
|
||||
period of time and negatively impact the health of the community longer term.
|
||||
Unacceptable behaviors often get resolved when individuals acknowledge their
|
||||
behavior and make amends for it in the setting the violation has taken place.
|
||||
|
||||
The Code of Conduct Committee receives reports about unacceptable behaviors
|
||||
when they don't get resolved through community discussions. The Code of
|
||||
Conduct committee takes measures to restore productive and respectful
|
||||
collaboration when an unacceptable behavior has negatively impacted that
|
||||
relationship.
|
||||
|
||||
The Code of Conduct Committee has the obligation to keep the reports and
|
||||
reporters' information private. Reports could come from injured parties
|
||||
and community members who are observers of unacceptable behaviors. The
|
||||
Code of Conduct Committee has the responsibility to investigate and resolve
|
||||
these reports, working with all involved parties.
|
||||
|
||||
The Code of Conduct Committee works with the individual to bring about
|
||||
change in their understanding of the importance to repair the damage caused
|
||||
by their behavior to the injured party and the long term negative impact
|
||||
on the community.
|
||||
|
||||
The goal is to reach a resolution which is agreeable to all parties. If
|
||||
working with the individual fails to bring about the desired outcome, the
|
||||
Code of Conduct Committee will evaluate other measures such as seeking
|
||||
public apology to repair the damage.
|
||||
|
||||
Seek public apology for the violation
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The Code of Conduct Committee publicly calls out the behavior in the
|
||||
setting in which the violation has taken place, seeking public apology
|
||||
for the violation.
|
||||
|
||||
A public apology for the violation is the first step towards rebuilding
|
||||
the trust. Trust is essential for the continued success and health of the
|
||||
community which operates on trust and respect.
|
||||
|
||||
Remedial measures if there is no public apology for the violation
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The Code of Conduct Committee determines the next course of action to restore
|
||||
the healthy collaboration by recommending remedial measure(s) to the TAB for
|
||||
approval.
|
||||
|
||||
- Ban violator from participating in the kernel development process for
|
||||
a period of up to a full kernel development cycle. The Code of Conduct
|
||||
Committee could require public apology as a condition for lifting the
|
||||
ban.
|
||||
|
||||
The scope of the ban for a period of time could include:
|
||||
|
||||
a. denying patch contributions and pull requests
|
||||
b. pausing collaboration with the violator by ignoring their
|
||||
contributions and/or blocking their email account(s)
|
||||
c. restricting their ability to communicate via kernel.org platforms,
|
||||
such as mailing lists and social media sites
|
||||
|
||||
Once the TAB approves one or more of the measures outlined in the scope of
|
||||
the ban by a two-thirds vote, the Code of Conduct Committee will enforce
|
||||
the TAB approved measure(s) in collaboration with the community, maintainers,
|
||||
sub-maintainers, and kernel.org administrators.
|
||||
|
||||
The Code of Conduct Committee is mindful of the negative impact of seeking
|
||||
public apology and instituting ban could have on individuals. It is also
|
||||
mindful of the longer term harm to the community that could result from
|
||||
not taking action when such serious public violations occur.
|
||||
|
||||
The effectiveness of the remedial measure(s) approved by the TAB depends
|
||||
on the trust and cooperation from the community, maintainers, sub-maintainers,
|
||||
and kernel.org administrators in enforcing them.
|
||||
|
||||
The Code of Conduct Committee sincerely hopes that unacceptable behaviors
|
||||
that require seeking public apologies continue to be exceedingly rare
|
||||
occurrences in the future.
|
||||
|
@ -72,17 +72,6 @@ On-line docs
|
||||
programming. Lots of examples. Currently the new version is being
|
||||
actively maintained at https://github.com/sysprog21/lkmpg.
|
||||
|
||||
* Title: **Rust for Linux**
|
||||
|
||||
:Author: various
|
||||
:URL: https://rust-for-linux.com/
|
||||
:Date: rolling version
|
||||
:Keywords: glossary, terms, linux-kernel.
|
||||
:Description: From the website: "Rust for Linux is the project adding
|
||||
support for the Rust language to the Linux kernel. This website is
|
||||
intended as a hub of links, documentation and resources related to
|
||||
the project".
|
||||
|
||||
Published books
|
||||
---------------
|
||||
|
||||
@ -220,6 +209,158 @@ Miscellaneous
|
||||
other original research and content related to Linux and software
|
||||
development.
|
||||
|
||||
Rust
|
||||
----
|
||||
|
||||
* Title: **Rust for Linux**
|
||||
|
||||
:Author: various
|
||||
:URL: https://rust-for-linux.com/
|
||||
:Date: rolling version
|
||||
:Keywords: glossary, terms, linux-kernel, rust.
|
||||
:Description: From the website: "Rust for Linux is the project adding
|
||||
support for the Rust language to the Linux kernel. This website is
|
||||
intended as a hub of links, documentation and resources related to
|
||||
the project".
|
||||
|
||||
* Title: **Learn Rust the Dangerous Way**
|
||||
|
||||
:Author: Cliff L. Biffle
|
||||
:URL: https://cliffle.com/p/dangerust/
|
||||
:Date: Accessed Sep 11 2024
|
||||
:Keywords: rust, blog.
|
||||
:Description: From the website: "LRtDW is a series of articles
|
||||
putting Rust features in context for low-level C programmers who
|
||||
maybe don’t have a formal CS background — the sort of people who
|
||||
work on firmware, game engines, OS kernels, and the like.
|
||||
Basically, people like me.". It illustrates line-by-line
|
||||
conversions from C to Rust.
|
||||
|
||||
* Title: **The Rust Book**
|
||||
|
||||
:Author: Steve Klabnik and Carol Nichols, with contributions from the
|
||||
Rust community
|
||||
:URL: https://doc.rust-lang.org/book/
|
||||
:Date: Accessed Sep 11 2024
|
||||
:Keywords: rust, book.
|
||||
:Description: From the website: "This book fully embraces the
|
||||
potential of Rust to empower its users. It’s a friendly and
|
||||
approachable text intended to help you level up not just your
|
||||
knowledge of Rust, but also your reach and confidence as a
|
||||
programmer in general. So dive in, get ready to learn—and welcome
|
||||
to the Rust community!".
|
||||
|
||||
* Title: **Rust for the Polyglot Programmer**
|
||||
|
||||
:Author: Ian Jackson
|
||||
:URL: https://www.chiark.greenend.org.uk/~ianmdlvl/rust-polyglot/index.html
|
||||
:Date: December 2022
|
||||
:Keywords: rust, blog, tooling.
|
||||
:Description: From the website: "There are many guides and
|
||||
introductions to Rust. This one is something different: it is
|
||||
intended for the experienced programmer who already knows many
|
||||
other programming languages. I try to be comprehensive enough to be
|
||||
a starting point for any area of Rust, but to avoid going into too
|
||||
much detail except where things are not as you might expect. Also
|
||||
this guide is not entirely free of opinion, including
|
||||
recommendations of libraries (crates), tooling, etc.".
|
||||
|
||||
* Title: **Fasterthanli.me**
|
||||
|
||||
:Author: Amos Wenger
|
||||
:URL: https://fasterthanli.me/
|
||||
:Date: Accessed Sep 11 2024
|
||||
:Keywords: rust, blog, news.
|
||||
:Description: From the website: "I make articles and videos about how
|
||||
computers work. My content is long-form, didactic and exploratory
|
||||
— and often an excuse to teach Rust!".
|
||||
|
||||
* Title: **Comprehensive Rust**
|
||||
|
||||
:Author: Android team at Google
|
||||
:URL: https://google.github.io/comprehensive-rust/
|
||||
:Date: Accessed Sep 13 2024
|
||||
:Keywords: rust, blog.
|
||||
:Description: From the website: "The course covers the full spectrum
|
||||
of Rust, from basic syntax to advanced topics like generics and
|
||||
error handling".
|
||||
|
||||
* Title: **The Embedded Rust Book**
|
||||
|
||||
:Author: Multiple contributors, mostly Jorge Aparicio
|
||||
:URL: https://docs.rust-embedded.org/book/
|
||||
:Date: Accessed Sep 13 2024
|
||||
:Keywords: rust, blog.
|
||||
:Description: From the website: "An introductory book about using
|
||||
the Rust Programming Language on "Bare Metal" embedded systems,
|
||||
such as Microcontrollers".
|
||||
|
||||
* Title: **Experiment: Improving the Rust Book**
|
||||
|
||||
:Author: Cognitive Engineering Lab at Brown University
|
||||
:URL: https://rust-book.cs.brown.edu/
|
||||
:Date: Accessed Sep 22 2024
|
||||
:Keywords: rust, blog.
|
||||
:Description: From the website: "The goal of this experiment is to
|
||||
evaluate and improve the content of the Rust Book to help people
|
||||
learn Rust more effectively.".
|
||||
|
||||
* Title: **New Rustacean** (podcast)
|
||||
|
||||
:Author: Chris Krycho
|
||||
:URL: https://newrustacean.com/
|
||||
:Date: Accessed Sep 22 2024
|
||||
:Keywords: rust, podcast.
|
||||
:Description: From the website: "This is a podcast about learning
|
||||
the programming language Rust—from scratch! Apart from this spiffy
|
||||
landing page, all the site content is built with Rust's own
|
||||
documentation tools.".
|
||||
|
||||
* Title: **Opsem-team** (repository)
|
||||
|
||||
:Author: Operational semantics team
|
||||
:URL: https://github.com/rust-lang/opsem-team/tree/main
|
||||
:Date: Accessed Sep 22 2024
|
||||
:Keywords: rust, repository.
|
||||
:Description: From the README: "The opsem team is the successor of
|
||||
the unsafe-code-guidelines working group and responsible for
|
||||
answering many of the difficult questions about the semantics of
|
||||
unsafe Rust".
|
||||
|
||||
* Title: **You Can't Spell Trust Without Rust**
|
||||
|
||||
:Author: Alexis Beingessner
|
||||
:URL: https://repository.library.carleton.ca/downloads/1j92g820w?locale=en
|
||||
:Date: 2015
|
||||
:Keywords: rust, master, thesis.
|
||||
:Description: This thesis focuses on Rust's ownership system, which
|
||||
ensures memory safety by controlling data manipulation and
|
||||
lifetime, while also highlighting its limitations and comparing it
|
||||
to similar systems in Cyclone and C++.
|
||||
|
||||
* Name: **Linux Plumbers (LPC) 2024 Rust presentations**
|
||||
|
||||
:Title: Rust microconference
|
||||
:URL: https://lpc.events/event/18/sessions/186/#20240918
|
||||
:Title: Rust for Linux
|
||||
:URL: https://lpc.events/event/18/contributions/1912/
|
||||
:Title: Journey of a C kernel engineer starting a Rust driver project
|
||||
:URL: https://lpc.events/event/18/contributions/1911/
|
||||
:Title: Crafting a Linux kernel scheduler that runs in user-space
|
||||
using Rust
|
||||
:URL: https://lpc.events/event/18/contributions/1723/
|
||||
:Title: openHCL: A Linux and Rust based paravisor
|
||||
:URL: https://lpc.events/event/18/contributions/1956/
|
||||
:Keywords: rust, lpc, presentations.
|
||||
:Description: A number of LPC talks related to Rust.
|
||||
|
||||
* Name: **The Rustacean Station Podcast**
|
||||
|
||||
:URL: https://rustacean-station.org/
|
||||
:Keywords: rust, podcasts.
|
||||
:Description: A community project for creating podcast content for
|
||||
the Rust programming language.
|
||||
|
||||
-------
|
||||
|
||||
This document was originally based on:
|
||||
|
@ -7,7 +7,7 @@ What is the tip tree?
|
||||
---------------------
|
||||
|
||||
The tip tree is a collection of several subsystems and areas of
|
||||
development. The tip tree is both a direct development tree and a
|
||||
development. The tip tree is both a direct development tree and an
|
||||
aggregation tree for several sub-maintainer trees. The tip tree gitweb URL
|
||||
is: https://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git
|
||||
|
||||
@ -121,7 +121,7 @@ The tip tree preferred format for patch subject prefixes is
|
||||
prefix. 'git log path/to/file' should give you a reasonable hint in most
|
||||
cases.
|
||||
|
||||
The condensed patch description in the subject line should start with a
|
||||
The condensed patch description in the subject line should start with an
|
||||
uppercase letter and should be written in imperative tone.
|
||||
|
||||
|
||||
|
@ -56,6 +56,9 @@ more details.
|
||||
arch-support
|
||||
testing
|
||||
|
||||
You can also find learning materials for Rust in its section in
|
||||
:doc:`../process/kernel-docs`.
|
||||
|
||||
.. only:: subproject and html
|
||||
|
||||
Indices
|
||||
|
@ -68,11 +68,11 @@ Changelog::
|
||||
===================== ================ ======================== ==========================================
|
||||
Magic Name Number Structure File
|
||||
===================== ================ ======================== ==========================================
|
||||
PG_MAGIC 'P' pg_{read,write}_hdr ``include/linux/pg.h``
|
||||
PG_MAGIC 'P' pg_{read,write}_hdr ``include/uapi/linux/pg.h``
|
||||
APM_BIOS_MAGIC 0x4101 apm_user ``arch/x86/kernel/apm_32.c``
|
||||
FASYNC_MAGIC 0x4601 fasync_struct ``include/linux/fs.h``
|
||||
SLIP_MAGIC 0x5302 slip ``drivers/net/slip.h``
|
||||
BAYCOM_MAGIC 0x19730510 baycom_state ``drivers/net/baycom_epp.c``
|
||||
SLIP_MAGIC 0x5302 slip ``drivers/net/slip/slip.h``
|
||||
BAYCOM_MAGIC 19730510 baycom_state ``drivers/net/hamradio/baycom_epp.c``
|
||||
HDLCDRV_MAGIC 0x5ac6e778 hdlcdrv_state ``include/linux/hdlcdrv.h``
|
||||
KV_MAGIC 0x5f4b565f kernel_vars_s ``arch/mips/include/asm/sn/klkernvars.h``
|
||||
CODA_MAGIC 0xC0DAC0DA coda_file_info ``fs/coda/coda_fs_i.h``
|
||||
|
@ -81,7 +81,7 @@ Documentation written by Tom Zanussi
|
||||
.usecs display a common_timestamp in microseconds
|
||||
.percent display a number of percentage value
|
||||
.graph display a bar-graph of a value
|
||||
.stacktrace display as a stacktrace (must by a long[] type)
|
||||
.stacktrace display as a stacktrace (must be a long[] type)
|
||||
============= =================================================
|
||||
|
||||
Note that in general the semantics of a given field aren't
|
||||
|
@ -24,6 +24,7 @@ Linux Tracing Technologies
|
||||
histogram
|
||||
histogram-design
|
||||
boottime-trace
|
||||
debugging
|
||||
hwlat_detector
|
||||
osnoise-tracer
|
||||
timerlat-tracer
|
||||
|
17
Documentation/translations/it_IT/dev-tools/index.rst
Normal file
17
Documentation/translations/it_IT/dev-tools/index.rst
Normal file
@ -0,0 +1,17 @@
|
||||
.. include:: ../disclaimer-ita.rst
|
||||
|
||||
:Original: Documentation/dev-tools/index.rst
|
||||
|
||||
===================================
|
||||
Strumenti di sviluppo per il kernel
|
||||
===================================
|
||||
|
||||
Qui raccogliamo i vari documenti riguardanti gli strumenti di sviluppo che
|
||||
possono essere usati per lavorare col kernel . Per ora, questa è una raccolta
|
||||
senza un particolare struttura; si accettano patch!
|
||||
|
||||
.. toctree::
|
||||
:caption: Tabella dei contenuti
|
||||
:maxdepth: 2
|
||||
|
||||
clang-format
|
@ -3,21 +3,17 @@ Introduzione a I2C e SMBus
|
||||
==========================
|
||||
|
||||
I²C (letteralmente "I al quadrato C" e scritto I2C nella documentazione del
|
||||
kernel) è un protocollo sviluppato da Philips. É un protocollo lento a 2 fili
|
||||
(a velocità variabile, al massimo 400KHz), con un'estensione per le velocità
|
||||
elevate (3.4 MHz). Questo protocollo offre un bus a basso costo per collegare
|
||||
dispositivi di vario genere a cui si accede sporadicamente e utilizzando
|
||||
poca banda. Alcuni sistemi usano varianti che non rispettano i requisiti
|
||||
originali, per cui non sono indicati come I2C, ma hanno nomi diversi, per
|
||||
esempio TWI (Interfaccia a due fili), IIC.
|
||||
kernel) è un protocollo sviluppato da Philips. É un protocollo a 2 fili (a
|
||||
velocità variabile, solitamente fino a 400KHz, e in modalità alta velocità fino
|
||||
a 5 MHz). Questo protocollo offre un bus a basso costo per collegare dispositivi
|
||||
di vario genere a cui si accede sporadicamente e utilizzando poca banda. I2C è
|
||||
ampiamente usato nei sistemi integrati. Alcuni sistemi usano varianti che non
|
||||
rispettano i requisiti originali, per cui non sono indicati come I2C, ma hanno
|
||||
nomi diversi, per esempio TWI (Interfaccia a due fili), IIC.
|
||||
|
||||
L'ultima specifica ufficiale I2C è la `"Specifica I2C-bus e manuale utente"
|
||||
(UM10204) <https://www.nxp.com/webapp/Download?colCode=UM10204>`_
|
||||
pubblicata da NXP Semiconductors. Tuttavia, è necessario effettuare il login
|
||||
al sito per accedere al PDF. Una versione precedente della specifica
|
||||
(revisione 6) è archiviata
|
||||
`qui <https://web.archive.org/web/20210813122132/
|
||||
https://www.nxp.com/docs/en/user-guide/UM10204.pdf>`_.
|
||||
(UM10204) <https://www.nxp.com/docs/en/user-guide/UM10204.pdf>`_ pubblicata da
|
||||
NXP Semiconductors, al momento della scrittura si tratta della versione 7
|
||||
|
||||
SMBus (Bus per la gestione del sistema) si basa sul protocollo I2C ed è
|
||||
principalmente un sottoinsieme di protocolli e segnali I2C. Molti dispositivi
|
||||
@ -27,38 +23,62 @@ SMBus. I più comuni dispositivi collegati tramite SMBus sono moduli RAM
|
||||
configurati utilizzando EEPROM I2C, e circuiti integrati di monitoraggio
|
||||
hardware.
|
||||
|
||||
Poiché SMBus è principalmente un sottoinsieme del bus I2C,
|
||||
possiamo farne uso su molti sistemi I2C. Ci sono però sistemi che non
|
||||
soddisfano i vincoli elettrici sia di SMBus che di I2C; e altri che non possono
|
||||
implementare tutta la semantica o messaggi comuni del protocollo SMBus.
|
||||
Poiché SMBus è principalmente un sottoinsieme del bus I2C, possiamo farne uso su
|
||||
molti sistemi I2C. Ci sono però sistemi che non soddisfano i vincoli elettrici
|
||||
sia di SMBus che di I2C; e altri che non possono implementare tutta la semantica
|
||||
o messaggi comuni del protocollo SMBus.
|
||||
|
||||
|
||||
Terminologia
|
||||
============
|
||||
|
||||
Utilizzando la terminologia della documentazione ufficiale, il bus I2C connette
|
||||
uno o più circuiti integrati *master* e uno o più circuiti integrati *slave*.
|
||||
Il bus I2C connette uno o più circuiti integrati controllori a dei dispositivi.
|
||||
|
||||
.. kernel-figure:: ../../../i2c/i2c_bus.svg
|
||||
:alt: Un semplice bus I2C con un master e 3 slave
|
||||
:alt: Un semplice bus I2C con un controllore e 3 dispositivi
|
||||
|
||||
Un semplice Bus I2C
|
||||
|
||||
Un circuito integrato **master** è un nodo che inizia le comunicazioni con gli
|
||||
slave. Nell'implementazione del kernel Linux è chiamato **adattatore** o bus. I
|
||||
driver degli adattatori si trovano nella sottocartella ``drivers/i2c/busses/``.
|
||||
Un circuito integrato **controllore** (*controller*) è un nodo che inizia le
|
||||
comunicazioni con i dispositivi (*targets*). Nell'implementazione del kernel
|
||||
Linux è chiamato **adattatore** o bus. I driver degli adattatori si trovano
|
||||
nella sottocartella ``drivers/i2c/busses/``.
|
||||
|
||||
Un **algoritmo** contiene codice generico che può essere utilizzato per
|
||||
implementare una intera classe di adattatori I2C. Ciascun driver dell'
|
||||
adattatore specifico dipende da un driver dell'algoritmo nella sottocartella
|
||||
``drivers/i2c/algos/`` o include la propria implementazione.
|
||||
|
||||
Un circuito integrato **slave** è un nodo che risponde alle comunicazioni
|
||||
quando indirizzato dal master. In Linux è chiamato **client** (dispositivo). I
|
||||
driver dei dispositivi sono contenuti in una cartella specifica per la
|
||||
Un circuito integrato **dispositivo** è un nodo che risponde alle comunicazioni
|
||||
quando indirizzato dal controllore. In Linux è chiamato **client**. Nonostante i
|
||||
dispositivi siano circuiti integrati esterni al sistema, Linux può agire come
|
||||
dispositivo (se l'hardware lo permette) e rispondere alla richieste di altri
|
||||
controllori sul bus. Questo verrà chiamato **dispositivo locale** (*local
|
||||
target*). Negli altri casi si parla di **dispositivo remoto** (*remote target*).
|
||||
|
||||
I driver dei dispositivi sono contenuti in una cartella specifica per la
|
||||
funzionalità che forniscono, ad esempio ``drivers/media/gpio/`` per espansori
|
||||
GPIO e ``drivers/media/i2c/`` per circuiti integrati relativi ai video.
|
||||
|
||||
Per la configurazione di esempio in figura, avrai bisogno di un driver per il
|
||||
tuo adattatore I2C e driver per i tuoi dispositivi I2C (solitamente un driver
|
||||
per ciascuno dispositivo).
|
||||
|
||||
Sinonimi
|
||||
--------
|
||||
|
||||
Come menzionato precedentemente, per ragioni storiche l'implementazione I2C del
|
||||
kernel Linux usa "adatattore" (*adapter*) per i controllori e "client" per i
|
||||
dispositivi. Un certo numero di strutture dati usano questi sinonimi nei loro
|
||||
nomi. Dunque, durante le discussioni riguardanti l'implementazione dovrete
|
||||
essere a coscienza anche di questi termini. Tuttavia si preferiscono i termini
|
||||
ufficiali.
|
||||
|
||||
Terminologia obsoleta
|
||||
---------------------
|
||||
|
||||
Nelle prime specifiche di I2C, il controllore veniva chiamato "master" ed i
|
||||
dispositivi "slave". Questi termini sono stati resi obsoleti con la versione 7
|
||||
della specifica. Inoltre, il loro uso viene scoraggiato dal codice di condotta
|
||||
del kernel Linux. Tuttavia, potreste ancora trovare questi termini in pagine non
|
||||
aggiornate. In generale si cerca di usare i termini controllore e dispositivo.
|
||||
|
@ -103,9 +103,11 @@ sviluppatori del kernel.
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
process/license-rules
|
||||
doc-guide/index
|
||||
kernel-hacking/index
|
||||
Regole sulle licenze <process/license-rules>
|
||||
Scrivere la documentazione <doc-guide/index>
|
||||
Strumenti di sviluppo <dev-tools/index>
|
||||
La guida all'*hacking*<kernel-hacking/index>
|
||||
|
||||
|
||||
Documentazione per gli utenti
|
||||
=============================
|
||||
|
@ -424,10 +424,10 @@ o entrambi.
|
||||
Molte delle liste di discussione del Kernel girano su vger.kernel.org;
|
||||
l'elenco principale lo si trova sul sito:
|
||||
|
||||
http://vger.kernel.org/vger-lists.html
|
||||
https://subspace.kernel.org
|
||||
|
||||
Esistono liste gestite altrove; un certo numero di queste sono in
|
||||
redhat.com/mailman/listinfo.
|
||||
Tuttavia, esistono liste gestite altrove; controllare il file MAINTAINERS per
|
||||
trovare la lista relativa ad un sottosistema specifico.
|
||||
|
||||
La lista di discussione principale per lo sviluppo del kernel è, ovviamente,
|
||||
linux-kernel. Questa lista è un luogo ostile dove trovarsi; i volumi possono
|
||||
|
@ -69,7 +69,7 @@ e per revisionare interi file per individuare errori nello stile di codifica,
|
||||
refusi e possibili miglioramenti. Inoltre è utile anche per classificare gli
|
||||
``#includes``, per allineare variabili/macro, per testi derivati ed altri
|
||||
compiti del genere. Consultate il file
|
||||
:ref:`Documentation/translations/it_IT/process/clang-format.rst <clangformat>`
|
||||
:ref:`Documentation/translations/it_IT/dev-tools/clang-format.rst <clangformat>`
|
||||
per maggiori dettagli
|
||||
|
||||
Se utilizzate un programma compatibile con EditorConfig, allora alcune
|
||||
|
@ -208,11 +208,6 @@ di commit in un sistema di controllo di versione. Sarà seguito da:
|
||||
l'opzione "-p" assocerà alla modifica il nome della funzione alla quale
|
||||
si riferisce, rendendo il risultato più facile da leggere per gli altri.
|
||||
|
||||
Dovreste evitare di includere nelle patch delle modifiche per file
|
||||
irrilevanti (quelli generati dal processo di generazione, per esempio, o i file
|
||||
di backup del vostro editor). Il file "dontdiff" nella cartella Documentation
|
||||
potrà esservi d'aiuto su questo punto; passatelo a diff con l'opzione "-X".
|
||||
|
||||
Le etichette sopracitate danno un'idea di come una patch prende vita e sono
|
||||
descritte nel dettaglio nel documento
|
||||
:ref:`Documentation/translations/it_IT/process/submitting-patches.rst <it_submittingpatches>`.
|
||||
|
@ -34,9 +34,9 @@ PC Card, per esempio, probabilmente non dovreste preoccuparvi di pcmciautils.
|
||||
====================== ================= ========================================
|
||||
GNU C 5.1 gcc --version
|
||||
Clang/LLVM (optional) 13.0.0 clang --version
|
||||
Rust (opzionale) 1.76.0 rustc --version
|
||||
Rust (opzionale) 1.78.0 rustc --version
|
||||
bindgen (opzionale) 0.65.1 bindgen --version
|
||||
GNU make 3.81 make --version
|
||||
GNU make 4.0 make --version
|
||||
bash 4.2 bash --version
|
||||
binutils 2.25 ld -v
|
||||
flex 2.5.35 flex --version
|
||||
@ -65,6 +65,8 @@ Sphinx\ [#f1]_ 2.4.4 sphinx-build --version
|
||||
cpio any cpio --version
|
||||
GNU tar 1.28 tar --version
|
||||
gtags (opzionale) 6.6.5 gtags --version
|
||||
mkimage (opzionale) 2017.01 mkimage --version
|
||||
Python (opzionale) 3.5.x python3 --version
|
||||
====================== ================= ========================================
|
||||
|
||||
.. [#f1] Sphinx è necessario solo per produrre la documentazione del Kernel
|
||||
@ -88,10 +90,25 @@ potremmo rimuovere gli espedienti che abbiamo implementato per farli
|
||||
funzionare. Per maggiori informazioni
|
||||
:ref:`Building Linux with Clang/LLVM <kbuild_llvm>`.
|
||||
|
||||
Rust (opzionale)
|
||||
----------------
|
||||
|
||||
È necessaria una versione recente del compilatore Rust.
|
||||
|
||||
Verificate le istruzioni Documentation/rust/quick-start.rst su come soddisfare i
|
||||
requisiti per compilare code Rust. In particolare, la regola ``rustavailable``
|
||||
nel ``Makefile`` è utile per verificare perché gli strumenti di compilazione non
|
||||
vengono trovati.
|
||||
|
||||
bindgen (opzionale)
|
||||
-------------------
|
||||
|
||||
``bindgen`` viene usato per generare il collegamento (binding) da Rust al lato C del kernel. Dipende da ``libclang``.
|
||||
|
||||
Make
|
||||
----
|
||||
|
||||
Per compilare il kernel vi servirà GNU make 3.81 o successivo.
|
||||
Per compilare il kernel vi servirà GNU make 4.0 o successivo.
|
||||
|
||||
Bash
|
||||
----
|
||||
@ -168,6 +185,16 @@ Il programma GNU GLOBAL versione 6.6.5, o successiva, è necessario quando si
|
||||
vuole eseguire ``make gtags`` e generare i relativi indici. Internamente si fa
|
||||
uso del parametro gtags ``-C (--directory)`` che compare in questa versione.
|
||||
|
||||
mkimage
|
||||
-------
|
||||
|
||||
Questo strumento viene usato per produrre un *Flat Image Tree* (FIT),
|
||||
tipicamente usato su sistemi ARM. Questo strumento è disponibile tramite il
|
||||
pacchetto ``u-boot-tools`` oppure può essere compilato dal codice sorgente di
|
||||
U-Boot. Consultate le istruzioni
|
||||
https://docs.u-boot.org/en/latest/build/tools.html#building-tools-for-linux
|
||||
|
||||
|
||||
Strumenti di sistema
|
||||
********************
|
||||
|
||||
|
@ -620,18 +620,6 @@ Lo stile preferito per i commenti più lunghi (multi-riga) è:
|
||||
* with beginning and ending almost-blank lines.
|
||||
*/
|
||||
|
||||
Per i file in net/ e in drivers/net/ lo stile preferito per i commenti
|
||||
più lunghi (multi-riga) è leggermente diverso.
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
/* The preferred comment style for files in net/ and drivers/net
|
||||
* looks like this.
|
||||
*
|
||||
* It is nearly the same as the generally preferred comment style,
|
||||
* but there is no initial almost-blank line.
|
||||
*/
|
||||
|
||||
È anche importante commentare i dati, sia per i tipi base che per tipi
|
||||
derivati. A questo scopo, dichiarate un dato per riga (niente virgole
|
||||
per una dichiarazione multipla). Questo vi lascerà spazio per un piccolo
|
||||
@ -726,7 +714,7 @@ di stile, refusi e possibilmente anche delle migliorie. È anche utile per
|
||||
ordinare gli ``#include``, per allineare variabili/macro, per ridistribuire
|
||||
il testo e altre cose simili.
|
||||
Per maggiori dettagli, consultate il file
|
||||
:ref:`Documentation/translations/it_IT/process/clang-format.rst <it_clangformat>`.
|
||||
:ref:`Documentation/translations/it_IT/dev-tools/clang-format.rst <it_clangformat>`.
|
||||
|
||||
Se utilizzate un programma compatibile con EditorConfig, allora alcune
|
||||
configurazioni basilari come l'indentazione e la fine delle righe verranno
|
||||
@ -827,6 +815,29 @@ blocco do - while:
|
||||
do_this(b, c); \
|
||||
} while (0)
|
||||
|
||||
Le macro che sembrano funzioni con parametri non usati dovrebbero essere
|
||||
sostituite da funzioni inline per evitare il problema.
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
static inline void fun(struct foo *foo)
|
||||
{
|
||||
}
|
||||
|
||||
Per motivi storici, molti file usano ancora l'approccio "cast a (void)" per
|
||||
valutare i parametri. Tuttavia, non è raccomandato. Le funzioni inline risolvono
|
||||
i problemi di "espressioni con effetti avversi valutate più di una volta",
|
||||
variabili non utilizzate, e in genere per qualche motivo sono documentate
|
||||
meglio.
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
/*
|
||||
* Avoid doing this whenever possible and instead opt for static
|
||||
* inline functions
|
||||
*/
|
||||
#define macrofun(foo) do { (void) (foo); } while (0)
|
||||
|
||||
Cose da evitare quando si usano le macro:
|
||||
|
||||
1) le macro che hanno effetti sul flusso del codice:
|
||||
|
@ -228,7 +228,7 @@ Mutt è molto personalizzabile. Qui di seguito trovate la configurazione minima
|
||||
per iniziare ad usare Mutt per inviare patch usando Gmail::
|
||||
|
||||
# .muttrc
|
||||
# ================ IMAP ====================
|
||||
# ================ IMAP ====================
|
||||
set imap_user = 'yourusername@gmail.com'
|
||||
set imap_pass = 'yourpassword'
|
||||
set spoolfile = imaps://imap.gmail.com/INBOX
|
||||
@ -365,27 +365,12 @@ un editor esterno.
|
||||
Un altro problema è che Gmail usa la codifica base64 per tutti quei messaggi
|
||||
che contengono caratteri non ASCII. Questo include cose tipo i nomi europei.
|
||||
|
||||
Proton Mail
|
||||
***********
|
||||
HacKerMaiL (TUI)
|
||||
****************
|
||||
|
||||
Il servizio Proton Mail ha una funzionalità che cripta tutti i messaggi verso
|
||||
ogni destinatario per cui è possibile trovare una chiave usando il *Web Key
|
||||
Directory* (WKD). Il servizio kernel.org pubblica il WKD per ogni sviluppatore
|
||||
in possesso di un conto kernel.org. Di conseguenza, tutti i messaggi inviati
|
||||
usando Proton Mail verso indirizzi kernel.org verranno criptati.
|
||||
|
||||
Proton Mail non fornisce alcun meccanismo per disabilitare questa funzionalità
|
||||
perché verrebbe considerato un problema per la riservatezza. Questa funzionalità
|
||||
è attiva anche quando si inviano messaggi usando il Proton Mail Bridge. Dunque
|
||||
tutta la posta in uscita verrà criptata, incluse le patch inviate con ``git
|
||||
send-email``.
|
||||
|
||||
I messaggi criptati sono una fonte di problemi; altri sviluppatori potrebbero
|
||||
non aver configurato i loro programmi, o strumenti, per gestire messaggi
|
||||
criptati; inoltre, alcuni programmi di posta elettronica potrebbero criptare le
|
||||
risposte a messaggi criptati per tutti i partecipanti alla discussione, inclusa
|
||||
la lista di discussione stessa.
|
||||
|
||||
A meno che non venga introdotta una maniera per disabilitare questa
|
||||
funzionalità, non è consigliato usare Proton Mail per contribuire allo sviluppo
|
||||
del kernel.
|
||||
HacKerMaiL (hkml) è una semplice casella pubblica per la gestione dei messaggi
|
||||
di posta che non richiede alcuna sottoscrizione ad una lista di discussione.
|
||||
Viene sviluppato e mantenuto dal manutentore di DAMON e si pone come obiettivo
|
||||
quello di gestire il processo di sviluppo semplice come quello di DAMON e più in
|
||||
generale i sottosistemi del kernel. Per maggiori dettagli, fate riferimento al
|
||||
documento README (https://github.com/sjp38/hackermail/blob/master/README.md).
|
||||
|
@ -344,7 +344,7 @@ principale 4.x, sarà necessario un test d'integrazione.
|
||||
A tale scopo, esiste un repositorio speciale di test nel quale virtualmente
|
||||
tutti i rami dei sottosistemi vengono inclusi su base quotidiana:
|
||||
|
||||
https://git.kernel.org/?p=linux/kernel/git/next/linux-next.git
|
||||
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
|
||||
|
||||
In questo modo, i kernel -next offrono uno sguardo riassuntivo su quello che
|
||||
ci si aspetterà essere nel kernel principale nel successivo periodo
|
||||
@ -389,12 +389,12 @@ sviluppatori del kernel partecipano alla lista di discussione Linux Kernel.
|
||||
I dettagli su come iscriversi e disiscriversi dalla lista possono essere
|
||||
trovati al sito:
|
||||
|
||||
http://vger.kernel.org/vger-lists.html#linux-kernel
|
||||
https://subspace.kernel.org/subscribing.html
|
||||
|
||||
Ci sono diversi archivi della lista di discussione. Usate un qualsiasi motore
|
||||
di ricerca per trovarli. Per esempio:
|
||||
|
||||
https://lore.kernel.org/lkml/
|
||||
https://lore.kernel.org/linux-kernel/
|
||||
|
||||
É caldamente consigliata una ricerca in questi archivi sul tema che volete
|
||||
sollevare, prima di pubblicarlo sulla lista. Molte cose sono già state
|
||||
@ -407,13 +407,13 @@ discussione e il loro uso.
|
||||
Molte di queste liste sono gestite su kernel.org. Per informazioni consultate
|
||||
la seguente pagina:
|
||||
|
||||
http://vger.kernel.org/vger-lists.html
|
||||
https://subspace.kernel.org
|
||||
|
||||
Per favore ricordatevi della buona educazione quando utilizzate queste liste.
|
||||
Sebbene sia un pò dozzinale, il seguente URL contiene alcune semplici linee
|
||||
guida per interagire con la lista (o con qualsiasi altra lista):
|
||||
|
||||
http://www.albion.com/netiquette/
|
||||
https://subspace.kernel.org/etiquette.html
|
||||
|
||||
Se diverse persone rispondo alla vostra mail, la lista dei riceventi (copia
|
||||
conoscenza) potrebbe diventare abbastanza lunga. Non cancellate nessuno dalla
|
||||
|
@ -99,16 +99,6 @@ degli sviluppatori:
|
||||
|
||||
kernel-docs
|
||||
|
||||
Ed infine, qui ci sono alcune guide più tecniche che son state messe qua solo
|
||||
perché non si è trovato un posto migliore.
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
magic-number
|
||||
clang-format
|
||||
../arch/riscv/patch-acceptance
|
||||
|
||||
.. only:: subproject and html
|
||||
|
||||
Indices
|
||||
|
@ -5,8 +5,9 @@
|
||||
|
||||
.. _it_submitchecklist:
|
||||
|
||||
============================================================================
|
||||
Lista delle verifiche da fare prima di inviare una patch per il kernel Linux
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
============================================================================
|
||||
|
||||
Qui troverete una lista di cose che uno sviluppatore dovrebbe fare per
|
||||
vedere le proprie patch accettate più rapidamente.
|
||||
@ -15,11 +16,74 @@ Tutti questi punti integrano la documentazione fornita riguardo alla
|
||||
sottomissione delle patch, in particolare
|
||||
:ref:`Documentation/translations/it_IT/process/submitting-patches.rst <it_submittingpatches>`.
|
||||
|
||||
Revisiona il tuo codice
|
||||
=======================
|
||||
|
||||
1) Se state usando delle funzionalità del kernel allora includete (#include)
|
||||
i file che le dichiarano/definiscono. Non dipendente dal fatto che un file
|
||||
d'intestazione include anche quelli usati da voi.
|
||||
|
||||
2) Compilazione pulita:
|
||||
2) Controllate lo stile del codice della vostra patch secondo le direttive
|
||||
scritte in :ref:`Documentation/translations/it_IT/process/coding-style.rst <it_codingstyle>`.
|
||||
|
||||
3) 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é.
|
||||
|
||||
Revisionate i cambiamenti a Kconfig
|
||||
===================================
|
||||
|
||||
1) Le opzioni ``CONFIG``, nuove o modificate, non scombussolano il menu
|
||||
di configurazione e sono preimpostate come disabilitate a meno che non
|
||||
soddisfino i criteri descritti in ``Documentation/kbuild/kconfig-language.rst``
|
||||
alla punto "Voci di menu: valori predefiniti".
|
||||
|
||||
2) Tutte le nuove opzioni ``Kconfig`` hanno un messaggio di aiuto.
|
||||
|
||||
3) La patch è stata accuratamente revisionata rispetto alle più importanti
|
||||
configurazioni ``Kconfig``. Questo è molto difficile da fare
|
||||
correttamente - un buono lavoro di testa sarà utile.
|
||||
|
||||
Fornite documentazione
|
||||
======================
|
||||
|
||||
1) Includete :ref:`kernel-doc <kernel_doc>` per documentare API globali del
|
||||
kernel.
|
||||
|
||||
2) Tutti i nuovi elementi in ``/proc`` sono documentati in ``Documentation/``.
|
||||
|
||||
3) Tutti i nuovi parametri d'avvio del kernel sono documentati in
|
||||
``Documentation/admin-guide/kernel-parameters.rst``.
|
||||
|
||||
4) Tutti i nuovi parametri dei moduli sono documentati con ``MODULE_PARM_DESC()``.
|
||||
|
||||
5) Tutte le nuove interfacce verso lo spazio utente sono documentate in
|
||||
``Documentation/ABI/``. Leggete ``Documentation/ABI/README`` per maggiori
|
||||
informazioni. Le patch che modificano le interfacce utente dovrebbero
|
||||
essere inviate in copia anche a linux-api@vger.kernel.org.
|
||||
|
||||
6) Se la patch aggiunge nuove chiamate ioctl, allora aggiornate
|
||||
``Documentation/userspace-api/ioctl/ioctl-number.rst``.
|
||||
|
||||
Verificate il vostro codice con gli strumenti
|
||||
=============================================
|
||||
|
||||
1) Prima dell'invio della patch, usate il verificatore di stile
|
||||
(``script/checkpatch.pl``) per scovare le violazioni più semplici.
|
||||
Dovreste essere in grado di giustificare tutte le violazioni rimanenti nella
|
||||
vostra patch.
|
||||
|
||||
2) Verificare il codice con sparse.
|
||||
|
||||
|
||||
3) Usare ``make checkstack`` e correggere tutti i problemi rilevati. Da notare
|
||||
che ``checkstack`` non evidenzia esplicitamente i problemi, ma una funzione
|
||||
che usa più di 512 byte sullo stack è una buona candidata per una correzione.
|
||||
|
||||
Compilare il codice
|
||||
===================
|
||||
|
||||
1) Compilazione pulita:
|
||||
|
||||
a) con le opzioni ``CONFIG`` negli stati ``=y``, ``=m`` e ``=n``. Nessun
|
||||
avviso/errore di ``gcc`` e nessun avviso/errore dal linker.
|
||||
@ -32,101 +96,46 @@ sottomissione delle patch, in particolare
|
||||
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.
|
||||
2) Compilare per diverse architetture di processore usando strumenti per la
|
||||
cross-compilazione o altri. Una buona architettura per la verifica della
|
||||
cross-compilazione è la ppc64 perché tende ad usare ``unsigned long`` per le
|
||||
quantità a 64-bit.
|
||||
|
||||
4) Una buona architettura per la verifica della cross-compilazione è la ppc64
|
||||
perché tende ad usare ``unsigned long`` per le quantità a 64-bit.
|
||||
|
||||
5) Controllate lo stile del codice della vostra patch secondo le direttive
|
||||
scritte in :ref:`Documentation/translations/it_IT/process/coding-style.rst <it_codingstyle>`.
|
||||
Prima dell'invio della patch, usate il verificatore di stile
|
||||
(``script/checkpatch.pl``) per scovare le violazioni più semplici.
|
||||
Dovreste essere in grado di giustificare tutte le violazioni rimanenti nella
|
||||
vostra patch.
|
||||
|
||||
6) Le opzioni ``CONFIG``, nuove o modificate, non scombussolano il menu
|
||||
di configurazione e sono preimpostate come disabilitate a meno che non
|
||||
soddisfino i criteri descritti in ``Documentation/kbuild/kconfig-language.rst``
|
||||
alla punto "Voci di menu: valori predefiniti".
|
||||
|
||||
7) Tutte le nuove opzioni ``Kconfig`` hanno un messaggio di aiuto.
|
||||
|
||||
8) La patch è stata accuratamente revisionata rispetto alle più importanti
|
||||
configurazioni ``Kconfig``. Questo è molto difficile da fare
|
||||
correttamente - un buono lavoro di testa sarà utile.
|
||||
|
||||
9) Verificare con sparse.
|
||||
|
||||
10) Usare ``make checkstack`` e correggere tutti i problemi rilevati.
|
||||
|
||||
.. note::
|
||||
|
||||
``checkstack`` non evidenzia esplicitamente i problemi, ma una funzione
|
||||
che usa più di 512 byte sullo stack è una buona candidata per una
|
||||
correzione.
|
||||
|
||||
11) Includete commenti :ref:`kernel-doc <kernel_doc>` per documentare API
|
||||
globali del kernel. Usate ``make htmldocs`` o ``make pdfdocs`` per
|
||||
verificare i commenti :ref:`kernel-doc <kernel_doc>` ed eventualmente
|
||||
correggerli.
|
||||
|
||||
12) La patch è stata verificata con le seguenti opzioni abilitate
|
||||
contemporaneamente: ``CONFIG_PREEMPT``, ``CONFIG_DEBUG_PREEMPT``,
|
||||
``CONFIG_DEBUG_SLAB``, ``CONFIG_DEBUG_PAGEALLOC``, ``CONFIG_DEBUG_MUTEXES``,
|
||||
``CONFIG_DEBUG_SPINLOCK``, ``CONFIG_DEBUG_ATOMIC_SLEEP``,
|
||||
``CONFIG_PROVE_RCU`` e ``CONFIG_DEBUG_OBJECTS_RCU_HEAD``.
|
||||
|
||||
13) La patch è stata compilata e verificata in esecuzione con, e senza,
|
||||
le opzioni ``CONFIG_SMP`` e ``CONFIG_PREEMPT``.
|
||||
|
||||
14) Se la patch ha effetti sull'IO dei dischi, eccetera: allora dev'essere
|
||||
verificata con, e senza, l'opzione ``CONFIG_LBDAF``.
|
||||
|
||||
15) Tutti i percorsi del codice sono stati verificati con tutte le funzionalità
|
||||
di lockdep abilitate.
|
||||
|
||||
16) Tutti i nuovi elementi in ``/proc`` sono documentati in ``Documentation/``.
|
||||
|
||||
17) Tutti i nuovi parametri d'avvio del kernel sono documentati in
|
||||
``Documentation/admin-guide/kernel-parameters.rst``.
|
||||
|
||||
18) Tutti i nuovi parametri dei moduli sono documentati con ``MODULE_PARM_DESC()``.
|
||||
|
||||
19) Tutte le nuove interfacce verso lo spazio utente sono documentate in
|
||||
``Documentation/ABI/``. Leggete ``Documentation/ABI/README`` per maggiori
|
||||
informazioni. Le patch che modificano le interfacce utente dovrebbero
|
||||
essere inviate in copia anche a linux-api@vger.kernel.org.
|
||||
|
||||
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.
|
||||
|
||||
21) Il nuovo codice è stato compilato con ``gcc -W`` (usate
|
||||
3) 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".
|
||||
|
||||
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.
|
||||
4) 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
|
||||
possibilità) [non tutti contemporaneamente, solo diverse combinazioni
|
||||
casuali]:
|
||||
|
||||
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é.
|
||||
``CONFIG_SMP``, ``CONFIG_SYSFS``, ``CONFIG_PROC_FS``, ``CONFIG_INPUT``,
|
||||
``CONFIG_PCI``, ``CONFIG_BLOCK``, ``CONFIG_PM``, ``CONFIG_MAGIC_SYSRQ``,
|
||||
``CONFIG_NET``, ``CONFIG_INET=n`` (ma l'ultimo con ``CONFIG_NET=y``).
|
||||
|
||||
24) Se la patch aggiunge nuove chiamate ioctl, allora aggiornate
|
||||
``Documentation/userspace-api/ioctl/ioctl-number.rst``.
|
||||
Verificate il vostro codice
|
||||
===========================
|
||||
|
||||
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
|
||||
possibilità) [non tutti contemporaneamente, solo diverse combinazioni
|
||||
casuali]:
|
||||
1) La patch è stata verificata con le seguenti opzioni abilitate
|
||||
contemporaneamente: ``CONFIG_PREEMPT``, ``CONFIG_DEBUG_PREEMPT``,
|
||||
``CONFIG_DEBUG_SLAB``, ``CONFIG_DEBUG_PAGEALLOC``, ``CONFIG_DEBUG_MUTEXES``,
|
||||
``CONFIG_DEBUG_SPINLOCK``, ``CONFIG_DEBUG_ATOMIC_SLEEP``,
|
||||
``CONFIG_PROVE_RCU`` e ``CONFIG_DEBUG_OBJECTS_RCU_HEAD``.
|
||||
|
||||
``CONFIG_SMP``, ``CONFIG_SYSFS``, ``CONFIG_PROC_FS``, ``CONFIG_INPUT``,
|
||||
``CONFIG_PCI``, ``CONFIG_BLOCK``, ``CONFIG_PM``, ``CONFIG_MAGIC_SYSRQ``,
|
||||
``CONFIG_NET``, ``CONFIG_INET=n`` (ma l'ultimo con ``CONFIG_NET=y``).
|
||||
2) La patch è stata compilata e verificata in esecuzione con, e senza,
|
||||
le opzioni ``CONFIG_SMP`` e ``CONFIG_PREEMPT``.
|
||||
|
||||
3) Tutti i percorsi del codice sono stati verificati con tutte le funzionalità
|
||||
di lockdep abilitate.
|
||||
|
||||
4) 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.
|
||||
|
||||
5) La patch è stata verificata sul tag più recente di linux-next per assicurarsi
|
||||
che funzioni assieme a tutte le altre patch in coda, assieme ai vari
|
||||
cambiamenti nei sottosistemi VM, VFS e altri.
|
||||
|
@ -137,10 +137,10 @@ questione.
|
||||
|
||||
Quando volete fare riferimento ad una lista di discussione, preferite il
|
||||
servizio d'archiviazione lore.kernel.org. Per create un collegamento URL è
|
||||
sufficiente usare il campo ``Message-Id``, presente nell'intestazione del
|
||||
sufficiente usare il campo ``Message-ID``, presente nell'intestazione del
|
||||
messaggio, senza parentesi angolari. Per esempio::
|
||||
|
||||
Link: https://lore.kernel.org/r/30th.anniversary.repost@klaava.Helsinki.FI/
|
||||
Link: https://lore.kernel.org/30th.anniversary.repost@klaava.Helsinki.FI
|
||||
|
||||
Prima d'inviare il messaggio ricordatevi di verificare che il collegamento così
|
||||
creato funzioni e che indirizzi verso il messaggio desiderato.
|
||||
@ -275,11 +275,9 @@ patch riceverà molta più attenzione. Tuttavia, per favore, non spammate le lis
|
||||
di discussione che non sono interessate al vostro lavoro.
|
||||
|
||||
Molte delle liste di discussione relative al kernel vengono ospitate su
|
||||
vger.kernel.org; potete trovare un loro elenco alla pagina
|
||||
http://vger.kernel.org/vger-lists.html. Tuttavia, ci sono altre liste di
|
||||
discussione ospitate altrove.
|
||||
|
||||
Non inviate più di 15 patch alla volta sulle liste di discussione vger!!!
|
||||
kernel.org; potete trovare un loro elenco alla pagina
|
||||
https://subspace.kernel.org. Tuttavia, ci sono altre liste di discussione
|
||||
ospitate altrove.
|
||||
|
||||
L'ultimo giudizio sull'integrazione delle modifiche accettate spetta a
|
||||
Linux Torvalds. Il suo indirizzo e-mail è <torvalds@linux-foundation.org>.
|
||||
@ -891,6 +889,14 @@ Assicuratevi che il commit si basi su sorgenti ufficiali del
|
||||
manutentore/mainline e non su sorgenti interni, accessibile solo a voi,
|
||||
altrimenti sarebbe inutile.
|
||||
|
||||
Strumenti
|
||||
---------
|
||||
|
||||
Molti degli aspetti più tecnici di questo processo possono essere automatizzati
|
||||
usando b4, la cui documentazione è disponibile all'indirizzo
|
||||
<https://b4.docs.kernel.org/en/latest/>. Può aiutare a tracciare la dipendenze,
|
||||
eseguire checkpatch e con la formattazione e l'invio di messaggi di posta.
|
||||
|
||||
Riferimenti
|
||||
-----------
|
||||
|
||||
@ -913,9 +919,6 @@ Greg Kroah-Hartman, "Come scocciare un manutentore di un sottosistema"
|
||||
|
||||
<http://www.kroah.com/log/linux/maintainer-06.html>
|
||||
|
||||
No!!!! Basta gigantesche bombe patch alle persone sulla lista linux-kernel@vger.kernel.org!
|
||||
<https://lore.kernel.org/r/20050711.125305.08322243.davem@davemloft.net>
|
||||
|
||||
Kernel Documentation/translations/it_IT/process/coding-style.rst.
|
||||
|
||||
E-mail di Linus Torvalds sul formato canonico di una patch:
|
||||
|
13
Documentation/translations/it_IT/staging/index.rst
Normal file
13
Documentation/translations/it_IT/staging/index.rst
Normal file
@ -0,0 +1,13 @@
|
||||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
.. include:: ../disclaimer-ita.rst
|
||||
|
||||
:Original: :ref:`Documentation/staging/index.rst <process_index>`
|
||||
|
||||
Documenti in ordine sparso
|
||||
==========================
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
magic-number
|
@ -361,7 +361,7 @@ https://patchwork.kernel.org/ でリストされています。
|
||||
全サブシステムツリーからほぼ毎日プルされてできる特別なテスト用のリポジ
|
||||
トリが存在します-
|
||||
|
||||
https://git.kernel.org/?p=linux/kernel/git/next/linux-next.git
|
||||
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
|
||||
|
||||
このやり方によって、linux-next は次のマージ機会でどんなものがメイン
|
||||
ラインにマージされるか、おおまかな展望を提供します。
|
||||
@ -401,12 +401,12 @@ https://bugzilla.kernel.org でバグ報告を調べようとする人もいる
|
||||
は Linux kernel メーリングリストに参加しています。このリストの登録/脱
|
||||
退の方法については以下を参照してください-
|
||||
|
||||
http://vger.kernel.org/vger-lists.html#linux-kernel
|
||||
https://subspace.kernel.org/subscribing.html
|
||||
|
||||
このメーリングリストのアーカイブは web 上の多数の場所に存在します。こ
|
||||
れらのアーカイブを探すにはサーチエンジンを使いましょう。例えば-
|
||||
|
||||
https://lore.kernel.org/lkml/
|
||||
https://lore.kernel.org/linux-kernel/
|
||||
|
||||
リストに投稿する前にすでにその話題がアーカイブに存在するかどうかを検索
|
||||
することを是非やってください。多数の事がすでに詳細に渡って議論されてお
|
||||
@ -419,13 +419,13 @@ MAINTAINERS ファイルにリストがありますので参照してくださ
|
||||
多くのリストは kernel.org でホストされています。これらの情報は以下にあ
|
||||
ります -
|
||||
|
||||
http://vger.kernel.org/vger-lists.html
|
||||
https://subspace.kernel.org
|
||||
|
||||
メーリングリストを使う場合、良い行動習慣に従うようにしましょう。少し安っ
|
||||
ぽいが、以下の URL は上のリスト(や他のリスト)で会話する場合のシンプル
|
||||
なガイドラインを示しています -
|
||||
|
||||
http://www.albion.com/netiquette/
|
||||
https://subspace.kernel.org/etiquette.html
|
||||
|
||||
もし複数の人があなたのメールに返事をした場合、CC: で受ける人のリストは
|
||||
だいぶ多くなるでしょう。正当な理由がない限り、CC: リストから誰かを削除
|
||||
|
@ -7,3 +7,4 @@
|
||||
|
||||
sched-design-CFS
|
||||
sched-eevdf
|
||||
sched-bwc
|
||||
|
287
Documentation/translations/sp_SP/scheduler/sched-bwc.rst
Normal file
287
Documentation/translations/sp_SP/scheduler/sched-bwc.rst
Normal file
@ -0,0 +1,287 @@
|
||||
.. include:: ../disclaimer-sp.rst
|
||||
|
||||
:Original: :ref:`Documentation/scheduler/sched-design-CFS.rst <sched_design_CFS>`
|
||||
:Translator: Sergio González Collado <sergio.collado@gmail.com>
|
||||
|
||||
.. _sp_sched_bwc:
|
||||
|
||||
=================================
|
||||
CFS con control de ancho de banda
|
||||
=================================
|
||||
|
||||
.. note::
|
||||
Este documento únicamente trata el control de ancho de banda de CPUs
|
||||
para SCHED_NORMAL. El caso de SCHED_RT se trata en Documentation/scheduler/sched-rt-group.rst
|
||||
|
||||
El control de ancho de banda es una extensión CONFIG_FAIR_GROUP_SCHED que
|
||||
permite especificar el máximo uso disponible de CPU para un grupo o una jerarquía.
|
||||
|
||||
El ancho de banda permitido para un grupo de tareas se especifica usando una
|
||||
cuota y un periodo. Dentro de un "periodo" (microsegundos), a un grupo
|
||||
de tareas se le asigna hasta su "cuota" de tiempo de uso de CPU en
|
||||
microsegundos. Esa cuota es asignada para cada CPU en colas de ejecución
|
||||
en porciones de tiempo de ejecución en la CPU según los hilos de ejecución
|
||||
del grupo de tareas van siendo candidatos a ejecutarse. Una vez toda la cuota
|
||||
ha sido asignada cualquier petición adicional de cuota resultará en esos hilos
|
||||
de ejecución siendo limitados/estrangulados. Los hilos de ejecución limitados
|
||||
no serán capaces de ejecutarse de nuevo hasta el siguiente periodo cuando
|
||||
la cuota sea restablecida.
|
||||
|
||||
La cuota sin asignar de un grupo es monitorizada globalmente, siendo
|
||||
restablecidas cfs_quota unidades al final de cada periodo. Según los
|
||||
hilos de ejecución van consumiendo este ancho de banda, este se
|
||||
transfiere a los "silos" de las cpu-locales en base a la demanda. La
|
||||
cantidad transferida en cada una de esas actualizaciones es ajustable y
|
||||
es descrito como un "slice".
|
||||
|
||||
Característica de ráfaga
|
||||
--------------------------
|
||||
|
||||
Esta característica toma prestado tiempo ahora, que en un futuro tendrá que
|
||||
devolver, con el coste de una mayor interferencia hacia los otros usuarios
|
||||
del sistema. Todo acotado perfectamente.
|
||||
|
||||
El tradicional control de ancho de banda (UP-EDF) es algo como:
|
||||
|
||||
(U = \Sum u_i) <= 1
|
||||
|
||||
Esto garantiza dos cosas: que cada tiempo límite de ejecución es cumplido
|
||||
y que el sistema es estable. De todas formas, si U fuese > 1, entonces
|
||||
por cada segundo de tiempo de reloj de una tarea, tendríamos que
|
||||
ejecutar más de un segundo y obviamente no se cumpliría con el tiempo
|
||||
límite de ejecución de la tarea, pero en el siguiente periodo de ejecución
|
||||
el tiempo límite de la tarea estaría todavía más lejos, y nunca se tendría
|
||||
tiempo de alcanzar la ejecución, cayendo así en un fallo no acotado.
|
||||
|
||||
La característica de ráfaga implica que el trabajo de una tarea no siempre
|
||||
consuma totalmente la cuota; esto permite que se pueda describir u_i
|
||||
como una distribución estadística.
|
||||
|
||||
Por ejemplo, se tiene u_i = {x,e}_i, donde x es el p(95) y x+e p(100)
|
||||
(el tradicional WCET (WCET:Worst Case Execution Time: son las siglas
|
||||
en inglés para "peor tiempo de ejecución")). Esto efectivamente permite
|
||||
a u ser más pequeño, aumentando la eficiencia (podemos ejecutar más
|
||||
tareas en el sistema), pero al coste de perder el instante límite de
|
||||
finalización deseado de la tarea, cuando coincidan las peores
|
||||
probabilidades. De todas formas, si se mantiene la estabilidad, ya que
|
||||
cada sobre-ejecución se empareja con una infra-ejecución en tanto x esté
|
||||
por encima de la media.
|
||||
|
||||
Es decir, supóngase que se tienen 2 tareas, ambas específicamente
|
||||
con p(95), entonces tenemos p(95)*p(95) = 90.25% de probabilidad de
|
||||
que ambas tareas se ejecuten dentro de su cuota asignada y todo
|
||||
salga bien. Al mismo tiempo se tiene que p(5)*p(5) = 0.25% de
|
||||
probabilidad que ambas tareas excedan su cuota de ejecución (fallo
|
||||
garantizado de su tiempo final de ejecución). En algún punto por
|
||||
en medio, hay un umbral donde una tarea excede su tiempo límite de
|
||||
ejecución y la otra no, de forma que se compensan; esto depende de la
|
||||
función de probabilidad acumulada específica de la tarea.
|
||||
|
||||
Al mismo tiempo, se puede decir que el peor caso de sobrepasar el
|
||||
tiempo límite de ejecución será \Sum e_i; esto es una retraso acotado
|
||||
(asumiendo que x+e es de hecho el WCET).
|
||||
|
||||
La interferencia cuando se usa una ráfaga se evalúa por las posibilidades
|
||||
de fallar en el cumplimiento del tiempo límite y el promedio de WCET.
|
||||
Los resultados de los tests han mostrado que cuando hay muchos cgroups o
|
||||
una CPU está infrautilizada, la interferencia es más limitada. Más detalles
|
||||
se aportan en: https://lore.kernel.org/lkml/5371BD36-55AE-4F71-B9D7-B86DC32E3D2B@linux.alibaba.com/
|
||||
|
||||
Gestión:
|
||||
--------
|
||||
|
||||
Cuota, periodo y ráfaga se gestionan dentro del subsistema de cpu por medio
|
||||
de cgroupfs.
|
||||
|
||||
.. note::
|
||||
Los archivos cgroupfs descritos en esta sección solo se aplican al cgroup
|
||||
v1. Para cgroup v2, ver :ref:`Documentation/admin-guide/cgroup-v2.rst <cgroup-v2-cpu>`.
|
||||
|
||||
- cpu.cfs_quota_us: tiempo de ejecución que se refresca cada periodo (en microsegundos)
|
||||
- cpu.cfs_period_us: la duración del periodo (en microsegundos)
|
||||
- cpu.stat: exporta las estadísticas de limitación [explicado a continuación]
|
||||
- cpu.cfs_burst_us: el máximo tiempo de ejecución acumulado (en microsegundos)
|
||||
|
||||
Los valores por defecto son::
|
||||
|
||||
cpu.cfs_period_us=100ms
|
||||
cpu.cfs_quota_us=-1
|
||||
cpu.cfs_burst_us=0
|
||||
|
||||
Un valor de -1 para cpu.cfs_quota_us indica que el grupo no tiene ninguna
|
||||
restricción de ancho de banda aplicado, ese grupo se describe como un grupo
|
||||
con ancho de banda sin restringir. Esto representa el comportamiento
|
||||
tradicional para CFS.
|
||||
|
||||
Asignar cualquier valor (válido) y positivo no menor que cpu.cfs_burst_us
|
||||
definirá el límite del ancho de banda. La cuota mínima permitida para
|
||||
la cuota o periodo es 1ms. Hay también un límite superior en la duración del
|
||||
periodo de 1s. Existen restricciones adicionales cuando los límites de
|
||||
ancho de banda se usan de manera jerárquica, estos se explican en mayor
|
||||
detalle más adelante.
|
||||
|
||||
Asignar cualquier valor negativo a cpu.cfs_quota_us eliminará el límite de
|
||||
ancho de banda y devolverá de nuevo al grupo a un estado sin restricciones.
|
||||
|
||||
Un valor de 0 para cpu.cfs_burst_us indica que el grupo no puede acumular
|
||||
ningún ancho de banda sin usar. Esto hace que el control del comportamiento
|
||||
tradicional del ancho de banda para CFS no cambie. Definir cualquier valor
|
||||
(válido) positivo no mayor que cpu.cfs_quota_us en cpu.cgs_burst_us definirá
|
||||
el límite con el ancho de banda acumulado no usado.
|
||||
|
||||
Cualquier actualización a las especificaciones del ancho de banda usado
|
||||
por un grupo resultará en que se deje de limitar si está en un estado
|
||||
restringido.
|
||||
|
||||
Ajustes globales del sistema
|
||||
----------------------------
|
||||
|
||||
Por eficiencia el tiempo de ejecución es transferido en lotes desde una reserva
|
||||
global y el "silo" de una CPU local. Esto reduce en gran medida la presión
|
||||
por la contabilidad en grandes sistemas. La cantidad transferida cada vez
|
||||
que se requiere una actualización se describe como "slice".
|
||||
|
||||
Esto es ajustable vía procfs::
|
||||
|
||||
/proc/sys/kernel/sched_cfs_bandwidth_slice_us (valor por defecto=5ms)
|
||||
|
||||
Valores de "slice" más grandes reducirán el costo de transferencia, mientras
|
||||
que valores más pequeños permitirán un control más fino del consumo.
|
||||
|
||||
Estadísticas
|
||||
------------
|
||||
|
||||
Las estadísticas del ancho de banda de un grupo se exponen en 5 campos en cpu.stat.
|
||||
|
||||
cpu.stat:
|
||||
|
||||
- nr_periods: Número de intervalos aplicados que han pasado.
|
||||
- nr_throttled: Número de veces que el grupo ha sido restringido/limitado.
|
||||
- throttled_time: La duración de tiempo total (en nanosegundos) en las
|
||||
que las entidades del grupo han sido limitadas.
|
||||
- nr_bursts: Número de periodos en que ha ocurrido una ráfaga.
|
||||
- burst_time: Tiempo acumulado (en nanosegundos) en la que una CPU ha
|
||||
usado más de su cuota en los respectivos periodos.
|
||||
|
||||
Este interfaz es de solo lectura.
|
||||
|
||||
Consideraciones jerárquicas
|
||||
---------------------------
|
||||
|
||||
La interfaz refuerza que el ancho de banda de una entidad individual
|
||||
sea siempre factible, esto es: max(c_i) <= C. De todas maneras,
|
||||
la sobre-suscripción en el caso agregado está explícitamente permitida
|
||||
para hacer posible semánticas de conservación de trabajo dentro de una
|
||||
jerarquia.
|
||||
|
||||
e.g. \Sum (c_i) puede superar C
|
||||
|
||||
[ Donde C es el ancho de banda de el padre, y c_i el de su hijo ]
|
||||
|
||||
Hay dos formas en las que un grupo puede ser limitado:
|
||||
|
||||
a. este consume totalmente su propia cuota en un periodo.
|
||||
b. la cuota del padre es consumida totalmente en su periodo.
|
||||
|
||||
En el caso b) anterior, incluso si el hijo pudiera tener tiempo de
|
||||
ejecución restante, este no le será permitido hasta que el tiempo de
|
||||
ejecución del padre sea actualizado.
|
||||
|
||||
Advertencias sobre el CFS con control de cuota de ancho de banda
|
||||
----------------------------------------------------------------
|
||||
|
||||
Una vez una "slice" se asigna a una cpu esta no expira. A pesar de eso todas,
|
||||
excepto las "slices" menos las de 1ms, puede ser devueltas a la reserva global
|
||||
si todos los hilos en esa cpu pasan a ser no ejecutables. Esto se configura
|
||||
en el tiempo de compilación por la variable min_cfs_rq_runtime. Esto es un
|
||||
ajuste en la eficacia que ayuda a prevenir añadir bloqueos en el candado global.
|
||||
|
||||
El hecho de que las "slices" de una cpu local no expiren tiene como resultado
|
||||
algunos casos extremos interesantes que debieran ser comprendidos.
|
||||
|
||||
Para una aplicación que es un cgroup y que está limitada en su uso de cpu
|
||||
es un punto discutible ya que de forma natural consumirá toda su parte
|
||||
de cuota así como también la totalidad de su cuota en cpu locales en cada
|
||||
periodo. Como resultado se espera que nr_periods sea aproximadamente igual
|
||||
a nr_throttled, y que cpuacct.usage se incremente aproximadamente igual
|
||||
a cfs_quota_us en cada periodo.
|
||||
|
||||
Para aplicaciones que tienen un gran número de hilos de ejecución y que no
|
||||
estan ligadas a una cpu, este matiz de la no-expiración permite que las
|
||||
aplicaciones brevemente sobrepasen su cuota límite en la cantidad que
|
||||
no ha sido usada en cada cpu en la que el grupo de tareas se está ejecutando
|
||||
(típicamente como mucho 1ms por cada cpu o lo que se ha definido como
|
||||
min_cfs_rq_runtime). Este pequeño sobreuso únicamente tiene lugar si
|
||||
la cuota que ha sido asignada a una cpu y no ha sido completamente usada
|
||||
o devuelta en periodos anteriores. Esta cantidad de sobreuso no será
|
||||
transferida entre núcleos. Como resultado, este mecanismo todavía cumplirá
|
||||
estrictamente los límites de la tarea de grupo en el promedio del uso,
|
||||
pero sobre una ventana de tiempo mayor que un único periodo. Esto
|
||||
también limita la habilidad de un sobreuso a no más de 1ms por cada cpu.
|
||||
Esto provee de una experiencia de uso más predecible para aplicaciones
|
||||
con muchos hilos y con límites de cuota pequeños en máquinas con muchos
|
||||
núcleos. Esto también elimina la propensión a limitar estas
|
||||
aplicaciones mientras que simultáneamente usan menores cuotas
|
||||
de uso por cpu. Otra forma de decir esto es que permitiendo que
|
||||
la parte no usada de una "slice" permanezca válida entre periodos
|
||||
disminuye la posibilidad de malgastare cuota que va a expirar en
|
||||
las reservas de la cpu locales que no necesitan una "slice" completa
|
||||
de tiempo de ejecución de cpu.
|
||||
|
||||
La interacción entre las aplicaciones ligadas a una CPU y las que no están
|
||||
ligadas a ninguna cpu ha de ser también considerada, especialmente cuando
|
||||
un único núcleo tiene un uso del 100%. Si se da a cada una de esas
|
||||
aplicaciones la mitad de la capacidad de una CPU-núcleo y ambas
|
||||
están gestionadas en la misma CPU es teóricamente posible que la aplicación
|
||||
no ligada a ninguna CPU use su 1ms adicional de cuota en algunos periodos,
|
||||
y por tanto evite que la aplicación ligada a una CPU pueda usar su
|
||||
cuota completa por esa misma cantidad. En esos caso el algoritmo CFS (vea
|
||||
sched-design-CFS.rst) el que decida qué aplicación es la elegida para
|
||||
ejecutarse, ya que ambas serán candidatas a ser ejecutadas y tienen
|
||||
cuota restante. Esta discrepancia en el tiempo de ejecución se compensará
|
||||
en los periodos siguientes cuando el sistema esté inactivo.
|
||||
|
||||
Ejemplos
|
||||
---------
|
||||
|
||||
1. Un grupo limitado a 1 CPU de tiempo de ejecución.
|
||||
|
||||
Si el periodo son 250ms y la cuota son 250ms el grupo de tareas tendrá el tiempo
|
||||
de ejecución de 1 CPU cada 250ms::
|
||||
|
||||
# echo 250000 > cpu.cfs_quota_us /* cuota = 250ms */
|
||||
# echo 250000 > cpu.cfs_period_us /* periodo = 250ms */
|
||||
|
||||
2. Un grupo limitado al tiempo de ejecución de 2 CPUs en una máquina varias CPUs.
|
||||
|
||||
Con un periodo de 500ms y una cuota de 1000ms el grupo de tareas tiene el tiempo
|
||||
de ejecución de 2 CPUs cada 500ms::
|
||||
|
||||
# echo 1000000 > cpu.cfs_quota_us /* cuota = 1000ms */
|
||||
# echo 500000 > cpu.cfs_period_us /* periodo = 500ms */
|
||||
|
||||
El periodo más largo aquí permite una capacidad de ráfaga mayor.
|
||||
|
||||
3. Un grupo limitado a un 20% de 1 CPU.
|
||||
|
||||
Con un periodo de 50ms, 10ms de cuota son equivalentes al 20% de 1 CPUs::
|
||||
|
||||
# echo 10000 > cpu.cfs_quota_us /* cuota = 10ms */
|
||||
# echo 50000 > cpu.cfs_period_us /* periodo = 50ms */
|
||||
|
||||
Usando un periodo pequeño aquí nos aseguramos una respuesta de
|
||||
la latencia consistente a expensas de capacidad de ráfaga.
|
||||
|
||||
4. Un grupo limitado al 40% de 1 CPU, y permite acumular adicionalmente
|
||||
hasta un 20% de 1 CPU.
|
||||
|
||||
Con un periodo de 50ms, 20ms de cuota son equivalentes al 40% de
|
||||
1 CPU. Y 10ms de ráfaga, son equivalentes a un 20% de 1 CPU::
|
||||
|
||||
# echo 20000 > cpu.cfs_quota_us /* cuota = 20ms */
|
||||
# echo 50000 > cpu.cfs_period_us /* periodo = 50ms */
|
||||
# echo 10000 > cpu.cfs_burst_us /* ráfaga = 10ms */
|
||||
|
||||
Un ajuste mayor en la capacidad de almacenamiento (no mayor que la cuota)
|
||||
permite una mayor capacidad de ráfaga.
|
||||
|
@ -120,7 +120,7 @@ gcov的内核分析插桩支持内核的编译和运行是在同一台机器上
|
||||
如果内核编译和运行是不同的机器,那么需要额外的准备工作,这取决于gcov工具
|
||||
是在哪里使用的:
|
||||
|
||||
.. _gcov-test_zh:
|
||||
.. _gcov-test_zh_CN:
|
||||
|
||||
a) 若gcov运行在测试机上
|
||||
|
||||
@ -140,7 +140,7 @@ a) 若gcov运行在测试机上
|
||||
如果文件是软链接,需要替换成真正的目录文件(这是由make的当前工作
|
||||
目录变量CURDIR引起的)。
|
||||
|
||||
.. _gcov-build_zh:
|
||||
.. _gcov-build_zh_CN:
|
||||
|
||||
b) 若gcov运行在编译机上
|
||||
|
||||
@ -205,7 +205,7 @@ kconfig会根据编译工具链的检查自动选择合适的gcov格式。
|
||||
--------------------------
|
||||
|
||||
用于在编译机上收集覆盖率元文件的示例脚本
|
||||
(见 :ref:`编译机和测试机分离 a. <gcov-test_zh>` )
|
||||
(见 :ref:`编译机和测试机分离 a. <gcov-test_zh_CN>` )
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
@ -238,7 +238,7 @@ kconfig会根据编译工具链的检查自动选择合适的gcov格式。
|
||||
-------------------------
|
||||
|
||||
用于在测试机上收集覆盖率数据文件的示例脚本
|
||||
(见 :ref:`编译机和测试机分离 b. <gcov-build_zh>` )
|
||||
(见 :ref:`编译机和测试机分离 b. <gcov-build_zh_CN>` )
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
|
@ -22,6 +22,7 @@ Documentation/translations/zh_CN/dev-tools/testing-overview.rst
|
||||
sparse
|
||||
kcov
|
||||
kcsan
|
||||
kmsan
|
||||
gcov
|
||||
kasan
|
||||
ubsan
|
||||
@ -32,7 +33,6 @@ Todolist:
|
||||
|
||||
- checkpatch
|
||||
- coccinelle
|
||||
- kmsan
|
||||
- kfence
|
||||
- kgdb
|
||||
- kselftest
|
||||
|
392
Documentation/translations/zh_CN/dev-tools/kmsan.rst
Normal file
392
Documentation/translations/zh_CN/dev-tools/kmsan.rst
Normal file
@ -0,0 +1,392 @@
|
||||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
.. include:: ../disclaimer-zh_CN.rst
|
||||
|
||||
:Original: Documentation/dev-tools/kmsan.rst
|
||||
:Translator: 刘浩阳 Haoyang Liu <tttturtleruss@hust.edu.cn>
|
||||
|
||||
=======================
|
||||
内核内存消毒剂(KMSAN)
|
||||
=======================
|
||||
|
||||
KMSAN 是一个动态错误检测器,旨在查找未初始化值的使用。它基于编译器插桩,类似于用
|
||||
户空间的 `MemorySanitizer tool`_。
|
||||
|
||||
需要注意的是 KMSAN 并不适合生产环境,因为它会大幅增加内核内存占用并降低系统运行速度。
|
||||
|
||||
使用方法
|
||||
========
|
||||
|
||||
构建内核
|
||||
--------
|
||||
|
||||
要构建带有 KMSAN 的内核,你需要一个较新的 Clang (14.0.6+)。
|
||||
请参阅 `LLVM documentation`_ 了解如何构建 Clang。
|
||||
|
||||
现在配置并构建一个启用 CONFIG_KMSAN 的内核。
|
||||
|
||||
示例报告
|
||||
--------
|
||||
|
||||
以下是一个 KMSAN 报告的示例::
|
||||
|
||||
=====================================================
|
||||
BUG: KMSAN: uninit-value in test_uninit_kmsan_check_memory+0x1be/0x380 [kmsan_test]
|
||||
test_uninit_kmsan_check_memory+0x1be/0x380 mm/kmsan/kmsan_test.c:273
|
||||
kunit_run_case_internal lib/kunit/test.c:333
|
||||
kunit_try_run_case+0x206/0x420 lib/kunit/test.c:374
|
||||
kunit_generic_run_threadfn_adapter+0x6d/0xc0 lib/kunit/try-catch.c:28
|
||||
kthread+0x721/0x850 kernel/kthread.c:327
|
||||
ret_from_fork+0x1f/0x30 ??:?
|
||||
|
||||
Uninit was stored to memory at:
|
||||
do_uninit_local_array+0xfa/0x110 mm/kmsan/kmsan_test.c:260
|
||||
test_uninit_kmsan_check_memory+0x1a2/0x380 mm/kmsan/kmsan_test.c:271
|
||||
kunit_run_case_internal lib/kunit/test.c:333
|
||||
kunit_try_run_case+0x206/0x420 lib/kunit/test.c:374
|
||||
kunit_generic_run_threadfn_adapter+0x6d/0xc0 lib/kunit/try-catch.c:28
|
||||
kthread+0x721/0x850 kernel/kthread.c:327
|
||||
ret_from_fork+0x1f/0x30 ??:?
|
||||
|
||||
Local variable uninit created at:
|
||||
do_uninit_local_array+0x4a/0x110 mm/kmsan/kmsan_test.c:256
|
||||
test_uninit_kmsan_check_memory+0x1a2/0x380 mm/kmsan/kmsan_test.c:271
|
||||
|
||||
Bytes 4-7 of 8 are uninitialized
|
||||
Memory access of size 8 starts at ffff888083fe3da0
|
||||
|
||||
CPU: 0 PID: 6731 Comm: kunit_try_catch Tainted: G B E 5.16.0-rc3+ #104
|
||||
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.14.0-2 04/01/2014
|
||||
=====================================================
|
||||
|
||||
报告指出本地变量 ``uninit`` 在 ``do_uninit_local_array()`` 中未初始化。
|
||||
第三个堆栈跟踪对应于该变量创建的位置。
|
||||
|
||||
第一个堆栈跟踪显示了未初始化值的使用位置(在
|
||||
``test_uninit_kmsan_check_memory()``)。
|
||||
工具显示了局部变量中未初始化的字节及其被复制到其他内存位置前的堆栈。
|
||||
|
||||
KMSAN 会在以下情况下报告未初始化的值 ``v``:
|
||||
|
||||
- 在条件判断中,例如 ``if (v) { ... }``;
|
||||
- 在索引或指针解引用中,例如 ``array[v]`` 或 ``*v``;
|
||||
- 当它被复制到用户空间或硬件时,例如 ``copy_to_user(..., &v, ...)``;
|
||||
- 当它作为函数参数传递,并且启用 ``CONFIG_KMSAN_CHECK_PARAM_RETVAL`` 时(见下文)。
|
||||
|
||||
这些情况(除了复制数据到用户空间或硬件外,这是一个安全问题)被视为 C11 标准下的未定义行为。
|
||||
|
||||
禁用插桩
|
||||
--------
|
||||
|
||||
可以用 ``__no_kmsan_checks`` 标记函数。这样,KMSAN 会忽略该函数中的未初始化值,
|
||||
并将其输出标记为已初始化。如此,用户不会收到与该函数相关的 KMSAN 报告。
|
||||
|
||||
KMSAN 还支持 ``__no_sanitize_memory`` 函数属性。KMSAN 不会对拥有该属性的函数进行
|
||||
插桩,这在我们不希望编译器干扰某些底层代码(例如标记为 ``noinstr`` 的代码,该
|
||||
代码隐式添加了 ``__no_sanitize_memory``)时可能很有用。
|
||||
|
||||
然而,这会有代价:此类函数的栈分配将具有不正确的影子/初始值,可能导致误报。来
|
||||
自非插桩代码的函数也可能接收到不正确的元数据。
|
||||
|
||||
|
||||
作为经验之谈,避免显式使用 ``__no_sanitize_memory``。
|
||||
|
||||
也可以通过 Makefile 禁用 KMSAN 对某个文件(例如 main.o)的作用::
|
||||
|
||||
KMSAN_SANITIZE_main.o := n
|
||||
|
||||
或者对整个目录::
|
||||
|
||||
KMSAN_SANITIZE := n
|
||||
|
||||
将其应用到文件或目录中的每个函数。大多数用户不会需要 KMSAN_SANITIZE,
|
||||
除非他们的代码被 KMSAN 破坏(例如在早期启动时运行的代码)。
|
||||
|
||||
还可以通过调用 ``kmsan_disable_current()`` 和 ``kmsan_enable_current()``
|
||||
暂时对当前任务禁用 KMSAN 检查。每个 ``kmsan_enable_current()`` 必须在
|
||||
``kmsan_disable_current()`` 之后调用;这些调用对可以嵌套。在调用时需要注意保持
|
||||
嵌套区域简短,并且尽可能使用其他方法禁用插桩。
|
||||
|
||||
支持
|
||||
====
|
||||
|
||||
为了使用 KMSAN,内核必须使用 Clang 构建,到目前为止,Clang 是唯一支持 KMSAN
|
||||
的编译器。内核插桩过程基于用户空间的 `MemorySanitizer tool`_。
|
||||
|
||||
目前运行时库仅支持 x86_64 架构。
|
||||
|
||||
KMSAN 的工作原理
|
||||
================
|
||||
|
||||
KMSAN 阴影内存
|
||||
--------------
|
||||
|
||||
KMSAN 将一个元数据字节(也称为阴影字节)与每个内核内存字节关联。仅当内核内存字节
|
||||
的相应位未初始化时,阴影字节中的一个比特位才会被设置。将内存标记为未初始化(即
|
||||
将其阴影字节设置为 ``0xff``)称为中毒,将其标记为已初始化(将阴影字节设置为
|
||||
``0x00``)称为解毒。
|
||||
|
||||
当在栈上分配新变量时,默认情况下它会中毒,这由编译器插入的插桩代码完成(除非它
|
||||
是立即初始化的栈变量)。任何未使用 ``__GFP_ZERO`` 的堆分配也会中毒。
|
||||
|
||||
编译器插桩还跟踪阴影值在代码中的使用。当需要时,插桩代码会调用 ``mm/kmsan/`` 中
|
||||
的运行时库以持久化阴影值。
|
||||
|
||||
基本或复合类型的阴影值是长度相同的字节数组。当常量值写入内存时,该内存会被解毒
|
||||
。当从内存读取值时,其阴影内存也会被获取,并传递到所有使用该值的操作中。对于每
|
||||
个需要一个或多个值的指令,编译器会生成代码根据这些值及其阴影来计算结果的阴影。
|
||||
|
||||
|
||||
示例::
|
||||
|
||||
int a = 0xff; // i.e. 0x000000ff
|
||||
int b;
|
||||
int c = a | b;
|
||||
|
||||
在这种情况下, ``a`` 的阴影为 ``0``, ``b`` 的阴影为 ``0xffffffff``,
|
||||
``c`` 的阴影为 ``0xffffff00``。这意味着 ``c`` 的高三个字节未初始化,而低字节已
|
||||
初始化。
|
||||
|
||||
起源跟踪
|
||||
--------
|
||||
|
||||
每四字节的内核内存都有一个所谓的源点与之映射。这个源点描述了在程序执行中,未初
|
||||
始化值的创建点。每个源点都与完整的分配栈(对于堆分配的内存)或包含未初始化变
|
||||
量的函数(对于局部变量)相关联。
|
||||
|
||||
当一个未初始化的变量在栈或堆上分配时,会创建一个新的源点值,并将该变量的初始值
|
||||
填充为这个值。当从内存中读取一个值时,其初始值也会被读取并与阴影一起保留。对于
|
||||
每个接受一个或多个值的指令,结果的源点是与任何未初始化输入相对应的源点之一。如
|
||||
果一个污染值被写入内存,其起源也会被写入相应的存储中。
|
||||
|
||||
示例 1::
|
||||
|
||||
int a = 42;
|
||||
int b;
|
||||
int c = a + b;
|
||||
|
||||
在这种情况下, ``b`` 的源点是在函数入口时生成的,并在加法结果写入内存之前存储到
|
||||
``c`` 的源点中。
|
||||
|
||||
如果几个变量共享相同的源点地址,则它们被存储在同一个四字节块中。在这种情况下,
|
||||
对任何变量的每次写入都会更新所有变量的源点。在这种情况下我们必须牺牲精度,因
|
||||
为为单独的位(甚至字节)存储源点成本过高。
|
||||
|
||||
示例 2::
|
||||
|
||||
int combine(short a, short b) {
|
||||
union ret_t {
|
||||
int i;
|
||||
short s[2];
|
||||
} ret;
|
||||
ret.s[0] = a;
|
||||
ret.s[1] = b;
|
||||
return ret.i;
|
||||
}
|
||||
|
||||
如果 ``a`` 已初始化而 ``b`` 未初始化,则结果的阴影为 0xffff0000,结果的源点为
|
||||
``b`` 的源点。 ``ret.s[0]`` 会有相同的起源,但它不会被使用,因为该变量已初始化。
|
||||
|
||||
如果两个函数参数都未初始化,则只保留第二个参数的源点。
|
||||
|
||||
源点链
|
||||
~~~~~~
|
||||
|
||||
为了便于调试,KMSAN 在每次将未初始化值存储到内存时都会创建一个新的源点。新的源点
|
||||
引用了其创建栈以及值的前一个起源。这可能导致内存消耗增加,因此我们在运行时限制
|
||||
了源点链的长度。
|
||||
|
||||
Clang 插桩 API
|
||||
--------------
|
||||
|
||||
Clang 插桩通过在内核代码中插入定义在 ``mm/kmsan/instrumentation.c`` 中的函数调用
|
||||
来实现。
|
||||
|
||||
|
||||
阴影操作
|
||||
~~~~~~~~
|
||||
|
||||
对于每次内存访问,编译器都会发出一个函数调用,该函数返回一对指针,指向给定内存
|
||||
的阴影和原始地址::
|
||||
|
||||
typedef struct {
|
||||
void *shadow, *origin;
|
||||
} shadow_origin_ptr_t
|
||||
|
||||
shadow_origin_ptr_t __msan_metadata_ptr_for_load_{1,2,4,8}(void *addr)
|
||||
shadow_origin_ptr_t __msan_metadata_ptr_for_store_{1,2,4,8}(void *addr)
|
||||
shadow_origin_ptr_t __msan_metadata_ptr_for_load_n(void *addr, uintptr_t size)
|
||||
shadow_origin_ptr_t __msan_metadata_ptr_for_store_n(void *addr, uintptr_t size)
|
||||
|
||||
函数名依赖于内存访问的大小。
|
||||
|
||||
编译器确保对于每个加载的值,其阴影和原始值都从内存中读取。当一个值存储到内存时
|
||||
,其阴影和原始值也会通过元数据指针进行存储。
|
||||
|
||||
处理局部变量
|
||||
~~~~~~~~~~~~
|
||||
|
||||
一个特殊的函数用于为局部变量创建一个新的原始值,并将该变量的原始值设置为该值::
|
||||
|
||||
void __msan_poison_alloca(void *addr, uintptr_t size, char *descr)
|
||||
|
||||
访问每个任务数据
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
在每个插桩函数的开始处,KMSAN 插入一个对 ``__msan_get_context_state()`` 的调用
|
||||
::
|
||||
|
||||
kmsan_context_state *__msan_get_context_state(void)
|
||||
|
||||
``kmsan_context_state`` 在 ``include/linux/kmsan.h`` 中声明::
|
||||
|
||||
struct kmsan_context_state {
|
||||
char param_tls[KMSAN_PARAM_SIZE];
|
||||
char retval_tls[KMSAN_RETVAL_SIZE];
|
||||
char va_arg_tls[KMSAN_PARAM_SIZE];
|
||||
char va_arg_origin_tls[KMSAN_PARAM_SIZE];
|
||||
u64 va_arg_overflow_size_tls;
|
||||
char param_origin_tls[KMSAN_PARAM_SIZE];
|
||||
depot_stack_handle_t retval_origin_tls;
|
||||
};
|
||||
|
||||
KMSAN 使用此结构体在插桩函数之间传递参数阴影和原始值(除非立刻通过
|
||||
``CONFIG_KMSAN_CHECK_PARAM_RETVAL`` 检查参数)。
|
||||
|
||||
将未初始化的值传递给函数
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Clang 的 MemorySanitizer 插桩有一个选项 ``-fsanitize-memory-param-retval``,该
|
||||
选项使编译器检查按值传递的函数参数,以及函数返回值。
|
||||
|
||||
该选项由 ``CONFIG_KMSAN_CHECK_PARAM_RETVAL`` 控制,默认启用以便 KMSAN 更早报告
|
||||
未初始化的值。有关更多细节,请参考 `LKML discussion`_。
|
||||
|
||||
由于 LLVM 中的实现检查的方式(它们仅应用于标记为 ``noundef`` 的参数),并不是所
|
||||
有参数都能保证被检查,因此我们不能放弃 ``kmsan_context_state`` 中的元数据存储
|
||||
。
|
||||
|
||||
字符串函数
|
||||
~~~~~~~~~~~
|
||||
|
||||
编译器将对 ``memcpy()``/``memmove()``/``memset()`` 的调用替换为以下函数。这些函
|
||||
数在数据结构初始化或复制时也会被调用,确保阴影和原始值与数据一起复制::
|
||||
|
||||
void *__msan_memcpy(void *dst, void *src, uintptr_t n)
|
||||
void *__msan_memmove(void *dst, void *src, uintptr_t n)
|
||||
void *__msan_memset(void *dst, int c, uintptr_t n)
|
||||
|
||||
错误报告
|
||||
~~~~~~~~
|
||||
|
||||
对于每个值的使用,编译器发出一个阴影检查,在值中毒的情况下调用
|
||||
``__msan_warning()``::
|
||||
|
||||
void __msan_warning(u32 origin)
|
||||
|
||||
``__msan_warning()`` 使 KMSAN 运行时打印错误报告。
|
||||
|
||||
内联汇编插桩
|
||||
~~~~~~~~~~~~
|
||||
|
||||
KMSAN 对每个内联汇编输出进行插桩,调用::
|
||||
|
||||
void __msan_instrument_asm_store(void *addr, uintptr_t size)
|
||||
|
||||
,该函数解除内存区域的污染。
|
||||
|
||||
这种方法可能会掩盖某些错误,但也有助于避免许多位操作、原子操作等中的假阳性。
|
||||
|
||||
有时传递给内联汇编的指针不指向有效内存。在这种情况下,它们在运行时被忽略。
|
||||
|
||||
|
||||
运行时库
|
||||
--------
|
||||
|
||||
代码位于 ``mm/kmsan/``。
|
||||
|
||||
每个任务 KMSAN 状态
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
每个 task_struct 都有一个关联的 KMSAN 任务状态,它保存 KMSAN
|
||||
上下文(见上文)和一个每个任务计数器以禁止 KMSAN 报告::
|
||||
|
||||
struct kmsan_context {
|
||||
...
|
||||
unsigned int depth;
|
||||
struct kmsan_context_state cstate;
|
||||
...
|
||||
}
|
||||
|
||||
struct task_struct {
|
||||
...
|
||||
struct kmsan_context kmsan;
|
||||
...
|
||||
}
|
||||
|
||||
KMSAN 上下文
|
||||
~~~~~~~~~~~~
|
||||
|
||||
在内核任务上下文中运行时,KMSAN 使用 ``current->kmsan.cstate`` 来
|
||||
保存函数参数和返回值的元数据。
|
||||
|
||||
但在内核运行于中断、softirq 或 NMI 上下文中, ``current`` 不可用时,
|
||||
KMSAN 切换到每 CPU 中断状态::
|
||||
|
||||
DEFINE_PER_CPU(struct kmsan_ctx, kmsan_percpu_ctx);
|
||||
|
||||
元数据分配
|
||||
~~~~~~~~~~
|
||||
|
||||
内核中有多个地方存储元数据。
|
||||
|
||||
1. 每个 ``struct page`` 实例包含两个指向其影子和内存页面的指针
|
||||
::
|
||||
|
||||
struct page {
|
||||
...
|
||||
struct page *shadow, *origin;
|
||||
...
|
||||
};
|
||||
|
||||
在启动时,内核为每个可用的内核页面分配影子和源页面。这是在内核地址空间已经碎片
|
||||
化时后完成的,完成的相当晚,因此普通数据页面可能与元数据页面任意交错。
|
||||
|
||||
这意味着通常两个相邻的内存页面,它们的影子/源页面可能不是连续的。因此,如果内存
|
||||
访问跨越内存块的边界,访问影子/源内存可能会破坏其他页面或从中读取错误的值。
|
||||
|
||||
实际上,由相同 ``alloc_pages()`` 调用返回的连续内存页面将具有连续的元数据,而
|
||||
如果这些页面属于两个不同的分配,它们的元数据页面可能会被碎片化。
|
||||
|
||||
对于内核数据( ``.data``、 ``.bss`` 等)和每 CPU 内存区域,也没有对元数据连续
|
||||
性的保证。
|
||||
|
||||
在 ``__msan_metadata_ptr_for_XXX_YYY()`` 遇到两个页面之间的
|
||||
非连续元数据边界时,它返回指向假影子/源区域的指针::
|
||||
|
||||
char dummy_load_page[PAGE_SIZE] __attribute__((aligned(PAGE_SIZE)));
|
||||
char dummy_store_page[PAGE_SIZE] __attribute__((aligned(PAGE_SIZE)));
|
||||
|
||||
``dummy_load_page`` 被初始化为零,因此读取它始终返回零。对 ``dummy_store_page`` 的
|
||||
所有写入都被忽略。
|
||||
|
||||
2. 对于 vmalloc 内存和模块,内存范围、影子和源之间有一个直接映射。KMSAN 将
|
||||
vmalloc 区域缩小了 3/4,仅使前四分之一可用于 ``vmalloc()``。vmalloc
|
||||
区域的第二个四分之一包含第一个四分之一的影子内存,第三个四分之一保存源。第四个
|
||||
四分之一的小部分包含内核模块的影子和源。有关更多详细信息,请参阅
|
||||
``arch/x86/include/asm/pgtable_64_types.h``。
|
||||
|
||||
当一系列页面映射到一个连续的虚拟内存空间时,它们的影子和源页面也以连续区域的方
|
||||
式映射。
|
||||
|
||||
参考文献
|
||||
========
|
||||
|
||||
E. Stepanov, K. Serebryany. `MemorySanitizer: fast detector of uninitialized
|
||||
memory use in C++
|
||||
<https://static.googleusercontent.com/media/research.google.com/en//pubs/archive/43308.pdf>`_.
|
||||
In Proceedings of CGO 2015.
|
||||
|
||||
.. _MemorySanitizer tool: https://clang.llvm.org/docs/MemorySanitizer.html
|
||||
.. _LLVM documentation: https://llvm.org/docs/GettingStarted.html
|
||||
.. _LKML discussion: https://lore.kernel.org/all/20220614144853.3693273-1-glider@google.com/
|
@ -34,3 +34,4 @@
|
||||
* semaphores: 信号量。
|
||||
* spinlock: 自旋锁。
|
||||
* watermark: 水位,一般指页表的消耗水平。
|
||||
* PTE: 页表项。(Page Table Entry)
|
||||
|
@ -12,20 +12,21 @@
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
kconfig
|
||||
headers_install
|
||||
gcc-plugins
|
||||
kbuild
|
||||
reproducible-builds
|
||||
llvm
|
||||
|
||||
TODO:
|
||||
|
||||
- kconfig-language
|
||||
- kconfig-macro-language
|
||||
- kbuild
|
||||
- kconfig
|
||||
- makefiles
|
||||
- modules
|
||||
- issues
|
||||
- reproducible-builds
|
||||
- llvm
|
||||
|
||||
|
||||
.. only:: subproject and html
|
||||
|
||||
|
304
Documentation/translations/zh_CN/kbuild/kbuild.rst
Normal file
304
Documentation/translations/zh_CN/kbuild/kbuild.rst
Normal file
@ -0,0 +1,304 @@
|
||||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
.. include:: ../disclaimer-zh_CN.rst
|
||||
|
||||
:Original: Documentation/kbuild/kbuild.rst
|
||||
:Translator: 慕冬亮 Dongliang Mu <dzm91@hust.edu.cn>
|
||||
|
||||
======
|
||||
Kbuild
|
||||
======
|
||||
|
||||
|
||||
输出文件
|
||||
========
|
||||
|
||||
modules.order
|
||||
-------------
|
||||
该文件记录模块在 Makefile 中出现的顺序。modprobe 使用该文件来确定性
|
||||
解析匹配多个模块的别名。
|
||||
|
||||
modules.builtin
|
||||
---------------
|
||||
该文件列出了所有内置到内核中的模块。modprobe 使用该文件来避免尝试加载
|
||||
内置模块时出错。
|
||||
|
||||
modules.builtin.modinfo
|
||||
-----------------------
|
||||
该文件包含所有内置模块的 modinfo。与单独模块的 modinfo 不同,所有字段
|
||||
都带有模块名称前缀。
|
||||
|
||||
modules.builtin.ranges
|
||||
----------------------
|
||||
该文件包含所有内核内置模块的地址偏移范围(每个 ELF 节)。结合 System.map
|
||||
文件,它可以用来将模块名称与符号关联起来。
|
||||
|
||||
环境变量
|
||||
========
|
||||
|
||||
KCPPFLAGS
|
||||
---------
|
||||
在预处理时传递的额外选项。kbuild 进行所有预处理(包括构建 C 文件和汇编文件)
|
||||
时,都会使用这些预处理选项。
|
||||
|
||||
KAFLAGS
|
||||
-------
|
||||
传递给汇编器的额外选项(适用于内置模块和外部模块)。
|
||||
|
||||
AFLAGS_MODULE
|
||||
-------------
|
||||
外部模块的额外汇编选项。
|
||||
|
||||
AFLAGS_KERNEL
|
||||
-------------
|
||||
内置模块的额外汇编选项。
|
||||
|
||||
KCFLAGS
|
||||
-------
|
||||
传递给 C 编译器的额外选项(适用于内置模块和外部模块)。
|
||||
|
||||
KRUSTFLAGS
|
||||
----------
|
||||
传递给 Rust 编译器的额外选项(适用于内置模块和外部模块)。
|
||||
|
||||
CFLAGS_KERNEL
|
||||
-------------
|
||||
在编译内置代码时,传递给 $(CC) 的额外选项。
|
||||
|
||||
CFLAGS_MODULE
|
||||
-------------
|
||||
编译外部模块时,传递给 $(CC) 的额外模块特定选项。
|
||||
|
||||
RUSTFLAGS_KERNEL
|
||||
----------------
|
||||
在编译内置代码时,传递给 $(RUSTC) 的额外选项。
|
||||
|
||||
RUSTFLAGS_MODULE
|
||||
----------------
|
||||
用于 $(RUSTC) 的额外模块特定选项。
|
||||
|
||||
LDFLAGS_MODULE
|
||||
--------------
|
||||
用于 $(LD) 链接模块时的额外选项。
|
||||
|
||||
HOSTCFLAGS
|
||||
----------
|
||||
在构建主机程序时传递给 $(HOSTCC) 的额外标志。
|
||||
|
||||
HOSTCXXFLAGS
|
||||
------------
|
||||
在构建主机程序时传递给 $(HOSTCXX) 的额外标志。
|
||||
|
||||
HOSTRUSTFLAGS
|
||||
-------------
|
||||
在构建主机程序时传递给 $(HOSTRUSTC) 的额外标志。
|
||||
|
||||
HOSTLDFLAGS
|
||||
-----------
|
||||
链接主机程序时传递的额外选项。
|
||||
|
||||
HOSTLDLIBS
|
||||
----------
|
||||
在构建主机程序时链接的额外库。
|
||||
|
||||
.. _zh_cn_userkbuildflags:
|
||||
|
||||
USERCFLAGS
|
||||
----------
|
||||
用于 $(CC) 编译用户程序(userprogs)时的额外选项。
|
||||
|
||||
USERLDFLAGS
|
||||
-----------
|
||||
用于 $(LD) 链接用户程序时的额外选项。用户程序(userprogs)是使用 CC 链接的,
|
||||
因此 $(USERLDFLAGS) 应该根据需要包含 "-Wl," 前缀。
|
||||
|
||||
KBUILD_KCONFIG
|
||||
--------------
|
||||
将顶级 Kconfig 文件设置为此环境变量的值。默认名称为 "Kconfig"。
|
||||
|
||||
KBUILD_VERBOSE
|
||||
--------------
|
||||
设置 kbuild 的详细程度。可以分配与 "V=..." 相同的值。
|
||||
|
||||
有关完整列表,请参见 `make help`。
|
||||
|
||||
设置 "V=..." 优先于 KBUILD_VERBOSE。
|
||||
|
||||
KBUILD_EXTMOD
|
||||
-------------
|
||||
在构建外部模块时设置内核源代码的搜索目录。
|
||||
|
||||
设置 "M=..." 优先于 KBUILD_EXTMOD。
|
||||
|
||||
KBUILD_OUTPUT
|
||||
-------------
|
||||
指定内核构建的输出目录。
|
||||
|
||||
在单独的构建目录中为预构建内核构建外部模块时,这个变量也可以指向内核输出目录。请注意,
|
||||
这并不指定外部模块本身的输出目录。
|
||||
|
||||
输出目录也可以使用 "O=..." 指定。
|
||||
|
||||
设置 "O=..." 优先于 KBUILD_OUTPUT。
|
||||
|
||||
KBUILD_EXTRA_WARN
|
||||
-----------------
|
||||
指定额外的构建检查。也可以通过在命令行传递 "W=..." 来设置相同的值。
|
||||
|
||||
请参阅 `make help` 了解支持的值列表。
|
||||
|
||||
设置 "W=..." 优先于 KBUILD_EXTRA_WARN。
|
||||
|
||||
KBUILD_DEBARCH
|
||||
--------------
|
||||
对于 deb-pkg 目标,允许覆盖 deb-pkg 部署的正常启发式方法。通常 deb-pkg 尝试根据
|
||||
UTS_MACHINE 变量(在某些架构中还包括内核配置)来猜测正确的架构。KBUILD_DEBARCH
|
||||
的值假定(不检查)为有效的 Debian 架构。
|
||||
|
||||
KDOCFLAGS
|
||||
---------
|
||||
指定在构建过程中用于 kernel-doc 检查的额外(警告/错误)标志,查看
|
||||
scripts/kernel-doc 了解支持的标志。请注意,这目前不适用于文档构建。
|
||||
|
||||
ARCH
|
||||
----
|
||||
设置 ARCH 为要构建的架构。
|
||||
|
||||
在大多数情况下,架构的名称与 arch/ 目录中的子目录名称相同。
|
||||
|
||||
但某些架构(如 x86 和 sparc)有别名。
|
||||
|
||||
- x86: i386 表示 32 位,x86_64 表示 64 位
|
||||
- parisc: parisc64 表示 64 位
|
||||
- sparc: sparc32 表示 32 位,sparc64 表示 64 位
|
||||
|
||||
CROSS_COMPILE
|
||||
-------------
|
||||
指定 binutils 文件名的可选固定部分。CROSS_COMPILE 可以是文件名的一部分或完整路径。
|
||||
|
||||
在某些设置中,CROSS_COMPILE 也用于 ccache。
|
||||
|
||||
CF
|
||||
--
|
||||
用于 sparse 的额外选项。
|
||||
|
||||
CF 通常在命令行中如下所示使用::
|
||||
|
||||
make CF=-Wbitwise C=2
|
||||
|
||||
INSTALL_PATH
|
||||
------------
|
||||
INSTALL_PATH 指定放置更新后的内核和系统映像的路径。默认值是 /boot,但你可以设置
|
||||
为其他值。
|
||||
|
||||
INSTALLKERNEL
|
||||
-------------
|
||||
使用 "make install" 时调用的安装脚本。
|
||||
默认名称是 "installkernel"。
|
||||
|
||||
该脚本将会以以下参数调用:
|
||||
|
||||
- $1 - 内核版本
|
||||
- $2 - 内核映像文件
|
||||
- $3 - 内核映射文件
|
||||
- $4 - 默认安装路径(如果为空,则使用根目录)
|
||||
|
||||
"make install" 的实现是架构特定的,可能与上述有所不同。
|
||||
|
||||
提供 INSTALLKERNEL 以便在交叉编译内核时可以指定自定义安装程序。
|
||||
|
||||
MODLIB
|
||||
------
|
||||
指定模块的安装位置。
|
||||
默认值为::
|
||||
|
||||
$(INSTALL_MOD_PATH)/lib/modules/$(KERNELRELEASE)
|
||||
|
||||
该值可以被覆盖,在这种情况下将忽略默认值。
|
||||
|
||||
INSTALL_MOD_PATH
|
||||
----------------
|
||||
INSTALL_MOD_PATH 指定了模块目录重定位时 MODLIB 的前缀,通常由构建根
|
||||
(build roots)所需。它没有在 makefile 中定义,但如果需要,可以作为
|
||||
参数传递给 make。
|
||||
|
||||
INSTALL_MOD_STRIP
|
||||
-----------------
|
||||
如果 INSTALL_MOD_STRIP 被定义,内核模块在安装后会被剥离。如果
|
||||
INSTALL_MOD_STRIP 的值为 '1',则会使用默认选项 --strip-debug。否则,
|
||||
INSTALL_MOD_STRIP 的值将作为 strip 命令的选项。
|
||||
|
||||
INSTALL_HDR_PATH
|
||||
----------------
|
||||
INSTALL_HDR_PATH 指定了执行 "make headers_*" 时,用户空间头文件的安装位置。
|
||||
|
||||
默认值为::
|
||||
|
||||
$(objtree)/usr
|
||||
|
||||
$(objtree) 是保存输出文件的目录。
|
||||
输出目录通常使用命令行中的 "O=..." 进行设置。
|
||||
|
||||
该值可以被覆盖,在这种情况下将忽略默认值。
|
||||
|
||||
INSTALL_DTBS_PATH
|
||||
-----------------
|
||||
INSTALL_DTBS_PATH 指定了设备树二进制文件的安装位置,通常由构建根(build roots)所需。
|
||||
它没有在 makefile 中定义,但如果需要,可以作为参数传递给 make。
|
||||
|
||||
KBUILD_ABS_SRCTREE
|
||||
--------------------------------------------------
|
||||
Kbuild 在可能的情况下使用相对路径指向源代码树。例如,在源代码树中构建时,源代码树路径是
|
||||
'.'。
|
||||
|
||||
设置该标志请求 Kbuild 使用源代码树的绝对路径。
|
||||
在某些情况下这是有用的,例如在生成带有绝对路径条目的标签文件时等。
|
||||
|
||||
KBUILD_SIGN_PIN
|
||||
---------------
|
||||
当签署内核模块时,如果私钥需要密码或 PIN,此变量允许将密码或 PIN 传递给 sign-file 工具。
|
||||
|
||||
KBUILD_MODPOST_WARN
|
||||
-------------------
|
||||
KBUILD_MODPOST_WARN 可以设置为在最终模块链接阶段出现未定义符号时避免错误。它将这些错误
|
||||
转为警告。
|
||||
|
||||
KBUILD_MODPOST_NOFINAL
|
||||
----------------------
|
||||
KBUILD_MODPOST_NOFINAL 可以设置为跳过模块的最终链接。这仅在加速编译测试时有用。
|
||||
|
||||
KBUILD_EXTRA_SYMBOLS
|
||||
--------------------
|
||||
用于依赖其他模块符号的模块。详见 modules.rst。
|
||||
|
||||
ALLSOURCE_ARCHS
|
||||
---------------
|
||||
对于 tags/TAGS/cscope 目标,可以指定包含在数据库中的多个架构,用空格分隔。例如::
|
||||
|
||||
$ make ALLSOURCE_ARCHS="x86 mips arm" tags
|
||||
|
||||
要获取所有可用架构,也可以指定 all。例如::
|
||||
|
||||
$ make ALLSOURCE_ARCHS=all tags
|
||||
|
||||
IGNORE_DIRS
|
||||
-----------
|
||||
对于 tags/TAGS/cscope 目标,可以选择不包含在数据库中的目录,用空格分隔。例如::
|
||||
|
||||
$ make IGNORE_DIRS="drivers/gpu/drm/radeon tools" cscope
|
||||
|
||||
KBUILD_BUILD_TIMESTAMP
|
||||
----------------------
|
||||
将该环境变量设置为日期字符串,可以覆盖在 UTS_VERSION 定义中使用的时间戳
|
||||
(运行内核时的 uname -v)。该值必须是一个可以传递给 date -d 的字符串。默认值是
|
||||
内核构建某个时刻的 date 命令输出。
|
||||
|
||||
KBUILD_BUILD_USER, KBUILD_BUILD_HOST
|
||||
------------------------------------
|
||||
这两个变量允许覆盖启动时显示的 user@host 字符串以及 /proc/version 中的信息。
|
||||
默认值分别是 whoami 和 host 命令的输出。
|
||||
|
||||
LLVM
|
||||
----
|
||||
如果该变量设置为 1,Kbuild 将使用 Clang 和 LLVM 工具,而不是 GCC 和 GNU
|
||||
binutils 来构建内核。
|
259
Documentation/translations/zh_CN/kbuild/kconfig.rst
Normal file
259
Documentation/translations/zh_CN/kbuild/kconfig.rst
Normal file
@ -0,0 +1,259 @@
|
||||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
.. include:: ../disclaimer-zh_CN.rst
|
||||
|
||||
:Original: Documentation/kbuild/kconfig.rst
|
||||
:Translator: 慕冬亮 Dongliang Mu <dzm91@hust.edu.cn>
|
||||
|
||||
================
|
||||
配置目标和编辑器
|
||||
================
|
||||
|
||||
本文件包含使用 ``make *config`` 的一些帮助。
|
||||
|
||||
使用 ``make help`` 列出所有可能的配置目标。
|
||||
|
||||
xconfig('qconf')、menuconfig('mconf')和 nconfig('nconf')程序也包含
|
||||
内嵌的帮助文本。请务必查看这些帮助文本以获取导航、搜索和其他帮助信息。
|
||||
|
||||
gconfig('gconf')程序的帮助文本较少。
|
||||
|
||||
|
||||
通用信息
|
||||
========
|
||||
|
||||
新的内核版本通常会引入新的配置符号。更重要的是,新的内核版本可能会重命名配置符号。
|
||||
当这种情况发生时,使用之前正常工作的 .config 文件并运行 "make oldconfig"
|
||||
不一定会生成一个可正常工作的新内核,因此,你可能需要查看哪些新的内核符号被引入。
|
||||
|
||||
要查看新配置符号的列表,请使用::
|
||||
|
||||
cp user/some/old.config .config
|
||||
make listnewconfig
|
||||
|
||||
配置程序将列出所有新配置符号,每行一个。
|
||||
|
||||
或者,你可以使用暴力破解方法::
|
||||
|
||||
make oldconfig
|
||||
scripts/diffconfig .config.old .config | less
|
||||
|
||||
|
||||
环境变量
|
||||
========
|
||||
|
||||
``*config`` 的环境变量:
|
||||
|
||||
``KCONFIG_CONFIG``
|
||||
该环境变量可用于指定一个默认的内核配置文件名,以覆盖默认的 ".config"。
|
||||
|
||||
``KCONFIG_DEFCONFIG_LIST``
|
||||
该环境变量指定了一个配置文件列表,当 .config 不存在时,这些文件可用作基础配置。
|
||||
列表中的条目以空格分隔,只有第一个存在的文件会被使用。
|
||||
|
||||
``KCONFIG_OVERWRITECONFIG``
|
||||
如果该环境变量被设置,当 .config 是指向其他位置的符号链接时,Kconfig 不会
|
||||
破坏符号链接。
|
||||
|
||||
``KCONFIG_WARN_UNKNOWN_SYMBOLS``
|
||||
该环境变量使 Kconfig 对配置输入中所有无法识别的符号发出警告。
|
||||
|
||||
``KCONFIG_WERROR``
|
||||
如果该环境变量被设置,Kconfig 将所有警告视为错误。
|
||||
|
||||
``CONFIG_``
|
||||
如果该环境变量被设置,Kconfig 将在保存配置时,为所有符号添加其值作为前缀,
|
||||
而不是使用默认值。
|
||||
|
||||
``{allyes/allmod/allno/rand}config`` 的环境变量:
|
||||
|
||||
``KCONFIG_ALLCONFIG``
|
||||
allyesconfig/allmodconfig/allnoconfig/randconfig 这些变体也可以使用环境
|
||||
变量 KCONFIG_ALLCONFIG 作为标志或包含用户要求设置为特定值的配置符号的文件名。
|
||||
如果 KCONFIG_ALLCONFIG 未指定文件名,即 KCONFIG_ALLCONFIG == "" 或
|
||||
KCONFIG_ALLCONFIG == "1",则 ``make *config`` 将查找名为
|
||||
"all{yes/mod/no/def/random}.config" 的文件(对应于所使用的 ``*config``
|
||||
命令)以强制符号值。如果找不到此文件,它会查找名为 "all.config" 的文件以包含
|
||||
强制值。
|
||||
|
||||
这可以创建“微型”配置(miniconfig)或自定义配置文件,其中仅包含感兴趣的配置符号。
|
||||
然后,内核配置系统将生成完整的 .config 文件,包括 miniconfig 文件中的符号。
|
||||
|
||||
``KCONFIG_ALLCONFIG`` 文件包含许多预设配置符号(通常是所有符号的子集)。
|
||||
这些变量设置仍需遵守正常的依赖性检查。
|
||||
|
||||
示例::
|
||||
|
||||
KCONFIG_ALLCONFIG=custom-notebook.config make allnoconfig
|
||||
|
||||
或::
|
||||
|
||||
KCONFIG_ALLCONFIG=mini.config make allnoconfig
|
||||
|
||||
或::
|
||||
|
||||
make KCONFIG_ALLCONFIG=mini.config allnoconfig
|
||||
|
||||
这些示例将禁用大多数配置选项(allnoconfig),但启用或禁用 miniconfig 文件
|
||||
中显式列出的选项。
|
||||
|
||||
``randconfig`` 的环境变量:
|
||||
|
||||
``KCONFIG_SEED``
|
||||
如果你想调试 kconfig 解析器/前端的行为,你可以将此变量设置整数值,用于初始化
|
||||
随机数生成器。如果未设置,将使用当前时间。
|
||||
|
||||
``KCONFIG_PROBABILITY``
|
||||
该变量可用于倾斜概率分布。此变量可不设置或设置为空,或设置为以下三种不同格式:
|
||||
|
||||
======================= ================== =====================
|
||||
KCONFIG_PROBABILITY y:n 分配 y:m:n 分配
|
||||
======================= ================== =====================
|
||||
未设置或设置为空 50 : 50 33 : 33 : 34
|
||||
N N : 100-N N/2 : N/2 : 100-N
|
||||
[1] N:M N+M : 100-(N+M) N : M : 100-(N+M)
|
||||
[2] N:M:L N : 100-N M : L : 100-(M+L)
|
||||
======================= ================== =====================
|
||||
|
||||
其中 N、M 和 L 是范围在 [0,100] 内的整数(以十进制表示),并且需满足:
|
||||
|
||||
[1] N+M 的范围在 [0,100] 之间
|
||||
|
||||
[2] M+L 的范围在 [0,100] 之间
|
||||
|
||||
示例::
|
||||
|
||||
KCONFIG_PROBABILITY=10
|
||||
10% 的布尔值将设置为 'y',90% 设置为 'n'
|
||||
5% 的三态值将设置为 'y',5% 设置为 'm',90% 设置为 'n'
|
||||
KCONFIG_PROBABILITY=15:25
|
||||
40% 的布尔值将设置为 'y',60% 设置为 'n'
|
||||
15% 的三态值将设置为 'y',25% 设置为 'm',60% 设置为 'n'
|
||||
KCONFIG_PROBABILITY=10:15:15
|
||||
10% 的布尔值将设置为 'y',90% 设置为 'n'
|
||||
15% 的三态值将设置为 'y',15% 设置为 'm',70% 设置为 'n'
|
||||
|
||||
``syncconfig`` 的环境变量:
|
||||
|
||||
``KCONFIG_NOSILENTUPDATE``
|
||||
如果该变量非空,它将阻止静默的内核配置更新(需要明确更新)。
|
||||
|
||||
``KCONFIG_AUTOCONFIG``
|
||||
该环境变量可以设置为 "auto.conf" 文件的路径和名称。默认值为
|
||||
"include/config/auto.conf"。
|
||||
|
||||
``KCONFIG_AUTOHEADER``
|
||||
该环境变量可以设置为 "autoconf.h" 头文件的路径和名称。默认值为
|
||||
"include/generated/autoconf.h"。
|
||||
|
||||
menuconfig
|
||||
==========
|
||||
|
||||
在 menuconfig 中搜索:
|
||||
|
||||
搜索功能会搜索内核配置符号名称,因此你必须知道欲搜索内容的大致名称。
|
||||
|
||||
示例::
|
||||
|
||||
/hotplug
|
||||
这会列出所有包含 "hotplug" 的配置符号,例如,HOTPLUG_CPU,
|
||||
MEMORY_HOTPLUG。
|
||||
|
||||
若需要搜索帮助,输入 / 后跟 TAB-TAB(高亮显示 <Help>)并按回车键。
|
||||
这说明你还可以在搜索字符串中使用正则表达式(regex),所以如果你对
|
||||
MEMORY_HOTPLUG 不感兴趣,你可以尝试::
|
||||
|
||||
/^hotplug
|
||||
|
||||
在搜索时,符号将按以下顺序排序:
|
||||
|
||||
- 首先,完全匹配的符号,按字母顺序排列(完全匹配是指搜索与符号名称完全匹配);
|
||||
- 然后是其他匹配项,按字母顺序排列。
|
||||
|
||||
例如,^ATH.K 匹配::
|
||||
|
||||
ATH5K ATH9K ATH5K_AHB ATH5K_DEBUG [...] ATH6KL ATH6KL_DEBUG
|
||||
[...] ATH9K_AHB ATH9K_BTCOEX_SUPPORT ATH9K_COMMON [...]
|
||||
|
||||
其中只有 ATH5K 和 ATH9K 完全匹配,因此它们排在前面(按字母顺序),
|
||||
接下来是其他符号,同样按字母顺序排列。
|
||||
|
||||
在此菜单中,按下以 (#) 为前缀的键将直接跳转到该位置。退出此新菜单后,
|
||||
你将返回当前的搜索结果。
|
||||
|
||||
'menuconfig' 的用户界面选项:
|
||||
|
||||
``MENUCONFIG_COLOR``
|
||||
可以使用变量 MENUCONFIG_COLOR 选择不同的配色主题。使用以下命令选择主题::
|
||||
|
||||
make MENUCONFIG_COLOR=<theme> menuconfig
|
||||
|
||||
可用的主题有::
|
||||
|
||||
- mono => 选择适合单色显示器的颜色
|
||||
- blackbg => 选择具有黑色背景的配色方案
|
||||
- classic => 经典外观,蓝色背景
|
||||
- bluetitle => 经典外观的 LCD 友好版本(默认)
|
||||
|
||||
``MENUCONFIG_MODE``
|
||||
此模式会将所有子菜单显示为一个大树状结构。
|
||||
|
||||
示例::
|
||||
|
||||
make MENUCONFIG_MODE=single_menu menuconfig
|
||||
|
||||
nconfig
|
||||
=======
|
||||
|
||||
nconfig 是一个替代的基于文本的配置工具。它在终端(窗口)底部列出功能键,用于执行
|
||||
命令。除非你在数据输入窗口中,否则你也可以直接使用相应的数字键来执行命令。例如,你
|
||||
可以直接按 6,而非 F6 进行保存。
|
||||
|
||||
使用 F1 获取全局帮助或 F3 打开简短帮助菜单。
|
||||
|
||||
在 nconfig 中搜索:
|
||||
|
||||
你可以在菜单项“提示”字符串中或配置符号中进行搜索。
|
||||
|
||||
使用 / 开始在菜单项中搜索。这不支持正则表达式。使用 <Down> 或 <Up>
|
||||
分别为下一个命中项和上一个命中项。使用 <Esc> 退出搜索模式。
|
||||
|
||||
F8(SymSearch)在配置符号中搜索给定的字符串或正则表达式(regex)。
|
||||
|
||||
在 SymSearch 中,按下 (#) 前缀的键会直接跳转到该位置。退出该新菜单后,
|
||||
你将返回到当前的搜索结果。
|
||||
|
||||
环境变量:
|
||||
|
||||
``NCONFIG_MODE``
|
||||
此模式会将所有子菜单显示为一个大型树结构。
|
||||
|
||||
示例::
|
||||
|
||||
make NCONFIG_MODE=single_menu nconfig
|
||||
|
||||
xconfig
|
||||
=======
|
||||
|
||||
在 xconfig 中搜索:
|
||||
|
||||
搜索功能会搜索内核配置符号名称,因此你必须知道欲搜索内容的大致名称。
|
||||
|
||||
示例::
|
||||
|
||||
Ctrl-F hotplug
|
||||
|
||||
或::
|
||||
|
||||
菜单:File, Search, hotplug
|
||||
|
||||
列出所有符号名称中包含 "hotplug" 的配置符号项。在此搜索对话框中,
|
||||
你可以更改任何未灰显条目的配置设置。你还可以输入不同的搜索字符串,
|
||||
而无需返回主菜单。
|
||||
|
||||
gconfig
|
||||
=======
|
||||
|
||||
在 gconfig 中搜索:
|
||||
|
||||
gconfig 中没有搜索命令。然而,gconfig 具有几种不同的查看选择、模式和选项。
|
203
Documentation/translations/zh_CN/kbuild/llvm.rst
Normal file
203
Documentation/translations/zh_CN/kbuild/llvm.rst
Normal file
@ -0,0 +1,203 @@
|
||||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
.. include:: ../disclaimer-zh_CN.rst
|
||||
|
||||
:Original: Documentation/kbuild/llvm.rst
|
||||
:Translator: 慕冬亮 Dongliang Mu <dzm91@hust.edu.cn>
|
||||
|
||||
==========================
|
||||
使用 Clang/LLVM 构建 Linux
|
||||
==========================
|
||||
|
||||
本文档介绍如何使用 Clang 和 LLVM 工具构建 Linux 内核。
|
||||
|
||||
关于
|
||||
----
|
||||
|
||||
Linux 内核传统上一直使用 GNU 工具链(如 GCC 和 binutils)进行编译。持续的工作使得
|
||||
`Clang <https://clang.llvm.org/>`_ 和 `LLVM <https://llvm.org/>`_ 工具可
|
||||
作为可行的替代品。一些发行版,如 `Android <https://www.android.com/>`_、
|
||||
`ChromeOS <https://www.chromium.org/chromium-os>`_、`OpenMandriva
|
||||
<https://www.openmandriva.org/>`_ 和 `Chimera Linux
|
||||
<https://chimera-linux.org/>`_ 使用 Clang 编译的内核。谷歌和 Meta 的数据中心
|
||||
集群也运行由 Clang 编译的内核。
|
||||
|
||||
`LLVM 是由 C++ 对象实现的工具链组件集合 <https://www.aosabook.org/en/llvm.html>`_。
|
||||
Clang 是 LLVM 的前端,支持 C 语言和内核所需的 GNU C 扩展,其发音为 "klang",而非
|
||||
"see-lang"。
|
||||
|
||||
使用 LLVM 构建
|
||||
--------------
|
||||
|
||||
通过以下命令调用 ``make``::
|
||||
|
||||
make LLVM=1
|
||||
|
||||
为主机目标进行编译。对于交叉编译::
|
||||
|
||||
make LLVM=1 ARCH=arm64
|
||||
|
||||
LLVM= 参数
|
||||
----------
|
||||
|
||||
LLVM 有 GNU binutils 工具的替代品。这些工具可以单独启用。以下是支持的 make 变量
|
||||
完整列表::
|
||||
|
||||
make CC=clang LD=ld.lld AR=llvm-ar NM=llvm-nm STRIP=llvm-strip \
|
||||
OBJCOPY=llvm-objcopy OBJDUMP=llvm-objdump READELF=llvm-readelf \
|
||||
HOSTCC=clang HOSTCXX=clang++ HOSTAR=llvm-ar HOSTLD=ld.lld
|
||||
|
||||
``LLVM=1`` 扩展为上述命令。
|
||||
|
||||
如果你的 LLVM 工具不在 PATH 中,你可以使用以斜杠结尾的 LLVM 变量提供它们的位置::
|
||||
|
||||
make LLVM=/path/to/llvm/
|
||||
|
||||
这将使用 ``/path/to/llvm/clang``、``/path/to/llvm/ld.lld`` 等工具。也可以
|
||||
使用以下命令::
|
||||
|
||||
PATH=/path/to/llvm:$PATH make LLVM=1
|
||||
|
||||
如果你的 LLVM 工具带有版本后缀,并且你希望测试该特定版本而非无后缀的可执行文件,
|
||||
类似于 ``LLVM=1``,你可以使用 ``LLVM`` 变量传递该后缀::
|
||||
|
||||
make LLVM=-14
|
||||
|
||||
这将使用 ``clang-14``、``ld.lld-14`` 等工具。为了支持带有版本后缀的树外路径组合,
|
||||
我们建议::
|
||||
|
||||
PATH=/path/to/llvm/:$PATH make LLVM=-14
|
||||
|
||||
``LLVM=0`` 与省略 ``LLVM`` 完全不同,它将表现得像 ``LLVM=1``。如果你只希望使用
|
||||
某些 LLVM 工具,请使用它们各自的 make 变量。
|
||||
|
||||
在通过不同命令配置和构建时,应为每次调用 ``make`` 设置相同的 ``LLVM=`` 值。如果
|
||||
运行的脚本最终会调用 ``make``,则还应将 ``LLVM=`` 设置为环境变量。
|
||||
|
||||
交叉编译
|
||||
--------
|
||||
|
||||
单个 Clang 编译器二进制文件(及其对应的 LLVM 工具)通常会包含所有支持的后端,这可以
|
||||
简化交叉编译,尤其是使用 ``LLVM=1`` 时。如果仅使用 LLVM 工具,``CROSS_COMPILE``
|
||||
或目标三元组前缀就变得不必要。示例::
|
||||
|
||||
make LLVM=1 ARCH=arm64
|
||||
|
||||
作为混合 LLVM 和 GNU 工具的示例,对于像 ``ARCH=s390`` 这样目前尚不支持
|
||||
``ld.lld`` 或 ``llvm-objcopy`` 的目标,你可以通过以下方式调用 ``make``::
|
||||
|
||||
make LLVM=1 ARCH=s390 LD=s390x-linux-gnu-ld.bfd \
|
||||
OBJCOPY=s390x-linux-gnu-objcopy
|
||||
|
||||
此示例将调用 ``s390x-linux-gnu-ld.bfd`` 作为链接器和
|
||||
``s390x-linux-gnu-objcopy``,因此请确保它们在你的 ``$PATH`` 中。
|
||||
|
||||
当 ``LLVM=1`` 未设置时,``CROSS_COMPILE`` 不会用于给 Clang 编译器二进制文件
|
||||
(或相应的 LLVM 工具)添加前缀,而 GNU 工具则需要这样做。
|
||||
|
||||
LLVM_IAS= 参数
|
||||
--------------
|
||||
|
||||
Clang 可以编译汇编代码。你可以传递 ``LLVM_IAS=0`` 禁用此行为,使 Clang 调用
|
||||
相应的非集成汇编器。示例::
|
||||
|
||||
make LLVM=1 LLVM_IAS=0
|
||||
|
||||
在交叉编译时,你需要使用 ``CROSS_COMPILE`` 与 ``LLVM_IAS=0``,从而设置
|
||||
``--prefix=`` 使得编译器可以对应的非集成汇编器(通常,在面向另一种架构时,
|
||||
你不想使用系统汇编器)。例如::
|
||||
|
||||
make LLVM=1 ARCH=arm LLVM_IAS=0 CROSS_COMPILE=arm-linux-gnueabi-
|
||||
|
||||
Ccache
|
||||
------
|
||||
|
||||
``ccache`` 可以与 ``clang`` 一起使用,以改善后续构建(尽管在不同构建之间
|
||||
KBUILD_BUILD_TIMESTAMP_ 应设置为同一确定值,以避免 100% 的缓存未命中,
|
||||
详见 Reproducible_builds_ 获取更多信息)::
|
||||
|
||||
KBUILD_BUILD_TIMESTAMP='' make LLVM=1 CC="ccache clang"
|
||||
|
||||
.. _KBUILD_BUILD_TIMESTAMP: kbuild.html#kbuild-build-timestamp
|
||||
.. _Reproducible_builds: reproducible-builds.html#timestamps
|
||||
|
||||
支持的架构
|
||||
----------
|
||||
|
||||
LLVM 并不支持 Linux 内核所有可支持的架构,同样,即使 LLVM 支持某一架构,也并不意味着在
|
||||
该架构下内核可以正常构建或工作。以下是当前 ``CC=clang`` 或 ``LLVM=1`` 支持的架构总结。
|
||||
支持级别对应于 MAINTAINERS 文件中的 "S" 值。如果某个架构未列出,则表示 LLVM 不支持它
|
||||
或存在已知问题。使用最新的稳定版 LLVM 或甚至开发版本通常会得到最佳结果。一个架构的
|
||||
``defconfig`` 通常预期能够良好工作,但某些配置可能存在尚未发现的问题。欢迎在以下
|
||||
问题跟踪器中提交错误报告!
|
||||
|
||||
.. list-table::
|
||||
:widths: 10 10 10
|
||||
:header-rows: 1
|
||||
|
||||
* - 架构
|
||||
- 支持级别
|
||||
- ``make`` 命令
|
||||
* - arm
|
||||
- 支持
|
||||
- ``LLVM=1``
|
||||
* - arm64
|
||||
- 支持
|
||||
- ``LLVM=1``
|
||||
* - hexagon
|
||||
- 维护
|
||||
- ``LLVM=1``
|
||||
* - loongarch
|
||||
- 维护
|
||||
- ``LLVM=1``
|
||||
* - mips
|
||||
- 维护
|
||||
- ``LLVM=1``
|
||||
* - powerpc
|
||||
- 维护
|
||||
- ``LLVM=1``
|
||||
* - riscv
|
||||
- 支持
|
||||
- ``LLVM=1``
|
||||
* - s390
|
||||
- 维护
|
||||
- ``LLVM=1`` (LLVM >= 18.1.0),``CC=clang`` (LLVM < 18.1.0)
|
||||
* - um (用户模式)
|
||||
- 维护
|
||||
- ``LLVM=1``
|
||||
* - x86
|
||||
- 支持
|
||||
- ``LLVM=1``
|
||||
|
||||
获取帮助
|
||||
--------
|
||||
|
||||
- `网站 <https://clangbuiltlinux.github.io/>`_
|
||||
- `邮件列表 <https://lore.kernel.org/llvm/>`_: <llvm@lists.linux.dev>
|
||||
- `旧邮件列表档案 <https://groups.google.com/g/clang-built-linux>`_
|
||||
- `问题跟踪器 <https://github.com/ClangBuiltLinux/linux/issues>`_
|
||||
- IRC: #clangbuiltlinux 在 irc.libera.chat
|
||||
- `Telegram <https://t.me/ClangBuiltLinux>`_: @ClangBuiltLinux
|
||||
- `维基 <https://github.com/ClangBuiltLinux/linux/wiki>`_
|
||||
- `初学者问题 <https://github.com/ClangBuiltLinux/linux/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22>`_
|
||||
|
||||
.. _zh_cn_getting_llvm:
|
||||
|
||||
获取 LLVM
|
||||
---------
|
||||
|
||||
我们在 `kernel.org <https://kernel.org/pub/tools/llvm/>`_ 提供预编译的稳定版 LLVM。
|
||||
这些版本已经针对 Linux 内核构建,使用配置文件数据进行优化。相较于其他发行版中的 LLVM,它们应该
|
||||
能提高内核构建效率。
|
||||
|
||||
以下是一些有助于从源代码构建 LLVM 或通过发行版的包管理器获取 LLVM 的链接。
|
||||
|
||||
- https://releases.llvm.org/download.html
|
||||
- https://github.com/llvm/llvm-project
|
||||
- https://llvm.org/docs/GettingStarted.html
|
||||
- https://llvm.org/docs/CMake.html
|
||||
- https://apt.llvm.org/
|
||||
- https://www.archlinux.org/packages/extra/x86_64/llvm/
|
||||
- https://github.com/ClangBuiltLinux/tc-build
|
||||
- https://github.com/ClangBuiltLinux/linux/wiki/Building-Clang-from-source
|
||||
- https://android.googlesource.com/platform/prebuilts/clang/host/linux-x86/
|
114
Documentation/translations/zh_CN/kbuild/reproducible-builds.rst
Normal file
114
Documentation/translations/zh_CN/kbuild/reproducible-builds.rst
Normal file
@ -0,0 +1,114 @@
|
||||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
.. include:: ../disclaimer-zh_CN.rst
|
||||
|
||||
:Original: Documentation/kbuild/reproducible-builds.rst
|
||||
|
||||
:Translator: 慕冬亮 Dongliang Mu <dzm91@hust.edu.cn>
|
||||
|
||||
============
|
||||
可重现的构建
|
||||
============
|
||||
|
||||
通常希望使用相同工具集构建相同源代码是可重现的,即,输出始终完全相同。这使得能够验证
|
||||
二进制分发或嵌入式系统的构建基础设施未被篡改。这样也更容易验证源代码或工具的更改不会
|
||||
影响最终生成的二进制文件。
|
||||
|
||||
`可重现构建项目`_ 提供了有关该主题的更多信息。本文档涵盖了构建内核可能不可重现的
|
||||
各种原因,以及如何避免这些问题。
|
||||
|
||||
时间戳
|
||||
------
|
||||
|
||||
内核在三个地方嵌入时间戳:
|
||||
|
||||
* 通过 ``uname()`` 显示与包含在 ``/proc/version`` 中的版本字符串
|
||||
|
||||
* initramfs 中的文件时间戳
|
||||
|
||||
* 如果启动 ``CONFIG_IKHEADERS``,内核或相应模块中嵌入的内核头文件的时间戳,
|
||||
通过 ``/sys/kernel/kheaders.tar.xz`` 显示
|
||||
|
||||
默认情况下,时间戳为当前时间或内核头文件的修改时间。这个内容必须使用
|
||||
`KBUILD_BUILD_TIMESTAMP`_ 变量进行覆盖。如果你从某个 git 提交进行构建,
|
||||
可以使用其提交日期。
|
||||
|
||||
内核 *不* 使用 ``__DATE__`` 和 ``__TIME__`` 宏,并在使用这些宏时启用警告。
|
||||
如果你合并的外部代码使用这些宏,则必须通过设置 `SOURCE_DATE_EPOCH`_ 环境
|
||||
变量来覆盖它们对应的时间戳。
|
||||
|
||||
用户,主机
|
||||
----------
|
||||
|
||||
内核在 ``/proc/version`` 中嵌入构建用户和主机名。必须使用
|
||||
`KBUILD_BUILD_USER 和 KBUILD_BUILD_HOST`_ 变量来覆盖这些设置。如果
|
||||
您从某个 git 提交进行构建,可以使用其提交者地址。
|
||||
|
||||
绝对文件名
|
||||
----------
|
||||
|
||||
当内核在树外构建时,调试信息可能包括源文件的绝对文件名。这些信息必须通过在
|
||||
`KCFLAGS`_ 变量中包含 ``-fdebug-prefix-map`` 选项来覆盖。
|
||||
|
||||
根据使用的编译器,``__FILE__`` 宏在树外构建中也可能扩展为绝对文件名。Kbuild
|
||||
自动使用 ``-fmacro-prefix-map`` 选项来防止这种情况,前提是它被支持。
|
||||
|
||||
可重现构建网站提供了有关这些 `prefix-map 选项`_ 的更多信息。
|
||||
|
||||
在源包中的生成文件
|
||||
------------------
|
||||
|
||||
在 ``tools/`` 子目录下,一些程序的构建过程并不完全支持树外构建。这可能导致后续
|
||||
使用如 ``make rpm-pkg`` 构建的源码包包含生成的文件。在构建源码包之前,您应该通过
|
||||
运行 ``make mrproper`` 或 ``git clean -d -f -x`` 来确保源码树是干净的。
|
||||
|
||||
模块签名
|
||||
--------
|
||||
|
||||
如果你启用 ``CONFIG_MODULE_SIG_ALL``,默认行为是为每次构建生成不同的临时密钥,
|
||||
从而导致模块不可重现。然而,将签名密钥包含在源代码中显然会违背签名模块的目的。
|
||||
|
||||
一种方法是将构建过程分为几个部分,以便不可重现的部分可以作为源处理:
|
||||
|
||||
1. 生成一个持久的签名密钥。将该密钥的证书添加到内核源代码中。
|
||||
|
||||
2. 将 ``CONFIG_SYSTEM_TRUSTED_KEYS`` 符号设置为包括签名密钥的证书,将
|
||||
``CONFIG_MODULE_SIG_KEY`` 设置为空字符串,并禁用 ``CONFIG_MODULE_SIG_ALL``。
|
||||
最后,构建内核和模块。
|
||||
|
||||
3. 为模块创建分离的签名,并将它们作为源发布。
|
||||
|
||||
4. 附加模块签名并进行第二次构建。这可以重建模块,或使用步骤 2 的输出。
|
||||
|
||||
结构随机化
|
||||
----------
|
||||
|
||||
如果你启用 ``CONFIG_RANDSTRUCT``,则需要在 ``scripts/basic/randstruct.seed``
|
||||
中预生成随机种子,以便每次构建都使用相同的值。有关详细信息,请参见
|
||||
``scripts/gen-randstruct-seed.sh``。
|
||||
|
||||
调试信息冲突
|
||||
------------
|
||||
|
||||
这并非是个不可重现性的问题,而是生成的文件 *过于* 可重现的问题。
|
||||
|
||||
一旦你设置了所有必要的变量来开展可重现构建,vDSO 的调试信息可能即使对于不同的内核版
|
||||
本也是相同的。这会导致不同内核版本的调试信息软件包之间发生文件冲突。
|
||||
|
||||
为了避免这种情况,你可以通过在 vDSO 中包含一个任意的 salt 字符串,使其对于不同的
|
||||
内核版本是不同的。这种机制由 Kconfig 符号 ``CONFIG_BUILD_SALT`` 指定。
|
||||
|
||||
Git
|
||||
---
|
||||
|
||||
未提交的更改或 Git 中的不同提交 ID 也可能导致不同的编译结果。例如,在执行
|
||||
``git reset HEAD^`` 后,即使代码相同,编译期间生成的
|
||||
``include/config/kernel.release`` 也会不同,导致最终生成的二进制文件也不尽相同。
|
||||
有关详细信息,请参见 ``scripts/setlocalversion``。
|
||||
|
||||
.. _KBUILD_BUILD_TIMESTAMP: kbuild.html#kbuild-build-timestamp
|
||||
.. _KBUILD_BUILD_USER 和 KBUILD_BUILD_HOST: kbuild.html#kbuild-build-user-kbuild-build-host
|
||||
.. _KCFLAGS: kbuild.html#kcflags
|
||||
.. _prefix-map 选项: https://reproducible-builds.org/docs/build-path/
|
||||
.. _可重现构建项目: https://reproducible-builds.org/
|
||||
.. _SOURCE_DATE_EPOCH: https://reproducible-builds.org/docs/source-date-epoch/
|
@ -13,6 +13,11 @@
|
||||
Active MM
|
||||
=========
|
||||
|
||||
注意,在配置了 CONFIG_MMU_LAZY_TLB_REFCOUNT=n 的内核中,mm_count 引用计数
|
||||
可能不再包括“懒惰”用户(运行任务中 ->active_mm == mm && ->mm == NULL)。
|
||||
获取和释放这些懒惰引用必须使用 mmgrab_lazy_tlb() 和 mmdrop_lazy_tlb() 这
|
||||
两个辅助函数,它们抽象了这个配置选项。
|
||||
|
||||
这是一封linux之父回复开发者的一封邮件,所以翻译时我尽量保持邮件格式的完整。
|
||||
|
||||
::
|
||||
|
@ -13,23 +13,6 @@
|
||||
常见问题
|
||||
========
|
||||
|
||||
为什么是一个新的子系统,而不是扩展perf或其他用户空间工具?
|
||||
==========================================================
|
||||
|
||||
首先,因为它需要尽可能的轻量级,以便可以在线使用,所以应该避免任何不必要的开销,如内核-用户
|
||||
空间的上下文切换成本。第二,DAMON的目标是被包括内核在内的其他程序所使用。因此,对特定工具
|
||||
(如perf)的依赖性是不可取的。这就是DAMON在内核空间实现的两个最大的原因。
|
||||
|
||||
|
||||
“闲置页面跟踪” 或 “perf mem” 可以替代DAMON吗?
|
||||
==============================================
|
||||
|
||||
闲置页跟踪是物理地址空间访问检查的一个低层次的原始方法。“perf mem”也是类似的,尽管它可以
|
||||
使用采样来减少开销。另一方面,DAMON是一个更高层次的框架,用于监控各种地址空间。它专注于内
|
||||
存管理优化,并提供复杂的精度/开销处理机制。因此,“空闲页面跟踪” 和 “perf mem” 可以提供
|
||||
DAMON输出的一个子集,但不能替代DAMON。
|
||||
|
||||
|
||||
DAMON是否只支持虚拟内存?
|
||||
=========================
|
||||
|
||||
|
@ -129,13 +129,7 @@ struct page可以与现有的 mm 机制进行最简单、最干净的集成。
|
||||
int hmm_range_fault(struct hmm_range *range);
|
||||
|
||||
如果请求写访问,它将在丢失或只读条目上触发缺页异常(见下文)。缺页异常使用通用的 mm 缺
|
||||
页异常代码路径,就像 CPU 缺页异常一样。
|
||||
|
||||
这两个函数都将 CPU 页表条目复制到它们的 pfns 数组参数中。该数组中的每个条目对应于虚拟
|
||||
范围中的一个地址。HMM 提供了一组标志来帮助驱动程序识别特殊的 CPU 页表项。
|
||||
|
||||
在 sync_cpu_device_pagetables() 回调中锁定是驱动程序必须尊重的最重要的方面,以保
|
||||
持事物正确同步。使用模式是::
|
||||
页异常代码路径,就像 CPU 缺页异常一样。使用模式是::
|
||||
|
||||
int driver_populate_range(...)
|
||||
{
|
||||
|
@ -53,6 +53,8 @@ Linux内存管理文档
|
||||
page_migration
|
||||
page_owner
|
||||
page_table_check
|
||||
page_tables
|
||||
physical_memory
|
||||
remap_file_pages
|
||||
split_page_table_lock
|
||||
vmalloced-kernel-stacks
|
||||
|
@ -16,8 +16,7 @@ Linux内核支持下列超量使用处理模式
|
||||
|
||||
0
|
||||
启发式超量使用处理。拒绝明显的地址空间超量使用。用于一个典型的系统。
|
||||
它确保严重的疯狂分配失败,同时允许超量使用以减少swap的使用。在这种模式下,
|
||||
允许root分配稍多的内存。这是默认的。
|
||||
它确保严重的疯狂分配失败,同时允许超量使用以减少swap的使用。这是默认的。
|
||||
1
|
||||
总是超量使用。适用于一些科学应用。经典的例子是使用稀疏数组的代码,只是依赖
|
||||
几乎完全由零页组成的虚拟内存
|
||||
|
@ -26,6 +26,9 @@ page owner是用来追踪谁分配的每一个页面。它可以用来调试内
|
||||
页面所有者也可以用于各种目的。例如,可以通过每个页面的gfp标志信息获得精确的碎片
|
||||
统计。如果启用了page owner,它就已经实现并激活了。我们非常欢迎其他用途。
|
||||
|
||||
它也可以用来显示所有的栈以及它们当前分配的基础页面数,这让我们能够快速了解内存的
|
||||
使用情况,而无需浏览所有页面并匹配分配和释放操作。
|
||||
|
||||
page owner在默认情况下是禁用的。所以,如果你想使用它,你需要在你的启动cmdline
|
||||
中加入"page_owner=on"。如果内核是用page owner构建的,并且由于没有启用启动
|
||||
选项而在运行时禁用page owner,那么运行时的开销是很小的。如果在运行时禁用,它不
|
||||
@ -60,6 +63,49 @@ page owner在默认情况下是禁用的。所以,如果你想使用它,你
|
||||
|
||||
4) 分析来自页面所有者的信息::
|
||||
|
||||
cat /sys/kernel/debug/page_owner_stacks/show_stacks > stacks.txt
|
||||
cat stacks.txt
|
||||
post_alloc_hook+0x177/0x1a0
|
||||
get_page_from_freelist+0xd01/0xd80
|
||||
__alloc_pages+0x39e/0x7e0
|
||||
allocate_slab+0xbc/0x3f0
|
||||
___slab_alloc+0x528/0x8a0
|
||||
kmem_cache_alloc+0x224/0x3b0
|
||||
sk_prot_alloc+0x58/0x1a0
|
||||
sk_alloc+0x32/0x4f0
|
||||
inet_create+0x427/0xb50
|
||||
__sock_create+0x2e4/0x650
|
||||
inet_ctl_sock_create+0x30/0x180
|
||||
igmp_net_init+0xc1/0x130
|
||||
ops_init+0x167/0x410
|
||||
setup_net+0x304/0xa60
|
||||
copy_net_ns+0x29b/0x4a0
|
||||
create_new_namespaces+0x4a1/0x820
|
||||
nr_base_pages: 16
|
||||
...
|
||||
...
|
||||
echo 7000 > /sys/kernel/debug/page_owner_stacks/count_threshold
|
||||
cat /sys/kernel/debug/page_owner_stacks/show_stacks> stacks_7000.txt
|
||||
cat stacks_7000.txt
|
||||
post_alloc_hook+0x177/0x1a0
|
||||
get_page_from_freelist+0xd01/0xd80
|
||||
__alloc_pages+0x39e/0x7e0
|
||||
alloc_pages_mpol+0x22e/0x490
|
||||
folio_alloc+0xd5/0x110
|
||||
filemap_alloc_folio+0x78/0x230
|
||||
page_cache_ra_order+0x287/0x6f0
|
||||
filemap_get_pages+0x517/0x1160
|
||||
filemap_read+0x304/0x9f0
|
||||
xfs_file_buffered_read+0xe6/0x1d0 [xfs]
|
||||
xfs_file_read_iter+0x1f0/0x380 [xfs]
|
||||
__kernel_read+0x3b9/0x730
|
||||
kernel_read_file+0x309/0x4d0
|
||||
__do_sys_finit_module+0x381/0x730
|
||||
do_syscall_64+0x8d/0x150
|
||||
entry_SYSCALL_64_after_hwframe+0x62/0x6a
|
||||
nr_base_pages: 20824
|
||||
...
|
||||
|
||||
cat /sys/kernel/debug/page_owner > page_owner_full.txt
|
||||
./page_owner_sort page_owner_full.txt sorted_page_owner.txt
|
||||
|
||||
|
@ -54,3 +54,16 @@
|
||||
|
||||
可以选择用PAGE_TABLE_CHECK_ENFORCED来构建内核,以便在没有额外的内核参数的情况下获得页表
|
||||
支持。
|
||||
|
||||
实现注意事项
|
||||
============
|
||||
|
||||
我们特意决定不使用 VMA 信息,以避免依赖于 MM 状态(除了有限的 “struct page” 信息)。页表检查
|
||||
独立于 Linux-MM 状态机,它验证用户可访问的页面不会被错误地共享。
|
||||
|
||||
PAGE_TABLE_CHECK 依赖于 EXCLUSIVE_SYSTEM_RAM。原因在于,若没有 EXCLUSIVE_SYSTEM_RAM,
|
||||
用户被允许通过 /dev/mem 将任意物理内存区域映射到用户空间。同时,页面可能在映射到用户空间期间
|
||||
改变自己的属性(例如,从匿名页面变为命名页面),导致页表检查检测到“损坏”。
|
||||
|
||||
即使有 EXCLUSIVE_SYSTEM_RAM,I/O 页面可能仍然被允许通过 /dev/mem 映射。然而,这些页面始终
|
||||
被视为命名页面,所以它们不会破坏页表检查中使用的逻辑。
|
||||
|
221
Documentation/translations/zh_CN/mm/page_tables.rst
Normal file
221
Documentation/translations/zh_CN/mm/page_tables.rst
Normal file
@ -0,0 +1,221 @@
|
||||
.. SPDX-License-Identifier: GPL-2.0
|
||||
.. include:: ../disclaimer-zh_CN.rst
|
||||
|
||||
:Original: Documentation/mm/page_tables.rst
|
||||
|
||||
:翻译:
|
||||
|
||||
张鹏宇 Pengyu Zhang <zpenya1314@gmail.com>
|
||||
|
||||
:校译:
|
||||
|
||||
====
|
||||
页表
|
||||
====
|
||||
|
||||
分页虚拟内存是随虚拟内存的概念一起于 1962 年在 Ferranti Atlas 计算机上被提出的,
|
||||
这是第一台有分页虚拟内存的计算机。随着时间推移,这个特性被迁移到更新的计算机上,
|
||||
并且成为所有类 Unix 系统实际的特性。在 1985 年,这个特性被包含在了英特尔 80386
|
||||
中,也就是运行 Linux 1.0 的CPU。
|
||||
|
||||
页表将 CPU 看到的虚拟地址映射到外部内存总线上看到的物理地址。
|
||||
|
||||
Linux 将页表定义为一个分级结构,目前有五级。对于支持的每种架构,其代码会根据硬件
|
||||
限制对这个层级结构进行映射。
|
||||
|
||||
虚拟地址对应的物理地址通常由底层物理页帧引用。 **页帧号(page frame number,pfn)**
|
||||
是页的物理地址(在外部内存总线看到的地址)除以 `PAGE_SIZE` 得到的值。
|
||||
|
||||
物理内存地址 0 对应 *pfn 0*,而最大的 pfn 对应处理器外部地址总线所能寻址物理地址
|
||||
的最后一页。
|
||||
|
||||
在页粒度为 4KB 且地址范围为32位的情况下,pfn 0 对应地址0x00000000,pfn 1 对应
|
||||
地址0x00001000,pfn 2 对应地址 0x00002000,以此类推,直到 pfn 0xfffff 对应
|
||||
0xfffff000。如果页粒度为 16KB,则 pfn 分别对应地址 0x00004000、0x00008000
|
||||
... 0xffffc000,pfn 的范围从 0 到 0x3ffff。
|
||||
|
||||
如你所见,对于 4KB 页面粒度,页基址使用地址的 12-31 位,这就是为什么在这种情况下
|
||||
`PAGE_SHIFT` 被定义为 12,并且 `PAGE_SIZE` 通常由页偏移定义,为 `(1 << PAGE_SHIFT)`。
|
||||
|
||||
随着内存容量的增加,久而久之层级结构逐渐加深。Linux 最初使用 4KB 页面和一个名为
|
||||
`swapper_pg_dir` 的页表,该页表拥有 1024 个表项(entries),覆盖 4MB 的内存,
|
||||
事实上Torvald 的第一台计算机正好就有 4MB 物理内存。表项在这张表中被称为 *PTE*:s
|
||||
- 页表项(page table entries)。
|
||||
|
||||
软件页表层级结构反映了页表硬件已经变得分层化的事实,而这种分层化的目的是为了节省
|
||||
页表内存并加快地址映射速度。
|
||||
|
||||
当然,人们可以想象一张拥有大量表项的单一线性的页表将整个内存分为一个个页。而且,
|
||||
这样的页表会非常稀疏,因为虚拟内存中大部分位置通常是未使用的。通过页表分层,虚拟
|
||||
内存中的大量空洞不会浪费宝贵的页表内存,因为只需要在上层页表中将大块的区域标记为
|
||||
未映射即可。
|
||||
|
||||
另外,在现代处理器中,上层页表项可以直接指向一个物理地址范围,这使得单个上层
|
||||
页表项可以连续映射几兆字节甚至几千兆字节的内存范围,从而快捷地实现虚拟地址到
|
||||
物理地址的映射:当你找到一个像这样的大型映射范围时,无需在层级结构中进一步遍历。
|
||||
|
||||
页表的层级结构目前发展为如下所示::
|
||||
|
||||
+-----+
|
||||
| PGD |
|
||||
+-----+
|
||||
|
|
||||
| +-----+
|
||||
+-->| P4D |
|
||||
+-----+
|
||||
|
|
||||
| +-----+
|
||||
+-->| PUD |
|
||||
+-----+
|
||||
|
|
||||
| +-----+
|
||||
+-->| PMD |
|
||||
+-----+
|
||||
|
|
||||
| +-----+
|
||||
+-->| PTE |
|
||||
+-----+
|
||||
|
||||
|
||||
不同页表层级的符号含义从最底层开始如下:
|
||||
|
||||
- **pte**, `pte_t`, `pteval_t` = **页表项** - 前面提到过。*pte* 是一个由
|
||||
`PTRS_PER_PTE` 个 `pteval_t` 类型元素组成的数组,每个元素将一个虚拟内存页
|
||||
映射到一个物理内存页。体系结构定义了 `pteval_t` 的大小和内容。
|
||||
|
||||
一个典型的例子是 `pteval_t` 是一个 32 或者 64 位的值,其中高位是 **pfn**,
|
||||
而低位则一些特定体系架构相关的位,如内存保护。
|
||||
|
||||
这个 **表项(entry)** 有点令人困惑,因为在 Linux 1.0 中它确实指的是单层顶级
|
||||
页表中的单个页表项,但在首次引入二级页表时,它被重新定义为映射元素的数组。
|
||||
因此,*pte* 现在指的是最底层的页 *表*,而不是一个页表 *项*。
|
||||
|
||||
- **pmd**, `pmd_t`, `pmdval_t` = **页中间目录(Page Middle Directory)**,
|
||||
位于 *pte* 之上的层级结构,包含 `PTRS_PER_PMD` 个指向 *pte* 的引用。
|
||||
|
||||
- **pud**, `pud_t`, `pudval_t` = **页上级目录(Page Upper Directory)**
|
||||
是在其他层级之后引入的,用于处理四级页表。它可能未被使用,或者像我们稍后
|
||||
讨论的那样被“折叠”。
|
||||
|
||||
- **p4d**, `p4d_t`, `p4dval_t` = **页四级目录(Page Level 4 Directory)**
|
||||
是在 *pud* 之后用于处理五级页表引入的。至此,显然需要用数字来替代 *pgd*、
|
||||
*pmd*、*pud* 等目录层级的名称,不能再继续使用临时的命名方式。这个目录层级
|
||||
只在实际拥有五级页表的系统上使用,否则它会被折叠。
|
||||
|
||||
- **pgd**, `pgd_t`, `pgdval_t` = **页全局目录(Page Global Directory)** -
|
||||
Linux 内核用于处理内核内存的 *PGD* 主页表仍然位于 `swapper_pg_dir`。
|
||||
但系统中的每个用户空间进程也有自己的内存上下文,因此也有自己的 *pgd*,
|
||||
它位于 `struct mm_struct` 中,而 `struct mm_struct` 又在每个 `struct task_struct`
|
||||
中有引用。所以,任务(进程)存在一个形式为 `struct mm_struct` 的内存上下文,
|
||||
而这个结构体中有一个指向指向相应的页全局目录 `struct pgt_t *pgd` 指针。
|
||||
|
||||
重申一下:页表层级结构中的每一层都是一个 *指针数组*,所以 *pgd* 包含 `PTRS_PER_PGD`
|
||||
个指向下一层的指针,*p4d* 包含 `PTRS_PER_P4D` 个指向 *pud* 项的指针,依此类推。
|
||||
每一层的指针数量由体系结构定义。::
|
||||
|
||||
PMD
|
||||
--> +-----+ PTE
|
||||
| ptr |-------> +-----+
|
||||
| ptr |- | ptr |-------> PAGE
|
||||
| ptr | \ | ptr |
|
||||
| ptr | \ ...
|
||||
| ... | \
|
||||
| ptr | \ PTE
|
||||
+-----+ +----> +-----+
|
||||
| ptr |-------> PAGE
|
||||
| ptr |
|
||||
...
|
||||
|
||||
页表折叠
|
||||
========
|
||||
|
||||
如果架构不使用所有的页表层级,那么这些层级可以被 *折叠*,也就是说被跳过。在
|
||||
访问下一层时,所有在页表上执行的操作都会在编译时增强,以跳过这一层。
|
||||
|
||||
与架构无关的页表处理代码(例如虚拟内存管理器)需要编写得能够遍历当前的所有五个
|
||||
层级。对于特定架构的代码,也应优先采用这种风格,以便对未来的变化具有更好的适应性。
|
||||
|
||||
MMU,TLB 和缺页异常
|
||||
===================
|
||||
|
||||
`内存管理单元(MMU)` 是处理虚拟地址到物理地址转换的硬件组件。它可能会使用相对较小
|
||||
的硬件缓存,如 `转换后备缓冲区(TLB)` 和 `页遍历缓存`,以加快这些地址翻译过程。
|
||||
|
||||
当 CPU 访存时,它会向 MMU 提供一个虚拟地址。MMU 会首先检查 TLB 或者页遍历缓存
|
||||
(在支持的架构上)是否存在对应的转换结果。如果没有,MMU 会通过遍历来确定物理地址
|
||||
并且建立映射。
|
||||
|
||||
当页面被写入时,该页的脏位会被设置(即打开)。每个内存页面都有相关的权限位和脏位。
|
||||
后者表明这个页自从被加载到内存以来是否被修改。
|
||||
|
||||
如果没有任何阻碍,物理内存到头来可以被任意访问并且对物理帧进行请求的操作。
|
||||
|
||||
MMU 无法找到某些转换有多种原因。有可能是 CPU 试图去访问当前进程没有权限访问的
|
||||
内存,或者因为访问的数据还不在物理内存中。
|
||||
|
||||
当这些情况发生时,MMU 会触发缺页异常,这是一种异常类型,用于通知 CPU 暂停当前
|
||||
执行并运行一个特殊的函数去处理这些异常。
|
||||
|
||||
缺页异常有一些常见且预期的原因。这些因素是由称为“懒加载”和“写时复制”的进程管理
|
||||
优化技术来触发的。缺页异常也可能发生在当页帧被交换到持久存储(交换分区或者文件)
|
||||
并从其物理地址移出时。
|
||||
|
||||
这些技术提高了内存效率,减少了延迟,并且最小化了空间占用。本文档不会深入讨论
|
||||
“懒加载”和“写时复制”的细节,因为这些的主题属于进程地址管理范畴,超出了本文范围。
|
||||
|
||||
交换技术和前面提到的其他技术不同,因为它是在压力过大下情况下减少内存消耗的一种
|
||||
迫不得已的手段,因此是不受欢迎的。
|
||||
|
||||
交换不适用于由内核逻辑地址映射的内存。这些地址是内核虚拟地址空间的子集,直接映射
|
||||
一段连续的物理内存。对于提供的任意逻辑地址,它的物理地址可以通过对偏移量进行简单
|
||||
的算数运算来确定。对逻辑地址的访问很快,因为这避免了复杂的页表查找,但代价是这些
|
||||
内存不能被驱逐或置换。
|
||||
|
||||
如果内核无法为必须存在于物理帧中的数据腾出空间,那么它会调用内存不足(out-of-memory,
|
||||
OOM)杀手,通过杀掉低优先级的进程来腾出空间,直到内存压力下降到安全阈值之下。
|
||||
|
||||
另外,代码漏洞或指示 CPU 访问的精心制作的恶意地址也可能导致缺页异常。一个进程的
|
||||
线程可以利用指令来访问不属于其地址空间的(非共享)内存,或者试图执行写入只读位置
|
||||
的指令。
|
||||
|
||||
如果上述情况发生在用户态,内核会向当前线程发送 `段错误` (SIGSEGV)信号。该信号
|
||||
通常导致线程及其所属的进程终止。
|
||||
|
||||
本文将简化并概述 Linux 内核如何处理这些缺页中断、创建表和表项、检查内存是否存在,
|
||||
以及当内存不存在时,如何请求从持久存储或其他设备加载数据,并更新 MMU 及其缓存。
|
||||
|
||||
最初的步骤依赖于架构。大多是架构跳转到 `do_page_fault()`,而 x86 中断处理程序是由
|
||||
`DEFINE_IDTENTRY_RAW_ERRORCODE()` 宏定义的,该宏调用 `handle_page_fault()`。
|
||||
|
||||
无论调用路径如何,所有架构最终都会调用 `handle_mm_fault()`,该函数通常会调用
|
||||
`__handle_mm_fault()` 来执行实际分配页表的任务。
|
||||
|
||||
如果不幸无法调用 `__handle_mm_fault()` 则意味着虚拟地址指向了无权访问的物理
|
||||
内存区域(至少对于当前上下文如此)。这种情况会导致内核向该进程发送上述的 SIGSEGV
|
||||
信号,并引发前面提到的后果。
|
||||
|
||||
这些用于查找偏移量的函数名称通常以 `*_offset()` 结尾,其中“\*”可以是 pgd,p4d,
|
||||
pud,pmd 或者 pte;而分配相应层级页表的函数名称是 `*_alloc`,它们按照上述命名
|
||||
约定以对应页表层级的类型命名。
|
||||
|
||||
页表遍历可能在中间或者上层结束(PMD,PUD)。
|
||||
|
||||
Linux 支持比通常 4KB 更大的页面(即所谓的 `巨页`)。当使用这种较大的页面时,没有
|
||||
必要使用更低层的页表项(PTE)。巨页通常包含 2MB 到 1GB 的大块连续物理区域,分别由
|
||||
PMD 和 PUD 页表项映射。
|
||||
|
||||
巨页带来许多好处,如减少 TLB 压力,减少页表开销,提高内存分配效率,以及改善
|
||||
特定工作负载的性能。然而,这些好处也伴随着权衡,如内存浪费和分配难度增加。
|
||||
|
||||
在遍历和分配的最后,如果没有返回错误,`__handle_mm_fault()` 最终调用 `handle_pte_fault()`
|
||||
通过 `do_fault()` 执行 `do_read_fault()`、 `do_cow_fault()` 和 `do_shared_fault()`。
|
||||
“read”,“cow”和“shared”分别暗示了它处理错误的类型和原因。
|
||||
|
||||
实际的工作流程实现是非常复杂的。其设计允许 Linux 根据每种架构的特定特性处理缺页
|
||||
异常,同时仍然共享一个通用的整体结构。
|
||||
|
||||
为了总结 Linux 如何处理缺页中断的概述,需要补充的是,缺页异常处理程序可以通过
|
||||
`pagefault_disable()` 和 `pagefault_enable()` 分别禁用和启用。
|
||||
|
||||
许多代码路径使用了这两个函数,因为它们需要禁止陷入缺页异常处理程序,主要是为了
|
||||
防止死锁。
|
356
Documentation/translations/zh_CN/mm/physical_memory.rst
Normal file
356
Documentation/translations/zh_CN/mm/physical_memory.rst
Normal file
@ -0,0 +1,356 @@
|
||||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
.. include:: ../disclaimer-zh_CN.rst
|
||||
|
||||
:Original: Documentation/mm/physical_memory.rst
|
||||
|
||||
:翻译:
|
||||
|
||||
王亚鑫 Yaxin Wang <wang.yaxin@zte.com.cn>
|
||||
|
||||
========
|
||||
物理内存
|
||||
========
|
||||
|
||||
Linux可用于多种架构,因此需要一个与架构无关的抽象来表示物理内存。本章描述
|
||||
了管理运行系统中物理内存的结构。
|
||||
|
||||
第一个与内存管理相关的主要概念是 `非一致性内存访问(NUMA)
|
||||
<https://en.wikipedia.org/wiki/Non-uniform_memory_access>`
|
||||
|
||||
在多核和多插槽机器中,内存可能被组织成不同的存储区,这些存储区根据与处理器
|
||||
的距离“不同”而有不同的访问开销。例如,可能为每个CPU分配内存存储区,或者为
|
||||
外围设备在附近分配一个非常适合DMA的内存存储区。
|
||||
|
||||
每个存储区被称为一个节点,节点在Linux中表示为 ``struct pglist_data``,
|
||||
即使是在UMA架构中也是这样表示。该结构总是通过 ``pg_data_t`` 来引用。特
|
||||
定节点的 ``pg_data_t`` 结构体可以通过NODE_DATA(nid)引用,其中nid被称
|
||||
为该节点的ID。
|
||||
|
||||
对于非一致性内存访问(NUMA)架构,节点数据结构在引导时由特定于架构的代码早
|
||||
期分配。通常,这些结构在其所在的内存区上本地分配。对于一致性内存访问(UMA)
|
||||
架构,只使用一个静态的 ``pg_data_t`` 结构体,称为 ``contig_page_data``。
|
||||
节点将会在 :ref:`节点 <nodes>` 章节中进一步讨论。
|
||||
|
||||
整个物理内存被划分为一个或多个被称为区域的块,这些区域表示内存的范围。这
|
||||
些范围通常由访问内存的架构限制来决定。在节点内,与特定区域对应的内存范围
|
||||
由 ``struct zone`` 结构体描述,该结构被定义为 ``zone_t``,每种区域都
|
||||
属于以下描述类型的一种。
|
||||
|
||||
* ``ZONE_DMA`` 和 ``ZONE_DMA32`` 在历史上代表适用于DMA的内存,这些
|
||||
内存由那些不能访问所有可寻址内存的外设访问。多年来,已经有了更好、更稳
|
||||
固的接口来获取满足特定DMA需求的内存(这些接口由
|
||||
Documentation/core-api/dma-api.rst 文档描述),但是 ``ZONE_DMA``
|
||||
和 ``ZONE_DMA32`` 仍然表示访问受限的内存范围。
|
||||
|
||||
取决于架构的不同,这两种区域可以在构建时通过关闭 ``CONFIG_ZONE_DMA`` 和
|
||||
``CONFIG_ZONE_DMA32`` 配置选项来禁用。一些64位的平台可能需要这两种区域,
|
||||
因为他们支持具有不同DMA寻址限制的外设。
|
||||
|
||||
* ``ZONE_NORMAL`` 是普通内存的区域,这种内存可以被内核随时访问。如果DMA
|
||||
设备支持将数据传输到所有可寻址的内存区域,那么可在该区域的页面上执行DMA
|
||||
操作。``ZONE_NORMAL`` 总是开启的。
|
||||
|
||||
* ``ZONE_HIGHMEM`` 是指那些没有在内核页表中永久映射的物理内存部分。该区
|
||||
域的内存只能通过临时映射被内核访问。该区域只在某些32位架构上可用,并且是
|
||||
通过 ``CONFIG_HIGHMEM`` 选项开启。
|
||||
|
||||
* ``ZONE_MOVABLE`` 是指可访问的普通内存区域,就像 ``ZONE_NORMAL``
|
||||
一样。不同之处在于 ``ZONE_MOVABLE`` 中的大多数页面内容是可移动的。
|
||||
这意味着这些页面的虚拟地址不会改变,但它们的内容可能会在不同的物理页面
|
||||
之间移动。通常,在内存热插拔期间填充 ``ZONE_MOVABLE``,在启动时也可
|
||||
以使用 ``kernelcore``、``movablecore`` 和 ``movable_node``
|
||||
这些内核命令行参数来填充。更多详细信息,请参阅内核文档
|
||||
Documentation/mm/page_migration.rst 和
|
||||
Documentation/admin-guide/mm/memory-hotplug.rst。
|
||||
|
||||
* ``ZONE_DEVICE`` 表示位于持久性内存(PMEM)和图形处理单元(GPU)
|
||||
等设备上的内存。它与RAM区域类型有不同的特性,并且它的存在是为了提供
|
||||
:ref:`struct page<Pages>` 结构和内存映射服务,以便设备驱动程序能
|
||||
识别物理地址范围。``ZONE_DEVICE`` 通过 ``CONFIG_ZONE_DEVICE``
|
||||
选项开启。
|
||||
|
||||
需要注意的是,许多内核操作只能使用 ``ZONE_NORMAL`` 来执行,因此它是
|
||||
性能最关键区域。区域在 :ref:`区域 <zones>` 章节中有更详细的讨论。
|
||||
|
||||
节点和区域范围之间的关系由固件报告的物理内存映射决定,另外也由内存寻址
|
||||
的架构约束以及内核命令行中的某些参数决定。
|
||||
|
||||
例如,在具有2GB RAM的x86统一内存架构(UMA)机器上运行32位内核时,整
|
||||
个内存将位于节点0,并且将有三个区域: ``ZONE_DMA``、 ``ZONE_NORMAL``
|
||||
和 ``ZONE_HIGHMEM``::
|
||||
|
||||
0 2G
|
||||
+-------------------------------------------------------------+
|
||||
| node 0 |
|
||||
+-------------------------------------------------------------+
|
||||
|
||||
0 16M 896M 2G
|
||||
+----------+-----------------------+--------------------------+
|
||||
| ZONE_DMA | ZONE_NORMAL | ZONE_HIGHMEM |
|
||||
+----------+-----------------------+--------------------------+
|
||||
|
||||
|
||||
在内核构建时关闭 ``ZONE_DMA`` 开启 ``ZONE_DMA32``,并且具有16GB
|
||||
RAM平均分配在两个节点上的arm64机器上,使用 ``movablecore=80%`` 参数
|
||||
启动时,``ZONE_DMA32``、``ZONE_NORMAL`` 和 ``ZONE_MOVABLE``
|
||||
位于节点0,而 ``ZONE_NORMAL`` 和 ``ZONE_MOVABLE`` 位于节点1::
|
||||
|
||||
|
||||
1G 9G 17G
|
||||
+--------------------------------+ +--------------------------+
|
||||
| node 0 | | node 1 |
|
||||
+--------------------------------+ +--------------------------+
|
||||
|
||||
1G 4G 4200M 9G 9320M 17G
|
||||
+---------+----------+-----------+ +------------+-------------+
|
||||
| DMA32 | NORMAL | MOVABLE | | NORMAL | MOVABLE |
|
||||
+---------+----------+-----------+ +------------+-------------+
|
||||
|
||||
|
||||
内存存储区可能位于交错的节点。在下面的例子中,一台x86机器有16GB的RAM分
|
||||
布在4个内存存储区上,偶数编号的内存存储区属于节点0,奇数编号的内存条属于
|
||||
节点1::
|
||||
|
||||
0 4G 8G 12G 16G
|
||||
+-------------+ +-------------+ +-------------+ +-------------+
|
||||
| node 0 | | node 1 | | node 0 | | node 1 |
|
||||
+-------------+ +-------------+ +-------------+ +-------------+
|
||||
|
||||
0 16M 4G
|
||||
+-----+-------+ +-------------+ +-------------+ +-------------+
|
||||
| DMA | DMA32 | | NORMAL | | NORMAL | | NORMAL |
|
||||
+-----+-------+ +-------------+ +-------------+ +-------------+
|
||||
|
||||
在这种情况下,节点0将覆盖从0到12GB的内存范围,而节点1将覆盖从4GB到16GB
|
||||
的内存范围。
|
||||
|
||||
.. _nodes_zh_CN:
|
||||
|
||||
节点
|
||||
====
|
||||
|
||||
正如我们所提到的,内存中的每个节点由 ``pg_data_t`` 描述,通过
|
||||
``struct pglist_data`` 结构体的类型定义。在分配页面时,默认情况下,Linux
|
||||
使用节点本地分配策略,从离当前运行CPU的最近节点分配内存。由于进程倾向于在同
|
||||
一个CPU上运行,很可能会使用当前节点的内存。分配策略可以由用户控制,如内核文
|
||||
档 Documentation/admin-guide/mm/numa_memory_policy.rst 中所述。
|
||||
|
||||
大多数NUMA(非统一内存访问)架构维护了一个指向节点结构的指针数组。这些实际
|
||||
的结构在启动过程中的早期被分配,这时特定于架构的代码解析了固件报告的物理内
|
||||
存映射。节点初始化的大部分工作是在由free_area_init()实现的启动过程之后
|
||||
完成,该函数在后面的小节 :ref:`初始化 <initialization>` 中有详细描述。
|
||||
|
||||
除了节点结构,内核还维护了一个名为 ``node_states`` 的 ``nodemask_t``
|
||||
位掩码数组。这个数组中的每个位掩码代表一组特定属性的节点,这些属性由
|
||||
``enum node_states`` 定义,定义如下:
|
||||
|
||||
``N_POSSIBLE``
|
||||
节点可能在某个时刻上线。
|
||||
|
||||
``N_ONLINE``
|
||||
节点已经上线。
|
||||
|
||||
``N_NORMAL_MEMORY``
|
||||
节点拥有普通内存。
|
||||
|
||||
``N_HIGH_MEMORY``
|
||||
节点拥有普通或高端内存。当关闭 ``CONFIG_HIGHMEM`` 配置时,
|
||||
也可以称为 ``N_NORMAL_MEMORY``。
|
||||
|
||||
``N_MEMORY``
|
||||
节点拥有(普通、高端、可移动)内存。
|
||||
|
||||
``N_CPU``
|
||||
节点拥有一个或多个CPU。
|
||||
|
||||
对于具有上述属性的每个节点,``node_states[<property>]``
|
||||
掩码中对应于节点ID的位会被置位。
|
||||
|
||||
例如,对于具有常规内存和CPU的节点2,第二个bit将被设置::
|
||||
|
||||
node_states[N_POSSIBLE]
|
||||
node_states[N_ONLINE]
|
||||
node_states[N_NORMAL_MEMORY]
|
||||
node_states[N_HIGH_MEMORY]
|
||||
node_states[N_MEMORY]
|
||||
node_states[N_CPU]
|
||||
|
||||
有关使用节点掩码(nodemasks)可能进行的各种操作,请参考
|
||||
``include/linux/nodemask.h``。
|
||||
|
||||
除此之外,节点掩码(nodemasks)提供用于遍历节点的宏,即
|
||||
``for_each_node()`` 和 ``for_each_online_node()``。
|
||||
|
||||
例如,要为每个在线节点调用函数 foo(),可以这样操作::
|
||||
|
||||
for_each_online_node(nid) {
|
||||
pg_data_t *pgdat = NODE_DATA(nid);
|
||||
|
||||
foo(pgdat);
|
||||
}
|
||||
|
||||
节点数据结构
|
||||
------------
|
||||
|
||||
节点结构 ``struct pglist_data`` 在 ``include/linux/mmzone.h``
|
||||
中声明。这里我们将简要描述这个结构体的字段:
|
||||
|
||||
通用字段
|
||||
~~~~~~~~
|
||||
|
||||
``node_zones``
|
||||
表示该节点的区域列表。并非所有区域都可能被填充,但这是
|
||||
完整的列表。它被该节点的node_zonelists以及其它节点的
|
||||
node_zonelists引用。
|
||||
|
||||
``node_zonelists``
|
||||
表示所有节点中所有区域的列表。此列表定义了分配内存时首选的区域
|
||||
顺序。``node_zonelists`` 在核心内存管理结构初始化期间,
|
||||
由 ``mm/page_alloc.c`` 中的 ``build_zonelists()``
|
||||
函数设置。
|
||||
|
||||
``nr_zones``
|
||||
表示此节点中已填充区域的数量。
|
||||
|
||||
``node_mem_map``
|
||||
对于使用FLATMEM内存模型的UMA系统,0号节点的 ``node_mem_map``
|
||||
表示每个物理帧的struct pages数组。
|
||||
|
||||
``node_page_ext``
|
||||
对于使用FLATMEM内存模型的UMA系统,0号节点的 ``node_page_ext``
|
||||
是struct pages的扩展数组。只有在构建时开启了 ``CONFIG_PAGE_EXTENSION``
|
||||
选项的内核中才可用。
|
||||
|
||||
``node_start_pfn``
|
||||
表示此节点中起始页面帧的页面帧号。
|
||||
|
||||
``node_present_pages``
|
||||
表示此节点中存在的物理页面的总数。
|
||||
|
||||
``node_spanned_pages``
|
||||
表示包括空洞在内的物理页面范围的总大小。
|
||||
|
||||
``node_size_lock``
|
||||
一个保护定义节点范围字段的锁。仅在开启了 ``CONFIG_MEMORY_HOTPLUG`` 或
|
||||
``CONFIG_DEFERRED_STRUCT_PAGE_INIT`` 配置选项中的某一个时才定义。提
|
||||
供了 ``pgdat_resize_lock()`` 和 ``pgdat_resize_unlock()`` 用来操作
|
||||
``node_size_lock``,而无需检查 ``CONFIG_MEMORY_HOTPLUG`` 或
|
||||
``CONFIG_DEFERRED_STRUCT_PAGE_INIT`` 选项。
|
||||
|
||||
``node_id``
|
||||
节点的节点ID(NID),从0开始。
|
||||
|
||||
``totalreserve_pages``
|
||||
这是每个节点保留的页面,这些页面不可用于用户空间分配。
|
||||
|
||||
``first_deferred_pfn``
|
||||
如果大型机器上的内存初始化被推迟,那么第一个PFN(页帧号)是需要初始化的。
|
||||
在开启了 ``CONFIG_DEFERRED_STRUCT_PAGE_INIT`` 选项时定义。
|
||||
|
||||
``deferred_split_queue``
|
||||
每个节点的大页队列,这些大页的拆分被推迟了。仅在开启了 ``CONFIG_TRANSPARENT_HUGEPAGE``
|
||||
配置选项时定义。
|
||||
|
||||
``__lruvec``
|
||||
每个节点的lruvec持有LRU(最近最少使用)列表和相关参数。仅在禁用了内存
|
||||
控制组(cgroups)时使用。它不应该直接访问,而应该使用 ``mem_cgroup_lruvec()``
|
||||
来查找lruvecs。
|
||||
|
||||
回收控制
|
||||
~~~~~~~~
|
||||
|
||||
另见内核文档 Documentation/mm/page_reclaim.rst 文件。
|
||||
|
||||
``kswapd``
|
||||
每个节点的kswapd内核线程实例。
|
||||
|
||||
``kswapd_wait``, ``pfmemalloc_wait``, ``reclaim_wait``
|
||||
同步内存回收任务的工作队列。
|
||||
|
||||
``nr_writeback_throttled``
|
||||
等待写回脏页时,被限制的任务数量。
|
||||
|
||||
``kswapd_order``
|
||||
控制kswapd尝试回收的order。
|
||||
|
||||
``kswapd_highest_zoneidx``
|
||||
kswapd线程可以回收的最高区域索引。
|
||||
|
||||
``kswapd_failures``
|
||||
kswapd无法回收任何页面的运行次数。
|
||||
|
||||
``min_unmapped_pages``
|
||||
无法回收的未映射文件支持的最小页面数量。由 ``vm.min_unmapped_ratio``
|
||||
系统控制台(sysctl)参数决定。在开启 ``CONFIG_NUMA`` 配置时定义。
|
||||
|
||||
``min_slab_pages``
|
||||
无法回收的SLAB页面的最少数量。由 ``vm.min_slab_ratio`` 系统控制台
|
||||
(sysctl)参数决定。在开启 ``CONFIG_NUMA`` 时定义。
|
||||
|
||||
``flags``
|
||||
控制回收行为的标志位。
|
||||
|
||||
内存压缩控制
|
||||
~~~~~~~~~~~~
|
||||
|
||||
``kcompactd_max_order``
|
||||
kcompactd应尝试实现的页面order。
|
||||
|
||||
``kcompactd_highest_zoneidx``
|
||||
kcompactd可以压缩的最高区域索引。
|
||||
|
||||
``kcompactd_wait``
|
||||
同步内存压缩任务的工作队列。
|
||||
|
||||
``kcompactd``
|
||||
每个节点的kcompactd内核线程实例。
|
||||
|
||||
``proactive_compact_trigger``
|
||||
决定是否使用主动压缩。由 ``vm.compaction_proactiveness`` 系统控
|
||||
制台(sysctl)参数控制。
|
||||
|
||||
统计信息
|
||||
~~~~~~~~
|
||||
|
||||
``per_cpu_nodestats``
|
||||
表示节点的Per-CPU虚拟内存统计信息。
|
||||
|
||||
``vm_stat``
|
||||
表示节点的虚拟内存统计数据。
|
||||
|
||||
.. _zones_zh_CN:
|
||||
|
||||
区域
|
||||
====
|
||||
|
||||
.. admonition:: Stub
|
||||
|
||||
本节内容不完整。请列出并描述相应的字段。
|
||||
|
||||
.. _pages_zh_CN:
|
||||
|
||||
页
|
||||
====
|
||||
|
||||
.. admonition:: Stub
|
||||
|
||||
本节内容不完整。请列出并描述相应的字段。
|
||||
|
||||
.. _folios_zh_CN:
|
||||
|
||||
页码
|
||||
====
|
||||
|
||||
.. admonition:: Stub
|
||||
|
||||
本节内容不完整。请列出并描述相应的字段。
|
||||
|
||||
.. _initialization_zh_CN:
|
||||
|
||||
初始化
|
||||
======
|
||||
|
||||
.. admonition:: Stub
|
||||
|
||||
本节内容不完整。请列出并描述相应的字段。
|
@ -146,10 +146,6 @@
|
||||
- 补丁本身,采用统一的(“-u”)补丁格式。使用“-p”选项来diff将使函数名与
|
||||
更改相关联,从而使结果补丁更容易被其他人读取。
|
||||
|
||||
您应该避免在补丁中包括与更改不相关文件(例如,构建过程生成的文件或编辑器
|
||||
备份文件)。文档目录中的“dontdiff”文件在这方面有帮助;使用“-X”选项将
|
||||
其传递给diff。
|
||||
|
||||
上面提到的标签(tag)用于描述各种开发人员如何与这个补丁的开发相关联。
|
||||
:ref:`Documentation/translations/zh_CN/process/submitting-patches.rst <cn_submittingpatches>`
|
||||
文档中对它们进行了详细描述;下面是一个简短的总结。每一行的格式如下:
|
||||
|
@ -560,17 +560,6 @@ Documentation/translations/zh_CN/doc-guide/index.rst 和 scripts/kernel-doc 。
|
||||
* with beginning and ending almost-blank lines.
|
||||
*/
|
||||
|
||||
对于在 net/ 和 drivers/net/ 的文件,首选的长 (多行) 注释风格有些不同。
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
/* The preferred comment style for files in net/ and drivers/net
|
||||
* looks like this.
|
||||
*
|
||||
* It is nearly the same as the generally preferred comment style,
|
||||
* but there is no initial almost-blank line.
|
||||
*/
|
||||
|
||||
注释数据也是很重要的,不管是基本类型还是衍生类型。为了方便实现这一点,每一行
|
||||
应只声明一个数据 (不要使用逗号来一次声明多个数据)。这样你就有空间来为每个数据
|
||||
写一段小注释来解释它们的用途了。
|
||||
|
@ -197,7 +197,7 @@ Mutt不自带编辑器,所以不管你使用什么编辑器,不自动断行
|
||||
Mutt 是高度可配置的。 这里是个使用mutt通过 Gmail 发送的补丁的最小配置::
|
||||
|
||||
# .muttrc
|
||||
# ================ IMAP ====================
|
||||
# ================ IMAP ====================
|
||||
set imap_user = 'yourusername@gmail.com'
|
||||
set imap_pass = 'yourpassword'
|
||||
set spoolfile = imaps://imap.gmail.com/INBOX
|
||||
@ -325,3 +325,10 @@ Gmail网页客户端自动地把制表符转换为空格。
|
||||
另一个问题是Gmail还会把任何含有非ASCII的字符的消息改用base64编码,如欧洲人的
|
||||
名字。
|
||||
|
||||
HacKerMaiL (TUI)
|
||||
****************
|
||||
|
||||
HacKerMaiL (hkml) 是一个基于公共收件箱的简单邮件管理工具,它不需要订阅邮件列表。
|
||||
该工具由 DAMON 维护者开发和维护,旨在支持 DAMON 和通用内核子系统的基本开发工作
|
||||
流程。详细信息可参考 HacKerMaiL 的 README 文件
|
||||
(https://github.com/sjp38/hackermail/blob/master/README.md)。
|
||||
|
@ -3,25 +3,22 @@
|
||||
:Original: :ref:`Documentation/process/programming-language.rst <programming_language>`
|
||||
:Translator: Alex Shi <alex.shi@linux.alibaba.com>
|
||||
|
||||
.. _cn_programming_language:
|
||||
|
||||
程序设计语言
|
||||
============
|
||||
|
||||
内核是用C语言 :ref:`c-language <cn_c-language>` 编写的。更准确地说,内核通常是用 :ref:`gcc <cn_gcc>`
|
||||
在 ``-std=gnu11`` :ref:`gcc-c-dialect-options <cn_gcc-c-dialect-options>` 下编译的:ISO C11的 GNU 方言
|
||||
内核是用 C 编程语言编写的 [zh_cn_c-language]_。更准确地说,内核通常使用 ``gcc`` [zh_cn_gcc]_ 编译,
|
||||
并且使用 ``-std=gnu11`` [zh_cn_gcc-c-dialect-options]_:这是 ISO C11 的 GNU 方言。
|
||||
``clang`` [zh_cn_clang]_ 也得到了支持,详见文档:
|
||||
:ref:`使用 Clang/LLVM 构建 Linux <kbuild_llvm>`。
|
||||
|
||||
这种方言包含对语言 :ref:`gnu-extensions <cn_gnu-extensions>` 的许多扩展,当然,它们许多都在内核中使用。
|
||||
|
||||
对于一些体系结构,有一些使用 :ref:`clang <cn_clang>` 和 :ref:`icc <cn_icc>` 编译内核
|
||||
的支持,尽管在编写此文档时还没有完成,仍需要第三方补丁。
|
||||
这种方言包含对 C 语言的许多扩展 [zh_cn_gnu-extensions]_,当然,它们许多都在内核中使用。
|
||||
|
||||
属性
|
||||
----
|
||||
|
||||
在整个内核中使用的一个常见扩展是属性(attributes) :ref:`gcc-attribute-syntax <cn_gcc-attribute-syntax>`
|
||||
在整个内核中使用的一个常见扩展是属性(attributes) [zh_cn_gcc-attribute-syntax]_。
|
||||
属性允许将实现定义的语义引入语言实体(如变量、函数或类型),而无需对语言进行
|
||||
重大的语法更改(例如添加新关键字) :ref:`n2049 <cn_n2049>`
|
||||
重大的语法更改(例如添加新关键字) [zh_cn_n2049]_。
|
||||
|
||||
在某些情况下,属性是可选的(即不支持这些属性的编译器仍然应该生成正确的代码,
|
||||
即使其速度较慢或执行的编译时检查/诊断次数不够)
|
||||
@ -30,42 +27,27 @@
|
||||
``__attribute__((__pure__))`` ),以检测可以使用哪些关键字和/或缩短代码, 具体
|
||||
请参阅 ``include/linux/compiler_attributes.h``
|
||||
|
||||
.. _cn_c-language:
|
||||
Rust
|
||||
----
|
||||
|
||||
c-language
|
||||
http://www.open-std.org/jtc1/sc22/wg14/www/standards
|
||||
内核对 Rust 编程语言 [zh_cn_rust-language]_ 的支持是实验性的,并且可以通过配置选项
|
||||
``CONFIG_RUST`` 来启用。Rust 代码使用 ``rustc`` [zh_cn_rustc]_ 编译器在
|
||||
``--edition=2021`` [zh_cn_rust-editions]_ 选项下进行编译。版本(Editions)是一种
|
||||
在语言中引入非后向兼容的小型变更的方式。
|
||||
|
||||
.. _cn_gcc:
|
||||
除此之外,内核中还使用了一些不稳定的特性 [zh_cn_rust-unstable-features]_。这些不稳定
|
||||
的特性将来可能会发生变化,因此,一个重要的目标是达到仅使用稳定特性的程度。
|
||||
|
||||
gcc
|
||||
https://gcc.gnu.org
|
||||
具体请参阅 Documentation/rust/index.rst
|
||||
|
||||
.. _cn_clang:
|
||||
|
||||
clang
|
||||
https://clang.llvm.org
|
||||
|
||||
.. _cn_icc:
|
||||
|
||||
icc
|
||||
https://software.intel.com/en-us/c-compilers
|
||||
|
||||
.. _cn_gcc-c-dialect-options:
|
||||
|
||||
c-dialect-options
|
||||
https://gcc.gnu.org/onlinedocs/gcc/C-Dialect-Options.html
|
||||
|
||||
.. _cn_gnu-extensions:
|
||||
|
||||
gnu-extensions
|
||||
https://gcc.gnu.org/onlinedocs/gcc/C-Extensions.html
|
||||
|
||||
.. _cn_gcc-attribute-syntax:
|
||||
|
||||
gcc-attribute-syntax
|
||||
https://gcc.gnu.org/onlinedocs/gcc/Attribute-Syntax.html
|
||||
|
||||
.. _cn_n2049:
|
||||
|
||||
n2049
|
||||
http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2049.pdf
|
||||
.. [zh_cn_c-language] http://www.open-std.org/jtc1/sc22/wg14/www/standards
|
||||
.. [zh_cn_gcc] https://gcc.gnu.org
|
||||
.. [zh_cn_clang] https://clang.llvm.org
|
||||
.. [zh_cn_gcc-c-dialect-options] https://gcc.gnu.org/onlinedocs/gcc/C-Dialect-Options.html
|
||||
.. [zh_cn_gnu-extensions] https://gcc.gnu.org/onlinedocs/gcc/C-Extensions.html
|
||||
.. [zh_cn_gcc-attribute-syntax] https://gcc.gnu.org/onlinedocs/gcc/Attribute-Syntax.html
|
||||
.. [zh_cn_n2049] http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2049.pdf
|
||||
.. [zh_cn_rust-language] https://www.rust-lang.org
|
||||
.. [zh_cn_rustc] https://doc.rust-lang.org/rustc/
|
||||
.. [zh_cn_rust-editions] https://doc.rust-lang.org/edition-guide/editions/
|
||||
.. [zh_cn_rust-unstable-features] https://github.com/Rust-for-Linux/linux/issues/2
|
||||
|
@ -105,7 +105,7 @@ xyzzy do frotz”或“[I]changed xyzzy to do frotz”,就好像你在命令
|
||||
当链接到邮件列表存档时,请首选lore.kernel.org邮件存档服务。用邮件中的
|
||||
``Message-ID`` 头(去掉尖括号)可以创建链接URL。例如::
|
||||
|
||||
Link: https://lore.kernel.org/r/30th.anniversary.repost@klaava.Helsinki.FI/
|
||||
Link: https://lore.kernel.org/30th.anniversary.repost@klaava.Helsinki.FI
|
||||
|
||||
请检查该链接以确保可用且指向正确的邮件。
|
||||
|
||||
@ -195,11 +195,8 @@ scripts/get_maintainer.pl在这个步骤中非常有用。如果您找不到正
|
||||
在MAINTAINERS文件中查找子系统特定的列表;您的补丁可能会在那里得到更多的关注。
|
||||
不过,请不要发送垃圾邮件到无关的列表。
|
||||
|
||||
许多与内核相关的列表托管在vger.kernel.org上;您可以在
|
||||
http://vger.kernel.org/vger-lists.html 上找到它们的列表。不过,也有与内核相关
|
||||
的列表托管在其他地方。
|
||||
|
||||
不要一次发送超过15个补丁到vger邮件列表!!!!
|
||||
许多与内核相关的列表托管在 kernel.org 上;您可以在 https://subspace.kernel.org
|
||||
上找到它们的列表。不过,也有与内核相关的列表托管在其他地方。
|
||||
|
||||
Linus Torvalds是决定改动能否进入 Linux 内核的最终裁决者。他的邮件地址是
|
||||
torvalds@linux-foundation.org 。他收到的邮件很多,所以一般来说最好 **别**
|
||||
@ -621,6 +618,13 @@ Fixes: 指示补丁修复了之前提交的一个问题。它可以便于确定
|
||||
的工作所基于的树的提交哈希。你应该在封面邮件或系列的第一个补丁中添加它,它应
|
||||
该放在 ``---`` 行的下面或所有其他内容之后,即只在你的电子邮件签名之前。
|
||||
|
||||
工具
|
||||
----
|
||||
|
||||
这个过程的许多技术方面可以使用 b4 自动完成,其文档可在
|
||||
https://b4.docs.kernel.org/en/latest/ 查看。该工具可帮助处理诸如追踪依赖项、运行
|
||||
checkpatch 以及格式化和发送邮件等事务。
|
||||
|
||||
参考文献
|
||||
--------
|
||||
|
||||
@ -643,9 +647,6 @@ Greg Kroah-Hartman,“如何惹恼内核子系统维护人员”
|
||||
|
||||
<http://www.kroah.com/log/linux/maintainer-06.html>
|
||||
|
||||
不!!!别再发巨型补丁炸弹给linux-kernel@vger.kernel.org的人们了!
|
||||
<https://lore.kernel.org/r/20050711.125305.08322243.davem@davemloft.net>
|
||||
|
||||
内核 Documentation/translations/zh_CN/process/coding-style.rst
|
||||
|
||||
Linus Torvalds关于标准补丁格式的邮件
|
||||
|
@ -120,7 +120,7 @@ gcov的內核分析插樁支持內核的編譯和運行是在同一臺機器上
|
||||
如果內核編譯和運行是不同的機器,那麼需要額外的準備工作,這取決於gcov工具
|
||||
是在哪裏使用的:
|
||||
|
||||
.. _gcov-test_zh:
|
||||
.. _gcov-test_zh_TW:
|
||||
|
||||
a) 若gcov運行在測試機上
|
||||
|
||||
@ -140,7 +140,7 @@ a) 若gcov運行在測試機上
|
||||
如果文件是軟鏈接,需要替換成真正的目錄文件(這是由make的當前工作
|
||||
目錄變量CURDIR引起的)。
|
||||
|
||||
.. _gcov-build_zh:
|
||||
.. _gcov-build_zh_TW:
|
||||
|
||||
b) 若gcov運行在編譯機上
|
||||
|
||||
@ -205,7 +205,7 @@ kconfig會根據編譯工具鏈的檢查自動選擇合適的gcov格式。
|
||||
--------------------------
|
||||
|
||||
用於在編譯機上收集覆蓋率元文件的示例腳本
|
||||
(見 :ref:`編譯機和測試機分離 a. <gcov-test_zh>` )
|
||||
(見 :ref:`編譯機和測試機分離 a. <gcov-test_zh_TW>` )
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
@ -238,7 +238,7 @@ kconfig會根據編譯工具鏈的檢查自動選擇合適的gcov格式。
|
||||
-------------------------
|
||||
|
||||
用於在測試機上收集覆蓋率數據文件的示例腳本
|
||||
(見 :ref:`編譯機和測試機分離 b. <gcov-build_zh>` )
|
||||
(見 :ref:`編譯機和測試機分離 b. <gcov-build_zh_TW>` )
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
|
@ -149,10 +149,6 @@
|
||||
- 補丁本身,採用統一的(“-u”)補丁格式。使用“-p”選項來diff將使函數名與
|
||||
更改相關聯,從而使結果補丁更容易被其他人讀取。
|
||||
|
||||
您應該避免在補丁中包括與更改不相關文件(例如,構建過程生成的文件或編輯器
|
||||
備份文件)。文檔目錄中的“dontdiff”文件在這方面有幫助;使用“-X”選項將
|
||||
其傳遞給diff。
|
||||
|
||||
上面提到的標籤(tag)用於描述各種開發人員如何與這個補丁的開發相關聯。
|
||||
:ref:`Documentation/translations/zh_CN/process/submitting-patches.rst <tw_submittingpatches>`
|
||||
文檔中對它們進行了詳細描述;下面是一個簡短的總結。每一行的格式如下:
|
||||
|
@ -160,7 +160,7 @@ my @export_file_list;
|
||||
|
||||
my @build_time;
|
||||
if (defined($ENV{'KBUILD_BUILD_TIMESTAMP'}) &&
|
||||
(my $seconds = `date -d"${ENV{'KBUILD_BUILD_TIMESTAMP'}}" +%s`) ne '') {
|
||||
(my $seconds = `date -d "${ENV{'KBUILD_BUILD_TIMESTAMP'}}" +%s`) ne '') {
|
||||
@build_time = gmtime($seconds);
|
||||
} else {
|
||||
@build_time = localtime;
|
||||
@ -569,6 +569,8 @@ sub output_function_man(%) {
|
||||
my %args = %{$_[0]};
|
||||
my ($parameter, $section);
|
||||
my $count;
|
||||
my $func_macro = $args{'func_macro'};
|
||||
my $paramcount = $#{$args{'parameterlist'}}; # -1 is empty
|
||||
|
||||
print ".TH \"$args{'function'}\" 9 \"$args{'function'}\" \"$man_date\" \"Kernel Hacker's Manual\" LINUX\n";
|
||||
|
||||
@ -600,7 +602,10 @@ sub output_function_man(%) {
|
||||
$parenth = "";
|
||||
}
|
||||
|
||||
print ".SH ARGUMENTS\n";
|
||||
$paramcount = $#{$args{'parameterlist'}}; # -1 is empty
|
||||
if ($paramcount >= 0) {
|
||||
print ".SH ARGUMENTS\n";
|
||||
}
|
||||
foreach $parameter (@{$args{'parameterlist'}}) {
|
||||
my $parameter_name = $parameter;
|
||||
$parameter_name =~ s/\[.*//;
|
||||
@ -822,10 +827,16 @@ sub output_function_rst(%) {
|
||||
my $oldprefix = $lineprefix;
|
||||
|
||||
my $signature = "";
|
||||
if ($args{'functiontype'} ne "") {
|
||||
$signature = $args{'functiontype'} . " " . $args{'function'} . " (";
|
||||
} else {
|
||||
$signature = $args{'function'} . " (";
|
||||
my $func_macro = $args{'func_macro'};
|
||||
my $paramcount = $#{$args{'parameterlist'}}; # -1 is empty
|
||||
|
||||
if ($func_macro) {
|
||||
$signature = $args{'function'};
|
||||
} else {
|
||||
if ($args{'functiontype'}) {
|
||||
$signature = $args{'functiontype'} . " ";
|
||||
}
|
||||
$signature .= $args{'function'} . " (";
|
||||
}
|
||||
|
||||
my $count = 0;
|
||||
@ -844,7 +855,9 @@ sub output_function_rst(%) {
|
||||
}
|
||||
}
|
||||
|
||||
$signature .= ")";
|
||||
if (!$func_macro) {
|
||||
$signature .= ")";
|
||||
}
|
||||
|
||||
if ($sphinx_major < 3) {
|
||||
if ($args{'typedef'}) {
|
||||
@ -888,9 +901,11 @@ sub output_function_rst(%) {
|
||||
# Put our descriptive text into a container (thus an HTML <div>) to help
|
||||
# set the function prototypes apart.
|
||||
#
|
||||
print ".. container:: kernelindent\n\n";
|
||||
$lineprefix = " ";
|
||||
print $lineprefix . "**Parameters**\n\n";
|
||||
if ($paramcount >= 0) {
|
||||
print ".. container:: kernelindent\n\n";
|
||||
print $lineprefix . "**Parameters**\n\n";
|
||||
}
|
||||
foreach $parameter (@{$args{'parameterlist'}}) {
|
||||
my $parameter_name = $parameter;
|
||||
$parameter_name =~ s/\[.*//;
|
||||
@ -1704,7 +1719,7 @@ sub check_return_section {
|
||||
sub dump_function($$) {
|
||||
my $prototype = shift;
|
||||
my $file = shift;
|
||||
my $noret = 0;
|
||||
my $func_macro = 0;
|
||||
|
||||
print_lineno($new_start_line);
|
||||
|
||||
@ -1769,7 +1784,7 @@ sub dump_function($$) {
|
||||
# declaration_name and opening parenthesis (notice the \s+).
|
||||
$return_type = $1;
|
||||
$declaration_name = $2;
|
||||
$noret = 1;
|
||||
$func_macro = 1;
|
||||
} elsif ($prototype =~ m/^()($name)\s*$prototype_end/ ||
|
||||
$prototype =~ m/^($type1)\s+($name)\s*$prototype_end/ ||
|
||||
$prototype =~ m/^($type2+)\s*($name)\s*$prototype_end/) {
|
||||
@ -1796,7 +1811,7 @@ sub dump_function($$) {
|
||||
# of warnings goes sufficiently down, the check is only performed in
|
||||
# -Wreturn mode.
|
||||
# TODO: always perform the check.
|
||||
if ($Wreturn && !$noret) {
|
||||
if ($Wreturn && !$func_macro) {
|
||||
check_return_section($file, $declaration_name, $return_type);
|
||||
}
|
||||
|
||||
@ -1814,7 +1829,8 @@ sub dump_function($$) {
|
||||
'parametertypes' => \%parametertypes,
|
||||
'sectionlist' => \@sectionlist,
|
||||
'sections' => \%sections,
|
||||
'purpose' => $declaration_purpose
|
||||
'purpose' => $declaration_purpose,
|
||||
'func_macro' => $func_macro
|
||||
});
|
||||
} else {
|
||||
output_declaration($declaration_name,
|
||||
@ -1827,7 +1843,8 @@ sub dump_function($$) {
|
||||
'parametertypes' => \%parametertypes,
|
||||
'sectionlist' => \@sectionlist,
|
||||
'sections' => \%sections,
|
||||
'purpose' => $declaration_purpose
|
||||
'purpose' => $declaration_purpose,
|
||||
'func_macro' => $func_macro
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -2322,7 +2339,6 @@ sub process_inline($$) {
|
||||
|
||||
sub process_file($) {
|
||||
my $file;
|
||||
my $initial_section_counter = $section_counter;
|
||||
my ($orig_file) = @_;
|
||||
|
||||
$file = map_filename($orig_file);
|
||||
@ -2360,8 +2376,7 @@ sub process_file($) {
|
||||
}
|
||||
|
||||
# Make sure we got something interesting.
|
||||
if ($initial_section_counter == $section_counter && $
|
||||
output_mode ne "none") {
|
||||
if (!$section_counter && $output_mode ne "none") {
|
||||
if ($output_selection == OUTPUT_INCLUDE) {
|
||||
emit_warning("${file}:1", "'$_' not found\n")
|
||||
for keys %function_table;
|
||||
|
Loading…
Reference in New Issue
Block a user