提交 6312811b 编写于 作者: J Jonathan Corbet

Merge remote-tracking branch 'mauro-exp/docbook3' into death-to-docbook

Mauro says:

This patch series convert the remaining DocBooks to ReST.

The first version was originally
send as 3 patch series:

   [PATCH 00/36] Convert DocBook documents to ReST
   [PATCH 0/5] Convert more books to ReST
   [PATCH 00/13] Get rid of DocBook

The lsm book was added as if it were a text file under
Documentation. The plan is to merge it with another file
under Documentation/security, after both this series and
a security Documentation patch series gets merged.

It also adjusts some Sphinx-pedantic errors/warnings on
some kernel-doc markups.

I also added some patches here to add PDF output for all
existing ReST books.
......@@ -24,8 +24,6 @@ DMA-ISA-LPC.txt
- How to do DMA with ISA (and LPC) devices.
DMA-attributes.txt
- listing of the various possible attributes a DMA region can have
DocBook/
- directory with DocBook templates etc. for kernel documentation.
EDID/
- directory with info on customizing EDID for broken gfx/displays.
IPMI.txt
......@@ -40,8 +38,6 @@ Intel-IOMMU.txt
- basic info on the Intel IOMMU virtualization support.
Makefile
- It's not of interest for those who aren't touching the build system.
Makefile.sphinx
- It's not of interest for those who aren't touching the build system.
PCI/
- info related to PCI drivers.
RCU/
......@@ -264,6 +260,8 @@ logo.gif
- full colour GIF image of Linux logo (penguin - Tux).
logo.txt
- info on creator of above logo & site to get additional images from.
lsm.txt
- Linux Security Modules: General Security Hooks for Linux
lzo.txt
- kernel LZO decompressor input formats
m68k/
......
*.xml
*.ps
*.pdf
*.html
*.9.gz
*.9
*.aux
*.dvi
*.log
*.out
*.png
*.gif
*.svg
*.proc
*.db
media-indices.tmpl
media-entities.tmpl
###
# This makefile is used to generate the kernel documentation,
# primarily based on in-line comments in various source files.
# See Documentation/kernel-doc-nano-HOWTO.txt for instruction in how
# to document the SRC - and how to read it.
# To add a new book the only step required is to add the book to the
# list of DOCBOOKS.
DOCBOOKS := z8530book.xml \
kernel-hacking.xml kernel-locking.xml \
networking.xml \
filesystems.xml lsm.xml kgdb.xml \
libata.xml mtdnand.xml librs.xml rapidio.xml \
s390-drivers.xml scsi.xml \
sh.xml w1.xml
ifeq ($(DOCBOOKS),)
# Skip DocBook build if the user explicitly requested no DOCBOOKS.
.DEFAULT:
@echo " SKIP DocBook $@ target (DOCBOOKS=\"\" specified)."
else
ifneq ($(SPHINXDIRS),)
# Skip DocBook build if the user explicitly requested a sphinx dir
.DEFAULT:
@echo " SKIP DocBook $@ target (SPHINXDIRS specified)."
else
###
# The build process is as follows (targets):
# (xmldocs) [by docproc]
# file.tmpl --> file.xml +--> file.ps (psdocs) [by db2ps or xmlto]
# +--> file.pdf (pdfdocs) [by db2pdf or xmlto]
# +--> DIR=file (htmldocs) [by xmlto]
# +--> man/ (mandocs) [by xmlto]
# for PDF and PS output you can choose between xmlto and docbook-utils tools
PDF_METHOD = $(prefer-db2x)
PS_METHOD = $(prefer-db2x)
targets += $(DOCBOOKS)
BOOKS := $(addprefix $(obj)/,$(DOCBOOKS))
xmldocs: $(BOOKS)
sgmldocs: xmldocs
PS := $(patsubst %.xml, %.ps, $(BOOKS))
psdocs: $(PS)
PDF := $(patsubst %.xml, %.pdf, $(BOOKS))
pdfdocs: $(PDF)
HTML := $(sort $(patsubst %.xml, %.html, $(BOOKS)))
htmldocs: $(HTML)
$(call cmd,build_main_index)
MAN := $(patsubst %.xml, %.9, $(BOOKS))
mandocs: $(MAN)
find $(obj)/man -name '*.9' | xargs gzip -nf
# Default location for installed man pages
export INSTALL_MAN_PATH = $(objtree)/usr
installmandocs: mandocs
mkdir -p $(INSTALL_MAN_PATH)/man/man9/
find $(obj)/man -name '*.9.gz' -printf '%h %f\n' | \
sort -k 2 -k 1 | uniq -f 1 | sed -e 's: :/:' | \
xargs install -m 644 -t $(INSTALL_MAN_PATH)/man/man9/
# no-op for the DocBook toolchain
epubdocs:
latexdocs:
linkcheckdocs:
###
#External programs used
KERNELDOCXMLREF = $(srctree)/scripts/kernel-doc-xml-ref
KERNELDOC = $(srctree)/scripts/kernel-doc
DOCPROC = $(objtree)/scripts/docproc
CHECK_LC_CTYPE = $(objtree)/scripts/check-lc_ctype
# Use a fixed encoding - UTF-8 if the C library has support built-in
# or ASCII if not
LC_CTYPE := $(call try-run, LC_CTYPE=C.UTF-8 $(CHECK_LC_CTYPE),C.UTF-8,C)
export LC_CTYPE
XMLTOFLAGS = -m $(srctree)/$(src)/stylesheet.xsl
XMLTOFLAGS += --skip-validation
###
# DOCPROC is used for two purposes:
# 1) To generate a dependency list for a .tmpl file
# 2) To preprocess a .tmpl file and call kernel-doc with
# appropriate parameters.
# The following rules are used to generate the .xml documentation
# required to generate the final targets. (ps, pdf, html).
quiet_cmd_docproc = DOCPROC $@
cmd_docproc = SRCTREE=$(srctree)/ $(DOCPROC) doc $< >$@
define rule_docproc
set -e; \
$(if $($(quiet)cmd_$(1)),echo ' $($(quiet)cmd_$(1))';) \
$(cmd_$(1)); \
( \
echo 'cmd_$@ := $(cmd_$(1))'; \
echo $@: `SRCTREE=$(srctree) $(DOCPROC) depend $<`; \
) > $(dir $@).$(notdir $@).cmd
endef
%.xml: %.tmpl $(KERNELDOC) $(DOCPROC) $(KERNELDOCXMLREF) FORCE
$(call if_changed_rule,docproc)
# Tell kbuild to always build the programs
always := $(hostprogs-y)
notfoundtemplate = echo "*** You have to install docbook-utils or xmlto ***"; \
exit 1
db2xtemplate = db2TYPE -o $(dir $@) $<
xmltotemplate = xmlto TYPE $(XMLTOFLAGS) -o $(dir $@) $<
# determine which methods are available
ifeq ($(shell which db2ps >/dev/null 2>&1 && echo found),found)
use-db2x = db2x
prefer-db2x = db2x
else
use-db2x = notfound
prefer-db2x = $(use-xmlto)
endif
ifeq ($(shell which xmlto >/dev/null 2>&1 && echo found),found)
use-xmlto = xmlto
prefer-xmlto = xmlto
else
use-xmlto = notfound
prefer-xmlto = $(use-db2x)
endif
# the commands, generated from the chosen template
quiet_cmd_db2ps = PS $@
cmd_db2ps = $(subst TYPE,ps, $($(PS_METHOD)template))
%.ps : %.xml
$(call cmd,db2ps)
quiet_cmd_db2pdf = PDF $@
cmd_db2pdf = $(subst TYPE,pdf, $($(PDF_METHOD)template))
%.pdf : %.xml
$(call cmd,db2pdf)
index = index.html
main_idx = $(obj)/$(index)
quiet_cmd_build_main_index = HTML $(main_idx)
cmd_build_main_index = rm -rf $(main_idx); \
echo '<h1>Linux Kernel HTML Documentation</h1>' >> $(main_idx) && \
echo '<h2>Kernel Version: $(KERNELVERSION)</h2>' >> $(main_idx) && \
cat $(HTML) >> $(main_idx)
quiet_cmd_db2html = HTML $@
cmd_db2html = xmlto html $(XMLTOFLAGS) -o $(patsubst %.html,%,$@) $< && \
echo '<a HREF="$(patsubst %.html,%,$(notdir $@))/index.html"> \
$(patsubst %.html,%,$(notdir $@))</a><p>' > $@
###
# Rules to create an aux XML and .db, and use them to re-process the DocBook XML
# to fill internal hyperlinks
gen_aux_xml = :
quiet_gen_aux_xml = echo ' XMLREF $@'
silent_gen_aux_xml = :
%.aux.xml: %.xml
@$($(quiet)gen_aux_xml)
@rm -rf $@
@(cat $< | egrep "^<refentry id" | egrep -o "\".*\"" | cut -f 2 -d \" > $<.db)
@$(KERNELDOCXMLREF) -db $<.db $< > $@
.PRECIOUS: %.aux.xml
%.html: %.aux.xml
@(which xmlto > /dev/null 2>&1) || \
(echo "*** You need to install xmlto ***"; \
exit 1)
@rm -rf $@ $(patsubst %.html,%,$@)
$(call cmd,db2html)
@if [ ! -z "$(PNG-$(basename $(notdir $@)))" ]; then \
cp $(PNG-$(basename $(notdir $@))) $(patsubst %.html,%,$@); fi
quiet_cmd_db2man = MAN $@
cmd_db2man = if grep -q refentry $<; then xmlto man $(XMLTOFLAGS) -o $(obj)/man/$(*F) $< ; fi
%.9 : %.xml
@(which xmlto > /dev/null 2>&1) || \
(echo "*** You need to install xmlto ***"; \
exit 1)
$(Q)mkdir -p $(obj)/man/$(*F)
$(call cmd,db2man)
@touch $@
###
# Rules to generate postscripts and PNG images from .fig format files
quiet_cmd_fig2eps = FIG2EPS $@
cmd_fig2eps = fig2dev -Leps $< $@
%.eps: %.fig
@(which fig2dev > /dev/null 2>&1) || \
(echo "*** You need to install transfig ***"; \
exit 1)
$(call cmd,fig2eps)
quiet_cmd_fig2png = FIG2PNG $@
cmd_fig2png = fig2dev -Lpng $< $@
%.png: %.fig
@(which fig2dev > /dev/null 2>&1) || \
(echo "*** You need to install transfig ***"; \
exit 1)
$(call cmd,fig2png)
###
# Rule to convert a .c file to inline XML documentation
gen_xml = :
quiet_gen_xml = echo ' GEN $@'
silent_gen_xml = :
%.xml: %.c
@$($(quiet)gen_xml)
@( \
echo "<programlisting>"; \
expand --tabs=8 < $< | \
sed -e "s/&/\\&amp;/g" \
-e "s/</\\&lt;/g" \
-e "s/>/\\&gt;/g"; \
echo "</programlisting>") > $@
endif # DOCBOOKS=""
endif # SPHINDIR=...
###
# Help targets as used by the top-level makefile
dochelp:
@echo ' Linux kernel internal documentation in different formats (DocBook):'
@echo ' htmldocs - HTML'
@echo ' pdfdocs - PDF'
@echo ' psdocs - Postscript'
@echo ' xmldocs - XML DocBook'
@echo ' mandocs - man pages'
@echo ' installmandocs - install man pages generated by mandocs to INSTALL_MAN_PATH'; \
echo ' (default: $(INSTALL_MAN_PATH))'; \
echo ''
@echo ' cleandocs - clean all generated DocBook files'
@echo
@echo ' make DOCBOOKS="s1.xml s2.xml" [target] Generate only docs s1.xml s2.xml'
@echo ' valid values for DOCBOOKS are: $(DOCBOOKS)'
@echo
@echo " make DOCBOOKS=\"\" [target] Don't generate docs from Docbook"
@echo ' This is useful to generate only the ReST docs (Sphinx)'
###
# Temporary files left by various tools
clean-files := $(DOCBOOKS) \
$(patsubst %.xml, %.dvi, $(DOCBOOKS)) \
$(patsubst %.xml, %.aux, $(DOCBOOKS)) \
$(patsubst %.xml, %.tex, $(DOCBOOKS)) \
$(patsubst %.xml, %.log, $(DOCBOOKS)) \
$(patsubst %.xml, %.out, $(DOCBOOKS)) \
$(patsubst %.xml, %.ps, $(DOCBOOKS)) \
$(patsubst %.xml, %.pdf, $(DOCBOOKS)) \
$(patsubst %.xml, %.html, $(DOCBOOKS)) \
$(patsubst %.xml, %.9, $(DOCBOOKS)) \
$(patsubst %.xml, %.aux.xml, $(DOCBOOKS)) \
$(patsubst %.xml, %.xml.db, $(DOCBOOKS)) \
$(patsubst %.xml, %.xml, $(DOCBOOKS)) \
$(patsubst %.xml, .%.xml.cmd, $(DOCBOOKS)) \
$(index)
clean-dirs := $(patsubst %.xml,%,$(DOCBOOKS)) man
cleandocs:
$(Q)rm -f $(call objectify, $(clean-files))
$(Q)rm -rf $(call objectify, $(clean-dirs))
# Declare the contents of the .PHONY variable as phony. We keep that
# information in a variable so we can use it in if_changed and friends.
.PHONY: $(PHONY)
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
"http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" []>
<book id="Linux-filesystems-API">
<bookinfo>
<title>Linux Filesystems API</title>
<legalnotice>
<para>
This documentation is free software; you can redistribute
it and/or modify it under the terms of the GNU General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later
version.
</para>
<para>
This program is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied
warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
</para>
<para>
You should have received a copy of the GNU General Public
License along with this program; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
MA 02111-1307 USA
</para>
<para>
For more details see the file COPYING in the source
distribution of Linux.
</para>
</legalnotice>
</bookinfo>
<toc></toc>
<chapter id="vfs">
<title>The Linux VFS</title>
<sect1 id="the_filesystem_types"><title>The Filesystem types</title>
!Iinclude/linux/fs.h
</sect1>
<sect1 id="the_directory_cache"><title>The Directory Cache</title>
!Efs/dcache.c
!Iinclude/linux/dcache.h
</sect1>
<sect1 id="inode_handling"><title>Inode Handling</title>
!Efs/inode.c
!Efs/bad_inode.c
</sect1>
<sect1 id="registration_and_superblocks"><title>Registration and Superblocks</title>
!Efs/super.c
</sect1>
<sect1 id="file_locks"><title>File Locks</title>
!Efs/locks.c
!Ifs/locks.c
</sect1>
<sect1 id="other_functions"><title>Other Functions</title>
!Efs/mpage.c
!Efs/namei.c
!Efs/buffer.c
!Eblock/bio.c
!Efs/seq_file.c
!Efs/filesystems.c
!Efs/fs-writeback.c
!Efs/block_dev.c
</sect1>
</chapter>
<chapter id="proc">
<title>The proc filesystem</title>
<sect1 id="sysctl_interface"><title>sysctl interface</title>
!Ekernel/sysctl.c
</sect1>
<sect1 id="proc_filesystem_interface"><title>proc filesystem interface</title>
!Ifs/proc/base.c
</sect1>
</chapter>
<chapter id="fs_events">
<title>Events based on file descriptors</title>
!Efs/eventfd.c
</chapter>
<chapter id="sysfs">
<title>The Filesystem for Exporting Kernel Objects</title>
!Efs/sysfs/file.c
!Efs/sysfs/symlink.c
</chapter>
<chapter id="debugfs">
<title>The debugfs filesystem</title>
<sect1 id="debugfs_interface"><title>debugfs interface</title>
!Efs/debugfs/inode.c
!Efs/debugfs/file.c
</sect1>
</chapter>
<chapter id="LinuxJDBAPI">
<chapterinfo>
<title>The Linux Journalling API</title>
<authorgroup>
<author>
<firstname>Roger</firstname>
<surname>Gammans</surname>
<affiliation>
<address>
<email>rgammans@computer-surgery.co.uk</email>
</address>
</affiliation>
</author>
</authorgroup>
<authorgroup>
<author>
<firstname>Stephen</firstname>
<surname>Tweedie</surname>
<affiliation>
<address>
<email>sct@redhat.com</email>
</address>
</affiliation>
</author>
</authorgroup>
<copyright>
<year>2002</year>
<holder>Roger Gammans</holder>
</copyright>
</chapterinfo>
<title>The Linux Journalling API</title>
<sect1 id="journaling_overview">
<title>Overview</title>
<sect2 id="journaling_details">
<title>Details</title>
<para>
The journalling layer is easy to use. You need to
first of all create a journal_t data structure. There are
two calls to do this dependent on how you decide to allocate the physical
media on which the journal resides. The jbd2_journal_init_inode() call
is for journals stored in filesystem inodes, or the jbd2_journal_init_dev()
call can be used for journal stored on a raw device (in a continuous range
of blocks). A journal_t is a typedef for a struct pointer, so when
you are finally finished make sure you call jbd2_journal_destroy() on it
to free up any used kernel memory.
</para>
<para>
Once you have got your journal_t object you need to 'mount' or load the journal
file. The journalling layer expects the space for the journal was already
allocated and initialized properly by the userspace tools. When loading the
journal you must call jbd2_journal_load() to process journal contents. If the
client file system detects the journal contents does not need to be processed
(or even need not have valid contents), it may call jbd2_journal_wipe() to
clear the journal contents before calling jbd2_journal_load().
</para>
<para>
Note that jbd2_journal_wipe(..,0) calls jbd2_journal_skip_recovery() for you if
it detects any outstanding transactions in the journal and similarly
jbd2_journal_load() will call jbd2_journal_recover() if necessary. I would
advise reading ext4_load_journal() in fs/ext4/super.c for examples on this
stage.
</para>
<para>
Now you can go ahead and start modifying the underlying
filesystem. Almost.
</para>
<para>
You still need to actually journal your filesystem changes, this
is done by wrapping them into transactions. Additionally you
also need to wrap the modification of each of the buffers
with calls to the journal layer, so it knows what the modifications
you are actually making are. To do this use jbd2_journal_start() which
returns a transaction handle.
</para>
<para>
jbd2_journal_start()
and its counterpart jbd2_journal_stop(), which indicates the end of a
transaction are nestable calls, so you can reenter a transaction if necessary,
but remember you must call jbd2_journal_stop() the same number of times as
jbd2_journal_start() before the transaction is completed (or more accurately
leaves the update phase). Ext4/VFS makes use of this feature to simplify
handling of inode dirtying, quota support, etc.
</para>
<para>
Inside each transaction you need to wrap the modifications to the
individual buffers (blocks). Before you start to modify a buffer you
need to call jbd2_journal_get_{create,write,undo}_access() as appropriate,
this allows the journalling layer to copy the unmodified data if it
needs to. After all the buffer may be part of a previously uncommitted
transaction.
At this point you are at last ready to modify a buffer, and once
you are have done so you need to call jbd2_journal_dirty_{meta,}data().
Or if you've asked for access to a buffer you now know is now longer
required to be pushed back on the device you can call jbd2_journal_forget()
in much the same way as you might have used bforget() in the past.
</para>
<para>
A jbd2_journal_flush() may be called at any time to commit and checkpoint
all your transactions.
</para>
<para>
Then at umount time , in your put_super() you can then call jbd2_journal_destroy()
to clean up your in-core journal object.
</para>
<para>
Unfortunately there a couple of ways the journal layer can cause a deadlock.
The first thing to note is that each task can only have
a single outstanding transaction at any one time, remember nothing
commits until the outermost jbd2_journal_stop(). This means
you must complete the transaction at the end of each file/inode/address
etc. operation you perform, so that the journalling system isn't re-entered
on another journal. Since transactions can't be nested/batched
across differing journals, and another filesystem other than
yours (say ext4) may be modified in a later syscall.
</para>
<para>
The second case to bear in mind is that jbd2_journal_start() can
block if there isn't enough space in the journal for your transaction
(based on the passed nblocks param) - when it blocks it merely(!) needs to
wait for transactions to complete and be committed from other tasks,
so essentially we are waiting for jbd2_journal_stop(). So to avoid
deadlocks you must treat jbd2_journal_start/stop() as if they
were semaphores and include them in your semaphore ordering rules to prevent
deadlocks. Note that jbd2_journal_extend() has similar blocking behaviour to
jbd2_journal_start() so you can deadlock here just as easily as on
jbd2_journal_start().
</para>
<para>
Try to reserve the right number of blocks the first time. ;-). This will
be the maximum number of blocks you are going to touch in this transaction.
I advise having a look at at least ext4_jbd.h to see the basis on which
ext4 uses to make these decisions.
</para>
<para>
Another wriggle to watch out for is your on-disk block allocation strategy.
Why? Because, if you do a delete, you need to ensure you haven't reused any
of the freed blocks until the transaction freeing these blocks commits. If you
reused these blocks and crash happens, there is no way to restore the contents
of the reallocated blocks at the end of the last fully committed transaction.
One simple way of doing this is to mark blocks as free in internal in-memory
block allocation structures only after the transaction freeing them commits.
Ext4 uses journal commit callback for this purpose.
</para>
<para>
With journal commit callbacks you can ask the journalling layer to call a
callback function when the transaction is finally committed to disk, so that
you can do some of your own management. You ask the journalling layer for
calling the callback by simply setting journal->j_commit_callback function
pointer and that function is called after each transaction commit. You can also
use transaction->t_private_list for attaching entries to a transaction that
need processing when the transaction commits.
</para>
<para>
JBD2 also provides a way to block all transaction updates via
jbd2_journal_{un,}lock_updates(). Ext4 uses this when it wants a window with a
clean and stable fs for a moment. E.g.
</para>
<programlisting>
jbd2_journal_lock_updates() //stop new stuff happening..
jbd2_journal_flush() // checkpoint everything.
..do stuff on stable fs
jbd2_journal_unlock_updates() // carry on with filesystem use.
</programlisting>
<para>
The opportunities for abuse and DOS attacks with this should be obvious,
if you allow unprivileged userspace to trigger codepaths containing these
calls.
</para>
</sect2>
<sect2 id="jbd_summary">
<title>Summary</title>
<para>
Using the journal is a matter of wrapping the different context changes,
being each mount, each modification (transaction) and each changed buffer
to tell the journalling layer about them.
</para>
</sect2>
</sect1>
<sect1 id="data_types">
<title>Data Types</title>
<para>
The journalling layer uses typedefs to 'hide' the concrete definitions
of the structures used. As a client of the JBD2 layer you can
just rely on the using the pointer as a magic cookie of some sort.
Obviously the hiding is not enforced as this is 'C'.
</para>
<sect2 id="structures"><title>Structures</title>
!Iinclude/linux/jbd2.h
</sect2>
</sect1>
<sect1 id="functions">
<title>Functions</title>
<para>
The functions here are split into two groups those that
affect a journal as a whole, and those which are used to
manage transactions
</para>
<sect2 id="journal_level"><title>Journal Level</title>
!Efs/jbd2/journal.c
!Ifs/jbd2/recovery.c
</sect2>
<sect2 id="transaction_level"><title>Transasction Level</title>
!Efs/jbd2/transaction.c
</sect2>
</sect1>
<sect1 id="see_also">
<title>See also</title>
<para>
<citation>
<ulink url="http://kernel.org/pub/linux/kernel/people/sct/ext3/journal-design.ps.gz">
Journaling the Linux ext2fs Filesystem, LinuxExpo 98, Stephen Tweedie
</ulink>
</citation>
</para>
<para>
<citation>
<ulink url="http://olstrans.sourceforge.net/release/OLS2000-ext3/OLS2000-ext3.html">
Ext3 Journalling FileSystem, OLS 2000, Dr. Stephen Tweedie
</ulink>
</citation>
</para>
</sect1>
</chapter>
<chapter id="splice">
<title>splice API</title>
<para>
splice is a method for moving blocks of data around inside the
kernel, without continually transferring them between the kernel
and user space.
</para>
!Ffs/splice.c
</chapter>
<chapter id="pipes">
<title>pipes API</title>
<para>
Pipe interfaces are all for in-kernel (builtin image) use.
They are not exported for use by modules.
</para>
!Iinclude/linux/pipe_fs_i.h
!Ffs/pipe.c
</chapter>
</book>
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
"http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" []>
<book id="Reed-Solomon-Library-Guide">
<bookinfo>
<title>Reed-Solomon Library Programming Interface</title>
<authorgroup>
<author>
<firstname>Thomas</firstname>
<surname>Gleixner</surname>
<affiliation>
<address>
<email>tglx@linutronix.de</email>
</address>
</affiliation>
</author>
</authorgroup>
<copyright>
<year>2004</year>
<holder>Thomas Gleixner</holder>
</copyright>
<legalnotice>
<para>
This documentation is free software; you can redistribute
it and/or modify it under the terms of the GNU General Public
License version 2 as published by the Free Software Foundation.
</para>
<para>
This program is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied
warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
</para>
<para>
You should have received a copy of the GNU General Public
License along with this program; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
MA 02111-1307 USA
</para>
<para>
For more details see the file COPYING in the source
distribution of Linux.
</para>
</legalnotice>
</bookinfo>
<toc></toc>
<chapter id="intro">
<title>Introduction</title>
<para>
The generic Reed-Solomon Library provides encoding, decoding
and error correction functions.
</para>
<para>
Reed-Solomon codes are used in communication and storage
applications to ensure data integrity.
</para>
<para>
This documentation is provided for developers who want to utilize
the functions provided by the library.
</para>
</chapter>
<chapter id="bugs">
<title>Known Bugs And Assumptions</title>
<para>
None.
</para>
</chapter>
<chapter id="usage">
<title>Usage</title>
<para>
This chapter provides examples of how to use the library.
</para>
<sect1>
<title>Initializing</title>
<para>
The init function init_rs returns a pointer to an
rs decoder structure, which holds the necessary
information for encoding, decoding and error correction
with the given polynomial. It either uses an existing
matching decoder or creates a new one. On creation all
the lookup tables for fast en/decoding are created.
The function may take a while, so make sure not to
call it in critical code paths.
</para>
<programlisting>
/* the Reed Solomon control structure */
static struct rs_control *rs_decoder;
/* Symbolsize is 10 (bits)
* Primitive polynomial is x^10+x^3+1
* first consecutive root is 0
* primitive element to generate roots = 1
* generator polynomial degree (number of roots) = 6
*/
rs_decoder = init_rs (10, 0x409, 0, 1, 6);
</programlisting>
</sect1>
<sect1>
<title>Encoding</title>
<para>
The encoder calculates the Reed-Solomon code over
the given data length and stores the result in
the parity buffer. Note that the parity buffer must
be initialized before calling the encoder.
</para>
<para>
The expanded data can be inverted on the fly by
providing a non-zero inversion mask. The expanded data is
XOR'ed with the mask. This is used e.g. for FLASH
ECC, where the all 0xFF is inverted to an all 0x00.
The Reed-Solomon code for all 0x00 is all 0x00. The
code is inverted before storing to FLASH so it is 0xFF
too. This prevents that reading from an erased FLASH
results in ECC errors.
</para>
<para>
The databytes are expanded to the given symbol size
on the fly. There is no support for encoding continuous
bitstreams with a symbol size != 8 at the moment. If
it is necessary it should be not a big deal to implement
such functionality.
</para>
<programlisting>
/* Parity buffer. Size = number of roots */
uint16_t par[6];
/* Initialize the parity buffer */
memset(par, 0, sizeof(par));
/* Encode 512 byte in data8. Store parity in buffer par */
encode_rs8 (rs_decoder, data8, 512, par, 0);
</programlisting>
</sect1>
<sect1>
<title>Decoding</title>
<para>
The decoder calculates the syndrome over
the given data length and the received parity symbols
and corrects errors in the data.
</para>
<para>
If a syndrome is available from a hardware decoder
then the syndrome calculation is skipped.
</para>
<para>
The correction of the data buffer can be suppressed
by providing a correction pattern buffer and an error
location buffer to the decoder. The decoder stores the
calculated error location and the correction bitmask
in the given buffers. This is useful for hardware
decoders which use a weird bit ordering scheme.
</para>
<para>
The databytes are expanded to the given symbol size
on the fly. There is no support for decoding continuous
bitstreams with a symbolsize != 8 at the moment. If
it is necessary it should be not a big deal to implement
such functionality.
</para>
<sect2>
<title>
Decoding with syndrome calculation, direct data correction
</title>
<programlisting>
/* Parity buffer. Size = number of roots */
uint16_t par[6];
uint8_t data[512];
int numerr;
/* Receive data */
.....
/* Receive parity */
.....
/* Decode 512 byte in data8.*/
numerr = decode_rs8 (rs_decoder, data8, par, 512, NULL, 0, NULL, 0, NULL);
</programlisting>
</sect2>
<sect2>
<title>
Decoding with syndrome given by hardware decoder, direct data correction
</title>
<programlisting>
/* Parity buffer. Size = number of roots */
uint16_t par[6], syn[6];
uint8_t data[512];
int numerr;
/* Receive data */
.....
/* Receive parity */
.....
/* Get syndrome from hardware decoder */
.....
/* Decode 512 byte in data8.*/
numerr = decode_rs8 (rs_decoder, data8, par, 512, syn, 0, NULL, 0, NULL);
</programlisting>
</sect2>
<sect2>
<title>
Decoding with syndrome given by hardware decoder, no direct data correction.
</title>
<para>
Note: It's not necessary to give data and received parity to the decoder.
</para>
<programlisting>
/* Parity buffer. Size = number of roots */
uint16_t par[6], syn[6], corr[8];
uint8_t data[512];
int numerr, errpos[8];
/* Receive data */
.....
/* Receive parity */
.....
/* Get syndrome from hardware decoder */
.....
/* Decode 512 byte in data8.*/
numerr = decode_rs8 (rs_decoder, NULL, NULL, 512, syn, 0, errpos, 0, corr);
for (i = 0; i &lt; numerr; i++) {
do_error_correction_in_your_buffer(errpos[i], corr[i]);
}
</programlisting>
</sect2>
</sect1>
<sect1>
<title>Cleanup</title>
<para>
The function free_rs frees the allocated resources,
if the caller is the last user of the decoder.
</para>
<programlisting>
/* Release resources */
free_rs(rs_decoder);
</programlisting>
</sect1>
</chapter>
<chapter id="structs">
<title>Structures</title>
<para>
This chapter contains the autogenerated documentation of the structures which are
used in the Reed-Solomon Library and are relevant for a developer.
</para>
!Iinclude/linux/rslib.h
</chapter>
<chapter id="pubfunctions">
<title>Public Functions Provided</title>
<para>
This chapter contains the autogenerated documentation of the Reed-Solomon functions
which are exported.
</para>
!Elib/reed_solomon/reed_solomon.c
</chapter>
<chapter id="credits">
<title>Credits</title>
<para>
The library code for encoding and decoding was written by Phil Karn.
</para>
<programlisting>
Copyright 2002, Phil Karn, KA9Q
May be used under the terms of the GNU General Public License (GPL)
</programlisting>
<para>
The wrapper functions and interfaces are written by Thomas Gleixner.
</para>
<para>
Many users have provided bugfixes, improvements and helping hands for testing.
Thanks a lot.
</para>
<para>
The following people have contributed to this document:
</para>
<para>
Thomas Gleixner<email>tglx@linutronix.de</email>
</para>
</chapter>
</book>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
"http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" []>
<article class="whitepaper" id="LinuxSecurityModule" lang="en">
<articleinfo>
<title>Linux Security Modules: General Security Hooks for Linux</title>
<authorgroup>
<author>
<firstname>Stephen</firstname>
<surname>Smalley</surname>
<affiliation>
<orgname>NAI Labs</orgname>
<address><email>ssmalley@nai.com</email></address>
</affiliation>
</author>
<author>
<firstname>Timothy</firstname>
<surname>Fraser</surname>
<affiliation>
<orgname>NAI Labs</orgname>
<address><email>tfraser@nai.com</email></address>
</affiliation>
</author>
<author>
<firstname>Chris</firstname>
<surname>Vance</surname>
<affiliation>
<orgname>NAI Labs</orgname>
<address><email>cvance@nai.com</email></address>
</affiliation>
</author>
</authorgroup>
</articleinfo>
<sect1 id="Introduction"><title>Introduction</title>
<para>
In March 2001, the National Security Agency (NSA) gave a presentation
about Security-Enhanced Linux (SELinux) at the 2.5 Linux Kernel
Summit. SELinux is an implementation of flexible and fine-grained
nondiscretionary access controls in the Linux kernel, originally
implemented as its own particular kernel patch. Several other
security projects (e.g. RSBAC, Medusa) have also developed flexible
access control architectures for the Linux kernel, and various
projects have developed particular access control models for Linux
(e.g. LIDS, DTE, SubDomain). Each project has developed and
maintained its own kernel patch to support its security needs.
</para>
<para>
In response to the NSA presentation, Linus Torvalds made a set of
remarks that described a security framework he would be willing to
consider for inclusion in the mainstream Linux kernel. He described a
general framework that would provide a set of security hooks to
control operations on kernel objects and a set of opaque security
fields in kernel data structures for maintaining security attributes.
This framework could then be used by loadable kernel modules to
implement any desired model of security. Linus also suggested the
possibility of migrating the Linux capabilities code into such a
module.
</para>
<para>
The Linux Security Modules (LSM) project was started by WireX to
develop such a framework. LSM is a joint development effort by
several security projects, including Immunix, SELinux, SGI and Janus,
and several individuals, including Greg Kroah-Hartman and James
Morris, to develop a Linux kernel patch that implements this
framework. The patch is currently tracking the 2.4 series and is
targeted for integration into the 2.5 development series. This
technical report provides an overview of the framework and the example
capabilities security module provided by the LSM kernel patch.
</para>
</sect1>
<sect1 id="framework"><title>LSM Framework</title>
<para>
The LSM kernel patch provides a general kernel framework to support
security modules. In particular, the LSM framework is primarily
focused on supporting access control modules, although future
development is likely to address other security needs such as
auditing. By itself, the framework does not provide any additional
security; it merely provides the infrastructure to support security
modules. The LSM kernel patch also moves most of the capabilities
logic into an optional security module, with the system defaulting
to the traditional superuser logic. This capabilities module
is discussed further in <xref linkend="cap"/>.
</para>
<para>
The LSM kernel patch adds security fields to kernel data structures
and inserts calls to hook functions at critical points in the kernel
code to manage the security fields and to perform access control. It
also adds functions for registering and unregistering security
modules, and adds a general <function>security</function> system call
to support new system calls for security-aware applications.
</para>
<para>
The LSM security fields are simply <type>void*</type> pointers. For
process and program execution security information, security fields
were added to <structname>struct task_struct</structname> and
<structname>struct linux_binprm</structname>. For filesystem security
information, a security field was added to
<structname>struct super_block</structname>. For pipe, file, and socket
security information, security fields were added to
<structname>struct inode</structname> and
<structname>struct file</structname>. For packet and network device security
information, security fields were added to
<structname>struct sk_buff</structname> and
<structname>struct net_device</structname>. For System V IPC security
information, security fields were added to
<structname>struct kern_ipc_perm</structname> and
<structname>struct msg_msg</structname>; additionally, the definitions
for <structname>struct msg_msg</structname>, <structname>struct
msg_queue</structname>, and <structname>struct
shmid_kernel</structname> were moved to header files
(<filename>include/linux/msg.h</filename> and
<filename>include/linux/shm.h</filename> as appropriate) to allow
the security modules to use these definitions.
</para>
<para>
Each LSM hook is a function pointer in a global table,
security_ops. This table is a
<structname>security_operations</structname> structure as defined by
<filename>include/linux/security.h</filename>. Detailed documentation
for each hook is included in this header file. At present, this
structure consists of a collection of substructures that group related
hooks based on the kernel object (e.g. task, inode, file, sk_buff,
etc) as well as some top-level hook function pointers for system
operations. This structure is likely to be flattened in the future
for performance. The placement of the hook calls in the kernel code
is described by the "called:" lines in the per-hook documentation in
the header file. The hook calls can also be easily found in the
kernel code by looking for the string "security_ops->".
</para>
<para>
Linus mentioned per-process security hooks in his original remarks as a
possible alternative to global security hooks. However, if LSM were
to start from the perspective of per-process hooks, then the base
framework would have to deal with how to handle operations that
involve multiple processes (e.g. kill), since each process might have
its own hook for controlling the operation. This would require a
general mechanism for composing hooks in the base framework.
Additionally, LSM would still need global hooks for operations that
have no process context (e.g. network input operations).
Consequently, LSM provides global security hooks, but a security
module is free to implement per-process hooks (where that makes sense)
by storing a security_ops table in each process' security field and
then invoking these per-process hooks from the global hooks.
The problem of composition is thus deferred to the module.
</para>
<para>
The global security_ops table is initialized to a set of hook
functions provided by a dummy security module that provides
traditional superuser logic. A <function>register_security</function>
function (in <filename>security/security.c</filename>) is provided to
allow a security module to set security_ops to refer to its own hook
functions, and an <function>unregister_security</function> function is
provided to revert security_ops to the dummy module hooks. This
mechanism is used to set the primary security module, which is
responsible for making the final decision for each hook.
</para>
<para>
LSM also provides a simple mechanism for stacking additional security
modules with the primary security module. It defines
<function>register_security</function> and
<function>unregister_security</function> hooks in the
<structname>security_operations</structname> structure and provides
<function>mod_reg_security</function> and
<function>mod_unreg_security</function> functions that invoke these
hooks after performing some sanity checking. A security module can
call these functions in order to stack with other modules. However,
the actual details of how this stacking is handled are deferred to the
module, which can implement these hooks in any way it wishes
(including always returning an error if it does not wish to support
stacking). In this manner, LSM again defers the problem of
composition to the module.
</para>
<para>
Although the LSM hooks are organized into substructures based on
kernel object, all of the hooks can be viewed as falling into two
major categories: hooks that are used to manage the security fields
and hooks that are used to perform access control. Examples of the
first category of hooks include the
<function>alloc_security</function> and
<function>free_security</function> hooks defined for each kernel data
structure that has a security field. These hooks are used to allocate
and free security structures for kernel objects. The first category
of hooks also includes hooks that set information in the security
field after allocation, such as the <function>post_lookup</function>
hook in <structname>struct inode_security_ops</structname>. This hook
is used to set security information for inodes after successful lookup
operations. An example of the second category of hooks is the
<function>permission</function> hook in
<structname>struct inode_security_ops</structname>. This hook checks
permission when accessing an inode.
</para>
</sect1>
<sect1 id="cap"><title>LSM Capabilities Module</title>
<para>
The LSM kernel patch moves most of the existing POSIX.1e capabilities
logic into an optional security module stored in the file
<filename>security/capability.c</filename>. This change allows
users who do not want to use capabilities to omit this code entirely
from their kernel, instead using the dummy module for traditional
superuser logic or any other module that they desire. This change
also allows the developers of the capabilities logic to maintain and
enhance their code more freely, without needing to integrate patches
back into the base kernel.
</para>
<para>
In addition to moving the capabilities logic, the LSM kernel patch
could move the capability-related fields from the kernel data
structures into the new security fields managed by the security
modules. However, at present, the LSM kernel patch leaves the
capability fields in the kernel data structures. In his original
remarks, Linus suggested that this might be preferable so that other
security modules can be easily stacked with the capabilities module
without needing to chain multiple security structures on the security field.
It also avoids imposing extra overhead on the capabilities module
to manage the security fields. However, the LSM framework could
certainly support such a move if it is determined to be desirable,
with only a few additional changes described below.
</para>
<para>
At present, the capabilities logic for computing process capabilities
on <function>execve</function> and <function>set*uid</function>,
checking capabilities for a particular process, saving and checking
capabilities for netlink messages, and handling the
<function>capget</function> and <function>capset</function> system
calls have been moved into the capabilities module. There are still a
few locations in the base kernel where capability-related fields are
directly examined or modified, but the current version of the LSM
patch does allow a security module to completely replace the
assignment and testing of capabilities. These few locations would
need to be changed if the capability-related fields were moved into
the security field. The following is a list of known locations that
still perform such direct examination or modification of
capability-related fields:
<itemizedlist>
<listitem><para><filename>fs/open.c</filename>:<function>sys_access</function></para></listitem>
<listitem><para><filename>fs/lockd/host.c</filename>:<function>nlm_bind_host</function></para></listitem>
<listitem><para><filename>fs/nfsd/auth.c</filename>:<function>nfsd_setuser</function></para></listitem>
<listitem><para><filename>fs/proc/array.c</filename>:<function>task_cap</function></para></listitem>
</itemizedlist>
</para>
</sect1>
</article>
此差异已折叠。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
"http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" []>
<book id="LinuxNetworking">
<bookinfo>
<title>Linux Networking and Network Devices APIs</title>
<legalnotice>
<para>
This documentation is free software; you can redistribute
it and/or modify it under the terms of the GNU General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later
version.
</para>
<para>
This program is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied
warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
</para>
<para>
You should have received a copy of the GNU General Public
License along with this program; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
MA 02111-1307 USA
</para>
<para>
For more details see the file COPYING in the source
distribution of Linux.
</para>
</legalnotice>
</bookinfo>
<toc></toc>
<chapter id="netcore">
<title>Linux Networking</title>
<sect1><title>Networking Base Types</title>
!Iinclude/linux/net.h
</sect1>
<sect1><title>Socket Buffer Functions</title>
!Iinclude/linux/skbuff.h
!Iinclude/net/sock.h
!Enet/socket.c
!Enet/core/skbuff.c
!Enet/core/sock.c
!Enet/core/datagram.c
!Enet/core/stream.c
</sect1>
<sect1><title>Socket Filter</title>
!Enet/core/filter.c
</sect1>
<sect1><title>Generic Network Statistics</title>
!Iinclude/uapi/linux/gen_stats.h
!Enet/core/gen_stats.c
!Enet/core/gen_estimator.c
</sect1>
<sect1><title>SUN RPC subsystem</title>
<!-- The !D functionality is not perfect, garbage has to be protected by comments
!Dnet/sunrpc/sunrpc_syms.c
-->
!Enet/sunrpc/xdr.c
!Enet/sunrpc/svc_xprt.c
!Enet/sunrpc/xprt.c
!Enet/sunrpc/sched.c
!Enet/sunrpc/socklib.c
!Enet/sunrpc/stats.c
!Enet/sunrpc/rpc_pipe.c
!Enet/sunrpc/rpcb_clnt.c
!Enet/sunrpc/clnt.c
</sect1>
<sect1><title>WiMAX</title>
!Enet/wimax/op-msg.c
!Enet/wimax/op-reset.c
!Enet/wimax/op-rfkill.c
!Enet/wimax/stack.c
!Iinclude/net/wimax.h
!Iinclude/uapi/linux/wimax.h
</sect1>
</chapter>
<chapter id="netdev">
<title>Network device support</title>
<sect1><title>Driver Support</title>
!Enet/core/dev.c
!Enet/ethernet/eth.c
!Enet/sched/sch_generic.c
!Iinclude/linux/etherdevice.h
!Iinclude/linux/netdevice.h
</sect1>
<sect1><title>PHY Support</title>
!Edrivers/net/phy/phy.c
!Idrivers/net/phy/phy.c
!Edrivers/net/phy/phy_device.c
!Idrivers/net/phy/phy_device.c
!Edrivers/net/phy/mdio_bus.c
!Idrivers/net/phy/mdio_bus.c
</sect1>
<!-- FIXME: Removed for now since no structured comments in source
<sect1><title>Wireless</title>
X!Enet/core/wireless.c
</sect1>
-->
</chapter>
</book>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
"http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" [
<!ENTITY rapidio SYSTEM "rapidio.xml">
]>
<book id="RapidIO-Guide">
<bookinfo>
<title>RapidIO Subsystem Guide</title>
<authorgroup>
<author>
<firstname>Matt</firstname>
<surname>Porter</surname>
<affiliation>
<address>
<email>mporter@kernel.crashing.org</email>
<email>mporter@mvista.com</email>
</address>
</affiliation>
</author>
</authorgroup>
<copyright>
<year>2005</year>
<holder>MontaVista Software, Inc.</holder>
</copyright>
<legalnotice>
<para>
This documentation is free software; you can redistribute
it and/or modify it under the terms of the GNU General Public
License version 2 as published by the Free Software Foundation.
</para>
<para>
This program is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied
warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
</para>
<para>
You should have received a copy of the GNU General Public
License along with this program; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
MA 02111-1307 USA
</para>
<para>
For more details see the file COPYING in the source
distribution of Linux.
</para>
</legalnotice>
</bookinfo>
<toc></toc>
<chapter id="intro">
<title>Introduction</title>
<para>
RapidIO is a high speed switched fabric interconnect with
features aimed at the embedded market. RapidIO provides
support for memory-mapped I/O as well as message-based
transactions over the switched fabric network. RapidIO has
a standardized discovery mechanism not unlike the PCI bus
standard that allows simple detection of devices in a
network.
</para>
<para>
This documentation is provided for developers intending
to support RapidIO on new architectures, write new drivers,
or to understand the subsystem internals.
</para>
</chapter>
<chapter id="bugs">
<title>Known Bugs and Limitations</title>
<sect1 id="known_bugs">
<title>Bugs</title>
<para>None. ;)</para>
</sect1>
<sect1 id="Limitations">
<title>Limitations</title>
<para>
<orderedlist>
<listitem><para>Access/management of RapidIO memory regions is not supported</para></listitem>
<listitem><para>Multiple host enumeration is not supported</para></listitem>
</orderedlist>
</para>
</sect1>
</chapter>
<chapter id="drivers">
<title>RapidIO driver interface</title>
<para>
Drivers are provided a set of calls in order
to interface with the subsystem to gather info
on devices, request/map memory region resources,
and manage mailboxes/doorbells.
</para>
<sect1 id="Functions">
<title>Functions</title>
!Iinclude/linux/rio_drv.h
!Edrivers/rapidio/rio-driver.c
!Edrivers/rapidio/rio.c
</sect1>
</chapter>
<chapter id="internals">
<title>Internals</title>
<para>
This chapter contains the autogenerated documentation of the RapidIO
subsystem.
</para>
<sect1 id="Structures"><title>Structures</title>
!Iinclude/linux/rio.h
</sect1>
<sect1 id="Enumeration_and_Discovery"><title>Enumeration and Discovery</title>
!Idrivers/rapidio/rio-scan.c
</sect1>
<sect1 id="Driver_functionality"><title>Driver functionality</title>
!Idrivers/rapidio/rio.c
!Idrivers/rapidio/rio-access.c
</sect1>
<sect1 id="Device_model_support"><title>Device model support</title>
!Idrivers/rapidio/rio-driver.c
</sect1>
<sect1 id="PPC32_support"><title>PPC32 support</title>
!Iarch/powerpc/sysdev/fsl_rio.c
</sect1>
</chapter>
<chapter id="credits">
<title>Credits</title>
<para>
The following people have contributed to the RapidIO
subsystem directly or indirectly:
<orderedlist>
<listitem><para>Matt Porter<email>mporter@kernel.crashing.org</email></para></listitem>
<listitem><para>Randy Vinson<email>rvinson@mvista.com</email></para></listitem>
<listitem><para>Dan Malek<email>dan@embeddedalley.com</email></para></listitem>
</orderedlist>
</para>
<para>
The following people have contributed to this document:
<orderedlist>
<listitem><para>Matt Porter<email>mporter@kernel.crashing.org</email></para></listitem>
</orderedlist>
</para>
</chapter>
</book>
此差异已折叠。
此差异已折叠。
此差异已折叠。
<?xml version="1.0" encoding="UTF-8"?>
<stylesheet xmlns="http://www.w3.org/1999/XSL/Transform" version="1.0">
<param name="chunk.quietly">1</param>
<param name="funcsynopsis.style">ansi</param>
<param name="funcsynopsis.tabular.threshold">80</param>
<param name="callout.graphics">0</param>
<!-- <param name="paper.type">A4</param> -->
<param name="generate.consistent.ids">1</param>
<param name="generate.section.toc.level">2</param>
<param name="use.id.as.filename">1</param>
</stylesheet>
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册