diff --git a/Documentation/OS/usermanual/images/proc_task.png b/Documentation/OS/usermanual/images/proc_task.png
new file mode 100644
index 0000000000000000000000000000000000000000..93716dc52597b13eface77b7c2145591cbc8320b
Binary files /dev/null and b/Documentation/OS/usermanual/images/proc_task.png differ
diff --git a/Documentation/OS/usermanual/images/proc_tracker.png b/Documentation/OS/usermanual/images/proc_tracker.png
new file mode 100644
index 0000000000000000000000000000000000000000..ba0bf2b92168a88568c764a859125895b132a2ac
Binary files /dev/null and b/Documentation/OS/usermanual/images/proc_tracker.png differ
diff --git a/Documentation/OS/usermanual/images/task_network.png b/Documentation/OS/usermanual/images/task_network.png
new file mode 100644
index 0000000000000000000000000000000000000000..a12367f13b89153384699b76d9d497f923b944a7
Binary files /dev/null and b/Documentation/OS/usermanual/images/task_network.png differ
diff --git a/Documentation/doxygen/Doxyfile b/Documentation/doxygen/Doxyfile
index af3b53241733e7510859bc07dd8c051e6b4f06b6..04d1daf1a41b2b89c1b16c9bebe1d38433c34089 100644
--- a/Documentation/doxygen/Doxyfile
+++ b/Documentation/doxygen/Doxyfile
@@ -763,7 +763,8 @@ WARN_LOGFILE           =
 # spaces.
 # Note: If this tag is empty the current directory is searched.
 
-INPUT                  = ../../lib ../../arch/ ../../kernel ../../dsp
+INPUT                  = ../../lib ../../arch/ ../../kernel ../../dsp \
+			../../include ../../init
 
 # This tag can be used to specify the character encoding of the source files
 # that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
@@ -872,7 +873,7 @@ EXCLUDE_SYMBOLS        =
 # that contain example code fragments that are included (see the \include
 # command).
 
-EXAMPLE_PATH           = ../example ../spin
+EXAMPLE_PATH           = ../../samples
 
 # If the value of the EXAMPLE_PATH tag contains directories, you can use the
 # EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and
@@ -886,13 +887,13 @@ EXAMPLE_PATTERNS       = *
 # irrespective of the value of the RECURSIVE tag.
 # The default value is: NO.
 
-EXAMPLE_RECURSIVE      = NO
+EXAMPLE_RECURSIVE      = YES
 
 # The IMAGE_PATH tag can be used to specify one or more files or directories
 # that contain images that are to be included in the documentation (see the
 # \image command).
 
-IMAGE_PATH             = images 
+IMAGE_PATH             = images ../OS 
 
 # The INPUT_FILTER tag can be used to specify a program that doxygen should
 # invoke to filter for each input file. Doxygen will invoke the filter program
