[U-Boot] [RFC 1/3] uboot-doc: Initial support of user documentation generator

John Schmoller jschmoller at xes-inc.com
Tue Jul 28 18:34:01 CEST 2009


Initial support of U-Boot User's Manual documentation generator.
It makes use of the C pre-processor to gather context, and then
the doc-stream.pl program parses out interesting comments for
consideration by uboot-doc, which creates DocBook style XML from
autogenerated files as well as the template files.  Template
files are pseudo-XML with precompiler directives. Also includes
a stylesheet wrapper for manual customization.

Signed-off-by: John Schmoller <jschmoller at xes-inc.com>
---
 Makefile                          |    2 +
 config.mk                         |    1 +
 doc/manual/85xx_program_flow.tmpl |   74 ++++
 doc/manual/book_info.tmpl         |   35 ++
 doc/manual/booting_linux.tmpl     |  249 +++++++++++
 doc/manual/config.mk              |   74 ++++
 doc/manual/doc-stream.pl          |   34 ++
 doc/manual/introduction.tmpl      |  136 ++++++
 doc/manual/manual.tmpl            |   26 ++
 doc/manual/scripting.tmpl         |  154 +++++++
 doc/manual/setup.tmpl             |  294 +++++++++++++
 doc/manual/uboot-doc              |  866 +++++++++++++++++++++++++++++++++++++
 doc/manual/uboot_manual.xsl       |  286 ++++++++++++
 rules.mk                          |    7 +
 14 files changed, 2238 insertions(+), 0 deletions(-)
 create mode 100644 doc/manual/85xx_program_flow.tmpl
 create mode 100644 doc/manual/book_info.tmpl
 create mode 100644 doc/manual/booting_linux.tmpl
 create mode 100644 doc/manual/config.mk
 create mode 100644 doc/manual/doc-stream.pl
 create mode 100644 doc/manual/introduction.tmpl
 create mode 100644 doc/manual/manual.tmpl
 create mode 100644 doc/manual/scripting.tmpl
 create mode 100644 doc/manual/setup.tmpl
 create mode 100644 doc/manual/uboot-doc
 create mode 100644 doc/manual/uboot_manual.xsl

diff --git a/Makefile b/Makefile
index ef535ed..ff4f242 100644
--- a/Makefile
+++ b/Makefile
@@ -153,6 +153,7 @@ ifeq ($(obj)include/config.mk,$(wildcard $(obj)include/config.mk))
 all:
 sinclude $(obj)include/autoconf.mk.dep
 sinclude $(obj)include/autoconf.mk
+sinclude $(obj)doc/manual/config.mk
 
 # load ARCH, BOARD, and CPU configuration
 include $(obj)include/config.mk
@@ -3646,6 +3647,7 @@ clean:
 	@rm -f $(obj)include/bmp_logo.h
 	@rm -f $(obj)nand_spl/{u-boot-spl,u-boot-spl.map,System.map}
 	@rm -f $(obj)onenand_ipl/onenand-{ipl,ipl.bin,ipl-2k.bin,ipl-4k.bin,ipl.map}
