diff --git a/ci.nix b/ci.nix
index 147962c2..b3745e1f 100644
--- a/ci.nix
+++ b/ci.nix
@@ -59,15 +59,15 @@ let
           ];
           src = ./.;
           buildPhase = ''
-            cat ${json} | fennel --correlate doc/parse-options.fnl > doc/modules-generated.rst
-            cat ${json} | fennel --correlate doc/parse-options-outputs.fnl     > doc/outputs-generated.rst
+            cat ${json} | fennel --correlate doc/parse-options.fnl > doc/modules-generated.inc.rst
+            cat ${json} | fennel --correlate doc/parse-options-outputs.fnl     > doc/outputs-generated.inc.rst
             cp ${(import ./doc/hardware.nix)} doc/hardware.rst
             make -C doc html
           '';
           installPhase = ''
             mkdir -p $out/nix-support $out/share/doc/
             cd doc
-            cp *-generated.rst  $out
+            cp *-generated.inc.rst hardware.rst $out
             ln -s ${json} $out/options.json
             cp -a _build/html $out/share/doc/liminix
             echo "file source-dist \"$out/share/doc/liminix\"" \
diff --git a/devices/gl-mt300n-v2/default.nix b/devices/gl-mt300n-v2/default.nix
index 9061d4db..da3fbbab 100644
--- a/devices/gl-mt300n-v2/default.nix
+++ b/devices/gl-mt300n-v2/default.nix
@@ -13,7 +13,7 @@
     GL.iNet GL-MT300N-v2
     ********************
 
-    The GL-MT300N-v2 "Mango" is is very similar to the :ref:`MT300A <GL.iNet GL-MT300A>, but is
+    The GL-MT300N-v2 "Mango" is is very similar to the :ref:`gl-mt300a`, but is
     based on the MT7628 chipset instead of MT7620.  It's also marginally cheaper
     and comes in a yellow case not a blue one.  Be sure your device is
     v2 not v1, which is a different animal and has only half as much RAM.
diff --git a/devices/qemu-aarch64/default.nix b/devices/qemu-aarch64/default.nix
index 3c73b555..2b0ba4eb 100644
--- a/devices/qemu-aarch64/default.nix
+++ b/devices/qemu-aarch64/default.nix
@@ -19,7 +19,7 @@
     ARM targets differ from MIPS in that the kernel format expected
     by QEMU is an "Image" (raw binary file) rather than an ELF
     file, but this is taken care of by :command:`run.sh`. Check the
-    documentation for the :ref:`QEMU` (MIPS) target for more information.
+    documentation for the :ref:`qemu` target for more information.
 
   '';
 
diff --git a/doc/admin.rst b/doc/admin.rst
index 6afae134..6bb159a8 100644
--- a/doc/admin.rst
+++ b/doc/admin.rst
@@ -274,6 +274,8 @@ Note that this only copies the package to the device: it doesn't update
 any profile to add it to ``$PATH``
 
 
+.. _rebuilding the system:
+
 Rebuilding the system
 =====================
 
diff --git a/doc/conf.py b/doc/conf.py
index 94f1685e..37153c80 100644
--- a/doc/conf.py
+++ b/doc/conf.py
@@ -7,19 +7,19 @@
 # https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information
 
 project = 'Liminix'
-copyright = '2023, Daniel Barlow'
+copyright = '2023-2024 Daniel Barlow'
 author = 'Daniel Barlow'
 
 # -- General configuration ---------------------------------------------------
 # https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration
 
 extensions = [
-    'sphinx.ext.autosectionlabel'
+#    'sphinx.ext.autosectionlabel'
 ]
 autosectionlabel_prefix_document = True
 
 templates_path = ['_templates']
-exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
+exclude_patterns = ['*.inc.rst', '_build', 'Thumbs.db', '.DS_Store']
 
 
 
diff --git a/doc/hardware.nix b/doc/hardware.nix
index 5e7f5697..0a13578b 100644
--- a/doc/hardware.nix
+++ b/doc/hardware.nix
@@ -7,11 +7,15 @@ let
     n:
     let
       d = import ../devices/${n}/default.nix;
+      tag = ".. _${lib.strings.replaceStrings [" "] ["-"] n}:";
       d' = {
-        description = "${n}\n${substring 0 (stringLength n) "********************************"}\n";
+        description = ''
+          ${n}
+          ${substring 0 (stringLength n) "********************************"}
+        '';
       } // d;
     in
-    d'.description
+      "${tag}\n\n${d'.description}"
   ) devices;
 in
 writeText "hwdoc" ''
diff --git a/doc/modules.rst b/doc/modules.rst
index 8d29bba6..5d1187ea 100644
--- a/doc/modules.rst
+++ b/doc/modules.rst
@@ -1,4 +1,4 @@
 Module options
 ##############
 
-.. include:: modules-generated.rst
+.. include:: modules-generated.inc.rst
diff --git a/doc/outputs.rst b/doc/outputs.rst
index 971da157..477a69a1 100644
--- a/doc/outputs.rst
+++ b/doc/outputs.rst
@@ -10,4 +10,4 @@ different artefacts, or have different ways to get that artefact
 installed. The options available for a particular device are described in
 the section for that device.
 
-.. include:: outputs-generated.rst
+.. include:: outputs-generated.inc.rst
diff --git a/doc/parse-options-outputs.fnl b/doc/parse-options-outputs.fnl
index 3738a407..5c77d501 100644
--- a/doc/parse-options-outputs.fnl
+++ b/doc/parse-options-outputs.fnl
@@ -16,4 +16,4 @@
 (each [_ option (ipairs (sorted-options (yaml.load (io.read "*a"))))]
   (when (and (output? option) (not option.internal))
     (print (.. ".. _" (string.gsub option.name "%." "-") ":") "\n")
-    (print option.description)))
+    (print option.description "\n")))
diff --git a/doc/tutorial.rst b/doc/tutorial.rst
index 9ff5aff5..e563535b 100644
--- a/doc/tutorial.rst
+++ b/doc/tutorial.rst
@@ -300,7 +300,7 @@ machine, which for a test/demo system might involve a second network
 device in your build system - USB ethernet adapters are cheap - or
 a bit of messing around unplugging cables.)
 
-For more information about :code:`liminix-rebuild`, see the manual section :ref:`admin:Rebuilding the system`.
+For more information about :code:`liminix-rebuild`, see the manual section :ref:`Rebuilding the system`.
 
 
 Final thoughts
diff --git a/modules/outputs/kexecboot.nix b/modules/outputs/kexecboot.nix
index f7e0f0eb..768b8831 100644
--- a/modules/outputs/kexecboot.nix
+++ b/modules/outputs/kexecboot.nix
@@ -12,6 +12,9 @@ in {
     kexecboot = mkOption {
       type = types.package;
       description = ''
+        kexecboot
+        *********
+
         Directory containing files needed for kexec booting.
         Can be copied onto the target device using ssh or similar
       '';