diff --git a/Documentation/doxygen/doxy-boot.js b/Documentation/doxygen/doxy-boot.js
index f045d16f2b2aa6bded9165c8ad19f1a04eb3c9da..f377c65690541d47c5bd981afd34280baf6faa5d 100644
--- a/Documentation/doxygen/doxy-boot.js
+++ b/Documentation/doxygen/doxy-boot.js
@@ -4,7 +4,7 @@ $( document ).ready(function() {
     $("div.title").addClass("h1");
 
     $('li > a[href="index.html"] > span').before("<i class='fa fa-cog'></i> ");
-    $('li > a[href="index.html"] > span').text("CHEOPS IBSW");
+    $('li > a[href="index.html"] > span').text("LeanOS");
     $('li > a[href="modules.html"] > span').before("<i class='fa fa-square'></i> ");
     $('li > a[href="namespaces.html"] > span').before("<i class='fa fa-bars'></i> ");
     $('li > a[href="annotated.html"] > span').before("<i class='fa fa-list-ul'></i> ");
diff --git a/arch/sparc/include/init.h b/arch/sparc/include/init.h
index 4f64dd825322bb5c539460b741372429bded5a10..081e64865e0c9110892af4ed2e089ed198116981 100644
--- a/arch/sparc/include/init.h
+++ b/arch/sparc/include/init.h
@@ -1,5 +1,7 @@
 /**
  * @file arch/sparc/include/init.h
+ *
+ * @ingroup sparc
  */
 
 #ifndef _SPARC_INIT_H_
diff --git a/arch/sparc/include/srmmu.h b/arch/sparc/include/srmmu.h
index b62cc4d2902d663503f5f0ef3053a8c117cd7fd6..d90d32bcfb9d6b18254c95a8f99bcbfb5ad3a3f5 100644
--- a/arch/sparc/include/srmmu.h
+++ b/arch/sparc/include/srmmu.h
@@ -2,6 +2,8 @@
  * @brief SPARC Reference (SR) Memory Management Unit (MMU)
  * @author Armin Luntzer (armin.luntzer@univie.ac.at)
  *
+ * @ingroup srmmu
+ *
  * @see SPARCv8 Architecture Manual for more info
  */
 
diff --git a/arch/sparc/include/srmmu_access.h b/arch/sparc/include/srmmu_access.h
index 6dca38375327846380d08ed49d0bf20da2ff62ba..2aae1d332c8ce15a3ac31150a5c045d6adf684c7 100644
--- a/arch/sparc/include/srmmu_access.h
+++ b/arch/sparc/include/srmmu_access.h
@@ -2,6 +2,8 @@
  * @brief SPARC Reference (SR) Memory Management Unit (MMU) access functions
  * @author Armin Luntzer (armin.luntzer@univie.ac.at)
  *
+ * @ingroup srmmu
+ *
  * @see SPARCv8 Architecture Manual for more info
  */
 
diff --git a/arch/sparc/kernel/bootmem.c b/arch/sparc/kernel/bootmem.c
index 8d622552d44ddd034109035bf9eace82000cf195..14ea331d5e78ab62b482be0a0050cff1fe1f09e9 100644
--- a/arch/sparc/kernel/bootmem.c
+++ b/arch/sparc/kernel/bootmem.c
@@ -1,15 +1,19 @@
 /**
  * @file arch/sparc/kernel/bootmem.c
  *
- * This sets up a buddy system memory manager that handles the physical RAM
- * banks. The kernel image RAM section itself is reserved, and a more
- * fine-grained boot memory allocator is set up that can be used to reserve
- * memory for low-level kernel objects such as MMU tables.
+ * @ingroup sparc
+ *
+ * @brief uses @ref chunk to manage the physical RAM banks
+ *
+ * This sets up a buddy system memory manager via @ref chunk that 
+ * handles the physical RAM banks. The kernel image RAM section itself is
+ * reserved, and a more fine-grained boot memory allocator is set up that can be
+ * used to reserve memory for low-level kernel objects such as MMU tables.
  *
  * Note that because we don't use a two-stage bootstrap process at this time,
  * we will 1:1 map the relevant physical memory bank addresses through the MMU,
  * so the low level objects may be used without a translation step for now,
- * but we will migrate to a new kernel stack base at (2^32 - 1) once we
+ * but we will migrate to a new kernel stack base at (2^32 - 1) VA once we
  * have set up the MMU.
  *
  * Because of the above, user space memory will be mapped below the
diff --git a/arch/sparc/kernel/elf.c b/arch/sparc/kernel/elf.c
index f886290d2255cebca2129fbcf91739a79ab0823e..bba57c119270c9e0166c06c45e8a02112277252f 100644
--- a/arch/sparc/kernel/elf.c
+++ b/arch/sparc/kernel/elf.c
@@ -1,8 +1,13 @@
-#include <kernel/elf.h>
-
-
-
+/**
+ * @file arch/sparc/kernel/elf.c
+ *
+ * @ingroup sparc
+ *
+ * @brief implements the architecture-specific ELF interface
+ *
+ */
 
+#include <kernel/elf.h>
 
 
 /**
diff --git a/arch/sparc/kernel/init.c b/arch/sparc/kernel/init.c
index de081dba3ecfe99bb5ba411a8c1fc0b9bf297d70..13cfe952b8611f0953a8155d0d69203a2ac3259e 100644
--- a/arch/sparc/kernel/init.c
+++ b/arch/sparc/kernel/init.c
@@ -1,5 +1,9 @@
 /**
  * @file arch/sparc/kernel/init.c
+ *
+ * @ingroup sparc
+ *
+ * @brief initalises paging
  */
 
 #include <mm.h>
diff --git a/arch/sparc/kernel/irq.c b/arch/sparc/kernel/irq.c
index 2e67ef6746944f54c14900a5688b3e243c0cd975..547093a843c2db2ddc2649bb4c9c7f9bfdc7fdac 100644
--- a/arch/sparc/kernel/irq.c
+++ b/arch/sparc/kernel/irq.c
@@ -1,6 +1,7 @@
 /**
  * @file arch/sparc/kernel/irq.c
- *
+ * 
+ * @ingroup sparc
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
diff --git a/arch/sparc/kernel/mm.c b/arch/sparc/kernel/mm.c
index 9e3effbe53ed2bf5d67f046ec025379c22d2c0cf..fc3b53c8b80f9fab6408e9cd365981d773007982 100644
--- a/arch/sparc/kernel/mm.c
+++ b/arch/sparc/kernel/mm.c
@@ -1,5 +1,7 @@
 /**
  * @file arch/sparc/kernel/mm.c
+ *
+ * @ingroup sparc
  */
 
 #include <mm.h>
diff --git a/arch/sparc/kernel/mmu.c b/arch/sparc/kernel/mmu.c
index 6730862ee4473551a8071e01cd4d807a35176b32..66bc3ce6c204f6edfc89f74d2cd95dbad8ca5086 100644
--- a/arch/sparc/kernel/mmu.c
+++ b/arch/sparc/kernel/mmu.c
@@ -1,5 +1,10 @@
 /**
  * @file arch/sparc/kernel/mmu.c
+ *
+ * @ingroup sparc
+ * 
+ * @brief SPARC MMU initialisation, context, trap handling and sbrk()
+ *
  */
 
 #include <mm.h>
diff --git a/arch/sparc/kernel/module.c b/arch/sparc/kernel/module.c
index 7189813918a83b317bbd214e92f2ee2ad4ae270d..1736686dfdc57731e0367a09944c8b1bd44f8139 100644
--- a/arch/sparc/kernel/module.c
+++ b/arch/sparc/kernel/module.c
@@ -1,3 +1,10 @@
+/**
+ * @file arch/sparc/kernel/module.c
+ *
+ * @ingroup sparc
+ * @brief implements architecture-specific @ref kernel_module interfaces
+ */
+
 #include <kernel/module.h>
 #include <kernel/printk.h>
 #include <kernel/err.h>
diff --git a/arch/sparc/kernel/page.c b/arch/sparc/kernel/page.c
index 47c28333535c6d497560b27bf6e4375dcaf5dad7..29291a02f8d1f29078616d92889ff80265940d6d 100644
--- a/arch/sparc/kernel/page.c
+++ b/arch/sparc/kernel/page.c
@@ -1,15 +1,14 @@
 /**
  * @file arch/sparc/kernel/page.c
+ *
+ * @ingroup sparc
+ *
+ * things we need statically allocated in the image (i.e. in .bss)
+ * at boot for page map/memory pool management
  */
 
 #include <page.h>
 
-
-
-/* things we need statically allocated in the image (i.e. in .bss)
- * at boot
- */
-
 unsigned long mm_init_bitmap[MM_INIT_LEN_BITMAP];
 unsigned char mm_init_alloc_order[MM_INIT_NUM_BLOCKS];
 struct list_head mm_init_block_order[MM_BLOCK_ORDER_MAX + 1];
@@ -17,4 +16,3 @@ struct list_head mm_init_block_order[MM_BLOCK_ORDER_MAX + 1];
 struct mm_pool  mm_init_page_pool;
 struct page_map_node  mm_init_page_node;
 struct page_map_node *mm_init_page_map[INIT_PAGE_MAP_MAX_ENTRIES + 1];
-
diff --git a/arch/sparc/kernel/setup.c b/arch/sparc/kernel/setup.c
index 6cb4a7ea9915c14cb9d21fbfaf46a5ef2dc74ef9..eebd07c1e60570d7497255fe1b8c9712c73de562 100644
--- a/arch/sparc/kernel/setup.c
+++ b/arch/sparc/kernel/setup.c
@@ -1,5 +1,10 @@
 /**
  * @file arch/sparc/kernel/setup.c
+ *
+ * @ingroup sparc
+ * @defgroup sparc SPARC
+ * @brief the SPARC architecture-specific implementation
+ *
  */
 
 #include <string.h> /* memset() */
diff --git a/arch/sparc/kernel/stacktrace.c b/arch/sparc/kernel/stacktrace.c
index 889ffaf600934f3685295aae03ba720936931eae..1d1fc45d3309216559ecd4a09951362b36c0afd6 100644
--- a/arch/sparc/kernel/stacktrace.c
+++ b/arch/sparc/kernel/stacktrace.c
@@ -1,5 +1,9 @@
 /**
  * @file   arch/sparc/kernel/stacktrace.c
+ *
+ * @ingroup sparc
+ *
+ * @brief stack tracking for the SPARC target
  */
 
 #include <stdlib.h>
diff --git a/arch/sparc/mm/srmmu.c b/arch/sparc/mm/srmmu.c
index 549793bb5c3b01d0b912c1e8f8fe0e051a1e33ab..08c50eac9fcb6529c8a4376c05d9283cb3e9b1e1 100644
--- a/arch/sparc/mm/srmmu.c
+++ b/arch/sparc/mm/srmmu.c
@@ -2,6 +2,10 @@
  *
  * @file arch/sparc/mm/srmmu.c
  *
+ * @ingroup srmmu
+ * @defgroup srmmu SPARC Reference MMU
+ *
+ * @brief access to the SPARC Reference MMU (SRMMU)
  *
  *
  * ## Overview
@@ -19,9 +23,11 @@
  * address through the MMU, you can use the context table pointer (ctp) as
  * page table entry (pte):
  *
+ * @code{.c}
  *	srmmu_set_ctx_tbl_addr((unsigned long) _mmu_ctp);
  *	_mmu_ctp[0] = SRMMU_PTE(0x0, (SRMMU_CACHEABLE | SRMMU_ACC_S_RWX_2));
  *	srmmu_set_ctx(0);
+ * @endcode
  *
  * so the virtual address mapping starts at physical address address 0x0.
  * Note: accessing memory regions not actually mapped in hardware will
@@ -32,14 +38,19 @@
  * against accidential R/W/X operations, you can point a level 0 ctp to a
  * level 1 table by setting it up as a page table descriptor (ptd):
  *
+ * @code{.c}
  *	_mmu_ctp[0] = SRMMU_PTD((unsigned long) &ctx->tbl.lvl1[0]);
+ * @endcode
  *
  * Let's say you want to map a 16 MiB chunk starting at 0x40000000
  * transparently through the MMU, you would then set lvl 1 table entry
  * 0x40 (64), since lvl1 tables addresses are formed by the two highest-order
  * bytes:
+ *
+ * @code{.c}
  *	ctx->tbl.lvl1[0x40] =
  *		SRMMU_PTE(0x40000000, (SRMMU_CACHEABLE | SRMMU_ACC_S_RWX_2));
+ * @endcode
  *
  * an then select the MMU context.
  *
@@ -57,8 +68,10 @@
  *
  * Let's say you created a second mapping to the same physical address:
  *
+ * @code{.c}
  *	ctx->tbl.lvl1[0xaa] =
  *		SRMMU_PTE(0x40000000, (SRMMU_CACHEABLE | SRMMU_ACC_S_RWX_2));
+ * @endcode
  *
  * and try to access 0xaa123456. The MMU will then replace 0xaa with 0x40, and
  * you'll get the same physical address again!
@@ -72,15 +85,20 @@
  * setting up the entry as a pte, you would configure it as a ptd that
  * references a lvl 2 table, e.g.
  *
+ * @code{.c}
  *	ctx->tbl.lvl1[0x40] = SRMMU_PTD((unsigned long) &ctx->tbl->lvl2[0]);
+ * @endcode
  *
  * and then set up the lvl 2 table entries, which reference 64 chunks of 256 KiB
  * each, which means that the next 6 _bits_ in the address are used by the MMU
  * for the offset into the table, i.e. (addr & 0x00FC0000 ) >> 18
  *
  * If you configure a mapping for 0xaa04xxxx, you would set:
+ *
+ * @code{.c}
  *	ctx->tbl.lvl2[0xaa][0x01] =
  *		SRMMU_PTE(0x40000000, (SRMMU_CACHEABLE | SRMMU_ACC_S_RWX_2));
+ * @endcode
  *
  * and then access 0xaa04cdef, the MMU will strip the upper 14 bits from that
  * address and replace them with the upper 14 bits of 0x40000000 and hence
diff --git a/arch/sparc/mm/srmmu_access.c b/arch/sparc/mm/srmmu_access.c
index 77b5e1215ba8520bcc980bbba98a6d5d3ea84790..1407e66c876713c9ee414a5a95243b39ac302c2e 100644
--- a/arch/sparc/mm/srmmu_access.c
+++ b/arch/sparc/mm/srmmu_access.c
@@ -1,8 +1,9 @@
-
 /**
  * @brief SRMMU register access functions
  * @author Armin Luntzer (armin.luntzer@univie.ac.at)
  *
+ * @ingroup srmmu
+ *
  * @note only LEON ASI is supported
  */
 
diff --git a/dsp/xentium/include/dma.h b/dsp/xentium/include/dma.h
index 232d7015d8a8cfc1161ffcc611890305cce55018..bbd3a6827e1642fae9fc918dc15bb3082250d289 100644
--- a/dsp/xentium/include/dma.h
+++ b/dsp/xentium/include/dma.h
@@ -1,5 +1,6 @@
 /**
  * @file dsp/xentium/include/xdma.h
+ * @ingroup xen
  */
 
 #ifndef _DSP_XENTIUM_DMA_H_
diff --git a/dsp/xentium/include/xen.h b/dsp/xentium/include/xen.h
index a6fc120715a340a6ce198aa3f0ad14728940b425..f9dc22e9c6180946ee21fc3bee9f80e6f596521f 100644
--- a/dsp/xentium/include/xen.h
+++ b/dsp/xentium/include/xen.h
@@ -1,5 +1,12 @@
 /**
  * @file dsp/xentium/include/xen.h
+ * @ingroup xen
+ *
+ * @defgroup xen Xentium Kernel Interface
+ * @brief a host interface and support library for Xentium Processing Kernels
+ *
+ * @defgroup xen_kernel Xentium Processing Kernels
+ * @brief a set of Xentium Processing Kernels
  */
 
 #ifndef _DSP_XENTIUM_XEN_H_
diff --git a/dsp/xentium/include/xen_printf.h b/dsp/xentium/include/xen_printf.h
index 6790e9144e7579763bc3e00c8c746ba852201280..e535bd70f80fa94ef2e5e7d4b07bc007ee77d5f8 100644
--- a/dsp/xentium/include/xen_printf.h
+++ b/dsp/xentium/include/xen_printf.h
@@ -3,6 +3,8 @@
  * @author  Armin Luntzer (armin.luntzer@univie.ac.at)
  * @date    November, 2013
  *
+ * @ingroup xen
+ *
  *
  * @copyright 
  * This program is free software; you can redistribute it and/or modify it
diff --git a/dsp/xentium/kernel/deglitch/xen_deglitch.c b/dsp/xentium/kernel/deglitch/xen_deglitch.c
index 5810a7b83ef7b0fc52f691afb427677e9222d8d9..177199bd7ebefccfa7479f895a0b670e1836876f 100644
--- a/dsp/xentium/kernel/deglitch/xen_deglitch.c
+++ b/dsp/xentium/kernel/deglitch/xen_deglitch.c
@@ -1,4 +1,6 @@
 /**
+ * @ingroup xen_kernel
+ *
  * @brief deglitch an array
  *
  * NOTE: This is for demonstration purposes only. There are lot of things that
diff --git a/dsp/xentium/kernel/dummy/xen_dummy.c b/dsp/xentium/kernel/dummy/xen_dummy.c
index e6ccdf34e8b9f085f29de2d381b02810de2782e2..a79715cbf42fe24f172c196a2c9c7bf5467fdb77 100644
--- a/dsp/xentium/kernel/dummy/xen_dummy.c
+++ b/dsp/xentium/kernel/dummy/xen_dummy.c
@@ -1,4 +1,6 @@
 /**
+ * @ingroup xen_kernel
+ *
  * @brief this is just a dummy that uses the DMA to copy at most one TCM
  *	  bank of 32 bit words from the main memory and back
  */
diff --git a/dsp/xentium/kernel/rampfit/xen_rampfit.c b/dsp/xentium/kernel/rampfit/xen_rampfit.c
index 958def6f0a520a562d080467416a849b77413a20..05ec80c71316569e843860d4ec0923c422da5021 100644
--- a/dsp/xentium/kernel/rampfit/xen_rampfit.c
+++ b/dsp/xentium/kernel/rampfit/xen_rampfit.c
@@ -1,4 +1,6 @@
 /**
+ * @ingroup xen_kernel
+ *
  * @brief fit ramps to data in an array
  *
  * NOTE: This is for demonstration purposes only. There are lot of things that
diff --git a/dsp/xentium/kernel/stack/xen_stack.c b/dsp/xentium/kernel/stack/xen_stack.c
index 340cf22acb2436d3357e7af2cc36dc865edfaa95..bc67a4446b178345d85c9cd82ece43f945a38a1c 100644
--- a/dsp/xentium/kernel/stack/xen_stack.c
+++ b/dsp/xentium/kernel/stack/xen_stack.c
@@ -1,4 +1,7 @@
 /**
+ *
+ * @ingroup xen_kernel
+ *
  * @brief stack "frames"
  *
  * NOTE: This is for demonstration purposes only. There are lot of things that
diff --git a/dsp/xentium/lib/dma.c b/dsp/xentium/lib/dma.c
index 1d61c387615187eeefee4e5f9db8c0c70157ee3f..12ddbf6291eb6fa649439fc826735b40d6dc8522 100644
--- a/dsp/xentium/lib/dma.c
+++ b/dsp/xentium/lib/dma.c
@@ -1,5 +1,9 @@
 /**
- * @file dsp/xentium/lib/xdma.c
+ * @file dsp/xentium/lib/dma.c
+ *
+ * @ingroup xen
+ *
+ * @brief NoC DMA access from the Xentium
  *
  * These are mostly just duplicates of the noc_dma access functions...
  */
diff --git a/dsp/xentium/lib/kmem.c b/dsp/xentium/lib/kmem.c
index 10b7a9086b68ae42c2c8f1e626269f6e5ef21979..edbfcb310c9b8250de4f0d46dea0a9d367388ed6 100644
--- a/dsp/xentium/lib/kmem.c
+++ b/dsp/xentium/lib/kmem.c
@@ -1,6 +1,9 @@
 /**
+ * @file dsp/xentium/lib/kmem.c
  *
- * kmalloc/kfree via host processor for added convenience...
+ * @ingroup xen
+ *
+ * @brief kmalloc/kfree via host processor for added convenience...
  *
  */
 
diff --git a/dsp/xentium/lib/xen.c b/dsp/xentium/lib/xen.c
index 3fd66f79296946c5502f7a9e33d220e14c88948e..6821effcbce7ae21f3c22fe54b45823c4e69d0e0 100644
--- a/dsp/xentium/lib/xen.c
+++ b/dsp/xentium/lib/xen.c
@@ -1,5 +1,10 @@
 /**
  * @file dsp/xentium/lib/xen.c
+ *
+ * @ingroup xen
+ *
+ * @brief host processor and Xentium interaction
+ *
  */
 
 #include <xen.h>
diff --git a/dsp/xentium/lib/xen_printf.c b/dsp/xentium/lib/xen_printf.c
index 918c02a228346b675a31bb725c49889d4a4e97cd..56b66c79984ae871894b20fc9f09e7b9be2591d2 100644
--- a/dsp/xentium/lib/xen_printf.c
+++ b/dsp/xentium/lib/xen_printf.c
@@ -1,11 +1,13 @@
 /**
- * @file   xentium/xen_printf.c
+ * @file   dsp/xentium/lib/xen_printf.c
  * @author Armin Luntzer (armin.luntzer@univie.ac.at),
  * @date   November, 2013
  * @brief  a printf function suitable for use in xentium programs
  * @note  there are many like it, but this one is mine...
  * @note the lack of a cross-processor locking mechanism obviously implies that x_printf and leon printf writes might interfere
  *
+ * @ingroup xen
+ *
  * @copyright 
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
diff --git a/include/chunk.h b/include/chunk.h
index 4a7ad6291b1e3850e14d01357257bc022d0fe7f1..039191905b5f92593ab15f293e2347fbfd54d2d6 100644
--- a/include/chunk.h
+++ b/include/chunk.h
@@ -1,5 +1,7 @@
 /**
  * @file include/chunk.h
+ *
+ * @ingroup chunk
  */
 
 
diff --git a/include/data_proc_net.h b/include/data_proc_net.h
index 57d12675e29f227898006efca9bbcda5530f2c4b..9b548cfa53b611115781e901cfdb50acb41f6c3d 100644
--- a/include/data_proc_net.h
+++ b/include/data_proc_net.h
@@ -1,5 +1,7 @@
 /**
  * @file include/data_proc_net.h
+ *
+ * @ingroup data_proc_net
  */
 
 #ifndef _DATA_PROC_NET_H_
diff --git a/include/data_proc_tracker.h b/include/data_proc_tracker.h
index c18957ff7a933d4d72f0c49b1cd2b440dc0a620b..70df020c315fd274ab2fea1b5ca3379971901eef 100644
--- a/include/data_proc_tracker.h
+++ b/include/data_proc_tracker.h
@@ -1,5 +1,7 @@
 /**
  * @file include/data_proc_tracker.h
+ *
+ * @ingroup data_proc_tracker
  */
 
 #ifndef _DATA_PROC_TRACKER_H_
@@ -9,21 +11,27 @@
 #include <list.h>
 #include <data_proc_task.h>
 
-
-
+/**
+ * the operator function type associated with a processing tracker
+ */
 typedef int (*op_func_t)(unsigned long op_code, struct proc_task *);
 
+/**
+ * @struct the data processing tracker structure
+ */
 struct proc_tracker {
-	struct list_head tasks;
-	size_t n_tasks;
-	size_t n_tasks_crit;
+	struct list_head tasks;	/*!< a list head links the tracked tasks */ 
+	size_t n_tasks;		/*!< the current number of tracked tasks */
+	size_t n_tasks_crit;	/*!< the number of tasks above which the
+				  tracker should be considered critical */
 
-	unsigned long op_code;
+	unsigned long op_code;	/*!< the op code identifier of the tracker */
 
-	op_func_t op;
+	op_func_t op;		/*!< the operator function of this tracker */
 
 
-	struct list_head node;	/* to be used for external tracking */
+	struct list_head node;	/*!< may be used for external tracking of this
+				   tracker */
 };
 
 
diff --git a/include/elf.h b/include/elf.h
index 883eeaedd40301f3a6c63f0ac2ba6aef4af6f863..3ce0aa2a20830d6449a872cf63b87e6394244498 100644
--- a/include/elf.h
+++ b/include/elf.h
@@ -1,3 +1,8 @@
+/**
+ * @file include/elf.h
+ * @ingroup elf
+ */
+
 #ifndef _KERNEL_ELF_H_
 #define _KERNEL_ELF_H_
 
diff --git a/include/kernel/ar.h b/include/kernel/ar.h
index cb37e4bd107f1db02e532745aa05e428f3f41f11..7951c5a4ae413457958751a47349a94f4831faf8 100644
--- a/include/kernel/ar.h
+++ b/include/kernel/ar.h
@@ -1,3 +1,9 @@
+/**
+ * @file include/kernel/ar.h
+ * 
+ * @ingroup ar
+ */
+
 #ifndef _KERNEL_AR_H_
 #define _KERNEL_AR_H_
 
@@ -10,15 +16,17 @@
 #define GNU_AR_STR_TBL_MAG	"//"	/* marks a gnu archive string table */
 #define GNU_AR_SYM_TBL_MAG	"/ "	/* marks a gnu archive symbol table */
 
-
+/**
+ * an AR header
+ */
 struct ar_hdr {
-	char ar_name[16];	/* ar file identifier */
-	char ar_date[12];	/* file date, dec seconds since epoch */
-	char ar_uid[6];		/* user  ID; dec  */
-	char ar_gid[6];		/* group ID; dec  */
-	char ar_mode[8];	/* file mode; oct */
-	char ar_size[10];	/* file size; dec */
-	char ar_fmag[2];	/* AR_FMAG (0x60, 0x0a) */
+	char ar_name[16];	/**! ar file identifier */
+	char ar_date[12];	/**! file date, dec seconds since epoch */
+	char ar_uid[6];		/**! user  ID; dec  */
+	char ar_gid[6];		/**! group ID; dec  */
+	char ar_mode[8];	/**! file mode; oct */
+	char ar_size[10];	/**! file size; dec */
+	char ar_fmag[2];	/**! AR_FMAG (0x60, 0x0a) */
 };
 
 
@@ -27,19 +35,19 @@ struct ar_hdr {
  */
 
 struct archive {
-	char  *ar_base;		/* the archive's memory location */
-	unsigned long ar_size;	/* the size of the archive in bytes */
-	char  *ar_str;		/* the archive's string table */
-
-	unsigned int n_file;	/* the number of files in the archive */
-	char **fname;		/* pointer array to the file name strings */
-	char **p_file;		/* pointer array to the file(s) */
-	unsigned long *filesz;	/* the size of each file */
-	unsigned long *fnamesz;	/* the size of each file name */
-
-	uint32_t n_sym;		/* the number of symbols in the index */
-	char **sym;		/* pointer array to the symbol name strings */
-	void **p_sym;		/* pointer array to the file a symbol is in */
+	char  *ar_base;		/**! the archive's memory location */
+	unsigned long ar_size;	/**! the size of the archive in bytes */
+	char  *ar_str;		/**! the archive's string table */
+                                   
+	unsigned int n_file;	/**! the number of files in the archive */
+	char **fname;		/**! pointer array to the file name strings */
+	char **p_file;		/**! pointer array to the file(s) */
+	unsigned long *filesz;	/**! the size of each file */
+	unsigned long *fnamesz;	/**! the size of each file name */
+                                   
+	uint32_t n_sym;		/**! the number of symbols in the index */
+	char **sym;		/**! pointer array to the symbol name strings */
+	void **p_sym;		/**! pointer array to the file a symbol is in */
 
 };
 
diff --git a/include/kernel/irq.h b/include/kernel/irq.h
index 911f76eb4c493b1403cacf55bce4f16af5d4978b..b08bd0470c4dc713286f5e71c9c9f5982b6711e3 100644
--- a/include/kernel/irq.h
+++ b/include/kernel/irq.h
@@ -1,7 +1,8 @@
 /**
  * @file    include/kernel/irq.h
  * @author  Armin Luntzer (armin.luntzer@univie.ac.at)
- * @date    December, 2013
+ *
+ * @ingroup irq
  *
  * @copyright GPLv2
  *
diff --git a/include/kernel/kmem.h b/include/kernel/kmem.h
index 39f8f91aea8ebdcfa0407c151465112a3276a8d3..dbcd53ebd88b61ff2057de11c809dabadbc797d1 100644
--- a/include/kernel/kmem.h
+++ b/include/kernel/kmem.h
@@ -1,5 +1,6 @@
 /**
  * @file include/kernel/kmem.h
+ * @ingroup kmem
  */
 
 #ifndef _KERNEL_KMEM_H_
diff --git a/include/kernel/mm.h b/include/kernel/mm.h
index d96c9898fc4849549b6d8f503f2ceb34d29722be..68f06fc4fbbce34aa5b42ba5bfc240d8e760421d 100644
--- a/include/kernel/mm.h
+++ b/include/kernel/mm.h
@@ -1,5 +1,7 @@
 /**
  * @file include/kernel/mm.h
+ *
+ * @ingroup buddy_mm
  */
 
 #ifndef _KERNEL_MM_H_
@@ -19,15 +21,18 @@
 #define MM_BITMAP_LEN(order_max, order_min) \
 	(BITS_TO_LONGS(MM_NUM_BLOCKS_TRACKABLE(order_max, order_min)) + 1)
 
+/**
+ * the buddy memory pool
+ */
 struct mm_pool {
-	unsigned long    base;		/** base address of the memory pool */
-	unsigned long    max_order;	/** maximum order (i.e. pool size)  */
-	unsigned long    min_order;	/** block granularity		    */
-	unsigned long    n_blks;	/** number of managed blocks	    */
-	unsigned long    alloc_blks;	/** number of allocated blocks	    */
-	unsigned char    *alloc_order;	/** the allocated order of a block  */
-	unsigned long    *blk_free;	/** per-block allocation bitmap	    */
-	struct list_head *block_order;  /** anchor for unused blocks	    */
+	unsigned long    base;		/**! base address of the memory pool */
+	unsigned long    max_order;	/**! maximum order (i.e. pool size)  */
+	unsigned long    min_order;	/**! block granularity		    */
+	unsigned long    n_blks;	/**! number of managed blocks	    */
+	unsigned long    alloc_blks;	/**! number of allocated blocks	    */
+	unsigned char    *alloc_order;	/**! the allocated order of a block  */
+	unsigned long    *blk_free;	/**! per-block allocation bitmap    */
+	struct list_head *block_order;  /**! anchor for unused blocks	    */
 };
 
 
diff --git a/include/kernel/module.h b/include/kernel/module.h
index 1ed00cd606f548271b22d44d5b5fe8afe3dbdd46..e357eaff481c85521a2b49b71aa8778a5de4185b 100644
--- a/include/kernel/module.h
+++ b/include/kernel/module.h
@@ -1,3 +1,9 @@
+/**
+ * @file include/kernel/module.h
+ *
+ * @ingroup kernel_module
+ */
+
 #ifndef _KERNEL_MODULE_H_
 #define _KERNEL_MODULE_H_
 
diff --git a/include/kernel/string.h b/include/kernel/string.h
index 26825fae3082717b1b1876ce62a8564ecaa43e2c..980caa984947d590c256fc84811d053e6fe37b09 100644
--- a/include/kernel/string.h
+++ b/include/kernel/string.h
@@ -1,5 +1,7 @@
 /**
  * @file include/kernel/string.h
+ *
+ * @ingroup string
  */
 
 #ifndef _KERNEL_STRING_H_
diff --git a/include/kernel/xentium.h b/include/kernel/xentium.h
index e973d9153c39e479f653633196c09b9e94b0cbf4..f6c9213f686615ae9a2a1db087788d4fbf924cb4 100644
--- a/include/kernel/xentium.h
+++ b/include/kernel/xentium.h
@@ -1,5 +1,7 @@
 /**
  * @file include/kernel/xentium.h
+ *
+ * @ingroup xentium_driver
  */
 
 #ifndef _KERNEL_XENTIUM_H_
diff --git a/include/kernel/xentium_dev.h b/include/kernel/xentium_dev.h
index d16a0cecf011dca1b022f416bfe35cc2e29078fb..834a4f9e92cc4f74a1cb9142721e850683f2fc5d 100644
--- a/include/kernel/xentium_dev.h
+++ b/include/kernel/xentium_dev.h
@@ -1,6 +1,8 @@
 /**
  * @file include/kernel/xentium_dev.h
  *
+ * @ingroup xentium_driver
+ *
  * @note this file may also be included in xentium kernel code
  */
 
diff --git a/include/kernel/xentium_io.h b/include/kernel/xentium_io.h
index fcb56266b46ff4700271e5bec60ce72ed1a11ac2..47e4b8d5f1a4815c99b468f9b6500317faf33ccc 100644
--- a/include/kernel/xentium_io.h
+++ b/include/kernel/xentium_io.h
@@ -1,6 +1,8 @@
 /**
  * @file include/kernel/xentium_io.h
  *
+ * @ingroup xentium_driver
+ *
  * @note this file may also be included in xentium kernel code
  */
 
@@ -32,18 +34,18 @@ struct xen_kernel_cfg {
  */
 
 enum xen_cmd {
-	TASK_SUCCESS = PN_TASK_SUCCESS,	/* ready for next task in node */
-	TASK_STOP    = PN_TASK_STOP,    /* success, but abort processing node */
-	TASK_DETACH  = PN_TASK_DETACH,  /* task tracking is internal */
-	TASK_RESCHED = PN_TASK_RESCHED, /* requeue this task and abort */
-	TASK_SORTSEQ = PN_TASK_SORTSEQ, /* TASK_RESCHED and sort by seq cntr */
-	TASK_DESTROY = PN_TASK_DESTROY, /* something is wrong, destroy task */
-	TASK_ATTACH,			/* queue this task and let xentium continue */
-	TASK_DATA_REALLOC,		/* (re)allocate task data pointer */
-	TASK_KZALLOC,			/* request memory buffer */
-	TASK_KMALLOC,			/* request memory buffer */
-	TASK_KFREE,			/* release memory buffer */
-	TASK_EXIT,			/* Xentium exiting */
+	TASK_SUCCESS = PN_TASK_SUCCESS,	/*!< ready for next task in node */
+	TASK_STOP    = PN_TASK_STOP,    /*!< success, but abort processing node */
+	TASK_DETACH  = PN_TASK_DETACH,  /*!< task tracking is internal */
+	TASK_RESCHED = PN_TASK_RESCHED, /*!< requeue this task and abort */
+	TASK_SORTSEQ = PN_TASK_SORTSEQ, /*!< TASK_RESCHED and sort by seq cntr */
+	TASK_DESTROY = PN_TASK_DESTROY, /*!< something is wrong, destroy task */
+	TASK_ATTACH,			/*!< queue this task and let xentium continue */
+	TASK_DATA_REALLOC,		/*!< (re)allocate task data pointer */
+	TASK_KZALLOC,			/*!< request memory buffer and clear */
+	TASK_KMALLOC,			/*!< request memory buffer */
+	TASK_KFREE,			/*!< release memory buffer */
+	TASK_EXIT,			/*!< Xentium exiting */
 };
 
 
@@ -54,30 +56,26 @@ enum xen_cmd {
 struct xen_msg_data {
 
 	struct proc_task *t;
-	unsigned long xen_id;		/* the Xentium's id */
+	unsigned long xen_id;		/*!< the Xentium's id */
 
-	struct noc_dma_channel *dma;	/* the reserved DMA channel */
+	struct noc_dma_channel *dma;	/*!< the reserved DMA channel */
 
-	enum xen_cmd  cmd;		/* command request */
-	unsigned long cmd_param;	/* command parameter */
+	enum xen_cmd  cmd;		/*!< command request */
+	unsigned long cmd_param;	/*!< command parameter */
 
-	void *ptr;			/* kmem pointers */
-	size_t size;			/* kmem size request */
+	void *ptr;			/*!< kmem pointers */
+	size_t size;			/*!< kmem size request */
 };
 
 
 
-/**
- *  wait/status masks for the Xentium mailboxes
- */
-
+/* wait/status masks for the Xentium mailboxes */
 #define XEN_WAITMASK_MBOX_0  1
 #define XEN_WAITMASK_MBOX_1  2
 #define XEN_WAITMASK_MBOX_2  4
 #define XEN_WAITMASK_MBOX_3  8
 
-
-/**
+/*
  * xentium <> host I/O
  *
  * we need two mailboxes to exchange command, otherwise x_wait() may trigger on
diff --git a/init/main.c b/init/main.c
index 1162c3af82f83d0f34ee6155ef6cb8fe8795b6b4..dd43b1d2836c23e3c10d9b98bbe532c5788018b0 100644
--- a/init/main.c
+++ b/init/main.c
@@ -1,5 +1,13 @@
 /**
  * @file init/main.c
+ *
+ * @ingroup main
+ * @defgroup main Kernel Main Function
+ * 
+ * @brief the kernel main function
+ *
+ * Here we set up the kernel.
+ *
  */
 
 #include <generated/autoconf.h>
diff --git a/init/modules-image.c b/init/modules-image.c
index 79126c2658078b72d30c2da878227788e47e4f24..fab061e6c4d271432c543a794bc03b74ab119216 100644
--- a/init/modules-image.c
+++ b/init/modules-image.c
@@ -1,7 +1,10 @@
 /**
  * @file init/modules-image.c
  *
- * load files and modules in embedded modules.image
+ * @ingroup modimg
+ * @defgroup modimg Modules Image Loader
+ *
+ * @brief load files and modules in embedded modules.image
  */
 
 
diff --git a/init/xentium_demo.c b/init/xentium_demo.c
index a7eadceb12fe939135cd8a055e851c934ef93452..fec43a8778470736ac3332251f091341ad142e46 100644
--- a/init/xentium_demo.c
+++ b/init/xentium_demo.c
@@ -1,5 +1,8 @@
 /**
  * @file init/xentium_demo.c
+ * 
+ * @ingroup xen_demo
+ * @defgroup xen_demo Xentium Demonstrator
  *
  * @brief demonstrates how a Xentium processing network is used
  */
diff --git a/kernel/irq.c b/kernel/irq.c
index 3253f93c8e062d328da17e822a378258ea901411..b162072dd72b9ed6c446e052d884e56c145b4925 100644
--- a/kernel/irq.c
+++ b/kernel/irq.c
@@ -2,6 +2,11 @@
  * @file kernel/irq.c
  * @author Armin Luntzer (armin.luntzer@univie.ac.at)
  *
+ * @ingroup irq
+ * @defgroup irq IRQ interface
+ *
+ * @brief kernel IRQ interface
+ *
  * this implements the high-level IRQ logic (which is admittedly not very
  * thought-through)
  */
diff --git a/kernel/kmem.c b/kernel/kmem.c
index 2f89dc26a82d7c29232fc2ddf5b867601a4083b2..f9b2f4f141dc821790bab3bd7744f446dafbaf2a 100644
--- a/kernel/kmem.c
+++ b/kernel/kmem.c
@@ -1,11 +1,18 @@
 /**
  * @file kernel/kmem.c
  *
- * A simple high-level allocator that uses sbrk() to retrieve memory.
- * Is similar to lib/chunk.c, but a lot simpler. I need to respect sbrk()
- * so I can't just use _chunk_ because it may release any parent chunk,
- * while we need to do that from _kmem_last  to first as the become free.
- * I don't have time do do this properly, so this must do for now..
+ * @ingroup kmem
+ * @defgroup kmem Kernel Memory Allocator
+ *
+ * @brief a malloc-like kernel memory allocator 
+ *
+ * A simple high-level allocator that uses kernel_sbrk() implemented by the
+ * architecture-specific (MMU) code to allocate memory. If no MMU is available,
+ * it falls back to using the architecture's boot memory allocator.
+ *
+ * This is similar to @ref chunk, but a lot simpler. This needs to respect
+ * sbrk() so it can't just use @chunk because it may release any parent chunk,
+ * while we need to do that from _kmem_last to _kmem_init as they become free.
  */
 
 #include <list.h>
diff --git a/kernel/module.c b/kernel/module.c
index d205671a5112d5d5b9624ed1604f559c054e94f3..b15a5d7893e3b3e8c99ad0bbf4deb3884524b867 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -1,6 +1,13 @@
 /**
  * @file kernel/module.c
  *
+ * @ingroup kernel_module
+ * @defgroup kernel_module Loadable Kernel Module Support
+ *
+ * @brief implements loadable kernel modules
+ *
+ *
+ *
  *
  * TODO 1. module chainloading, reference counting and dependency
  *	   tracking for automatic unloading of unused modules
diff --git a/kernel/module_image.c b/kernel/module_image.c
index 51de991cf7de44f8e86fee9767c50662d66eb97b..c598c361e3ea7f87fae42eaf8707560acb022fda 100644
--- a/kernel/module_image.c
+++ b/kernel/module_image.c
@@ -1,5 +1,6 @@
 /**
  * linker references to embedded modules.image
+ * @ingroup modimg
  */
 
 extern unsigned char _binary_modules_image_start;
diff --git a/kernel/noc_dma.c b/kernel/noc_dma.c
index 56411bb646122808ca488906af1eb7c6e5f22e4c..e22c583cde44750262102ef71531b6254f402830 100644
--- a/kernel/noc_dma.c
+++ b/kernel/noc_dma.c
@@ -1,10 +1,33 @@
 /**
  * @file kernel/noc_dma.c
  *
+ * @ingroup noc_dma
+ * @defgroup noc_dma SSDP/MPPBv2 NoC DMA driver
+ *
+ * @brief a driver for the SSDP/MPPBv2 NoC DMA
+ *
+ *
+ *
+ * This implements transfers via the NoC DMA feature of the SSDP/MPPBv2.
+ *
+ * Complex transfers (2D) may be programmed via noc_dma_req_xfer(), simpler (1D)
+ * transfers may be requested via noc_dma_req_lin_xfer().
+ *
+ * A requested transfer is added to a queue of configurable length and executed
+ * as soon as a DMA channel becomes available. The caller is informed of
+ * transfer completion via a supplied callback notification function.
+ *
+ * Channels may be reserved for exclusive external use via
+ * noc_dma_reserve_channel() and returned by noc_dma_release_channel().
+ *
+ *
+ *
  * @note parameter limits are usually not checked, as they are implicit by type
  *
  * @todo stuck channel detection (needs threading or at least a timer service)
  *	 and reset (if possible, transfer size 0 maybe? need to test...)
+ *
+ * @example noc_dma_demo.c
  */
 
 
diff --git a/kernel/xentium.c b/kernel/xentium.c
index dd286b35cbfacd191884951e0c1bf8ce70373faa..8ec2dae031070fcf030d021c19422a737b363337 100644
--- a/kernel/xentium.c
+++ b/kernel/xentium.c
@@ -1,50 +1,62 @@
 /**
  * @file kernel/xentium.c
  *
+ * @ingroup xentium_driver
+ * @defgroup xentium_driver Xentium driver
  *
+ * @brief Xentium processing network driver
  *
- * This is the Xentium processing network driver. It builds upon data_proc_net.c
- * and maps tasks selected by op codes to the appropriate Xentium kernel
- * program. To load and set up the "op code" nodes, the user must load
- * corresponding ELF binaries of Xentium programs. These ELF binaries must
- * export their capabilities as a struct xen_kernel_cfg (see
- * kernel/xentium_io.h) and make use of the commanding exchange protocol (same
- * file). See also dsp/xentium for kernel programs.
+ * This is the Xentium processing network driver. It builds upon
+ * @ref data_proc_net and maps tasks selected by op codes to the appropriate
+ * Xentium kernel program. To load and set up the "op code" nodes, the user
+ * loads corresponding ELF binaries of Xentium programs. These ELF binaries must
+ * export their capabilities as a struct xen_kernel_cfg and make use of the
+ * command exchange protocol (see kernel/xentium_io.h).
+ * See also dsp/xentium/ subdirectory for kernel programs.
  *
  *
  * A minimum setup requires the user to add at least one kernel, e.g.
  *
+ * @code{.c}
  *	xentium_kernel_add(elf_kernel_binary_addr);
+ * @endcode
  *
  * and configure a custom output node that is of type op_func_t (see
  * data_proc_tracker.h):
  *
- * int xentium_config_output_node(xen_op_output)
- * {
- *	...
- *	return PN_TASK_SUCCESS;
- * }
+ * @code{.c}
+ *	int xentium_config_output_node(xen_op_output)
+ *	{
+ *		...
+ *		return PN_TASK_SUCCESS;
+ *	}
+ * @endcode
  *
  * via
+ *
+ * @code{.c}
  *	xentium_config_output_node(xen_op_output);
+ * @endcode
  *
  * which corresponds to the call to pn_create_output_node() when using the
- * generic processing network (data_proc_net.c) implementation
+ * generic @ref data_proc_net implementation
  *
  *
  * Note that the user is responsible to free the data pointer of the task
  * and the task itself (i.e. pt_destroy()), the same way that one would with
- * a non-DSP processing network (see samples/proc_chain/ for an example)
+ * a non-DSP processing network (see @ref proc_chain_demo.c)
  *
  *
  * New processing tasks can then be added into the network, e.g.
  *
+ * @code{.c}
  *	struct proc_task t = pt_create(data, ...);
  *
  *	pt_add_step(t, op1, ...));
  *	pt_add_step(t, op2, ...));
  *
  *	xentium_input_task(t);
+ * @endcode
  *
  * the task will then move through the selected nodes in the processing network.
  *
@@ -52,9 +64,9 @@
  * reference to the struct proc_task, which they must be able to interpret
  * and/or process as the user desires.
  *
- * In addition, the Xentiums are passed a DMA channel each, that they may use
- * to transfer memory contents to and from their local tightly couple memory
- * (TCM).
+ * In addition, the Xentiums are passed a DMA channel each (reserved from @ref
+ * noc_dma), which they may use to transfer memory contents to and from their
+ * local tightly couple memory (TCM).
  *
  * The task of the host processor consists of command exchange and loading of
  * the Xentium kernel programs as needed. Typically, a nodes are scheduled for
@@ -78,7 +90,9 @@
  * the output node. It is up to the user to retrieve and deallocate tasks form
  * this node by calling
  *
+ * @code{.c}
  *	xentium_output_tasks();
+ * @endcode
  *
  *
  * This will execute the output node previously configured by
diff --git a/lib/ar.c b/lib/ar.c
index ec81d89525fc349840e612ef91ef2aec095b02c4..6adae54f2979e41371fdb9dae71969e5daa055eb 100644
--- a/lib/ar.c
+++ b/lib/ar.c
@@ -1,4 +1,10 @@
 /**
+ * @file lib/ar.c
+ *
+ * @ingroup ar
+ * @defgroup ar AR reader
+ *
+ * @brief an AR file reader
  *
  * This is a very simple AR reader. It expects indexed SVR4/GNU type archive,
  * i.e. created invoking: ar rcs <archive> <files...>
@@ -16,6 +22,8 @@
  *
  * @note The sym array in struct archive may be used to lookup a module
  *       dependency when resolving symbols.
+ *
+ * @example ar_demo.c
  */
 
 
diff --git a/lib/chunk.c b/lib/chunk.c
index 12d687a32edd4b4b7a05c846a92fb357da97b5db..3e8dc9429c6d5377c203981f26b41da11ea6bbc1 100644
--- a/lib/chunk.c
+++ b/lib/chunk.c
@@ -1,6 +1,11 @@
 /**
  * @file lib/chunk.c
  *
+ * @ingroup chunk
+ * @defgroup chunk Memory Chunk Allocator
+ *
+ * @brief a chunk-based memory allocator
+ *
  *
  * This is a stepping stone to something like malloc()
  *
@@ -28,6 +33,7 @@
  *	 a single chunk up to the alignement boundary and adds it to the "full"
  *	 pool, then returns the following (aligned) chunk.
  *
+ * @example chunk_demo.c
  */
 
 #include <unistd.h>
diff --git a/lib/data_proc_net.c b/lib/data_proc_net.c
index 1d3fecfbff6ad39a0c1b6f97c8262aed6b6a7b8b..47c117e4cc83e47eb41d4b6a26dd4a4d763629b7 100644
--- a/lib/data_proc_net.c
+++ b/lib/data_proc_net.c
@@ -1,14 +1,20 @@
 /**
  * @file lib/data_proc_net.c
  *
+ * @ingroup data_proc_net
+ * @defgroup data_proc_net Data Processing Network
  *
- * This can be used to create data processing networks.
+ * @brief A generic data processing network.
+ *
+ * @image html usermanual/images/task_network.png
+ *
+ * This can be used to create arbitrary data processing networks.
  *
  * Each node in the network is a data processing tracker with a particular op
  * code. Tasks created with pt_create() are inserted into the network via the
  * input node and exit the network via the output node. Each processing task
  * is forwarded through the nodes as defined in its sequence of steps
- * (via pt_add_step()), which form the processing chain the task must pass
+ * (via pt_add_step()), which form the processing chain the task must pass,
  * in order to be completed from the "chain link nodes" of the network.
  *
  * The steps are defined as "op codes" that must match an op code of a node in
@@ -30,42 +36,51 @@
  * interpretable data buffers.
  *
  *
+ * A node processing cycle can be started by simply calling:
  *
- *
- *
- * Node procesing can be done by simply calling:
- *
- * pn_process_next()
+ * @code{.c}
+ *	pn_process_next()
+ * @endcode
  *
  * which does all the work and returns the number of tasks processed in the next
  * pending node.
  *
  *
  * This is equivalent to doing it manually:
- *
- * pt = pn_get_next_pending_tracker(pn)
- *
- * while (1) {
- *	t = pn_get_next_pending_task(pt)
- *	ret = pt->op(pt_get_pend_step_op_code(t), t);
- *	if (!pn_eval_task_status(pn, pt, t, ret))
- *		pn_node_to_queue_tail(pn, pt);
- *		abort_processing:
+ * 
+ * @code{.c}
+ *	pt = pn_get_next_pending_tracker(pn);
+ *
+ *	 while (1) {
+ *		t = pn_get_next_pending_task(pt)
+ *		ret = pt->op(pt_get_pend_step_op_code(t), t);
+ *		if (!pn_eval_task_status(pn, pt, t, ret))
+ *			pn_node_to_queue_tail(pn, pt);
+ *			abort_processing:
+ *		}
  *	}
- * }
+ * @endcode
  *
  * This may be used when the call to pt->op() needs special control.
  *
  *
  * Input and output nodes are special, they must be processed explicitly by
  * calling
+ *
+ * @code{.c}
  *	pn_process_inputs(pn);
+ * @endcode
+ *
  * and
+ *
+ * @code{.c}
  *	pn_process_outputs(pn);
+ * @endcode
  *
  * This allows the operator of the processing network to control the I/O rate.
  *
- *
+ * 
+ * @example proc_chain_demo.c
  */
 
 #include <kernel/printk.h>
diff --git a/lib/data_proc_task.c b/lib/data_proc_task.c
index aae5901175064477327419299e3422fdf3ca7f21..55d6467fe48991aeec0cb5a70bb4decaedbe8fae 100644
--- a/lib/data_proc_task.c
+++ b/lib/data_proc_task.c
@@ -1,8 +1,14 @@
 /**
  * @file lib/data_proc_task.c
  *
+ * @ingroup data_proc_task
+ * @defgroup data_proc_task Data Processing Task
  *
- * This manages processing tasks. Each task tracks an arbitrary number of steps
+ * @brief a data processing task
+ *
+ * @image html usermanual/images/proc_task.png
+ *
+ * Each processing task tracks an arbitrary number of steps
  * that each describe the next operation to perform on the data buffer tracked
  * by the processing task. Pending operations are stored in a "todo" list,
  * completed operations are stored in a "done" list.
@@ -16,11 +22,11 @@
  * by the first processing operation.
  *
  * The data buffer need not be tracked in kmalloc() and will not be freed
- * on pt_destroy, but all op_info data are and hence must be allocated
+ * on pt_destroy(), but all op_info data are and hence must be allocated
  * accordingly.
  *
  * The number of elements may be any value that can be interpreted by the
- * prcessing task and need not represent the actual size of the buffer. (They
+ * processing task and need not represent the actual size of the buffer. (They
  * should not exceed the buffer size tho...)
  *
  * The "done" list of processing steps is currently only used to rewind a list
diff --git a/lib/data_proc_tracker.c b/lib/data_proc_tracker.c
index 2bbd71df3d5aad6e7ab5eb5323a63f60702615b5..88394da24199f8f0d071282a767b9b762ea5ab79 100644
--- a/lib/data_proc_tracker.c
+++ b/lib/data_proc_tracker.c
@@ -1,9 +1,32 @@
 /**
  * @file lib/data_proc_tracker.c
  *
+ * @ingroup data_proc_tracker
+ * @defgroup data_proc_tracker Data Processing Task Tracker
  *
- * This is a list based processing task reference tracker.
+ * @brief A processing task reference tracker.
  *
+ * @image html usermanual/images/proc_tracker.png
+ *
+ * A data processing tracker tracks and executes tasks created with
+ * @ref data_proc_task. On creation, an operator function and a corresponding
+ * operation code identifier is assigned to the tracker.
+ *
+ * A critical level of input tasks may be assigned, which may be checked
+ * by the user to quickly determine if a tracker has accumulated a certain
+ * number of tasks for processing. This level is completely arbitrary and
+ * implementation dependent.
+ *
+ * Trackers do no do much themselves, they are essentially containers that
+ * are used as building blocks for a larger processing chain implementation
+ * (e.g. @ref data_proc_net) that manages the propagation of tasks.
+ * A user may add (pt_track_put()), execute (pt_track_execute_next()) and
+ * remove (pt_track_get()) tasks.
+ *
+ * pt_track_execute_next() executes the first item in the task list by feeding
+ * it to the operator function. It is up to the user to evaluate return codes,
+ * manipulate the step list of the @ref data_proc_task and remove it from the
+ * tracker.
  *
  */
 
diff --git a/lib/elf.c b/lib/elf.c
index 56123fdcd82f14a208491881dcb89c58caee5af9..89553fd1a52939164f1a9ea062d162c48b291eb0 100644
--- a/lib/elf.c
+++ b/lib/elf.c
@@ -1,5 +1,11 @@
 /**
  * @file lib/elf.c
+ *
+ * @ingroup elf
+ * @defgroup elf ELF file access
+ *
+ * @brief ELF file access
+ *
  */
 
 
diff --git a/lib/mm.c b/lib/mm.c
index 18c8f9653bf07a3fbe868ffabea67e2de8f570d3..ebb49ff65676a82900f7e4c77b7995c6093dcfa8 100644
--- a/lib/mm.c
+++ b/lib/mm.c
@@ -2,6 +2,10 @@
  *
  * @file lib/mm.c
  *
+ * @ingroup buddy_mm
+ * @defgroup buddy_mm Buddy-System Memory Manager
+ * @brief a buddy-system memory manager
+ *
  * This is a buddy-system memory manager.
  *
  *
@@ -33,6 +37,8 @@
  * chunk from the base and manage it on your own.
  *
  * @todo not atomic
+ *
+ * @example mm_demo.c
  */
 
 
diff --git a/lib/page.c b/lib/page.c
index fa5076c5fbef598fff2d471f8185163d127880a7..a7f48cd972ff8a0c541a1a8b4387916dc5a4dd00 100644
--- a/lib/page.c
+++ b/lib/page.c
@@ -1,6 +1,11 @@
 /**
  * @file kernel/page.c
+ * @ingroup page
+ * @defgroup page Page Map Manager
  *
+ * @brief a page map manager and allocator
+ * 
+ * Manages a memory pool managed by @ref buddy_mm 
  *
  * @note this only ever uses one page map at a time, so if you want to remap
  *	 boot memory, define a new map or just expand the number of nodes in the
diff --git a/lib/processing_tracker_circular.c b/lib/processing_tracker_circular.c
deleted file mode 100644
index ed4c858c8139eb1531437df9f4c6337e440db5c5..0000000000000000000000000000000000000000
--- a/lib/processing_tracker_circular.c
+++ /dev/null
@@ -1,175 +0,0 @@
-/**
- * @file kernel/processing_tracker_circular.c
- *
- *
- * This is a processing task reference tracker, it does NOT make copies of the
- * items stored. The member sizes of a buffer are powers of two, size arguments
- * will be rounded up if necessary.
- *
- * @note deprecated in favour of list based tracker
- */
-
-#include <kernel/printk.h>
-#include <kernel/kmem.h>
-#include <kernel/log2.h>
-#include <kernel/types.h>
-#include <errno.h>
-#include <list.h>
-
-#include <processing_task.h>
-
-
-
-struct proc_tracker{
-	struct proc_task **task;
-
-	size_t rd;
-	size_t wr;
-
-	size_t n;
-	size_t nmemb;
-	size_t mask;
-};
-
-
-/**
- * @brief returns the usage of the tracker
- *
- * @param pt a struct proc_tracker
- *
- * return tracker usage in percent, range 0...100
- */
-
-int pt_track_get_usage(struct proc_tracker *pt)
-{
-	return (pt->n * 100) / pt->nmemb;
-}
-
-
-/**
- * @brief add a new item to the processing tracker
- *
- * @param pt a struct processing_tracker
- *
- * @param t a pointer to a task
- *
- * @returns -1 if full
- */
-
-int pt_track_put(struct proc_tracker *pt,
-		 typeof((*((struct proc_tracker *)0)->task)) t)
-{
-	if (pt->n == pt->nmemb)
-		return -1;
-
-	pt->n++;
-	pt->rd++;
-	pt->rd &= pt->mask;
-
-	pt->task[pt->rd] = t;
-
-
-	return 0;
-}
-
-
-/**
- * @brief get an item from processing tracker
- *
- * @param pt a struct processing_tracker
- *
- * @return processing task item or NULL if empty
- */
-
-typeof((*((struct proc_tracker *)0)->task))
-pt_track_get(struct proc_tracker *pt)
-{
-	if (!pt->n)
-		return NULL;
-
-	pt->n--;
-	pt->wr++;
-	pt->wr &= pt->mask;
-
-	return pt->task[pt->wr];
-}
-
-
-
-/**
- * @brief create a processing tracker
- *
- * @param nmemb the number of elements to track
- *
- * @return processing tracker or NULL on error
- */
-
-struct proc_tracker *pt_track_create(size_t nmemb)
-{
-	struct proc_tracker *pt;
-
-
-	pt = (struct proc_tracker *) kzalloc(sizeof(struct proc_tracker));
-
-	if (!pt)
-		return NULL;
-
-	pt->nmemb = roundup_pow_of_two(nmemb);
-	pt->mask  = pt->nmemb - 1;
-
-	pt->task = (typeof(pt->task)) kzalloc(pt->nmemb *
-					      sizeof(typeof(pt->task)));
-
-	if (!pt->task) {
-		kfree(pt);
-		return NULL;
-	}
-
-
-	return pt;
-}
-
-
-/**
- * @brief expand a processing tracker
- *
- * @param pt a struct processing_tracker
- *
- * @param nmemb the number of extra elements to track
- *
- * @return -1 on error, 0 on success
- */
-
-int pt_track_expand(struct proc_tracker *pt, size_t nmemb)
-{
-	struct proc_tracker tmp;
-
-
-	tmp.task = (typeof(pt->task)) krealloc(pt->task, (pt->nmemb + nmemb) *
-					       sizeof(typeof(pt->task)));
-
-	if (!tmp.task)
-		return -1;
-
-
-	pt->nmemb += nmemb;
-
-	pt->mask = pt->nmemb - 1;
-
-	pt->task = tmp.task;
-
-	return 0;
-}
-
-
-/**
- * @brief destroy a processing tracker
- *
- * @param pt a struct processing_tracker
- */
-
-void pt_track_destroy(struct proc_tracker *pt)
-{
-	kfree(pt->task);
-	kfree(pt);
-}
diff --git a/lib/string.c b/lib/string.c
index 93d0e98e243e8213eaa9e5c6cc4c4dcf0594e7fe..15fa00a7f69fee252e6ca1c4a2d0467c073042fe 100644
--- a/lib/string.c
+++ b/lib/string.c
@@ -1,6 +1,12 @@
 /*+
  * @file lib/string.c
  *
+ * @ingroup string
+ *
+ * @defgroup string String Manipulation
+ *
+ * @brief implememnts generic string manipulation functions
+ *
  * @note some of theses are just wrappers
  * @todo these functions are very generic, for performance, add architecture
  * specific implementations
diff --git a/lib/sysctl.c b/lib/sysctl.c
index 2a37eca11977676373a4e63e097a6e577e83c764..0b4840591d48ab146d1918327c43fdd35cee89b1 100644
--- a/lib/sysctl.c
+++ b/lib/sysctl.c
@@ -15,8 +15,8 @@
  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
  * more details.
  *
- * @defgroup sysctl system control and statistics
- * @brief
+ * @defgroup sysctl System Control Interface
+ * @brief system control interface
  *
  * This system statistics/configuration functionality is tailored/derived
  * from how sysfs/kobjects works in Linux. For obvious reasons, access via a
@@ -44,6 +44,8 @@
  *
  *
  * @note explicit references to linux source files are not always given
+ *
+ * @example sysctl_demo.c
  */
 
 #include <kernel/printk.h>
diff --git a/samples/proc_chain/proc_chain_demo.c b/samples/proc_chain/proc_chain_demo.c
index 1267812105bb189bdc5c15e97b1cf4652bc365cc..81850c2ce11b77caa7513696d764717276388fd9 100644
--- a/samples/proc_chain/proc_chain_demo.c
+++ b/samples/proc_chain/proc_chain_demo.c
@@ -1,7 +1,6 @@
 /**
  * This creates a number processing nodes representing Xentium kernel
  * processing stages. Two special trackers are used for input and output.
- *
  */