+	@rm -f $(obj)doc/manual/{*.xml,*.html,*.fo,*.pdf,params.xsl}
 	@rm -f $(TIMESTAMP_FILE) $(VERSION_FILE)
 	@find $(OBJTREE) -type f \
 		\( -name 'core' -o -name '*.bak' -o -name '*~' \
diff --git a/config.mk b/config.mk
index fd56621..fb8bed0 100644
--- a/config.mk
+++ b/config.mk
@@ -96,6 +96,7 @@ BOARDDIR = $(VENDOR)/$(BOARD)
 else
 BOARDDIR = $(BOARD)
 endif
+export BOARDDIR
 ifdef	BOARD
 sinclude $(TOPDIR)/board/$(BOARDDIR)/config.mk	# include board specific rules
 endif
diff --git a/doc/manual/85xx_program_flow.tmpl b/doc/manual/85xx_program_flow.tmpl
new file mode 100644
index 0000000..1010780
--- /dev/null
+++ b/doc/manual/85xx_program_flow.tmpl
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+    <sect2 xmlns="http://docbook.org/ns/docbook"
+	   xml:id="uboot_setup_prog_flow">
+      <title>U-Boot Program Flow</title>
+      <para>U-Boot follows the following program flow.</para>
+      <orderedlist>
+	<listitem>
+	  <para>Reset</para>
+	</listitem>
+	<listitem>
+	  <para>Initialize Processor</para>
+	</listitem>
+	<listitem>
+	  <para>Set up data cache as stack</para>
+	</listitem>
+	<listitem>
+	  <para>Set up TLBs and LAWs</para>
+	</listitem>
+	<listitem>
+	  <para>Initialize U-Boot environment</para>
+	</listitem>
+	<listitem>
+	  <para>Initialize serial port</para>
+	</listitem>
+	<listitem>
+	  <para>Initialize I2C</para>
+	</listitem>
+	<listitem>
+	  <para>Initialize DRAM</para>
+	</listitem>
+	<listitem>
+	  <para>Relocate from Flash to RAM</para>
+	</listitem>
+	<listitem>
+	  <para>Set up data cache</para>
+	</listitem>
+	<listitem>
+	  <para>Initialize Flash Structure</para>
+	</listitem>
+	<listitem>
+	  <para>Initialize malloc area</para>
+	</listitem>
+	<listitem>
+	  <para>Initialize NAND device</para>
+	</listitem>
+	<listitem>
+	  <para>Initialize PCI</para>
+	</listitem>
+	<listitem>
+	  <para>Initialize Vector Table</para>
+	</listitem>
+	<listitem>
+	  <para>Initialize Ethernet</para>
+	</listitem>
+#ifdef CONFIG_PREBOOT
+	<listitem>
+	  <para>Exectue <link linkend="env_preboot"><literal>preboot</literal>
+	    </link> environment variable
+	  </para>
+	</listitem>
+#endif
+	<listitem>
+	  <para>Wait <link linkend="env_bootdelay"><literal>bootdelay</literal>
+	    </link> seconds to stop autoboot
+	  </para>
+	</listitem>
+	<listitem>
+	  <para>If not canceled, execute <link linkend="env_bootcmd">
+	      <literal>bootcmd</literal></link> or enter main loop.
+	  </para>
+	</listitem>
+      </orderedlist>
+    </sect2>
diff --git a/doc/manual/book_info.tmpl b/doc/manual/book_info.tmpl
new file mode 100644
index 0000000..a4cec17
--- /dev/null
+++ b/doc/manual/book_info.tmpl
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<info>
+  <title>${BOARD} U-Boot Manual</title>
+  <subtitle>U-Boot User's Manual</subtitle>
+  <releaseinfo>U-Boot version: ${VERSION}</releaseinfo>
+  <titleabbrev>${BOARD}</titleabbrev>
+  <pubdate>${DATE}</pubdate>
+  <legalnotice>
+    <para>
+      U-Boot 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>
+      U-Boot 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
+      <orgname>Free Software Foundation, Inc.</orgname>,
+      <address><street>59 Temple Place, Suite 330</street>
+	<city>Boston</city>, <state>MA</state> <postcode>02111-1307</postcode>
+	<country>USA</country>
+      </address>
+    </para>
+  </legalnotice>
+</info>
+
diff --git a/doc/manual/booting_linux.tmpl b/doc/manual/booting_linux.tmpl
new file mode 100644
index 0000000..e0ab37c
--- /dev/null
+++ b/doc/manual/booting_linux.tmpl
@@ -0,0 +1,249 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<chapter version="5.0" xml:id="uboot_booting_linux_chapter"
+	 xmlns="http://docbook.org/ns/docbook"
+	 xmlns:xi="http://www.w3.org/2001/XInclude">
+  <title>Booting Linux</title>
+
+
+  <sect1 xml:id="uboot_booting_linux">
+    <title>Booting Linux with U-Boot</title>
+    <sect2 xml:id="uboot_booting_linux_intro">
+      <title>Booting Linux</title>
+      <para>The following is intended to be a Quick Start guide for booting a
+	Linux kernel. More information can be found in your Linux Manual.
+      </para>
+
+      <para>Your Linux kernel can be booted from either RAM or from Flash.
+	Images booted from RAM will need to be downloaded from the network
+	using <link linkend="uboot_cmd_tftpboot"><literal>tftp</literal></link>
+	on every reset. Images booted from Flash will be copied from Flash to
+	RAM automatically.
+      </para>
+
+      <sect3 xml:id="uboot_booting_linux_ram">
+	<title>Booting from RAM</title>
+	<para>To boot an image from RAM, you will need to have your Linux
+	  kernel
+#ifdef CONFIG_OF_LIBFDT
+	  and Flat Device Tree image
+#endif
+	  on a TFTP server. See
+	  <link linkend="uboot_setup_network">
+	  <literal>Networking</literal></link> for more information about
+	  TFTP and TFTP servers. Next, you will need to set up your
+	  <link linkend="uboot_env_sect_networking">
+	  <literal>network environment variables</literal></link> to point to
+	  your TFTP server.
+#ifdef CONFIG_CMD_DHCP
+	  You can use a DHCP server to accomplish this if
+	  your network has one set up using the
+	  <link linkend="uboot_cmd_dhcp"><literal>dhcp</literal></link> command.
+#endif
+	  Download the Linux kernel using the
+	  <link linkend="uboot_cmd_tftpboot"><literal>tftp</literal></link>
+	  command.
+	  <screen>
+tftp 10000000 &lt;Path to Linux Kernel&gt;
+	  </screen>
+#ifdef CONFIG_OF_LIBFDT
+	  Download the Flat Device Tree image using the
+	  <link linkend="uboot_cmd_tftpboot"><literal>tftp</literal></link>
+	  command.
+	  <screen>
+tftp c000000 &lt;Path to Flat Device Tree image&gt;
+	  </screen>
+#endif
+	  Adjust the download address based on the size of your kernel image.
+	  Consult your Linux manual for the recommended
+	  <link linkend="uboot_env_bootargs"><literal>bootargs</literal></link>.
+	  Set the <link linkend="uboot_env_bootargs">
+	  <literal>bootargs</literal></link> using the
+	  <link linkend="uboot_cmd_setenv"><literal>setenv</literal></link>
+	  command. Finally, boot your kernel image.
+	  <screen>
+#ifdef CONFIG_OF_LIBFDT
+bootm 10000000 - c000000
+#else
+bootm 10000000
+#endif
+	  </screen>
+	  Since we didn't disguss downloading a file system, this option
+	  assumes you are booting an NFS file system.
+	</para>
+
+	<para>Your console input/output should look something like this.
+	  <screen>
+=> setenv serverip 10.52.0.33
+=> setenv gatewayip 10.52.0.1
+=> setenv netmask 255.255.0.0
+=> setenv ipaddr 10.52.4.240
+=> tftp 10000000 /home/jschmoller/uImage
+Enet starting in 1000BT/FD
+Speed: 1000, full duplex
+Using eTSEC2 device
+TFTP from server 10.52.0.33; our IP address is 10.52.4.240
+Filename '/home/jschmoller/uImage'.
+Load address: 0x10000000
+Loading: #################################################################
+	 #################################################################
+	 #################################################################
+	 #################################################################
+	 ######
+done
+Bytes transferred = 3901275 (3b875b hex)
+#ifdef CONFIG_OF_LIBFDT
+=> tftp c000000 /home/jschmoller/dtb
+Enet starting in 1000BT/FD
+Speed: 1000, full duplex
+Using eTSEC2 device
+TFTP from server 10.52.0.33; our IP address is 10.52.4.240
+Filename '/home/jschmoller/dtb'.
+Load address: 0xc000000
+Loading: ##
+done
+Bytes transferred = 16384 (4000 hex)
+#endif
+=> setenv bootargs console=ttyS0,115200 root=/dev/nfs rw ip=on
+#ifdef CONFIG_OF_LIBFDT
+=> bootm 10000000 - c000000
+#else
+=> bootm 10000000
+#endif
+## Booting kernel from Legacy Image at 10000000 ...
+   Image Name:   Linux-2.6.23.17-fsl_r1
+   Created:      2008-08-06  16:46:04 UTC
+   Image Type:   PowerPC Linux Kernel Image (gzip compressed)
+   Data Size:    3901211 Bytes =  3.7 MB
+   Load Address: 00000000
+   Entry Point:  00000000
+   Verifying Checksum ... OK
+   Uncompressing Kernel Image ... OK
+	  </screen>
+	</para>
+      </sect3>
+
+      <sect3 xml:id="uboot_booting_linux_flash">
+	<title>Booting from Flash</title>
+	<para>To boot an image from Flash, you will need to follow a similar
+	  procedure to load the Kernel
+#ifdef CONFIG_OF_LIBFDT
+	  and FDT
+#endif
+	  for the first time. Make sure you have your Kernel
+#ifdef CONFIG_OF_LIBFDT
+	  and FDT
+#endif
+	  on your TFTP server.  Set your
+	  <link linkend="uboot_env_sect_networking">
+	  <literal>network environment variables</literal></link> to point to
+	  your TFTP server. Download the Linux kernel using the
+	  <link linkend="uboot_cmd_tftpboot"><literal>tftp</literal></link>
+	  command and then erase Flash and copy it using the
+	  <link linkend="uboot_cmd_erase"><literal>erase</literal></link> and
+	  <link linkend="uboot_cmd_cp"><literal>cp</literal></link> commands.
+	  <screen>
+tftp 10000000 &lt;Path to Linux Kernel&gt;
+erase &lt;Flash start + 1000000&gt; +$filesize
+cp.b 10000000 &lt;Flash start + 1000000&gt; $filesize
+	  </screen>
+#ifdef CONFIG_OF_LIBFDT
+	  Download the Flat Device Tree image using the
+	  <link linkend="uboot_cmd_tftpboot"><literal>tftp</literal></link>
+	  command.
+	  <screen>
+tftp c000000 &lt;Path to Flat Device Tree image&gt;
+erase &lt;Flash start&gt; +$filesize
+cp.b c000000 &lt;Flash start&gt; $filesize
+	  </screen>
+#endif
+	  Consult your Linux manual for the recommended
+	  <link linkend="uboot_env_bootargs"><literal>bootargs</literal></link>.
+	  Set the <link linkend="uboot_env_bootargs">
+	  <literal>bootargs</literal></link> using the
+	  <link linkend="uboot_cmd_setenv"><literal>setenv</literal></link>
+	  command and then save them using <link linkend="uboot_cmd_saveenv">
+	  <literal>saveenv</literal></link>. Set up your
+	  <link linkend="uboot_env_bootcmd"><literal>bootcmd</literal></link>
+	  environment variable to automatically boot the Linux kernel.
+	  <screen>
+#ifdef CONFIG_OF_LIBFDT
+setenv bootcmd bootm &lt;Flash start + 1000000&gt; - &lt;Flash start&gt;
+#else
+setenv bootcmd bootm &lt;Flash start + 1000000&gt;
+#endif
+	  </screen>
+	  Finally, boot your kernel image by resetting the board.
+	  Since we didn't disguss downloading a file system, this option
+	  assumes you are booting an NFS file system.
+	</para>
+
+	<para>Your console input/output should look something like this.
+	  <screen>
+=> setenv serverip 10.52.0.33
+=> setenv gatewayip 10.52.0.1
+=> setenv netmask 255.255.0.0
+=> setenv ipaddr 10.52.4.240
+=> tftp 10000000 /home/jschmoller/uImage
+Enet starting in 1000BT/FD
+Speed: 1000, full duplex
+Using eTSEC2 device
+TFTP from server 10.52.0.33; our IP address is 10.52.4.240
+Filename '/home/jschmoller/uImage'.
+Load address: 0x10000000
+Loading: #################################################################
+	 #################################################################
+	 #################################################################
+	 #################################################################
+	 ######
+done
+Bytes transferred = 3901275 (3b875b hex)
+=> erase f9000000 +$filesize
+
+.............................. done
+Erased 30 sectors
+=> cp.b 10000000 f9000000 $filesize
+Copy to Flash... done
+#ifdef CONFIG_OF_LIBFDT
+=> tftp c000000 /home/jschmoller/dtb
+Enet starting in 1000BT/FD
+Speed: 1000, full duplex
+Using eTSEC2 device
+TFTP from server 10.52.0.33; our IP address is 10.52.4.240
+Filename '/home/jschmoller/dtb'.
+Load address: 0xc000000
+Loading: ##
+done
+Bytes transferred = 16384 (4000 hex)
+=> erase f8000000 +$filesize
+
+. done
+Erased 1 sectors
+=> cp.b c000000 f8000000 $filesize
+Copy to Flash... done
+#endif
+=> setenv bootargs console=ttyS0,115200 root=/dev/nfs rw ip=on
+#ifdef CONFIG_OF_LIBFDT
+=> setenv bootcmd bootm f9000000 - f8000000
+#else
+=> setenv bootcmd bootm f9000000
+#endif
+=> saveenv
+=> reset
+&lt;Board resets&gt;
+Hit any key to stop autoboot:  0
+## Booting kernel from Legacy Image at f9000000 ...
+   Image Name:   Linux-2.6.23.17-fsl_r1
+   Created:      2008-08-06  16:46:04 UTC
+   Image Type:   PowerPC Linux Kernel Image (gzip compressed)
+   Data Size:    3901211 Bytes =  3.7 MB
+   Load Address: 00000000
+   Entry Point:  00000000
+   Verifying Checksum ... OK
+   Uncompressing Kernel Image ... OK
+	  </screen>
+	</para>
+      </sect3>
+    </sect2>
+  </sect1>
+</chapter>
diff --git a/doc/manual/config.mk b/doc/manual/config.mk
new file mode 100644
index 0000000..59bebb7
--- /dev/null
+++ b/doc/manual/config.mk
@@ -0,0 +1,74 @@
+#
+# (C) Copyright 2009 Extreme Engineering Solutions
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program 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.
+#
+# 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.
+#
+# 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
+#
+#########################################################################
+
+ifndef DOCBOOK_XSL_DIR
+DOCBOOK_XSL_DIR		= /usr/share/xml/docbook/stylesheet/nwalsh
+endif
+export DOCBOOK_XSL_DIR
+
+ifndef XSLT_PROCESSOR
+XSLT_PROCESSOR = xsltproc
+endif
+
+ifndef FO_PROCESSOR
+FO_PROCESSOR = fop
+endif
+
+.PHONY = $(obj)man_parse $(obj)xml
+
+$(obj)man_parse:	$(obj)include/autoconf.mk $(TIMESTAMP_FILE) \
+		$(VERSION_FILE)
+	@for f in $(dir $(LIBS)); do \
+		echo $$f; \
+		$(MAKE) -C $$f _man_parse; \
+	done
+
+$(obj)xml:	$(obj)man_parse
+	perl $(TOPDIR)/doc/manual/uboot-doc \
+		$(TOPDIR)/doc/manual/autoconf-doc.txt
+	rm $(TOPDIR)/doc/manual/autoconf-doc.txt
+
+$(obj)text:	$(obj)xml
+	$(XSLT_PROCESSOR) -o $(TOPDIR)/doc/manual/ --xinclude \
+		--stringparam pages.template \
+		$(DOCBOOK_XSL_DIR)/roundtrip/template.xml \
+		$(DOCBOOK_XSL_DIR)/roundtrip/dbk2wordml.xsl \
+		$(TOPDIR)/doc/manual/manual.xml
+
+$(obj)html:	$(obj)xml
+	$(XSLT_PROCESSOR) -o $(TOPDIR)/doc/manual/ --xinclude \
+		$(DOCBOOK_XSL_DIR)/html/chunk.xsl \
+			$(TOPDIR)/doc/manual/manual.xml
+
+$(obj)xhtml:	$(obj)xml
+	$(XSLT_PROCESSOR) -o $(TOPDIR)/doc/manual/ --xinclude \
+		$(DOCBOOK_XSL_DIR)/xhtml/chunk.xsl \
+			$(TOPDIR)/doc/manual/manual.xml
+
+$(obj)pdf:	$(obj)xml
+	$(XSLT_PROCESSOR) -o $(TOPDIR)/doc/manual/$(BOARD).fo \
+		--stringparam docbook_path ${DOCBOOK_XSL_DIR} --xinclude \
+		$(TOPDIR)/doc/manual/uboot_manual.xsl \
+			$(TOPDIR)/doc/manual/manual.xml
+		$(FO_PROCESSOR) -fo $(TOPDIR)/doc/manual/$(BOARD).fo -pdf \
+		$(TOPDIR)/doc/manual/$(BOARD).pdf
diff --git a/doc/manual/doc-stream.pl b/doc/manual/doc-stream.pl
new file mode 100644
index 0000000..71b7d02
--- /dev/null
+++ b/doc/manual/doc-stream.pl
@@ -0,0 +1,34 @@
+#!/usr/bin/perl -w
+
+use strict;
+
+my $comment = "";
+my $in_comment = 0;
+
+# This file takes the output of the C pre-processor and scans it for
+# "interesting" comments (those that contain an @) and prints the comment.
+# Those comments are then dumped into a file that can be processed by
+# uboot-doc. Without this script, the output of the C pre-processor is
+# unnecesarily large (~36MB).
+while (<STDIN>) {
+    if (/^\s*\/\*\*\s*$/) {
+	$comment .= $_;
+	$in_comment = 1;
+    } elsif (/\*\//) {
+	if ($in_comment) {
+	    $comment .= $_;
+
+	    if ($comment =~ /.*[\s\*]+ at .*/) {
+		print $comment;
+	    }
+	}
+	$in_comment = 0;
+	$comment = "";
+    } elsif (/\s*\*\s*/) {
+	if ($in_comment) {
+	    $comment .= $_;
+	}
+    }
+}
+
+
diff --git a/doc/manual/introduction.tmpl b/doc/manual/introduction.tmpl
new file mode 100644
index 0000000..063a6b8
--- /dev/null
+++ b/doc/manual/introduction.tmpl
@@ -0,0 +1,136 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<chapter version="5.0" xml:id="uboot_introduction_chapter"
+	 xmlns="http://docbook.org/ns/docbook"
+	 xmlns:xi="http://www.w3.org/2001/XInclude">
+  <title>Das U-Boot</title>
+
+  <sect1 xml:id="uboot_introduction">
+    <title>Introduction to U-Boot</title>
+    <para>The ${BOARD} utilizes the U-Boot bootloader. U-Boot
+    is an open-source bootloader which provides low-level hardware
+    initialization, power on self tests (POSTs), access to onboard peripherals
+    (Ethernet, flash, EEPROMs, sensors, etc.), and contains a powerful
+    set of commands that allow booting a variety of
+    operation systems and applications. Additional U-Boot information
+    can be found at <link ns1:href="http://www.denx.de/wiki/U-Boot/WebHome"
+    xmlns:ns1="http://www.w3.org/1999/xlink"
+    >http://www.denx.de/wiki/U-Boot/WebHome</link>.</para>
+  </sect1>
+
+  <sect1 xml:id="uboot_introduction_terminology">
+    <title>Terminology and Conventions</title>
+    <para>Below is a glossary of terminology that is relevant to U-Boot</para>
+    <table xml:id="uboot_introduction_term_table">
+      <title>Terminology</title>
+      <tgroup cols="2">
+        <colspec colnum="1" colname="c1"/>
+        <colspec colnum="2" colname="c2"/>
+        <thead>
+          <row>
+            <entry>Settings</entry>
+            <entry>Value</entry>
+          </row>
+        </thead>
+        <tbody>
+	  <row xml:id="uboot_term_target">
+            <entry>
+              <literal>Target</literal>
+            </entry>
+	    <entry>The single-board computer being used, e.g.: ${BOARD}</entry>
+	  </row>
+#ifdef CONFIG_CMD_DHCP
+	  <row xml:id="uboot_term_bootp">
+            <entry>
+              <literal>BOOTP</literal>
+            </entry>
+	    <entry>Bootstrap Protocol. BOOTP can be used to configure the
+		target&apos;s network settings based on information provided
+		by a BOOTP server.</entry>
+	  </row>
+	  <row xml:id="uboot_term_dhcp">
+            <entry>
+              <literal>DHCP</literal>
+            </entry>
+	    <entry>Dynamic Host Configuration Protocol. DHCP can be used to
+	      configure the target&apos;s network settings based on information
+	      provided by a DHCP server. DHCP is very similar to BOOTP. It
+	      is newer and provides some advanced features which BOOTP lacks.
+	      Most DHCP servers also provide support for BOOTP.</entry>
+	  </row>
+#endif
+#ifdef CONFIG_CMD_SNTP
+	  <row xml:id="uboot_term_ntp">
+            <entry>
+              <literal>NTP</literal>
+            </entry>
+	    <entry>Network Time Protocol. NTP is used to synchronize the
+	      target&apos;s date and time with an NTP server</entry>
+	  </row>
+#endif
+	  <row xml:id="uboot_term_os">
+            <entry>
+              <literal>OS</literal>
+            </entry>
+	    <entry>Operating System. e.g.: Linux, VxWorks, QNX, INTEGRITY.</entry>
+	  </row>
+	  <row xml:id="uboot_term_uimage">
+            <entry>
+              <literal>uImage</literal>
+            </entry>
+	    <entry>An image format which contains a payload (OS image,
+	      application image, filesystem, script, etc) as well as metadata
+	      describing the payload. The metadata includes such information
+	      as a checksum, payload name, timestamp, load address, etc.
+	    </entry>
+	  </row>
+#ifdef CONFIG_OF_LIBFDT
+	  <row xml:id="uboot_term_device_tree">
+            <entry>
+              <literal>Device Tree</literal>
+            </entry>
+	    <entry>A device tree is a text file which contains information in
+	      a tree structure based on the Open Firmware specification. The
+	      most common use of a device tree is to specify board-specific
+	      information such as baud rate, CPU speed, number of flashes, etc
+	      which U-Boot can manipulate and pass to an operating system such
+	      as Linux.</entry>
+	  </row>
+	  <row xml:id="uboot_term_dtb">
+            <entry>
+              <literal>DTB</literal>
+            </entry>
+	    <entry>Device Tree Blob. A commonly used acronym for a flattened
+	      device tree blob. DTB can be used interchangeably with FDT.
+	    </entry>
+	  </row>
+	  <row xml:id="uboot_term_fdt">
+            <entry>
+              <literal>FDT</literal>
+            </entry>
+	    <entry>Flattened device tree. A FDT blob is a device tree which
+	      has been converted into a binary form (a &quot;blob&quot;).
+	    </entry>
+	  </row>
+#endif
+	  <row xml:id="uboot_term_primary_flash">
+            <entry>
+              <literal>Primary Flash</literal>
+            </entry>
+	    <entry>The primary NOR flash device on the target. Also referred
+	      to as Flash 1.
+	    </entry>
+	  </row>
+	  <row xml:id="uboot_term_secondary_flash">
+            <entry>
+              <literal>Secondary Flash</literal>
+            </entry>
+	    <entry>The secondary NOR flash device on the target. Also referred
+	      to as Flash 2.
+	    </entry>
+	  </row>
+        </tbody>
+      </tgroup>
+    </table>
+  </sect1>
+</chapter>
diff --git a/doc/manual/manual.tmpl b/doc/manual/manual.tmpl
new file mode 100644
index 0000000..37eb85d
--- /dev/null
+++ b/doc/manual/manual.tmpl
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<book xmlns="http://docbook.org/ns/docbook"
+      xmlns:xi="http://www.w3.org/2001/XInclude"
+      version="5.0"
+      xml:id="uboot_manual">
+
+  <xi:include href="${TOPDIR}/doc/manual/book_info.xml"/>
+
+  <xi:include href="${TOPDIR}/doc/manual/introduction.xml"/>
+
+  <xi:include href="${TOPDIR}/doc/manual/setup.xml"/>
+
+  <xi:include href="${TOPDIR}/doc/manual/booting_linux.xml"/>
+
+  <xi:include href="${TOPDIR}/doc/manual/memory_resources.xml"/>
+#ifdef CONFIG_POST
+  <xi:include href="${TOPDIR}/doc/manual/posts.xml"/>
+#endif
+  <xi:include href="${TOPDIR}/doc/manual/environment_variables.xml"/>
+
+  <xi:include href="${TOPDIR}/doc/manual/commands.xml"/>
+
+  <xi:include href="${TOPDIR}/doc/manual/scripting.xml"/>
+
+</book>
diff --git a/doc/manual/scripting.tmpl b/doc/manual/scripting.tmpl
new file mode 100644
index 0000000..21a7918
--- /dev/null
+++ b/doc/manual/scripting.tmpl
@@ -0,0 +1,154 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<chapter version="5.0" xml:id="uboot_scripting_chapter"
+	 xmlns="http://docbook.org/ns/docbook"
+	 xmlns:xi="http://www.w3.org/2001/XInclude">
+  <title>Scripting</title>
+
+  <sect1 xml:id="uboot_scripting">
+    <title>Scripting in U-Boot</title>
+    <sect2 xml:id="uboot_scripting_dollar_sign">
+      <title>Variable Expansion with $</title>
+      <para>Variable substitution can be done with the $ character. For
+	instance, <link linkend="uboot_cmd_printenv">
+	<literal>printenv</literal></link> <link linkend="uboot_env_bootargs">
+	<literal>bootargs</literal></link> could also be executed with
+	<link linkend="uboot_cmd_echo"><literal>echo</literal></link>
+	<link linkend="uboot_env_bootargs"><literal>$bootargs</literal></link>.
+	More powerfully, this variable substitution can be used in scripting.
+	See the example in the next section.
+      </para>
+    </sect2>
+
+    <sect2 xml:id="uboot_scripting_conditionals">
+      <title>Conditionals</title>
+      <para>U-Boot has a scripting language which can be used to customize
+	command execution. It contains if..then..else..fi, for..do..done,
+	while..do..done and until..do..done control flow operations.
+      </para>
+
+      <para>As an example, take the environment variable bootcmd_net.
+	<screen>
+bootcmd_net=run set_bootargs; $download_cmd $osaddr $osfile; if test $? -eq 0;
+then if test -n $fdtaddr; then $download_cmd $fdtaddr $fdtfile;
+if test $? -eq 0; then bootm $osaddr - $fdtaddr; else; echo FDT DOWNLOAD FAILED;
+fi; else; bootm $osaddr; fi; else; echo OS DOWNLOAD FAILED; fi;
+	</screen>
+	To walk through the script, we start with
+	<link linkend="uboot_cmd_run"><literal>run</literal></link>
+	<literal>set_bootargs</literal>, which executes the commands stored
+	in <literal>set_bootargs</literal>. Next, we execute the command stored
+	in <literal>download_cmd</literal> which we&apos;ll assume is set to
+	<link linkend="uboot_cmd_tftpboot"><literal>tftp</literal></link> and
+	download the file from the path stored in <literal>osfile</literal> to
+	the address stored in <literal>osaddr</literal>. The next step is
+	interesting. We start an <literal>if</literal> conditional, and use the
+	<link linkend="uboot_cmd_test"><literal>test</literal></link> command
+	to check to see if the return value (<literal>$?</literal>) of the
+	<literal>download_cmd</literal> is <literal>0</literal>. If it
+	isn&apos;t, meaning the download failed, we find the matching
+	<literal>then</literal> and see that we echo
+	<literal>DOWNLOAD FAILED</literal>. If it is <literal>0</literal>
+	meaning the download completed successfully, we start a new
+	<literal>if</literal> conditional and test to see if
+	<literal>fdtaddr</literal> is defined. If it is, use
+	<literal>download_cmd</literal> to download the file
+	stored in <literal>fdtfile</literal> to the address stored in
+	<literal>fdtaddr</literal>. Again, we verify that the download
+	completed successfully.  If everything has worked up until now, we
+	complete the script with
+	<link linkend="uboot_cmd_bootm"><literal>bootm</literal></link>
+	<literal>osaddr - fdtaddr</literal> and boot the image we just
+	downloaded. If <literal>fdtaddr</literal> had been undefined, we would
+	have executed
+	<link linkend="uboot_cmd_bootm"><literal>bootm</literal></link>
+	<literal>osaddr</literal> instead.
+      </para>
+    </sect2>
+
+    <sect2 xml:id="uboot_scripting_and_or">
+      <title>&amp;&amp; and ||</title>
+      <para>Another feature of the U-Boot scripting language are the
+	<literal>&amp;&amp;</literal> and <literal>||</literal> functions. The
+	<literal>&amp;&amp;</literal> is an if and only if command. For
+	instance, the command
+	<link linkend="uboot_cmd_echo"><literal>echo</literal></link>
+	<literal>$do_stuff &amp;&amp;</literal>
+	<link linkend="uboot_cmd_run"><literal>run</literal></link>
+	<literal>$do_stuff</literal> would run <literal>do_stuff</literal>
+	only if the <link linkend="uboot_cmd_echo">
+	<literal>echo</literal></link> command returned successfully, meaning
+	that <literal>do_stuff</literal> is defined. If
+	<literal>do_stuff</literal> was not defined, the
+	<link linkend="uboot_cmd_run"><literal>run</literal></link> command
+	would not be executed. Similarly, the <literal>||</literal> command will
+	execute the second command only if the first command fails. For
+	instance, if <literal>bank1</literal> stored the location of the OS in
+	flash bank 1 and <literal>bank2</literal> stored the location of the
+	OS in flash bank 2, the following command would try to boot the image
+	in bank 1. If unsuccessful it would boot the image in bank 2.  If that
+	failed, it would attempt to download the file over the network, and if
+	that succeeded, it would boot the image.
+	<screen>
+<literal>bootm $bank1 || bootm $bank2 || tftp $osaddr $osfile &amp;&amp; bootm</literal>
+	</screen>
+      </para>
+    </sect2>
+
+    <sect2 xml:id="uboot_scripting_quotes_and_ticks">
+      <title>Quotes and tick marks</title>
+      <para>Quotation marks and tick marks also have a special meaning in
+	U-Boot scripting. Let&apos;s say you wanted to create an environment
+	variable called <literal>do_stuff</literal> and this variable was going
+	to run <link linkend="uboot_cmd_printenv">
+	<literal>printenv</literal></link>
+	<link linkend="uboot_env_bootargs"><literal>bootargs</literal></link>
+	then run
+	<link linkend="uboot_env_bootcmd"><literal>bootcmd</literal></link>.
+	Depending on how you format the command, it&apos;s execution will
+	change. You could save the command as
+	<screen>
+setenv do_stuff &quot;print bootargs; run $bootcmd&quot;
+	</screen>
+	When you <link linkend="uboot_cmd_printenv">
+	<literal>printenv</literal></link> <literal>do_stuff</literal> you
+	should see something like
+	<screen>
+do_stuff=print bootargs; run bootm f8000000
+	</screen>
+	Notice how the variable specified with the $ was expanded. Now, if
+	you do the same thing, replacing the quotation marks with tick marks,
+	<screen>
+setenv do_stuff &apos;printenv bootargs; run $bootcmd&apos;
+	</screen>
+	you will see different behavior.
+	<screen>
+do_stuff=printenv bootargs; run $bootcmd
+	</screen>
+	Notice how the variables specified with the $ were not expanded. In
+	most cases, this would be the desired behavior as these variables
+	would be expanded when they are executed.  Then, any changes made to
+	<link linkend="uboot_env_bootcmd"><literal>bootcmd</literal></link>
+	between the time that <literal>do_stuff</literal> was set and it was
+	run would change the functionality of <literal>do_stuff</literal>.
+	For example,
+	<screen>
+setenv printscript print
+setenv do_stuff &quot;$printscript&quot;
+setenv printscript echo do nothing
+run do_stuff
+	</screen>
+	would result in printing all the environment variables, rather than
+	printing &quot;do nothing&quot;, whereas
+	<screen>
+setenv printscript print
+setenv do_stuff &apos;$printscript&apos;
+setenv printscript echo do nothing
+run do_stuff
+	</screen>
+	would result in printing &quot;do nothing&quot.
+      </para>
+    </sect2>
+  </sect1>
+</chapter>
+
diff --git a/doc/manual/setup.tmpl b/doc/manual/setup.tmpl
new file mode 100644
index 0000000..2d43a72
--- /dev/null
+++ b/doc/manual/setup.tmpl
@@ -0,0 +1,294 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<chapter version="5.0" xml:id="uboot_setup_chapter"
+ xmlns="http://docbook.org/ns/docbook"
+ xmlns:xi="http://www.w3.org/2001/XInclude">
+  <title>U-Boot Setup</title>
+
+  <sect1 xml:id="uboot_setup">
+    <title>Getting Started</title>
+#ifdef CONFIG_BAUDRATE
+    <sect2 xml:id="uboot_setup_serial">
+      <title>Serial</title>
+
+      <para>The U-Boot console can be accessed by a standard PC using terminal
+	software such as HyperTerminal or TeraTerm in Windows or minicom in
+	Linux.
+      </para>
+
+      <orderedlist>
+	<listitem>
+          <para>Plug the serial adapter cable into the ${BOARD}&apos;s serial
+	    connector.
+	  </para>
+	</listitem>
+	<listitem>
+          <para>Connect the other end of the serial adapter cable to the male
+	    DB9 to one of your host PC&apos;s COM ports; a DB9 extension cable
+	    may be required. A USB-to-Serial adapter may also be used if the
+	    host PC being used does not have a male DB9 port available.
+	  </para>
+	</listitem>
+	<listitem>
+	  <para>Start up your host PC terminal emulator (eg: HyperTerminal,
+	    TeraTerm, minicom) using the following parameters:
+	  </para>
+
+	  <table xml:id="setup_default_serial">
+	    <title>Default serial port settings</title>
+	    <tgroup cols="2">
+              <colspec colnum="1" colname="c1"/>
+              <colspec colnum="2" colname="c2"/>
+              <thead>
+		<row>
+		  <entry>Settings</entry>
+		  <entry>Value</entry>
+		</row>
+              </thead>
+              <tbody>
+		<row>
+		  <entry>
+		    <literal>Baud Rate</literal>
+		  </entry>
+		  <entry>@CONFIG_BAUDRATE</entry>
+		</row>
+		<row>
+		  <entry>
+		    <literal>Data Bits</literal>
+		  </entry>
+		  <entry>8</entry>
+		</row>
+		<row>
+		  <entry>
+		    <literal>Parity</literal>
+		  </entry>
+		  <entry>None</entry>
+		</row>
+		<row>
+		  <entry>
+		    <literal>Stop Bits</literal>
+		  </entry>
+		  <entry>1</entry>
+		</row>
+		<row>
+		  <entry>
+		    <literal>Flow Control</literal>
+		  </entry>
+		  <entry>None</entry>
+		</row>
+              </tbody>
+	    </tgroup>
+	  </table>
+	</listitem>
+      </orderedlist>
+
+      <para>After configuring the serial terminal, you should be able to
+	interact with the target. When the target is powered on, the user should
+	be presented with output similar to the following:
+	<screen>
+U-Boot 1.3.4-xes_r3 (Jan 06 2009 - 11:42:40)
+
+CPU0:  8572E, Version: 1.0, (0x80e80010)
+Core:  E500, Version: 3.0, (0x80210030)
+Clock Configuration:
+       CPU:1500 MHz, CCB:600  MHz,
+       DDR:300  MHz (600 MT/s data rate) (Synchronous), LBC:75   MHz
+L1:    D-cache 32 kB enabled
+       I-cache 32 kB enabled
+Board: X-ES XPedite5370 3U VPX SBC
+       Rev SA, Serial# 26081001, Cfg 90030065-1
+I2C:   ready
+DTT1:  45 C
+DTT2:  35 C
+DRAM:   2 GB (bank interleaving, ECC enabled)
+FLASH: Executed from FLASH1
+FLASH: 256 MB
+L2:    1024 KB enabled
+
+    PCIE1 connected as Root Complex (x4)
+               Scanning PCI bus 01
+        02  01  10b5  8518  0604  00
+        02  02  10b5  8518  0604  00
+        02  03  10b5  8518  0604  00
+        01  00  10b5  8518  0604  00
+    PCIE1 on bus 00 - 05
+
+    PCIE2 connected as End Point (x4)
+    PCIE2 on bus 06 - 06
+In:    serial
+Out:   serial
+Err:   serial
+Net:   eTSEC1, eTSEC2
+Hit any key to stop autoboot:  0
+=>
+	</screen>
+      </para>
+
+      <para>If you don't see console output:</para>
+
+      <orderedlist>
+	<listitem>
+          <para>Verify the serial cable is firmly connected to both the board
+	    and your PC.
+	  </para>
+	</listitem>
+	<listitem>
+          <para>Verify that your serial port has the settings listed above.
+	    If it does, your board may have been changed to a different
+	    baudrate. Try setting your terminal to 9600 baud and reset the
+	    board.
+	  </para>
+	</listitem>
+	<listitem>
+	  <para>Verify that your jumper settings are logical.</para>
+	</listitem>
+	<listitem>
+	  <para>Check to see if a reset LED is lit and stays lit. If it does,
+	    your board is being held in reset. Make sure the board has adequate
+	    power and that the shelf manager isn't powering it down.
+	  </para>
+	</listitem>
+#ifdef CONFIG_REDUNDANT_MONITORS
+	<listitem>
+	  <para>U-Boot has many valid baudrate options.  Rather than try all
+	    options, try booting from the other bank of flash, and thusly, the
+	    other set of environment variables. Power down the board and move
+	    the boot device select jumper to select the other bank.
+	  </para>
+	</listitem>
+#endif
+	<listitem>
+	  <para>Power on the board and wait for about a minute. If the board is
+	    working but the serial port is not, you should autoboot into an OS
+	    which may start a heartbeat LED. If you see an LED pulsing on and
+	    off after some time, your board is booting but your serial
+	    connection is bad. Try a different cable.
+	  </para>
+	</listitem>
+	<listitem>
+	  <para>Contact Tech Support</para>
+	</listitem>
+      </orderedlist>
+    </sect2>
+#endif CONFIG_BAUDRATE
+
+#ifdef CONFIG_MPC85xx
+    <xi:include href="${TOPDIR}/doc/manual/85xx_program_flow.xml"/>
+#endif CONFIG MPC85xx
+
+    <sect2 xml:id="uboot_setup_autoboot">
+      <title>Autoboot</title>
+      <para>Your ${BOARD} may be set up to autoboot into an Operating System.
+	In order to stop autoboot and drop down to the U-Boot prompt, press
+	any key when the autoboot count down starts. To disable autobooting, use
+	the <link linkend="uboot_cmd_setenv"><literal>setenv</literal></link>
+	command to set the <link linkend="uboot_env_bootdelay">
+	<literal>bootdelay</literal></link> environment variable to
+	<literal>-1</literal>. You must use the
+	<link linkend="uboot_cmd_saveenv"><literal>saveenv</literal></link>
+	command to save this change.
+      </para>
+    </sect2>
+
+    <sect2 xml:id="uboot_setup_shell">
+      <title>U-Boot Shell</title>
+      <para>U-Boot is designed to set up your ${BOARD} and turn execution over
+	to an OS. In order to transfer control, U-Boot provides many commands
+	to help customize the hardware.
+      </para>
+      <para>One way to customize your version of U-Boot is through the use of
+	<link linkend="uboot_env_vars">environment variables</link>. Variables
+	can be modified	with the
+	<link linkend="uboot_cmd_setenv"><literal>setenv</literal></link>
+	command. These variables will return to defaults after a reset unless a
+	<link linkend="uboot_cmd_saveenv"><literal>saveenv</literal></link>
+	command is executed. You can create any number of environment variables
+	to store instruction sequences. These variables can then be executed
+	with the <link linkend="uboot_cmd_run"><literal>run</literal></link>
+	command. By modifying the
+	<link linkend="uboot_env_bootcmd"><literal>bootcmd</literal></link> and
+	<link linkend="uboot_env_preboot"><literal>preboot</literal></link>
+	environment varaibles, you can automate the use of your customized
+	variables. In order to save a string of commands to your environment
+	variable, you must insert a semicolon between every command. You will
+	either need to escape your semicolon (\;) or put the entire variable in
+	quotation marks (&quot;&quot;). See the <link linkend="uboot_scripting">
+	<literal>Scripting in U-Boot</literal></link> section for more
+	information on quotation marks.
+      </para>
+      <para>To see a list of the commands available to you, type
+	<link linkend="uboot_cmd_help"><literal>help</literal></link> at the
+	command prompt.
+      </para>
+      <para>After entering a command, you can re-execute it simply by pressing
+	the ENTER or RETURN key. Some commands, such as memory display
+	(<link linkend="uboot_cmd_md"><literal>md</literal></link>),
+	auto-increment to the next address on each subsequent auto-repeat.
+      </para>
+    </sect2>
+
+
+    <sect2 xml:id="uboot_setup_network">
+      <title>Network</title>
+      <para>If network operations will be performed on the target, connect any
+	applicable Ethernet interfaces. The ${BOARD} supports IP, TCP, ARP,
+	DHCP, TFTP, UDP, and ICMP transactions. Please also reference the
+	<link linkend="uboot_env_sect_networking">
+	<literal>Network Environment Variables</literal></link> and
+	<link linkend="uboot_cmd_sect_networking">
+	<literal>Network Commands</literal></link> for information
+	on using the ${BOARD}&apos;s Ethernet ports.
+      </para>
+    </sect2>
+
+    <sect2 xml:id="uboot_setup_firmware_update">
+      <title>Firmware Update Procedure</title>
+      <para>In the even that you receive a firmware update or one of your
+	U-Boot images becomes corrupt, use the following procedure.
+      </para>
+      <orderedlist>
+	<listitem>
+	  <para>Place a good U-Boot image on a TFTP server.</para>
+	</listitem>
+	<listitem>
+	  <para>Set your <link linkend="uboot_env_sect_networking">
+	    <literal>network environment variables</literal></link> to reflect
+	    the location of your TFTP server.
+	  </para>
+	</listitem>
+	<listitem>
+	  <para>Download the new U-Boot image using the
+	    <link linkend="uboot_cmd_tftpboot"><literal>tftp</literal></link>
+	    command.
+	    <screen>
+tftp $loadaddr &lt;path to U-Boot image&gt;
+	    </screen>
+	  </para>
+	</listitem>
+	<listitem>
+	  <para>Erase the old U-Boot image, beginning at ${TEXT_BASE} using
+	    the <link linkend="uboot_cmd_erase"><literal>erase</literal></link>
+	    command.
+	    <screen>
+erase ${TEXT_BASE} +800000
+	    </screen>
+	  </para>
+	</listitem>
+	<listitem>
+	  <para>Copy the downloaded image to flash using the
+	    <link linkend="uboot_cmd_cp"><literal>cp</literal></link> command.
+	    <screen>
+cp.b $loadaddr ${TEXT_BASE} $filesize
+	    </screen>
+	  </para>
+	</listitem>
+	<listitem>
+	  <para>Reset the board to load the new image using the
+	    <link linkend="uboot_cmd_reset"><literal>reset</literal></link>
+	    command.
+	  </para>
+	</listitem>
+      </orderedlist>
+    </sect2>
+  </sect1>
+</chapter>
diff --git a/doc/manual/uboot-doc b/doc/manual/uboot-doc
new file mode 100644
index 0000000..c2939bc
--- /dev/null
+++ b/doc/manual/uboot-doc
@@ -0,0 +1,866 @@
+#!/usr/bin/perl -w
+
+use strict;
+
+## Copyright (C) 2009  Extreme Engineering Solutions
+##
+## Author: John Schmoller <jschmoller at xes-inc.com>
+##
+## This software falls under the GNU General Public License.
+## Please read the COPYING file for more information
+##
+## This file is loosly based on kernel-doc originally created by
+## Michael Zucchi from the Linux distribution.
+
+#
+# This will read a 'c' file and scan for embedded comments in the
+# style of gnome comments (+minor extensions - see below).
+#
+
+# usage:
+# uboot-doc inputfile ...
+#
+#  inputfile ... - a list of files which will be searched for comment
+#                  blocks to convert to XML.
+#
+#  All errors go to stderr.
+
+#
+# format of comments.
+# In the following table, (...)? signifies optional structure.
+#                         (...)* signifies 0 or more structure elements
+# /**
+#  * @cmd: cmd_name
+# (* @sect: sect_name)?
+# (* a blank line)?
+# (* @param([(o)?(r)?])?: param_name - description)*
+#  * @desc: Description of function
+#  (*        Function description extends through comment end.)*
+#  (*)?*/
+#
+# The @sect is optional, and specifies which command sub-section
+# to place the common. Any string is a valid @sect descriptor (e.g. "Memory",
+# "Networking", "Environment Modifying". If not
+# specified, the command will be placed in the "Other" section.
+#
+# There are two optional suffixes to the @param specifier.  o states whether
+# the parameter is optional, r states whether the parameter is replaceable.
+# Non-replaceable parameters are entered litterally, like i2c *probe*.
+# Replaceable parameters are substituted before the command is valid, like
+# md *addr* to md *100000*. Valid options are [or], [ro], [o], [r], [], and
+# nothing. [] means not optional and non-replaceable.  Nothing defaults to
+# not optional and replaceable.
+#
+# The @desc and @entry fields can have links to other points in the document.
+# To specify a link to a command, use @ccommand_name, and for environment
+# variables, @eenv_name.  For example, @cprintenv or @ebootdelay.
+#
+# So .. the trivial example would be:
+#
+# /**
+#  * @cmd: my_command
+#  */
+#
+#  Or more compicated:
+# /**
+#  * @cmd: my_function
+#  * @sect: Memory
+#  * @param: my_arg - its mine
+#  * @desc: Does my stuff explained.
+#  */
+# etc.
+#
+# Besides functions you can also write documentation for environment varaibles,
+# POSTs, and memory maps. Instead of @cmd name you must write the name
+# of the declaration; @env, @post, or @memmap must always precede
+# the name. Nesting of declarations is not supported.
+# e.g.
+# /**
+#  * @env: env_name
+#  (* @sect: sect_name)?
+#  * @desc: Environment variable description.
+#  (* Additional description.)*
+#  (*)?*/
+#
+# /**
+#  * @post: post_name
+#  * @desc: POST description.
+#  (* Additional description.)*
+#  (*)?*/
+#
+# /**
+#  * @memmap: Memory Map Name
+#  (* @entry: start_addr: end_addr: Entry description)*
+#  (*)?*/
+#
+# All @desc can be multiline.
+#
+
+my $manual_dir = "doc/manual";
+
+sub usage {
+    print "Usage: $0 outputfile\n";
+    exit 1;
+}
+
+# read arguments
+if ( $#ARGV == -1 ) {
+    usage();
+}
+
+# states
+# 0 - normal code
+# 1 - looking for command, env var, post, or memmap
+# 2 - parsing params and the first line of desc
+# 3 - finish parsing desc's, parse memmap entries
+my $state;
+
+# Regular expressions for matching section types
+my $doc_special    = '@';
+my $doc_system_env = '\$';
+my $doc_cmd_link   = $doc_special . 'c';
+my $doc_env_link   = $doc_special . 'e';
+my $doc_start = '^\s*/\*\*\s*$';    # Allow whitespace at end of comment start.
+my $doc_end   = '\*/';
+my $doc_com   = '\s*\*\s*';
+my $doc_sect         = $doc_special . 'sect:';
+my $doc_cmd          = $doc_special . 'cmd:\s*';
+my $doc_param        = $doc_special . 'param\s*\[?[or]*\]?:\s*';
+my $doc_env          = $doc_special . 'env:\s*';
+my $doc_desc         = $doc_special . 'desc:\s*';
+my $doc_post         = $doc_special . 'post:\s*';
+my $doc_memmap       = $doc_special . 'memmap:\s*';
+my $doc_memmap_entry = $doc_special . 'entry:\s*';
+
+# Hashes and arrays for storing output to files
+my @valuetype;
+my @valuename;
+my @valuedesc;
+my %cmdhash;
+my %envhash;
+my %posthash;
+my %definehash;
+my %memmaphash;
+my @definecontext = (1);
+
+reset_state();
+
+# Open up commands.xml to write and add the XML header
+if ( !open( CMDOUT, ">$manual_dir/commands.xml" ) ) {
+    print STDERR "Error: Cannot open file commamds.xml\n";
+    return;
+}
+print CMDOUT "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\n";
+print CMDOUT "<!-- THIS FILE IS AUTOMATICALLY GENERATED -->\n\n";
+print CMDOUT "<chapter version=\"5.0\" xml:id=\"uboot_commands\"\n";
+print CMDOUT " xmlns=\"http://docbook.org/ns/docbook\"\n";
+print CMDOUT " xmlns:xi=\"http://www.w3.org/2001/XInclude\">\n\n";
+print CMDOUT " <title>U-Boot Commands</title>\n\n";
+
+# Open up environment_variables.xml to write and add the XML header
+if ( !open( ENVOUT, ">$manual_dir/environment_variables.xml" ) ) {
+    print STDERR "Error: Cannot open file environment_variables.xml\n";
+    return;
+}
+print ENVOUT "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\n";
+print ENVOUT "<!-- THIS FILE IS AUTOMATICALLY GENERATED -->\n\n";
+print ENVOUT "<chapter version=\"5.0\" xml:id=\"uboot_env_vars\"\n";
+print ENVOUT " xmlns=\"http://docbook.org/ns/docbook\"\n";
+print ENVOUT " xmlns:xi=\"http://www.w3.org/2001/XInclude\">\n\n";
+print ENVOUT " <title>U-Boot Environment Variables</title>\n\n";
+
+# Open up posts.xml to write and add XML header
+if ( !open( POSTOUT, ">$manual_dir/posts.xml" ) ) {
+    print STDERR "Error: Cannot open file posts.xml\n";
+    return;
+}
+print POSTOUT "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\n";
+print POSTOUT "<!-- THIS FILE IS AUTOMATICALLY GENERATED -->\n\n";
+print POSTOUT "<chapter version=\"5.0\" xml:id=\"uboot_posts\"\n";
+print POSTOUT " xmlns=\"http://docbook.org/ns/docbook\"\n";
+print POSTOUT " xmlns:xi=\"http://www.w3.org/2001/XInclude\">\n\n";
+print POSTOUT " <title>U-Boot POST Descriptions</title>\n\n";
+
+# Open up memory_resources.xml to write and add XML header
+if ( !open( MEMOUT, ">$manual_dir/memory_resources.xml" ) ) {
+    print STDERR "Error: Cannot open file memory_resources.xml\n";
+    return;
+}
+print MEMOUT "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\n";
+print MEMOUT "<!-- THIS FILE IS AUTOMATICALLY GENERATED -->\n\n";
+print MEMOUT "<chapter version=\"5.0\" xml:id=\"uboot_mem_resources\"\n";
+print MEMOUT " xmlns=\"http://docbook.org/ns/docbook\"\n";
+print MEMOUT " xmlns:xi=\"http://www.w3.org/2001/XInclude\">\n\n";
+print MEMOUT " <title>U-Boot Memory Resources</title>\n\n";
+
+# Parse autoconf.mk for #defines
+if ( open( AUTOCONF, "<include/autoconf.mk" ) ) {
+    while (<AUTOCONF>) {
+        my $key   = $_;
+        my $value = $_;
+        $key   =~ s/=.*\s*$//;
+        $value =~ s/^.*?=//;
+        $value =~ s/\s*$//;
+        $definehash{$key} = $value;
+    }
+} else {
+    print STDERR "Error: Cannot open file autoconf.mk\n";
+}
+
+# Get date from timestamp_autogenerated.h
+my $DATE = "Jan 1, 2000";
+if ( open( TIMESTAMP, "<include/timestamp_autogenerated.h" ) ) {
+    while (<TIMESTAMP>) {
+        if (/U_BOOT_DATE\s*\"([\w\s]*)\"\s*$/) {
+            $DATE = $1;
+        }
+    }
+}
+
+# Get version from version_autogenerated.h
+my $VERSION = "U-Boot $DATE";
+if ( open( VERSION, "<include/version_autogenerated.h" ) ) {
+    while (<VERSION>) {
+        if (/U_BOOT_VERSION\s*\"U-Boot\s*(.*?)\"\s*$/) {
+            $VERSION = $1;
+        }
+    }
+}
+
+sub process_file($);
+
+foreach (@ARGV) {
+    chomp;
+    process_file($_);
+}
+
+# Finish off the commands.xml file
+foreach my $HoHkey ( sort ( keys(%cmdhash) ) ) {
+    my $tag_key = lc($HoHkey);
+    while ( $tag_key =~ / / ) {
+        $tag_key =~ s/ /_/;
+    }
+    print CMDOUT " <sect1 xml:id=\"uboot_cmd_sect_$tag_key\">\n";
+    print CMDOUT "  <title>$HoHkey Commands</title>\n";
+    foreach my $key ( sort ( keys %{ $cmdhash{$HoHkey} } ) ) {
+        print CMDOUT $cmdhash{$HoHkey}{$key};
+    }
+    print CMDOUT " </sect1>\n";
+}
+print CMDOUT "</chapter>";
+
+# Finish off the environment_variables.xml file
+foreach my $HoHkey ( sort ( keys(%envhash) ) ) {
+    my $tag_key = lc($HoHkey);
+    while ( $tag_key =~ / / ) {
+        $tag_key =~ s/ /_/;
+    }
+    print ENVOUT " <sect1 xml:id=\"uboot_env_sect_$tag_key\">\n";
+    print ENVOUT "  <title>$HoHkey Environment Variables</title>\n";
+    print ENVOUT "  <table xml:id=\"uboot_env_sect_" . $tag_key . "_table\">\n";
+    print ENVOUT "   <title>$HoHkey Environment Variables</title>\n";
+    print ENVOUT "   <tgroup cols=\"2\">\n";
+    print ENVOUT "    <colspec colname=\"c1\" colnum=\"1\"/>\n";
+    print ENVOUT "    <colspec colname=\"c2\" colnum=\"2\"/>\n";
+    print ENVOUT "    <thead>\n";
+    print ENVOUT "     <row>\n";
+    print ENVOUT "      <entry>Variable</entry>\n";
+    print ENVOUT "      <entry>Description</entry>\n";
+    print ENVOUT "     </row>\n";
+    print ENVOUT "    </thead>\n";
+    print ENVOUT "    <tbody>\n";
+
+    foreach my $key ( sort ( keys %{ $envhash{$HoHkey} } ) ) {
+        print ENVOUT $envhash{$HoHkey}{$key};
+    }
+    print ENVOUT "    </tbody>\n";
+    print ENVOUT "   </tgroup>\n";
+    print ENVOUT "  </table>\n";
+    print ENVOUT " </sect1>\n";
+}
+print ENVOUT "</chapter>";
+
+# Finish off the posts.xml file
+foreach my $key ( sort ( keys(%posthash) ) ) {
+    print POSTOUT $posthash{$key};
+}
+print POSTOUT "</chapter>";
+
+# Finish off the memory_resources.xml file
+# Set System Memory Map first, all others alphabetically
+foreach my $key ( sort ( keys(%memmaphash) ) ) {
+    my $tag_key = lc($key);
+    while ( $tag_key =~ / / ) {
+        $tag_key =~ s/ /_/;
+    }
+
+    print MEMOUT " <sect1 xml:id=\"uboot_memmap_$tag_key\">\n";
+    print MEMOUT "  <title>$key</title>\n";
+    print MEMOUT "  <table xml:id=\"uboot_memmap_" . $tag_key . "_table\">\n";
+    print MEMOUT "   <title>$key</title>\n";
+    print MEMOUT "   <tgroup cols=\"3\">\n";
+    print MEMOUT "    <colspec colname=\"c1\" colnum=\"1\"/>\n";
+    print MEMOUT "    <colspec colname=\"c2\" colnum=\"2\"/>\n";
+    print MEMOUT "    <colspec colname=\"c3\" colnum=\"3\"/>\n";
+    print MEMOUT "    <thead>\n";
+    print MEMOUT "     <row>\n";
+    print MEMOUT "      <entry>Start</entry>\n";
+    print MEMOUT "      <entry>End</entry>\n";
+    print MEMOUT "      <entry>Description</entry>\n";
+    print MEMOUT "     </row>\n";
+    print MEMOUT "    </thead>\n";
+    print MEMOUT "    <tbody>\n";
+    print MEMOUT $memmaphash{$key};
+    print MEMOUT "    </tbody>\n";
+    print MEMOUT "   </tgroup>\n";
+    print MEMOUT "  </table>\n";
+    print MEMOUT " </sect1>\n";
+}
+print MEMOUT "</chapter>";
+
+# Start processing the template files. Look first in $manual_dir/
+# then in board/$BOARDDIR/manual. Overwrite any duplicate
+# files found in $manual_dir/ with the ones found in board/.
+my %files;
+opendir( MANDIR, $ENV{'TOPDIR'} . "/$manual_dir" ) or die "$!";
+my @manfiles = grep { /.*\.tmpl/ } readdir MANDIR;
+close MANDIR;
+foreach my $file (@manfiles) {
+    $files{$file} = $ENV{'TOPDIR'} . "/$manual_dir/$file";
+}
+if ( opendir( BOARDDIR, $ENV{'TOPDIR'} . "/board/" .
+	      $ENV{'BOARDDIR'} . "/manual" ) )
+{
+    my @boardfiles = grep { /.*\.tmpl/ } readdir BOARDDIR;
+    close BOARDDIR;
+    foreach my $file (@boardfiles) {
+        $files{$file} =
+          $ENV{'TOPDIR'} . "/board/" . $ENV{'BOARDDIR'} . "/manual/$file";
+    }
+}
+
+foreach my $file ( keys(%files) ) {
+    @definecontext = ();
+    push( @definecontext, 1 );
+    my $define;
+    my $outfile = $file;
+    $outfile =~ s/\.tmpl//;
+    $outfile .= ".xml";
+    open( FH, "$files{$file}" ) or die "Cannot open file $files{$file}: $!";
+    open( OUT, ">$manual_dir/$outfile" ) or die "$!";
+
+    while (<FH>) {
+
+        # #else processing
+        if (/^#else/) {
+
+            if ( $definecontext[$#definecontext] ) {
+                $definecontext[$#definecontext] = 0;
+            } else {
+                $definecontext[$#definecontext] = 1;
+            }
+
+            # #endif processing
+        } elsif (/^#endif/) {
+            pop(@definecontext);
+
+            # #ifdef processing
+        } elsif (/^#ifdef\s*(\w*)\s*$/) {
+
+            if ( !$definecontext[$#definecontext] ) {
+                push( @definecontext, 0 );
+            } elsif ( exists( $definehash{$1} ) ) {
+                push( @definecontext, 1 );
+            } else {
+                push( @definecontext, 0 );
+            }
+
+            # ignore everything else until context changes
+        } elsif ( !$definecontext[$#definecontext] ) {
+            next;
+
+            # System environment and #define processing
+        } elsif (/[$doc_special$doc_system_env]/) {
+            my @words = split(/\s+/);
+            foreach my $word (@words) {
+                while ( $word =~ /^.*?$doc_special(\w*).*?$/ ) {
+                    $define = $1;
+
+                    if ( exists( $definehash{$define} ) ) {
+                        s/$doc_special\w*/$definehash{$define}/;
+                    } else {
+                        s/$doc_special/ at /;
+                    }
+                    $word =~ s/$doc_special/ at /;
+                }
+                while ( $word =~ /$doc_system_env\{(\w*)\}+/ ) {
+                    $define = $1;
+
+                    # Check for the special $VERSION and $DATE defines
+                    if ( $define eq "VERSION" ) {
+                        s/$doc_system_env\{\w*\}/$VERSION/;
+                    } elsif ( $define eq "DATE" ) {
+                        s/$doc_system_env\{\w*\}/$DATE/;
+                    } elsif ( exists $ENV{"$define"} ) {
+                        s/$doc_system_env\{\w*\}/$ENV{"$define"}/;
+                    } else {
+                        s/$doc_system_env\{(\w*)\}/\$$1/;
+                    }
+                    $word =~ s/$doc_system_env/ /;
+                }
+            }
+            print OUT $_;
+        } elsif ( $definecontext[$#definecontext] ) {
+            print OUT $_;
+        }
+    }
+    close(FH);
+}
+
+# Output the DOCBOOK_XSL_DIR variable so it's readable by the stylesheets
+if ( !open( PARAMS, ">$manual_dir/params.xsl" ) ) {
+    print STDERR "Error: Cannot open file params.xsl\n";
+    return;
+}
+print PARAMS "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\n";
+print PARAMS "<!-- THIS FILE IS AUTOMATICALLY GENERATED -->\n\n";
+print PARAMS "<xsl:stylesheet xmlns:xsl=";
+print PARAMS "\"http://www.w3.org/1999/XSL/Transform\"\n";
+print PARAMS "                xmlns:d=\"http://docbook.org/ns/docbook\"\n";
+print PARAMS "                xmlns:fo=\"http://www.w3.org/1999/XSL/Format\"\n";
+print PARAMS "                exclude-result-prefixes=\"d\"\n";
+print PARAMS "                version='1.0'>\n\n";
+print PARAMS "  <xsl:import href=\"" . $ENV{"DOCBOOK_XSL_DIR"} .
+    "/fo/docbook.xsl\"/>\n\n";
+print PARAMS "</xsl:stylesheet>\n";
+close(PARAMS);
+
+# Function to parse descriptive text to find possible XML links
+sub output_link($) {
+    my @words;
+    my $retstr = "";
+    $_ = $_[0];
+
+    @words = split(/\s+/);
+    foreach (@words) {
+        if (/^$doc_env_link(\w*)/) {    #link to environment element in doc
+            $retstr .= "<link linkend=\"uboot_env_$1\">";
+            $retstr .= "<literal>$1</literal></link> ";
+        } elsif (/^$doc_cmd_link(\w*)/) {    #link to command element in doc
+            $retstr .= "<link linkend=\"uboot_cmd_$1\">";
+            $retstr .= "<literal>$1</literal></link> ";
+        } else {
+            $retstr .= "$_ ";
+        }
+    }
+    return $retstr;
+}
+
+# Writes XML for a command to the command hash
+sub output_command {
+    my $i                  = 0;
+    my $conditional_prints = 1;
+    my $hashvalue          = "";
+    my $hashkey;
+    my $tag_key;
+    my $hashofhasheskey;
+
+    # Make sure we're not re-processing a command
+    if ( exists( $cmdhash{ $valuedesc[0] }{ $valuename[0] } ) ) {
+        return;
+    }
+
+    # Cycle through all the elements to the command
+    foreach (@valuetype) {
+
+        # The @cmd and @sect lines
+        if (/$doc_cmd/) {
+            $hashkey = $valuename[$i];
+            $tag_key = lc( $valuename[$i] );
+            while ( $tag_key =~ / / ) {
+                $tag_key =~ s/ /_/;
+            }
+            $hashvalue .= "  <sect2 xml:id=\"uboot_cmd_$tag_key\">\n";
+            $hashvalue .= "   <title>$valuename[$i]</title>\n";
+            $hashvalue .= "   <cmdsynopsis>\n";
+            $hashvalue .= "    <command>$valuename[$i]</command>\n";
+            $hashofhasheskey = $valuedesc[$i];
+
+            if ( $hashofhasheskey eq '0' ) {
+                $hashofhasheskey = "Other";
+            }
+
+            if ( !exists( $cmdhash{$hashofhasheskey} ) ) {
+                $cmdhash{$hashofhasheskey} = {};
+            }
+        } elsif (/$doc_param/) {    # The @param line
+            if (/\[[or]*\]/) {      #arg options specified
+                if (/\[\w?o\w?\]/) {    #arg optional
+                    $hashvalue .= "    <arg choice=\"opt\">\n";
+                } else {                #arg required
+                    $hashvalue .= "    <arg choice=\"req\">\n";
+                }
+
+                if (/\[\w?r\w?\]/) {    #arg replaceable
+                    $hashvalue .= "     <replaceable>$valuename[$i]";
+                    $hashvalue .= "</replaceable>\n";
+                } else {                #arg literal
+                    $hashvalue .= "     $valuename[$i]\n";
+                }
+                $hashvalue .= "    </arg>\n";
+            } else {    #assume [r]
+                $hashvalue .= "    <arg choice=\"req\">\n";
+                $hashvalue .= "     <replaceable>$valuename[$i]";
+                $hashvalue .= "</replaceable>\n";
+                $hashvalue .= "    </arg>\n";
+            }
+        } elsif (/$doc_desc/) {    # The @desc line
+            my @words;
+            if ($conditional_prints) {    #finish up the synopsis
+                $hashvalue .= "   </cmdsynopsis>\n";
+                $hashvalue .= "   <para>";
+                $conditional_prints = 0;
+            } else {
+                $hashvalue .= "  ";
+            }
+
+            if ( $valuedesc[$i] eq "\n" ) {
+                $hashvalue .= "</para>\n";
+                if ( $i != $#valuetype ) {
+                    $hashvalue .= "   <para>";
+                }
+                $i++;
+                next;
+            }
+
+            $hashvalue .= output_link( $valuedesc[$i] );
+
+            if ( ($i) == $#valuetype ) {
+                $hashvalue .= "</para>";
+            }
+
+            $hashvalue .= "\n";
+        }
+        $i++;
+    }
+
+    # Make a second run through the command to get the XML formatted correctly
+    $conditional_prints = 1;
+    $i                  = 0;
+    my $param_present = 0;
+    foreach (@valuetype) {
+        if (/$doc_param/) {
+            if ($conditional_prints) {
+                $hashvalue .= "   <variablelist>\n";
+                $hashvalue .= "    <title>Arguments</title>\n";
+                $conditional_prints = 0;
+                $param_present      = 1;
+            }
+
+            $hashvalue .= "    <varlistentry>\n";
+            $hashvalue .= "     <term>\n";
+
+            if (/\[\w?r\w?\]/) {    #replaceable arg option specified
+                $hashvalue .= "      <replaceable>$valuename[$i]";
+                $hashvalue .= "</replaceable>\n";
+            } elsif (/\[\w*\]/) {    #replaceable arg not specified
+                $hashvalue .= "      $valuename[$i]\n";
+            } else {                 #no args specified, default to replaceable
+                $hashvalue .= "      <replaceable>$valuename[$i]";
+                $hashvalue .= "</replaceable>\n";
+            }
+
+            $hashvalue .= "     </term>\n";
+            $hashvalue .= "     <listitem>\n";
+            $hashvalue .= "      <para>$valuedesc[$i]</para>\n";
+            $hashvalue .= "     </listitem>\n";
+            $hashvalue .= "    </varlistentry>\n";
+        }
+
+        if ( $i == $#valuetype ) {
+            if ($param_present) {
+                $hashvalue .= "   </variablelist>\n";
+            }
+            $hashvalue .= "  </sect2>\n";
+
+        }
+        $i++;
+    }
+
+    $cmdhash{$hashofhasheskey}{$hashkey} = $hashvalue;
+}
+
+# Function writes XML for an environment variable to the env hash
+sub output_env {
+    my @words;
+    my $conditional_prints = 1;
+    my $i                  = 0;
+    my $hashvalue          = "";
+    my $hashkey;
+    my $hashofhasheskey;
+
+    # Make sure we're not re-processing an environment variable
+    if ( exists( $envhash{ $valuedesc[0] }{ $valuename[0] } ) ) {
+        return;
+    }
+
+    $hashkey = $valuename[0];
+    $hashvalue .= "     <row xml:id=\"uboot_env_$valuename[0]\">\n";
+    $hashvalue .= "      <entry>\n";
+    $hashvalue .= "       <literal>$valuename[0]</literal>\n";
+    $hashvalue .= "      </entry>\n";
+    $hashvalue .= "      <entry>\n";
+    $hashvalue .= "       <para>";
+    $hashofhasheskey = $valuedesc[0];
+
+    if ( $hashofhasheskey eq '0' ) {
+        $hashofhasheskey = "Other";
+    }
+
+    if ( !exists( $envhash{$hashofhasheskey} ) ) {
+        $envhash{$hashofhasheskey} = {};
+    }
+
+    # For each description element, add to the env var description
+    foreach (@valuetype) {
+        if (/$doc_desc/) {
+            if ( $i != 0 ) {
+                $hashvalue .= "       ";
+            }
+
+            if ( $valuedesc[$i] eq "\n" ) {
+                $hashvalue .= "</para>\n";
+                if ( $i != $#valuetype ) {
+                    $hashvalue .= "       <para>";
+                }
+            } else {
+
+                $hashvalue .= output_link( $valuedesc[$i] );
+
+                if ( ($i) == $#valuetype ) {
+                    $hashvalue .= "</para>";
+                }
+
+                $hashvalue .= "\n";
+            }
+        }
+        $i++;
+    }
+
+    $hashvalue .= "      </entry>\n";
+    $hashvalue .= "     </row>\n";
+
+    $envhash{$hashofhasheskey}{$hashkey} = $hashvalue;
+}
+
+sub output_post {
+    my $hashvalue = "";
+    my $i         = 0;
+
+    if ( exists( $posthash{ $valuename[0] } ) ) {
+        return;
+    }
+
+    my $hashkey = $valuename[0];
+    my $tag_key = $hashkey;
+    while ( $tag_key =~ / / ) {
+        $tag_key =~ s/ /_/;
+    }
+
+    foreach (@valuetype) {
+        if (/$doc_post/) {
+            $hashvalue .= " <sect1 xml:id=\"uboot_post_$tag_key\">\n";
+            $hashvalue .= "  <title>$hashkey</title>\n";
+            $hashvalue .= "  <para>\n";
+        } elsif (/$doc_desc/) {
+            if ( $valuedesc[$i] eq "\n" ) {
+                $hashvalue .= "</para>\n";
+                if ( $i != $#valuetype ) {
+                    $hashvalue .= "  <para>";
+                }
+	    } else {
+                $hashvalue .= "   ";
+                $hashvalue .= output_link( $valuedesc[$i] );
+	    }
+        }
+        $i++;
+    }
+
+    $hashvalue .= "  </para>\n";
+    $hashvalue .= " </sect1>\n";
+
+    $posthash{$hashkey} = $hashvalue;
+}
+
+# Function writes XML for a memory map to the memmap hash
+sub output_memmap {
+    my @words;
+    my $conditional_prints = 1;
+    my $i                  = 0;
+    my $hashvalue          = "";
+    my $hashkey;
+
+    # Make sure we're not re-processing a memory map
+    if ( exists( $memmaphash{ $valuedesc[0] } ) ) {
+        return;
+    }
+
+    # Make a valid XML tag name out of memmap description
+    $hashkey = $valuedesc[0];
+    my $tag_key = lc($hashkey);
+    while ( $tag_key =~ / / ) {
+        $tag_key =~ s/ /_/;
+    }
+
+    # Cycle through all the memmap entries
+    foreach (@valuetype) {
+        my @words;
+        if (/$doc_memmap_entry/) {
+
+            $hashvalue .= "     <row>\n";
+
+            # Split up start and end and drop them in the table
+            @words = split( /\s*:\s*/, $valuedesc[$i] );
+            foreach my $word (@words) {
+                $hashvalue .= "      <entry>\n";
+                $hashvalue .= "       <literal>$word</literal>\n";
+                $hashvalue .= "      </entry>\n";
+            }
+
+            $hashvalue .= "      <entry>\n";
+            $hashvalue .= "       <para>";
+            $hashvalue .= output_link( $valuename[$i] );
+            $hashvalue .= "</para>\n";
+            $hashvalue .= "      </entry>\n";
+            $hashvalue .= "     </row>\n";
+
+        }
+        $i++;
+    }
+
+    $memmaphash{$hashkey} = $hashvalue;
+}
+
+# Call the appropriate output function
+sub output_section {
+    if ( $valuetype[0] =~ /$doc_cmd/io ) {
+        output_command();
+    } elsif ( $valuetype[0] =~ /$doc_env/io ) {
+        output_env();
+    } elsif ( $valuetype[0] =~ /$doc_post/io ) {
+        output_post();
+    } elsif ( $valuetype[0] =~ /$doc_memmap/io ) {
+        output_memmap();
+    }
+}
+
+# After each comment block, reset all our variables
+sub reset_state {
+
+    @valuetype = ();
+    @valuename = ();
+    @valuedesc = ();
+
+    $state = 0;
+}
+
+# Main processing loop
+sub process_file($) {
+    my $file;
+    my $identifier;
+    my $func;
+    my $descr;
+    my @links;
+
+    $file = "@_";
+
+    if ( !open( IN, "<$file" ) ) {
+        print STDERR "Error: Cannot open file $file\n";
+        return;
+    }
+
+    while (<IN>) {
+        if ( $state == 0 ) {    # Normal code
+            if (/$doc_start/io) {
+                $state = 1;
+            }
+        } elsif ( $state == 1 )
+        {                       # We got the start of a potential comment block
+            if (/^$doc_com$/io) {    # Got an empty line
+                next;
+
+            } elsif (/$doc_cmd\s*([\w\s-]*\w)\s*$/io) {    # Found a function
+                push @valuetype, $doc_cmd;
+                push @valuename, $1;
+                push @valuedesc, '0';
+
+                $state = 2;
+            } elsif (/$doc_env\s*([\w\s-]*\w)\s*$/io) {    # Found an env var
+                push @valuetype, $doc_env;
+                push @valuename, $1;
+                push @valuedesc, '0';
+
+                $state = 2;
+            } elsif (/$doc_post\s*([\w\s-]*\w)\s*$/io) { # Found POST descriptor
+                push @valuetype, $doc_post;
+                push @valuename, $1;
+                push @valuedesc, '0';
+
+                $state = 2;
+            } elsif (/$doc_memmap\s*([\w\s-]*\w)\s*$/io) {  # Found a memory map
+                push @valuetype, $doc_memmap;
+                push @valuename, '0';
+                push @valuedesc, $1;
+
+                $state = 3;
+            } elsif (/$doc_end/io) {    # Musta been a normal comment
+                $state = 0;
+            }
+        } elsif ( $state == 2 ) {    # Found a valid comment declaration
+            if (/^$doc_com$/io) {    # Got an empty line
+                next;
+            } elsif (/($doc_param)\s*([^-]*[^\s])\s*-\s*(.*)\s*$/io) {   # Param
+                push @valuetype, $1;
+                push @valuename, $2;
+                push @valuedesc, $3;
+            } elsif (/$doc_desc(.*\s*$)/io) {    # Got a description
+                push @valuetype, $doc_desc;
+                push @valuename, $doc_desc;
+                push @valuedesc, $1;
+
+                $state = 3;
+            } elsif (/$doc_sect\s*(.*[^\s])\s*$/io) {   # Got a sub-section decl
+                $valuedesc[$#valuedesc] = $1;
+            } else {    # Something undefined happened
+                print STDERR "Warning(${file}:$.): bad line: $_";
+                reset_state();
+            }
+        } elsif ( $state == 3 ) {    # Process descriptions and memmap entries
+            if (/$doc_end/) {        # End of comment block
+                                     # Write comment to proper hash
+                output_section();
+
+                # Reset hash variables and state
+                reset_state();
+            } elsif (/^$doc_com$/) {    # Empty line, push a newline
+                push @valuetype, $doc_desc;
+                push @valuename, $doc_desc;
+                push @valuedesc, "\n";
+
+                # Got memmap entry
+            } elsif (/$doc_memmap_entry\s*(\w*\s*:\s*\w*)\s*:\s*(.*)$/io) {
+                push @valuetype, $doc_memmap_entry;
+                push @valuename, $2;
+                push @valuedesc, $1;
+            } else {                    # No tag, keep pushing description
+                $descr = $_;
+                $descr =~ s/^$doc_com//io;
+
+                push @valuetype, $doc_desc;
+                push @valuename, $doc_desc;
+                push @valuedesc, $descr;
+            }
+        }
+    }
+}
+
diff --git a/doc/manual/uboot_manual.xsl b/doc/manual/uboot_manual.xsl
new file mode 100644
index 0000000..bc40b46
--- /dev/null
+++ b/doc/manual/uboot_manual.xsl
@@ -0,0 +1,286 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!-- **********************************************************************
+       U-Boot manual FO stylesheet
+
+       This stylesheet (DocBook customization layer) transforms U-Boot
+       manual XML documents into FO.
+
+       Since the DocBook stylesheets are currently in XSLT 1.0, this
+       stylesheet has to be XSLT 1.0.
+     ********************************************************************** -->
+
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                xmlns:d="http://docbook.org/ns/docbook"
+                xmlns:fo="http://www.w3.org/1999/XSL/Format"
+                exclude-result-prefixes="d"
+                version='1.0'>
+
+<!-- ======================================================================
+       Base DocBook stylesheet
+     ====================================================================== -->
+
+  <xsl:include href="params.xsl"/>
+
+<!-- ======================================================================
+       General customizations
+     ====================================================================== -->
+
+  <!-- General document settings. -->
+  <xsl:param name="draft.mode" select="'no'"/>
+  <xsl:param name="paper.type" select="'USletter'"/>
+  <xsl:param name="body.font.family" select="'sans-serif'"/>
+  <xsl:param name="body.font.master" select="10"/>
+
+<!-- ======================================================================
+       Section customizations
+     ====================================================================== -->
+
+  <!-- Add section numbering. -->
+  <xsl:param name="section.autolabel" select="1"/>
+  <xsl:param name="section.label.includes.component.label" select="1"/>
+
+  <!-- Section title properties. Only the 'space-before.*' attributes were
+       customized from their default values here. -->
+  <xsl:attribute-set name="section.title.properties">
+    <xsl:attribute name="font-family"><xsl:value-of select="$title.font.family"/></xsl:attribute>
+    <xsl:attribute name="font-weight">bold</xsl:attribute>
+    <!-- font size is calculated dynamically by section.heading template -->
+    <xsl:attribute name="keep-with-next.within-column">always</xsl:attribute>
+    <xsl:attribute name="space-before.minimum">2.8em</xsl:attribute>
+    <xsl:attribute name="space-before.optimum">3em</xsl:attribute>
+    <xsl:attribute name="space-before.maximum">3.2em</xsl:attribute>
+    <xsl:attribute name="text-align">left</xsl:attribute>
+    <xsl:attribute name="start-indent"><xsl:value-of select="$title.margin.left"/></xsl:attribute>
+  </xsl:attribute-set>
+
+<!-- ======================================================================
+       Front matter customizations
+     ====================================================================== -->
+
+  <!-- Title page template. Customized from fo/titlepage.templates.xsl.  -->
+  <xsl:template name="book.titlepage.recto">
+    <fo:block font-family="Book Antiqua" text-align="left" hyphenate="false">
+      <fo:block font-size="45pt">
+	<!-- EDIT: CUSTOMIZE PRODUCT NAME HERE -->
+	<fo:inline>
+	  <xsl:value-of select="ancestor-or-self::book/info/titleabbrev"/>
+	</fo:inline>
+	<!-- CUSTOMIZE PRODUCT NAME HERE -->
+      </fo:block>
+      <fo:block font-size="20pt" font-weight="bold"
+		space-before="2in">U-Boot User's Manual</fo:block>
+      <fo:block-container absolute-position="absolute" height="100%"
+			  display-align="after" break-after="page"
+			  left="10pt" bottom="10pt">
+        <fo:table table-layout="fixed" width="100%">
+          <fo:table-column column-number="1"
+			   column-width="proportional-column-width(1)"/>
+          <fo:table-column column-number="2"
+			   column-width="proportional-column-width(1)"/>
+          <fo:table-body>
+            <fo:table-row>
+              <fo:table-cell>
+                <fo:block>
+                  <fo:external-graphic height="1.2in"
+				       content-height="scale-to-fit">
+		    <xsl:attribute name="src">
+		      <xsl:text>url('</xsl:text>
+		      <xsl:apply-templates select="ancestor-or-self::book/info/mediaobject/imageobject/imagedata/@fileref"/>
+		      <xsl:text>')</xsl:text>
+		    </xsl:attribute>
+		  </fo:external-graphic>
+                </fo:block>
+              </fo:table-cell>
+              <fo:table-cell>
+                <fo:block font-size="10pt" text-align="right">
+                  <fo:block>
+		    <xsl:value-of select="ancestor-or-self::book/info/address/personname"/>
+		  </fo:block>
+                  <fo:block>
+		    <xsl:value-of select="ancestor-or-self::book/info/address/street"/>
+		  </fo:block>
+                  <fo:block>
+		    <xsl:value-of select="ancestor-or-self::book/info/address/city"/> <xsl:value-of select="ancestor-or-self::book/info/address/state"/> <xsl:value-of select="ancestor-or-self::book/info/address/postcode"/> <xsl:value-of select="ancestor-or-self::book/info/address/country"/>
+		  </fo:block>
+                  <fo:block><xsl:value-of select="ancestor-or-self::book/info/address/phone"/></fo:block>
+                  <fo:block><xsl:value-of select="ancestor-or-self::book/info/address/fax"/></fo:block>
+                  <fo:block><xsl:value-of select="ancestor-or-self::book/info/address/uri"/></fo:block>
+                  <fo:block><xsl:value-of select="ancestor-or-self::book/info/address/email"/></fo:block>
+                </fo:block>
+              </fo:table-cell>
+            </fo:table-row>
+          </fo:table-body>
+        </fo:table>
+        <fo:block font-size="10pt" font-weight="bold" text-align="center"
+          border-top="0.5pt solid black" padding-top="0.05in">
+        </fo:block>
+      </fo:block-container>
+    </fo:block>
+  </xsl:template>
+
+  <!-- Second page (legal/revhistory) template. Customized from
+       fo/titlepage.templates.xsl.
+
+       This template needs to be rewritten as well (see the comment for the
+       template above).
+  -->
+  <xsl:template name="book.titlepage.verso">
+    <fo:block font-family="sans-serif" font-size="18pt" font-weight="bold"><xsl:value-of select="ancestor-or-self::book/info/title"/></fo:block>
+    <xsl:apply-templates mode="book.titlepage.verso.auto.mode" select="info/copyright"/>
+    <xsl:apply-templates mode="book.titlepage.verso.auto.mode" select="info/pubdate"/>
+    <xsl:apply-templates mode="book.titlepage.verso.auto.mode" select="info/releaseinfo"/>
+    <xsl:apply-templates mode="book.titlepage.verso.auto.mode" select="info/legalnotice"/>
+
+  </xsl:template>
+
+  <xsl:template match="legalnotice//emphasis">
+    <xsl:call-template name="inline.boldseq"/>
+  </xsl:template>
+
+<!-- ======================================================================
+       Header/footer customizations
+     ====================================================================== -->
+
+  <!-- Customized from fo/pagesetup.xsl. -->
+  <xsl:template name="header.content">
+    <xsl:param name="pageclass" select="''"/>
+    <xsl:param name="sequence" select="''"/>
+    <xsl:param name="position" select="''"/>
+    <xsl:param name="gentext-key" select="''"/>
+
+    <fo:block>
+      <xsl:choose>
+        <xsl:when test="($pageclass = 'body' or $pageclass = 'lot') and $position = 'left'">
+          <xsl:value-of select="ancestor-or-self::d:book/d:info/d:author/d:orgname"/>
+        </xsl:when>
+        <xsl:when test="$pageclass = 'body' and $position = 'right'">
+          <xsl:apply-templates select="." mode="title.markup"/>
+        </xsl:when>
+        <xsl:otherwise/>
+      </xsl:choose>
+    </fo:block>
+  </xsl:template>
+
+  <!-- Customized from fo/pagesetup.xsl. -->
+  <xsl:template name="footer.content">
+    <xsl:param name="pageclass" select="''"/>
+    <xsl:param name="sequence" select="''"/>
+    <xsl:param name="position" select="''"/>
+    <xsl:param name="gentext-key" select="''"/>
+
+    <fo:block>
+      <xsl:choose>
+        <xsl:when test="($pageclass = 'body' or $pageclass = 'lot') and $position = 'left'">
+          <xsl:value-of select="ancestor-or-self::d:book/d:info/d:title"/>
+        </xsl:when>
+        <xsl:when test="($pageclass = 'body' or $pageclass = 'lot') and $position = 'right'">
+          <fo:page-number/>
+        </xsl:when>
+        <xsl:otherwise/>
+      </xsl:choose>
+    </fo:block>
+  </xsl:template>
+
+<!-- ======================================================================
+       Table customizations
+     ====================================================================== -->
+
+  <!-- Table customization. -->
+  <xsl:param name="default.table.frame" select="'none'"/>
+  <xsl:attribute-set name="table.properties" use-attribute-sets="formal.object.properties">
+    <xsl:attribute name="keep-together.within-column">always</xsl:attribute>
+  </xsl:attribute-set>
+
+<xsl:attribute-set name="formal.title.properties" use-attribute-sets="normal.para.spacing">
+  <xsl:attribute name="keep-with-next.within-column">always</xsl:attribute>
+  <xsl:attribute name="font-weight">bold</xsl:attribute>
+  <xsl:attribute name="font-size">
+    <xsl:value-of select="$body.font.master * 1.2"></xsl:value-of>
+    <xsl:text>pt</xsl:text>
+  </xsl:attribute>
+  <xsl:attribute name="hyphenate">false</xsl:attribute>
+  <xsl:attribute name="space-after.minimum">0.4em</xsl:attribute>
+  <xsl:attribute name="space-after.optimum">0.6em</xsl:attribute>
+  <xsl:attribute name="space-after.maximum">0.8em</xsl:attribute>
+</xsl:attribute-set>
+
+
+  <!-- Customized from fo/table.xsl. -->
+  <xsl:template name="table.row.properties">
+    <xsl:variable name="rownum">
+      <xsl:number from="d:tgroup" count="d:row"/>
+    </xsl:variable>
+
+    <xsl:choose>
+      <xsl:when test="ancestor::d:thead">
+        <xsl:attribute name="keep-with-next.within-column">always</xsl:attribute>
+        <xsl:attribute name="border-bottom">1.5pt solid black</xsl:attribute>
+        <xsl:attribute name="text-align">left</xsl:attribute>
+        <xsl:if test="ancestor::d:table/@role = 'wide'">
+          <xsl:attribute name="font-size">75%</xsl:attribute>
+        </xsl:if>
+      </xsl:when>
+      <xsl:otherwise>
+        <xsl:attribute name="text-align">left</xsl:attribute>
+        <xsl:if test="ancestor::d:table/@role = 'wide'">
+          <xsl:attribute name="font-size">60%</xsl:attribute>
+        </xsl:if>
+        <xsl:if test="$rownum mod 2 = 0">
+          <xsl:attribute name="background-color">#e6e6fb</xsl:attribute>
+        </xsl:if>
+      </xsl:otherwise>
+    </xsl:choose>
+  </xsl:template>
+
+  <xsl:template match="d:tbody/d:row/d:entry/d:emphasis">
+    <xsl:call-template name="inline.boldseq"/>
+  </xsl:template>
+
+  <xsl:param name="table.footnote.number.symbols" select="'*&#x2020;&#x2021;&#x25CA;&#x2720;'"/>
+
+  <xsl:attribute-set name="table.footnote.properties">
+    <xsl:attribute name="font-family"><xsl:value-of select="$body.fontset"></xsl:value-of></xsl:attribute>
+    <xsl:attribute name="font-size"><xsl:value-of select="$footnote.font.size"></xsl:value-of></xsl:attribute>
+    <xsl:attribute name="font-weight">normal</xsl:attribute>
+    <xsl:attribute name="font-style">normal</xsl:attribute>
+    <xsl:attribute name="space-before">4pt</xsl:attribute>
+    <xsl:attribute name="text-align"><xsl:value-of select="$alignment"></xsl:value-of></xsl:attribute>
+  </xsl:attribute-set>
+
+<!-- ======================================================================
+       List customizations
+     ====================================================================== -->
+
+  <xsl:attribute-set name="list.block.spacing">
+    <xsl:attribute name="space-before.optimum">1em</xsl:attribute>
+    <xsl:attribute name="space-before.minimum">0.8em</xsl:attribute>
+    <xsl:attribute name="space-before.maximum">1.2em</xsl:attribute>
+    <xsl:attribute name="space-after.optimum">1em</xsl:attribute>
+    <xsl:attribute name="space-after.minimum">0.8em</xsl:attribute>
+    <xsl:attribute name="space-after.maximum">1.2em</xsl:attribute>
+    <xsl:attribute name="margin-left">0.25in</xsl:attribute>
+  </xsl:attribute-set>
+
+<!-- ======================================================================
+       Shell command and software install instructions customizations
+     ====================================================================== -->
+
+  <xsl:param name="shade.verbatim" select="1"></xsl:param>
+  <xsl:attribute-set name="verbatim.properties">
+    <xsl:attribute name="space-before.minimum">0.8em</xsl:attribute>
+    <xsl:attribute name="space-before.optimum">1em</xsl:attribute>
+    <xsl:attribute name="space-before.maximum">1.2em</xsl:attribute>
+    <xsl:attribute name="space-after.minimum">0.8em</xsl:attribute>
+    <xsl:attribute name="space-after.optimum">1em</xsl:attribute>
+    <xsl:attribute name="space-after.maximum">1.2em</xsl:attribute>
+    <xsl:attribute name="hyphenate">false</xsl:attribute>
+    <xsl:attribute name="wrap-option">no-wrap</xsl:attribute>
+    <xsl:attribute name="white-space-collapse">false</xsl:attribute>
+    <xsl:attribute name="white-space-treatment">preserve</xsl:attribute>
+    <xsl:attribute name="linefeed-treatment">preserve</xsl:attribute>
+    <xsl:attribute name="text-align">start</xsl:attribute>
+    <xsl:attribute name="font-size">75%</xsl:attribute>
+  </xsl:attribute-set>
+
+</xsl:stylesheet>
diff --git a/rules.mk b/rules.mk
index 6f999dd..383bf6b 100644
--- a/rules.mk
+++ b/rules.mk
@@ -24,6 +24,7 @@
 #########################################################################
 
 _depend:	$(obj).depend
+_man_parse:	$(obj).man_parse
 
 $(obj).depend:	$(src)Makefile $(TOPDIR)/config.mk $(SRCS)
 		@rm -f $@
@@ -32,4 +33,10 @@ $(obj).depend:	$(src)Makefile $(TOPDIR)/config.mk $(SRCS)
 			$(CC) -M $(HOSTCFLAGS) $(CPPFLAGS) -MQ $(obj)$$g $$f >> $@ ; \
 		done
 
+$(obj).man_parse:	$(src)Makefile $(TOPDIR)/config.mk $(SRCS)
+		@for f in $(SRCS); do \
+			$(CPP)  $(CPPFLAGS) -C $$f | \
+			perl $(TOPDIR)/doc/manual/doc-stream.pl >> \
+				$(TOPDIR)/doc/manual/autoconf-doc.txt; \
+		done
 #########################################################################
-- 
1.6.0.4



More information about the U-Boot mailing list