summaryrefslogtreecommitdiff
path: root/man/10
diff options
context:
space:
mode:
authorCharles.Forsyth <devnull@localhost>2006-12-22 20:52:35 +0000
committerCharles.Forsyth <devnull@localhost>2006-12-22 20:52:35 +0000
commit46439007cf417cbd9ac8049bb4122c890097a0fa (patch)
tree6fdb25e5f3a2b6d5657eb23b35774b631d4d97e4 /man/10
parent37da2899f40661e3e9631e497da8dc59b971cbd0 (diff)
20060303-partial
Diffstat (limited to 'man/10')
-rw-r--r--man/10/0intro74
-rw-r--r--man/10/2a55
-rw-r--r--man/10/2c437
-rw-r--r--man/10/2l201
-rw-r--r--man/10/5coff82
-rw-r--r--man/10/5cv127
-rw-r--r--man/10/9load411
-rw-r--r--man/10/INDEX263
-rw-r--r--man/10/a.out242
-rw-r--r--man/10/acid373
-rw-r--r--man/10/allocb314
-rw-r--r--man/10/ar98
-rw-r--r--man/10/atoi127
-rw-r--r--man/10/c2l231
-rw-r--r--man/10/conf335
-rw-r--r--man/10/delay36
-rw-r--r--man/10/dev435
-rw-r--r--man/10/devattach701
-rw-r--r--man/10/dmainit86
-rw-r--r--man/10/dynld287
-rw-r--r--man/10/error175
-rw-r--r--man/10/eve42
-rw-r--r--man/10/getfields76
-rw-r--r--man/10/iar183
-rw-r--r--man/10/inb84
-rw-r--r--man/10/inm102
-rw-r--r--man/10/intrenable106
-rw-r--r--man/10/kbdputc105
-rw-r--r--man/10/kproc142
-rw-r--r--man/10/kprof34
-rw-r--r--man/10/ksize29
-rw-r--r--man/10/kstrip32
-rw-r--r--man/10/lock110
-rw-r--r--man/10/malloc81
-rw-r--r--man/10/memory117
-rw-r--r--man/10/mk668
-rw-r--r--man/10/ms258
-rw-r--r--man/10/newchan227
-rw-r--r--man/10/ntsrv69
-rw-r--r--man/10/odbc266
-rw-r--r--man/10/panic25
-rw-r--r--man/10/parsecmd68
-rw-r--r--man/10/plan9.ini789
-rw-r--r--man/10/print402
-rw-r--r--man/10/qio482
-rw-r--r--man/10/qlock106
-rw-r--r--man/10/readnum60
-rw-r--r--man/10/ref61
-rw-r--r--man/10/rune150
-rw-r--r--man/10/seconds64
-rw-r--r--man/10/sleep125
-rw-r--r--man/10/splhi55
-rw-r--r--man/10/srclist41
-rw-r--r--man/10/strcat170
-rw-r--r--man/10/styx364
-rw-r--r--man/10/styxserver611
-rw-r--r--man/10/xalloc70
57 files changed, 11264 insertions, 0 deletions
diff --git a/man/10/0intro b/man/10/0intro
new file mode 100644
index 00000000..dded3a06
--- /dev/null
+++ b/man/10/0intro
@@ -0,0 +1,74 @@
+.TH INTRO 10
+.SH NAME
+intro \- introduction to hosted and native implementation
+.SH DESCRIPTION
+Inferno provides a collection of compiler suites, libraries and two closely-related
+kernels to span a range of host and native platforms.
+Section 10 of this manual is divided into subsections numbered
+in the same way as the main manual: 10.1 for commands, 10.2
+for library and kernel routines, and 10.6 for file formats.
+.PP
+Section 10.1 describes the various compiler and utility commands
+provided to support compilation and cross-compilation of native
+kernels.
+These are derived from similarly named programs of the system Plan 9 from Bell Labs,
+converted to ANSI C to
+provide a consistent, portable environment for cross-compiling
+any native kernel on any host platform.
+.PP
+Section 10.2 describes the functions publicly available to the authors of
+kernel code, particularly device drivers (real and virtual).
+This section will eventually be much expanded, but this makes a start.
+See the description of the conventional header files below.
+.PP
+Section 10.6 describes include the native object file formats,
+the Inferno (Plan 9) object library (archive) format,
+and system configuration files.
+.PP
+Section 10.8 describes bootstrap programs and procedures for
+native Inferno systems.
+.SS Native kernel declarations
+The
+.SM SYNOPSIS
+subsections in section 10.2 do not show the header files needed for
+the standard kernel declarations.
+The primary combinations summarised below:
+.IP
+.RS
+.ta \w'\fL#include 'u
+.nf
+.B
+#include "u.h"
+.B
+#include "../port/lib.h"
+.B
+#include "mem.h"
+.B
+#include "dat.h"
+.B
+#include "fns.h"
+.B
+#include "../port/error.h"
+.PP
+.I "furthermore, added in IP code:"
+.br
+.B
+#include "../ip/ip.h"
+.PP
+.I "furthermore, in hardware device drivers:"
+.br
+.B
+#include "io.h"
+.br
+.B
+#include "ureg.h"
+.PP
+.I "furthermore, in network interfaces or ether drivers:"
+.B
+#include "../port/netif.h"
+.fi
+.RE
+.PP
+There might also be specific include files needed by
+drivers on particular platforms or to use specialised kernel interfaces.
+The easiest method is to check the source of likely-looking drivers nearby.
diff --git a/man/10/2a b/man/10/2a
new file mode 100644
index 00000000..bd9e3357
--- /dev/null
+++ b/man/10/2a
@@ -0,0 +1,55 @@
+.TH 2A 10.1
+.SH NAME
+0a, 1a, 2a, 5a, 6a, 7a, 8a, ka, qa, va \- assemblers
+.SH SYNOPSIS
+.B 2a
+[
+.I option ...
+]
+[
+.I name ...
+]
+.br
+etc.
+.SH DESCRIPTION
+These programs
+assemble the named files into object files
+for the corresponding architectures; see
+.IR 2c (10.1)
+for the correspondence between an architecture and the character
+.RB ( 1 ,
+.RB 2 ,
+etc.) that specifies it.
+The assemblers handle the most common C preprocessor directives and the associated
+command-line options
+.BR -D
+and
+.BR -I .
+Other options are:
+.TP
+.BI -o " obj"
+Place output in file
+.I obj
+(allowed only if there is just one input file).
+Default is to take the last element of the input path name,
+strip any trailing
+.BR .s ,
+and append
+.RI . O ,
+where
+.I O
+is first letter of the assembler's name.
+.SH FILES
+The directory
+.B /sys/include
+is searched for include files after
+machine-dependent files in
+.BR /$objtype/include .
+.SH SOURCE
+.BR /utils/2a ,
+etc.
+.SH SEE ALSO
+.IR 2c (10.1),
+.IR 2l (10.1).
+.PP
+Rob Pike, ``A manual for the Plan 9/Inferno assembler'', Volume 2
diff --git a/man/10/2c b/man/10/2c
new file mode 100644
index 00000000..1e4d9f0a
--- /dev/null
+++ b/man/10/2c
@@ -0,0 +1,437 @@
+.TH 2C 10.1
+.SH NAME
+0c, 1c, 2c, 5c, 6c, 7c, 8c, kc, qc, vc \- C compilers
+.SH SYNOPSIS
+.B 2c
+[
+.I option ...
+]
+[
+.I file ...
+]
+.br
+etc.
+.SH DESCRIPTION
+These commands compile the named C
+.I files
+into object files for the corresponding architecture.
+Associated with each compiler is a string
+.IR objtype ,
+for example
+.TP 1.5i
+.B "0c spim
+Little-endian MIPS
+.TP
+.B "1c 68000
+Motorola MC68000
+.TP
+.B "2c 68020
+Motorola MC68020
+.TP
+.B "5c arm
+ARM 7500
+.TP
+.B "6c amd64
+AMD64 extension to x86
+.TP
+.B "7c alpha
+Digital Alpha APX
+.TP
+.B "8c 386
+Intel i386, i486, Pentium, etc.
+.TP
+.B "kc sparc
+Sun SPARC
+.TP
+.B "qc power
+Power PC,
+.TP
+.B "vc mips
+big-endian MIPS 3000 family
+.PP
+Let the first letter of the compiler name be
+.IR O =
+.BR 0 ,
+.BR 1 ,
+.BR 2 ,
+.BR 5 ,
+.BR 6 ,
+.BR 7 ,
+.BR 8 ,
+.BR k ,
+.BR q ,
+or
+.BR v .
+The output object files end in
+.RI . O .
+The letter is also the prefix of related programs:
+.IB O a
+is the assembler,
+.IB O l
+is the loader.
+.PP
+Plan 9 conventionally sets the
+.B $objtype
+environment variable to the
+.I objtype
+string appropriate to the current machine's type.
+Plan 9 also conventionally has
+.RI / objtype
+directories, which contain among other things:
+.BR include ,
+for machine-dependent include files;
+.BR lib ,
+for public object code libraries;
+.BR bin ,
+for public programs;
+and
+.BR mkfile ,
+for preconditioning
+.IR mk (10.1).
+.PP
+For Inferno cross-compilation on all platforms, not just Plan 9, both
+.B $objtype
+and
+.B $OBJTYPE
+are set by every native kernel
+.B mkfile
+to correspond to the target processor type.
+The Inferno
+.B mkfiles
+also set the
+.B -I
+option appropriately to search the Inferno include directories,
+since the Plan 9 defaults are inappropriate.
+.PP
+The compiler options are:
+.TP 1i
+.BI -o " obj"
+Place output in file
+.I obj
+(allowed only if there is just one input file).
+Default is to take the last element of the input file name,
+strip any trailing
+.BR .c ,
+and append
+.RI . O .
+.TP
+.B -w
+Print warning messages about unused variables, etc.
+.TP
+.B -B
+Accept functions without a new-style
+ANSI C function prototype.
+By default, the compilers reject functions
+used without a defined prototype,
+although ANSI C permits them.
+.TP
+.BI -D\*S name=def
+.br
+.ns
+.TP
+.BI -D \*Sname
+Define the
+.I name
+to the preprocessor,
+as if by
+.LR #define .
+If no definition is given, the name is defined as
+.LR 1 .
+.TP
+.B -F
+Warn when the elements of a format
+(eg, those used by
+.IR print )
+disagree with in type or size with the corresponding parameter,
+or there is a mismatch in number.
+See the discussion of extensions, below.
+.TP
+.BI -I \*Sdir
+An
+.L #include
+file whose name does not begin with
+slash
+or is enclosed in double quotes
+is always
+sought first in the directory
+of the
+.I file
+argument. If this fails,
+the
+.I -.
+flag is given or the name is enclosed in
+.BR <> ,
+it is then sought
+in directories named in
+.B -I
+options,
+then in
+.BR /sys/include ,
+and finally in
+.BR /$objtype/include .
+.TP
+.B -.
+Suppress the automatic searching for include files in
+the directory of the file argument.
+.TP
+.B -N
+Suppress automatic registerization and optimization.
+.TP
+.B -S
+Print an assembly language version of the object code
+on standard output as well as generating the
+.RI . O
+file.
+.TP
+.B -T
+Pass type signatures on all external and global entities.
+The signature is based on the C
+.B signof
+operator,
+an extension in this compiler.
+See
+.IR dynld (10.2).
+.TP
+.B -V
+By default, the compilers are non-standardly lax about type equality between
+.B void*
+values and other pointers; this flag requires ANSI C conformance.
+.TP
+.B -a
+Instead of compiling, print on standard output acid functions (see
+.IR acid (10.1))
+for examining structures declared in the source files.
+.TP
+.B -aa
+Like
+.B -a
+except suppress information about structures
+declared in included header files.
+.PP
+The compilers handle most preprocessing directives themselves, but support
+excludes the
+.B #if
+and
+.B #elif
+directives, and the
+.B ##
+preprocessor operation.
+.PP
+The compilers support several extensions to ANSI C:
+.TP
+\-
+A structure or union may contain unnamed substructures and subunions.
+The fields of the substructures or
+subunions can then be used as if they were members of the parent
+structure or union (the resolution of a name conflict is unspecified).
+When a pointer to the outer structure or union is used in a context
+that is only legal for the unnamed substructure, the compiler promotes
+the type and adjusts the pointer value to point at the substructure.
+If the unnamed structure or union is of a type with a tag name specified by a
+.B typedef
+statement,
+the unnamed structure or union can be explicitly referenced
+by <struct variable>.<tagname>.
+.TP
+\-
+A structure value can be formed with an expression such as
+.EX
+ (struct S){v1, v2, v3}
+.EE
+where the list elements are values for the fields of struct
+.BR S .
+.TP
+\-
+Array initializers can specify the indices of the array in square
+brackets, as
+.EX
+ int a[] = { [3] 1, [10] 5 };
+.EE
+which initializes the third and tenth elements of the eleven-element array
+.BR a .
+.TP
+\-
+Structure initializers can specify the structure element by using the name
+following a period, as
+.EX
+ struct { int x; int y; } s = { .y 1, .x 5 };
+.EE
+which initializes elements
+.B y
+and then
+.B x
+of the structure
+.BR s .
+These forms also accept the new ANSI C notation, which includes an equal sign:
+.EX
+ int a[] = { [3] = 1, [10] = 5 };
+ struct { int x; int y; } s = { .y = 1, .x = 5 };
+.EE
+.TP
+\-
+A global variable can be dedicated to a register
+by declaring it
+.B "extern register"
+in
+.I all
+modules and libraries.
+.TP
+\-
+A
+.B #pragma
+of the form
+.EX
+ #pragma lib "libbio.a"
+.EE
+records that the program needs to be loaded with file
+.BR /$objtype/lib/libbio.a ;
+such lines, typically placed in library header files, obviate the
+.B -l
+option of the loaders. To help identify files in non-standard directories,
+within the file names in the
+.B #pragmas
+the string
+.B $M
+represents the name of the architecture
+(e.g.,
+.BR mips )
+and
+.B $O
+represents its identifying character
+(e.g.,
+.BR v ).
+.TP
+\-
+Two
+.B #pragma
+requests to define rules for checking
+.IR print -like
+formats (see the
+.B -F
+option above).
+One
+.B #pragma
+tells for a given routine which argument is the format.
+For example:
+.EX
+ #pragma varargck argpos print 1
+ #pragma varargck argpos sprint 2
+.EE
+say that
+.I print
+has a format as its first argument,
+and
+.I sprint
+has one as its second.
+Another
+.B #pragma
+associates format character sequences and types:
+.EX
+ #pragma varargck type "lld" vlong
+ #pragma varargck type "lx" void*
+ #pragma varargck type "S" Rune*
+.EE
+where the format characters are those following the
+.B %
+in the format (ignoring any preceding formatting flags).
+Note the assumption that all formats arguments are compatible.
+The system include files have appropriate
+.B #pragma
+lines for the standard format elements and formatting functions.
+.TP
+\-
+A
+.B #pragma
+of the form
+.EX
+ #pragma incomplete \fItype\fP
+.EE
+tells the compiler that
+.I type
+should have its signature calculated as an incomplete type
+even when it is fully defined.
+This allows the type signature mechanism to work in the presence
+of opaque types declared in header files, with their full definitions
+visible only to the code which manipulates them.
+With some imported software it might be necessary to turn off the
+signature generation completely for a large body of code (typically
+at the start and end of a particular include file).
+If
+.I type
+is the word
+.BR _off_ ,
+signature generation is turned off; if
+.I type
+is the word
+.BR _on_ ,
+the compiler will generate signatures.
+.TP
+\-
+The C++ comment
+.RB ( //
+to end of line)
+is accepted as well as the normal
+convention of
+.B /*
+.BR */ .
+.TP
+\-
+The compilers accept
+.B long
+.B long
+variables as a 64-bit type.
+The standard header typedefs this to
+.BR vlong .
+Arithmetic on
+.B vlong
+values is usually emulated by a run-time library.
+.SH EXAMPLE
+For the 68020, produce a program
+.B prog
+from C files
+.BR main.c
+and
+.BR sub.c :
+.IP
+.EX
+2c -FVw main.c sub.c
+2l -o prog main.2 sub.2
+.EE
+.SH FILES
+.TF /$objtype/include
+.TP
+.B /sys/include
+host system area for machine-independent
+.B #include
+directives.
+.TP
+.B /$objtype/include
+host system area for machine-dependent
+.B #include
+directives.
+.SH SOURCE
+.TF /utils/2c,\ etc.
+.TP
+.B /utils/cc
+machine-independent part
+.TP
+.BR /utils/2c ,\ etc.
+machine-dependent part
+.SH "SEE ALSO"
+.IR 2a (10.1),
+.IR 2l (10.1),
+.IR mk (10.1),
+.IR inm (10.1),
+.IR acid (10.1),
+.PP
+Rob Pike,
+``How to Use the Plan 9 C Compiler''
+.SH BUGS
+The preprocessor only handles
+.LR #define ,
+.LR #include ,
+.LR #undef ,
+.LR #ifdef ,
+.LR #line ,
+and
+.LR #ifndef .
diff --git a/man/10/2l b/man/10/2l
new file mode 100644
index 00000000..c2bf1998
--- /dev/null
+++ b/man/10/2l
@@ -0,0 +1,201 @@
+.TH 2L 10.1
+.SH NAME
+0l, 1l, 2l, 5l, 6l, 7l, 8l, kl, ql, vl \- loaders
+.SH SYNOPSIS
+.B 2l
+[
+.I option ...
+]
+[
+.I file ...
+]
+.br
+etc.
+.SH DESCRIPTION
+These commands load the named
+.I files
+into executable files for the corresponding architectures; see
+.IR 2c (10.1)
+for the correspondence between an architecture and the character
+.RB ( 1 ,
+.BR 2 ,
+etc.)
+that specifies it.
+The files should be object files or libraries (archives of object files)
+for the appropriate architecture.
+Also, a name like
+.BI -l ext
+represents the library
+.BI lib ext .a
+in
+.BR /$objtype/lib ,
+where
+.I objtype
+is one of
+.BR 68000 ,
+etc. as listed in
+.IR 2c (10.1).
+The libraries must have tables of contents
+(see
+.IR iar (10.1)).
+.PP
+In practice,
+.B -l
+options are rarely necessary as the header files for
+the libraries cause their archives to be included automatically in the load
+(see
+.IR 2c (10.1)).
+For example, any program that includes header file
+.B libc.h
+causes the loader
+to search the C library
+.BR /$objtype/lib/libc.a .
+Also, the loader creates an undefined symbol
+.B _main
+(or
+.B _mainp
+if profiling is enabled) to force loading of the
+startup linkage from the C library.
+.PP
+The order of search to resolve undefined symbols is to load all files and libraries
+mentioned explicitly on the command line, and then to resolve remaining symbols
+by searching in topological order
+libraries mentioned in header files included by files already loaded.
+When scanning such libraries, the algorithm is to scan each library repeatedly until
+no new undefined symbols are picked up, then to start on the next library. Thus if library
+.I A
+needs
+.I B
+which needs
+.I A
+again, it may be necessary to mention
+.I A
+explicitly so it will be read a second time.
+.PP
+The loader options are:
+.TP 1i
+.B -l
+(As a bare option.)
+Suppress the default loading of the startup linkage and libraries
+specified by header files.
+.TP
+.BI -o " out"
+Place output in file
+.IR out .
+Default is
+.IB O .out\f1,
+where
+.I O
+is the first letter of the loader name.
+.TP
+.B -p
+Insert profiling code into the executable output; no special action is needed
+during compilation or assembly.
+.TP
+.B -s
+Strip the symbol tables from the output file.
+.TP
+.B -a
+Print the object code in assembly language, with addresses.
+.TP
+.B -v
+Print debugging output that annotates the activities of the load.
+.TP
+.BI -M
+.RI ( kl
+only) Generate instructions rather than calls to emulation routines
+for multiply and divide.
+.TP
+.BI -E symbol
+The entry point for the binary is
+.I symbol
+(default
+.BR _main ;
+.B _mainp
+under
+.BR -p ).
+.TP
+.B -x
+[
+.I file
+]
+Produce an export table in the executable.
+The optional
+.I file
+restricts the exported symbols to those listed in the file.
+See
+.IR dynld (10.2).
+.TP
+.B -u
+[
+.I file
+]
+Produce an export table, import table
+and a dynamic load section in the executable.
+The optional
+.I file
+restricts the imported symbols to those listed in the file.
+See
+.IR dynld (10.2).
+.TP
+.BI -H n
+Executable header is type
+.IR n .
+The meaning of the types is architecture-dependent; typically
+type 1 is Plan 9 boot format and type 2 is the
+regular Plan 9 format, the default. These are reversed on the MIPS.
+The Next boot format is 3. Type 4 in
+.I vl
+creates a MIPS executable for an SGI Unix system.
+.TP
+.BI -T t
+The text segment starts at address
+.IR t .
+.TP
+.BI -D d
+The data segment starts at address
+.IR d .
+.TP
+.BI -R r
+The text segment is rounded to a multiple of
+.I r
+(if
+.I r
+is nonzero).
+.PP
+The numbers in the above options can begin with
+.L 0x
+or
+.L 0
+to change the default base from decimal to hexadecimal or octal.
+The defaults for the values depend on the compiler and the
+header type.
+.PP
+The loaded image has several symbols inserted by the loader:
+.B etext
+is the address of the end of the text segment;
+.B bdata
+is the address of the beginning of the data segment;
+.B edata
+is the address of the end of the data segment;
+and
+.B end
+is the address of the end of the bss segment, and of the program.
+.SH FILES
+.TF /$objtype/lib
+.TP
+.B /$objtype/lib
+for
+.BI -l lib
+arguments.
+.SH SOURCE
+.B /utils/2l
+etc.
+.SH "SEE ALSO"
+.IR 2c (10.1),
+.IR 2a (10.1),
+.IR iar (10.1),
+.IR inm (10.1)
+.PP
+Rob Pike,
+``How to Use the Plan 9 C Compiler''
diff --git a/man/10/5coff b/man/10/5coff
new file mode 100644
index 00000000..f32443f1
--- /dev/null
+++ b/man/10/5coff
@@ -0,0 +1,82 @@
+.TH 5COFF 10.1
+.SH NAME
+5coff \- converter to coff format
+.SH SYNOPSIS
+.B 5coff
+[
+.B -T
+.I t
+]
+[
+.B -D
+.I d
+]
+[
+.B -R
+.I r
+]
+[
+.B -E
+.I e
+]
+[
+.B -d
+]
+.I ifile ofile
+.SH DESCRIPTION
+.I 5coff
+converts an executable file
+.I ifile
+in
+.IR a.out (10.6)
+format as
+produced by
+.I 5l
+(see
+.IR 2l (10.1))
+to one in
+.SM COFF
+format, which it writes to
+.IR ofile .
+The options to
+.I 5coff
+are as follows:
+.TP
+.BI -T t
+The text segment starts at address
+.I t.
+.TP
+.BI -D d
+The data segment starts at address
+.I d.
+.TP
+.BI -R r
+The text segment is rounded up to a multiple of
+.I r
+if non-zero.
+.TP
+.BI -E e
+The entry point is at address
+.I e.
+.TP
+.B -d
+Print debugging information.
+.PP
+.SH EXAMPLE
+An executable built with the command
+.IP
+.EX
+5l -T0x04010000 -R4 -o abc ...
+.EE
+.PP
+can be converted to coff format by
+.IP
+.EX
+5coff -T0x04010000 -R4 abc abc.coff
+.EE
+.SH SOURCE
+.B /utils/5coff
+.SH SEE ALSO
+.IR 2l (10.1),
+.IR 5cv (10.1),
+.IR a.out (10.6)
diff --git a/man/10/5cv b/man/10/5cv
new file mode 100644
index 00000000..25469ce5
--- /dev/null
+++ b/man/10/5cv
@@ -0,0 +1,127 @@
+.TH 5CV 10.1
+.SH NAME
+5cv, mkppcimage, sqz \- convert kernel executable to boot format
+.SH SYNOPSIS
+.B 5cv
+[
+.BI -D n
+] [
+.BI -H n
+] [
+.B -s
+]
+.I "executable outfile"
+.PP
+.B mkppcimage
+[
+.BI -l " loadaddr"
+]
+.I "executable outfile"
+.PP
+.B sqz
+[
+.B -w
+] [
+.B -t
+]
+.I executable
+.SH DESCRIPTION
+These commands convert a kernel executable in Inferno/Plan 9
+.IR a.out (10.5)
+format into another
+format used by a third party's boot loader.
+Most convert the input
+.I executable
+and write the new format to
+.IR outfile .
+.PP
+.IR 5cv
+converts an ARM executable into one of several alternative formats.
+The output format is controlled by the
+.B -H
+option:
+.TP 8n
+.BI -H1
+AIF for RISCOS.
+.TP
+.BI -H2
+Plan 9.
+.TP
+.BI -H3
+Boot for NetBSD.
+.TP
+.BI -H4
+Headerless, stripped, and padded to 2K in length. Used for the ROM resident serial
+bootstrap
+loader in a Cirrus EP72xx.
+.TP
+.BI -H5
+Headerless, and stripped, for general use.
+.TP
+.BI -H6
+EPOC IMG format. Not a complete conversion, currently sufficient for use with some
+NT based downloaders which autosense the file type by the "EP" signature, and then
+ignore the contents of the header.
+.PP
+The other options are:
+.TP
+.BI -s
+Strip symbol table.
+.TP
+.BI -D n
+Enables debug output.
+.PP
+.I Mkppcimage
+converts a PowerPC or ARM
+.I executable
+to a boot image format used by
+.SM PPCBOOT
+and
+.SM UBOOT\c
+\&.
+The output file has a
+.SM PPCBOOT
+image with one component labelled as an `OS kernel' for the appropriate architecture,
+containing the
+.IR a.out (10.6)
+header, text and initialised data, all uncompressed.
+Symbols are not included.
+By default the load address is deduced from the executable's entry point;
+the
+.B -l
+option allows
+.I loadaddr
+to be set explicitly, with the number in C syntax (decimal by default).
+Other attributes are deduced from the executable.
+.PP
+.I Sqz
+squeezes (compresses) the given
+ARM or PowerPC
+.I executable
+using a method that achieves respectable compression for executables but is much faster to decompress than
+(say)
+.BR gzip 's.
+By default, both the program text and initialised data are compressed; the
+.B -t
+option causes
+.I sqz
+to compress only the program text, leaving the data as-is.
+By default,
+.I sqz
+prints compression statistics on its standard error output;
+the
+.B -w
+option causes it also to write the compressed file on its standard output.
+Either the bootstrap that loads it must decompress the result, or a small uncompressed
+stub must also be loaded that decompresses the remainder.
+.SH SOURCE
+.B /utils/5cv
+.br
+.B /utils/mkppcimage
+.br
+.B /utils/sqz
+.SH "SEE ALSO"
+.IR 2l (10.1),
+.IR 5cv (10.1),
+.IR ms2 (10.1),
+.IR a.out (10.5)
diff --git a/man/10/9load b/man/10/9load
new file mode 100644
index 00000000..b1c696c3
--- /dev/null
+++ b/man/10/9load
@@ -0,0 +1,411 @@
+.TH 9LOAD 10.8
+.SH NAME
+9load, ld, 9pxeload \- PC bootstrap program
+.SH SYNOPSIS
+.I "(Under MS-DOS)
+.br
+[
+.I drive
+:][
+.I path
+.RB ] ld
+[
+.I 9load
+]
+.SH DESCRIPTION
+On the PC, bootstrap programs from Plan 9 are used to boot Inferno as well
+(hence the naming convention).
+.I 9load
+and
+.I ld
+are programs that reside in a FAT file system and bootstrap Inferno.
+.I 9load
+loads the kernel, but it cannot be run from DOS; use
+.I ld
+to bootstrap (by starting
+.IR 9load )
+if DOS is running.
+.I 9load
+is run automatically by the boot procedures described below;
+it cannot be run directly by hand.
+There are three bootstrap sequences:
+.IP \-
+BIOS, MBR, disk partition PBS,
+.IR 9load ,
+kernel
+.IP \-
+BIOS, floppy PBS,
+.IR 9load ,
+kernel
+.IP \-
+BIOS, MBR, DOS,
+.IR ld ,
+.IR 9load ,
+kernel.
+.PP
+Details follow.
+.PP
+.I 9load
+is a bootstrap program that loads and starts a program,
+typically the kernel, on a PC.
+It is run by the PC partition boot sector program (PBS),
+which usually resides in the first
+sector of the active partition.
+A copy of the Plan 9 PBS is kept in
+.BR /Inferno/386/pbs ,
+but due to the ``cylinder-head-sector'' (CHS) addressing mode of old BIOSes, it can only
+operate up to 8.5GB into the disk.
+Plan 9 partitions further into the disk
+can only be booted using
+.BR /Inferno/386/pbslba ,
+and then only if the machine's BIOS supports
+linear block addressing (LBA) mode for disk transfers.
+.PP
+When booting from floppy or hard disk, the BIOS loads the
+first sector of the medium at location 0x7C00. In the
+case of a floppy, this is the PBS. In the case of a hard
+disk it it the master boot record (MBR).
+The MBR copies itself to address
+.BR 0x600 ,
+finds the active partition and loads its PBS at address
+.BR 0x7C00 .
+A copy of the Plan 9 MBR is kept in
+.BR /Inferno/386/mbr ;
+some commercial MBRs cannot read sectors
+past 2GB.
+The Plan 9 MBR can read sectors up to 8.5GB into
+the disk, and further if the BIOS supports LBA.
+The single file
+.B /Inferno/386/mbr
+detects whether the BIOS supports LBA and
+acts appropriately, defaulting to CHS mode
+when LBA is not present.
+The PBSs cannot do this due to code size considerations.
+The Plan 9 MBR is suitable for booting non-Plan 9
+operating systems,
+and (modulo the large disk constraints just described)
+non-Plan 9 MBRs are suitable for booting Plan 9.
+.PP
+Thus the default sequence is: BIOS, MBR, PBS,
+.IR 9load ,
+kernel.
+.PP
+Because it contains many device drivers for different
+disks and networks,
+.I 9load
+is larger than 64K and cannot be run as a DOS
+.RB `` .com ''
+executable.
+A stripped-down version that knows about disks but not networks,
+called
+.I ld
+(really
+.BR ld.com ),
+fits in 64K and can be used under DOS to load and start a program (default
+.IR 9load )
+from the FAT16 partition.
+Its command line argument is of the same format as the
+.I bootfile
+specifiers described below.
+This profusion of loaders is unfortunate, but at least
+.I ld
+and
+.I 9load
+are compiled from the same source.
+.PP
+.I 9load
+begins execution at address
+.B 0x80010000
+(64K) and
+loads the
+.I bootfile
+at the entry address specified by the header,
+usually
+.BR 0x80100020 .
+After loading, control is passed to the entry location.
+.PP
+Finally,
+.I 9pxeload
+is a version of
+.I 9load
+that can be booted using the PXE download
+found on some ethernet card BIOSs.
+.PP
+In summary,
+Inferno and Plan 9 can be booted on a PC three different ways:
+either by booting MS-DOS and using
+.I ld
+to start
+.I 9load
+in the appropriate directory,
+by booting directly from an Inferno/Plan 9 boot floppy or disk
+partition
+prepared using
+.B format
+to install the appropriate files and bootstrap sectors
+(see
+.IR prep (8)),
+or by using a PXE capable BIOS to boot
+.I 9pxeload
+directly over the ethernet.
+.PP
+The
+.IR bootfile ,
+which may be compressed with
+.IR gzip (1),
+can be specified to
+.I 9load
+as a
+.B bootfile=
+entry in
+.IR plan9.ini ,
+or if booting from the ethernet, by a BOOTP server.
+If the
+.B plan9.ini
+file contains multiple
+.B bootfile=
+entries,
+.I 9load
+will present a numerical menu of the choices; type
+the corresponding number to select an entry.
+.PP
+The format of the
+.I bootfile
+name is
+.IB device ! file
+or
+.IB device ! partition ! file\f1.
+If
+.BI ! file
+is omitted, the default for the particular
+.I device
+is used.
+Supported
+.I devices
+are
+.TF \fLethern
+.TP
+.BI fd n
+An MS-DOS floppy disk.
+.I N
+specifies the floppy drive, either
+0 or 1.
+The
+.I bootfile
+is the contents of the MS-DOS
+.IR file .
+There is no default file.
+For compatibility with hard disks, a
+.I partition
+may be given, but only
+.B dos
+is recognized:
+.BI fd0!dos! file\f1.
+.TP
+.BI ether n
+Ethernet.
+.I N
+specifies the Ethernet device number.
+If a
+.I partition
+is specified, it is taken to be the name of a host machine
+from which to load the kernel.
+.I file
+is determined by the
+.B /lib/ndb
+(see
+.IR ndb (6))
+entry for this PC.
+.TP
+.BI sd Cn
+Non-floppy disk.
+The device name format is described in
+.IR sd (3).
+A
+.I partition
+must be given and must
+name a partition containing a FAT file system.
+The name
+.B dos
+refers to the first DOS partition on a given device.
+It is common for Inferno/Plan 9 partitions to contain a small
+FAT file system for configuration.
+By convention, this partition is called
+.BR 9fat .
+There is no default partition or pathname.
+.PD
+.PP
+When
+.I 9load
+starts running at physical address 0x10000,
+it switches to 32-bit mode.
+It then double maps the first 16Mb of physical memory to
+virtual addresses 0 and 0x80000000.
+Physical memory from 0x300000 upwards is used as data
+space.
+Next, in order to find configuration information,
+.I 9load
+searches all units on devices
+.BR fd
+and
+.BI sd Cn \fR,
+in that order, for a file called
+.B plan9\eplan9.ini
+or
+.B plan9.ini
+(see
+.IR plan9.ini (10.6))
+on a partition named
+.B dos
+or
+.BR 9fat .
+If one is found, searching stops and the file is read into memory
+at physical address 0x1200
+where it can be found later by any loaded
+.IR bootfile .
+Some options in
+.B plan9.ini
+are used by
+.IR 9load :
+.TF bootfile=manual
+.TP
+.B console
+.TP
+.B baud
+Specifies the console device and baud rate if not a display.
+.TP
+.BI ether n
+Ethernet interfaces. These can be used to load the
+.I bootfile
+over a network.
+Probing for Ethernet interfaces is too prone to error.
+.TP
+.BI bootfile= bootfile
+Specifies the
+.IR bootfile .
+This option is overridden by a command-line argument.
+.TP
+.B bootfile=auto
+Default.
+.TP
+.B bootfile=local
+Like
+.IR auto ,
+but do not attempt to load over the network.
+.TP
+.B bootfile=manual
+After determining which devices are available for loading from,
+enter prompt mode.
+.PD
+.PP
+When the search for
+.B plan9.ini
+is done,
+.I 9load
+proceeds to determine which bootfile to load.
+If there was no
+.I bootfile
+option,
+.I 9load
+chooses a default
+from the following prioritized device list:
+.EX
+ fd sd ether
+.EE
+.I 9load
+then attempts to load the
+.I bootfile
+unless
+the
+.B bootfile=manual
+option was given, in which case prompt mode is entered immediately.
+If the default device is
+.BR fd ,
+.I 9load
+will prompt the user for input before proceeding with the
+default bootfile load after 5 seconds;
+this prompt is omitted if
+a command-line argument or
+.I bootfile
+option
+was given.
+.PP
+.I 9load
+prints the list of available
+.IR device s
+and
+enters prompt mode on encountering any error
+or if directed to do so by a
+.B bootfile=manual
+option.
+In prompt mode, the user is required to type
+a
+.IB bootfile
+in response to the
+.L "Boot from:
+prompt.
+.PP
+.I 9load
+parses the master boot record and Plan 9 partition tables
+(see
+.IR prep (8)),
+leaving partitioning information appended to the
+in-memory contents of
+.I plan9.ini
+for the
+.IR bootfile .
+This is used by
+.IR sd (3)
+to initialize partitions so that a
+file system in a partition can be found and mounted as the root file system.
+A more extensive partitioning is typically done by system initialisation in
+.B osinit.dis
+(see
+.IR root (3)).
+.PP
+A
+control-P
+character typed at any time on the console causes
+.B 9load
+to perform a hardware reset
+(Ctrl-Alt-Del can also be used on a PC keyboard).
+.PP
+When loaded from a PBS (rather than from
+.IR ld.com ),
+.I 9load
+must be contiguously allocated on
+the disk.
+See
+.IR dossrv (4)
+for information on ensuring this.
+.SH FILES
+.RI [ drive :]
+[
+.I path
+.RB ] 9load
+.br
+.RI [ drive :]
+[
+.I path
+.RB ] ld
+.br
+.IB "FAT filesystem" :\eplan9\eplan9.ini
+.br
+.IB "FAT filesystem" :\eplan9.ini
+.SH SOURCE
+.B /os/boot/pc
+.SH "SEE ALSO"
+.IR plan9.ini (10.6),
+.IR prep (8)
+.SH BUGS
+Much of the work done by
+.B 9load
+is duplicated by the loaded kernel.
+.PP
+If
+.I ld
+detects an installed MS-DOS Extended Memory Manager,
+it attempts to de-install it, but the technique
+used may not always work.
+It is safer not to install the Extended Memory Manager before running
+.IR ld .
diff --git a/man/10/INDEX b/man/10/INDEX
new file mode 100644
index 00000000..fedbc2c9
--- /dev/null
+++ b/man/10/INDEX
@@ -0,0 +1,263 @@
+intro 0intro
+0a 2a
+1a 2a
+2a 2a
+5a 2a
+6a 2a
+7a 2a
+8a 2a
+ka 2a
+qa 2a
+va 2a
+0c 2c
+1c 2c
+2c 2c
+5c 2c
+6c 2c
+7c 2c
+8c 2c
+kc 2c
+qc 2c
+vc 2c
+0l 2l
+1l 2l
+2l 2l
+5l 2l
+6l 2l
+7l 2l
+8l 2l
+kl 2l
+ql 2l
+vl 2l
+5coff 5coff
+5cv 5cv
+mkppcimage 5cv
+sqz 5cv
+9load 9load
+9pxeload 9load
+ld 9load
+a.out a.out
+acid acid
+adjustblock allocb
+allocb allocb
+blen allocb
+blocklen allocb
+checkb allocb
+concatblock allocb
+copyblock allocb
+freeb allocb
+freeblist allocb
+iallocb allocb
+packblock allocb
+padblock allocb
+pullblock allocb
+pullupblock allocb
+trimblock allocb
+ar ar
+atoi atoi
+atol atoi
+charstod atoi
+strtod atoi
+strtol atoi
+strtoll atoi
+strtoul atoi
+c2l c2l
+conf conf
+addclock0link delay
+delay delay
+microdelay delay
+dev dev
+devattach devattach
+devbread devattach
+devbwrite devattach
+devclone devattach
+devcreate devattach
+devdir devattach
+devdirread devattach
+devgen devattach
+devinit devattach
+devopen devattach
+devremove devattach
+devreset devattach
+devshutdown devattach
+devstat devattach
+devwalk devattach
+devwstat devattach
+openmode devattach
+dmacount dmainit
+dmadone dmainit
+dmaend dmainit
+dmainit dmainit
+dmasetup dmainit
+dynfindsym dynld
+dynfreeimport dynld
+dynld dynld
+dynloadfd dynld
+dynloadgen dynld
+dynobjfree dynld
+dyntabsize dynld
+error error
+nexterror error
+poperror error
+waserror error
+eve eve
+iseve eve
+getfields getfields
+tokenize getfields
+iar iar
+inb inb
+inl inb
+ins inb
+insb inb
+insl inb
+inss inb
+outb inb
+outl inb
+outs inb
+outsb inb
+outsl inb
+outss inb
+inm inm
+intrdisable intrenable
+intrenable intrenable
+kbdclock kbdputc
+kbdputc kbdputc
+kbdq kbdputc
+kbdrepeat kbdputc
+kproc kproc
+pexit kproc
+setpri kproc
+swiproc kproc
+kprof kprof
+ksize ksize
+kstrip kstrip
+canlock lock
+ilock lock
+iunlock lock
+lock lock
+unlock lock
+calloc malloc
+free malloc
+malloc malloc
+mallocz malloc
+realloc malloc
+smalloc malloc
+memccpy memory
+memchr memory
+memcmp memory
+memcpy memory
+memmove memory
+memory memory
+memset memory
+mk mk
+ms2 ms2
+cclose newchan
+chanfree newchan
+eqchan newchan
+eqqid newchan
+fdtochan newchan
+isdir newchan
+namec newchan
+newchan newchan
+ntsrv ntsrv
+odbc odbc
+panic panic
+parsecmd parsecmd
+plan9.ini plan9.ini
+fprint print
+print print
+seprint print
+smprint print
+snprint print
+sprint print
+vfprint print
+vseprint print
+vsmprint print
+vsnprint print
+qbread qio
+qbwrite qio
+qcanread qio
+qclose qio
+qconsume qio
+qcopy qio
+qdiscard qio
+qflush qio
+qfree qio
+qfull qio
+qget qio
+qhangup qio
+qio qio
+qiwrite qio
+qlen qio
+qnoblock qio
+qopen qio
+qpass qio
+qproduce qio
+qread qio
+qreopen qio
+qsetlimit qio
+qwindow qio
+qwrite qio
+canqlock qlock
+qlock qlock
+qunlock qlock
+rlock qlock
+runlock qlock
+wlock qlock
+wunlock qlock
+readnum readnum
+readstr readnum
+decref ref
+incref ref
+ref ref
+chartorune rune
+fullrune rune
+rune rune
+runelen rune
+runetochar rune
+utflen rune
+utfrrune rune
+utfrune rune
+utfutf rune
+hz seconds
+ms2hz seconds
+ms2tk seconds
+seconds seconds
+ticks seconds
+tk2ms seconds
+tk2sec seconds
+return0 sleep
+sleep sleep
+tsleep sleep
+wakeup sleep
+islo splhi
+splhi splhi
+spllo splhi
+splx splhi
+srclist srclist
+strcat strcat
+strchr strcat
+strcmp strcat
+strcpy strcat
+strdup strcat
+strlen strcat
+strncmp strcat
+strncpy strcat
+strrchr strcat
+strstr strcat
+convd2m styx
+convm2d styx
+convm2s styx
+convs2m styx
+dirfmt styx
+dirmodefmt styx
+fcall styx
+fcallfmt styx
+sized2m styx
+sizes2m styx
+statcheck styx
+styx styx
+styxserver styxserver
+xalloc xalloc
+xfree xalloc
+xspanalloc xalloc
diff --git a/man/10/a.out b/man/10/a.out
new file mode 100644
index 00000000..6e5841d0
--- /dev/null
+++ b/man/10/a.out
@@ -0,0 +1,242 @@
+.TH A.OUT 10.6
+.SH NAME
+a.out \- native kernel object file format
+.SH SYNOPSIS
+.B #include <a.out.h>
+.SH DESCRIPTION
+An executable native binary file has up to six sections:
+a header, the program text, the data,
+a symbol table, a PC/SP offset table (MC680x0 only),
+and finally a PC/line number table.
+The header, given by a structure in
+.BR <a.out.h> ,
+contains 4-byte integers in big-endian order:
+.PP
+.EX
+typedef struct Exec {
+ long magic; /* magic number */
+ long text; /* size of text segment */
+ long data; /* size of initialized data */
+ long bss; /* size of uninitialized data */
+ long syms; /* size of symbol table */
+ long entry; /* entry point */
+ long spsz; /* size of pc/sp offset table */
+ long pcsz; /* size of pc/line number table */
+} Exec;
+#define _MAGIC(b) ((((4*b)+0)*b)+7)
+#define A_MAGIC _MAGIC(8) /* 68020 */
+#define I_MAGIC _MAGIC(11) /* intel 386 */
+#define J_MAGIC _MAGIC(12) /* intel 960 */
+#define K_MAGIC _MAGIC(13) /* sparc */
+#define V_MAGIC _MAGIC(16) /* mips 3000 */
+#define X_MAGIC _MAGIC(17) /* att dsp 3210 */
+#define M_MAGIC _MAGIC(18) /* mips 4000 */
+#define D_MAGIC _MAGIC(19) /* amd 29000 */
+#define E_MAGIC _MAGIC(20) /* arm 7-something */
+#define Q_MAGIC _MAGIC(21) /* powerpc */
+#define N_MAGIC _MAGIC(22) /* mips 4000-le */
+#define L_MAGIC _MAGIC(23) /* dec alpha */
+.EE
+.DT
+.PP
+Sizes are expressed in bytes.
+The size of the header is not included in any of the other sizes.
+.PP
+When a Plan 9 binary file is executed,
+a memory image of three segments is
+set up: the text segment, the data segment, and the stack.
+The text segment begins at a virtual address which is
+a multiple of the machine-dependent page size.
+The text segment consists of the header and the first
+.B text
+bytes of the binary file.
+The
+.B entry
+field gives the virtual address of the entry point of the program.
+The data segment starts at the first page-rounded virtual address
+after the text segment.
+It consists of the next
+.B data
+bytes of the binary file, followed by
+.B bss
+bytes initialized to zero.
+The stack occupies the highest possible locations
+in the core image, automatically growing downwards.
+.PP
+The next
+.B syms
+(possibly zero)
+bytes of the file contain symbol table
+entries, each laid out as:
+.IP
+.EX
+uchar value[4];
+char type;
+char name[\f2n\fP]; /* NUL-terminated */
+.EE
+.PP
+The
+.B value
+is in big-endian order and
+the size of the
+.B name
+field is not pre-defined: it is a zero-terminated array of
+variable length.
+.PP
+The
+.B type
+field is one of the following characters:
+.RS
+.TP
+.B T
+text segment symbol
+.PD0
+.TP
+.B t
+static text segment symbol
+.TP
+.B L
+leaf function text segment symbol
+.TP
+.B l
+static leaf function text segment symbol
+.TP
+.B D
+data segment symbol
+.TP
+.B d
+static data segment symbol
+.TP
+.B B
+bss segment symbol
+.TP
+.B b
+static bss segment symbol
+.TP
+.B a
+automatic (local) variable symbol
+.TP
+.B p
+function parameter symbol
+.RE
+.PD
+.PP
+A few others are described below.
+The symbols in the symbol table appear in the same order
+as the program components they describe.
+.PP
+The Plan 9 compilers implement a virtual stack frame pointer rather
+than dedicating a register;
+moreover, on the MC680x0
+there is a variable offset between the stack pointer and the
+frame pointer.
+Following the symbol table,
+MC680x0 executable files contain a
+.BR spsz -byte
+table encoding the offset
+of the stack frame pointer as a function of program location;
+this section is not present for other architectures.
+The PC/SP table is encoded as a byte stream.
+By setting the PC to the base of the text segment
+and the offset to zero and interpreting the stream,
+the offset can be computed for any PC.
+A byte value of 0 is followed by four bytes that hold, in big-endian order,
+a constant to be added to the offset.
+A byte value of 1 to 64 is multiplied by four and added, without sign
+extension, to the offset.
+A byte value of 65 to 128 is reduced by 64, multiplied by four, and
+subtracted from the offset.
+A byte value of 129 to 255 is reduced by 129, multiplied by the quantum
+of instruction size
+(e.g. two on the MC680x0),
+and added to the current PC without changing the offset.
+After any of these operations, the instruction quantum is added to the PC.
+.PP
+A similar table, occupying
+.BR pcsz -bytes,
+is the next section in an executable; it is present for all architectures.
+The same algorithm may be run using this table to
+recover the absolute source line number from a given program location.
+The absolute line number (starting from zero) counts the newlines
+in the C-preprocessed source seen by the compiler.
+Three symbol types in the main symbol table facilitate conversion of the absolute
+number to source file and line number:
+.RS
+.TP
+.B f
+source file name components
+.TP
+.B z
+source file name
+.TP
+.B Z
+source file line offset
+.RE
+.PP
+The
+.B f
+symbol associates an integer (the
+.B value
+field of the `symbol') with
+a unique file path name component (the
+.B name
+of the `symbol').
+These path components are used by the
+.B z
+symbol to represent a file name: the
+first byte of the name field is always 0; the remaining
+bytes hold a zero-terminated array of 16-bit values (in big-endian order)
+that represent file name components from
+.B f
+symbols.
+These components, when separated by slashes, form a file name.
+The initial slash of a file name is recorded in the symbol table by an
+.B f
+symbol; when forming file names from
+.B z
+symbols an initial slash is not to be assumed.
+The
+.B z
+symbols are clustered, one set for each object file in the program,
+before any text symbols from that object file.
+The set of
+.B z
+symbols for an object file form a
+.I history stack
+of the included source files from which the object file was compiled.
+The value associated with each
+.B z
+symbol is the absolute line number at which that file was included in the source;
+if the name associated with the
+.B z
+symbol is null, the symbol represents the end of an included file, that is,
+a pop of the history stack.
+If the value of the
+.B z
+symbol is 1 (one),
+it represents the start of a new history stack.
+To recover the source file and line number for a program location,
+find the text symbol containing the location
+and then the first history stack preceding the text symbol in the symbol table.
+Next, interpret the PC/line offset table to discover the absolute line number
+for the program location.
+Using the line number, scan the history stack to find the set of source
+files open at that location.
+The line number within the file can be found using the line numbers
+in the history stack.
+The
+.B Z
+symbols correspond to
+.B #line
+directives in the source; they specify an adjustment to the line number
+to be printed by the above algorithm. The offset is associated with the
+first previous
+.B z
+symbol in the symbol table.
+.SH "SEE ALSO"
+.IR acid (10.1),
+.IR 2a (10.1),
+.IR 2l (10.1),
+.IR inm (10.1)
+.SH BUGS
+There is no type information in the symbol table.
diff --git a/man/10/acid b/man/10/acid
new file mode 100644
index 00000000..ea816187
--- /dev/null
+++ b/man/10/acid
@@ -0,0 +1,373 @@
+.TH ACID 10.1
+.SH NAME
+acid \- debugger
+.SH SYNOPSIS
+.B acid
+[
+.BI -l " libfile
+]
+[
+.B -wq
+] [
+.B -m
+.I machine
+] [
+.I pid
+]
+[
+.I textfile
+]
+.SH DESCRIPTION
+.I Acid
+is a programmable symbolic debugger.
+It can inspect one or more processes that share an address space.
+A program to be debugged may be specified by the process id of
+a running or defunct process,
+or by the name of the program's text file
+.RB ( v.out
+by default).
+At the prompt,
+.I acid
+will store function definitions or print the value of expressions.
+Options are
+.TP .9i
+.B -w
+Allow the textfile to be modified.
+.TP
+.B -q
+Don't print variable renamings at startup.
+.TP
+.BI -l " library
+Load from
+.I library
+at startup; see below.
+.TP
+.BI -m " machine
+Assume instructions are for the given CPU type
+(one of
+.BR 386 ,
+.BR 86 ,
+.BR 68020 ,
+.BR 960 ,
+.BR power ,
+.BR arm ,
+.BR mips ,
+.BR mipsco ,
+.BR sparc ,
+or
+.BR sunsparc )
+instead of using the magic number to select
+the CPU type.
+.PP
+At startup,
+.I acid
+obtains standard function definitions from the library file
+.BR /lib/acid/port ,
+architecture-dependent functions from
+.BR /lib/acid/$objtype ,
+user-specified functions from
+.BR $home/lib/acid ,
+and further functions from
+.B -l
+files.
+Definitions in any file may override previously defined functions.
+If the function
+.IR acidinit ()
+is defined, it will be invoked after all modules have been loaded.
+See
+.IR 2c (10.1)
+for information about creating
+.I acid
+functions for examining data structures.
+.SS Language
+Symbols of the program being debugged become integer
+variables whose values are addresses.
+Contents of addresses are obtained by indirection.
+Local variables are qualified by
+function name, for example
+.BR main:argv .
+When program symbols conflict with
+.I acid
+words, distinguishing
+.B $
+signs are prefixed.
+Such renamings are reported at startup; option
+.B -q
+suppresses them.
+.PP
+Variable types
+.RI ( "integer, float, list, string" )
+and formats are inferred from assignments.
+Truth values false/true are attributed to zero/nonzero
+integers or floats and to empty/nonempty lists or strings.
+Lists are sequences of expressions surrounded by
+.BR {\^}
+and separated by commas.
+.PP
+Expressions are much as in C or Alef,
+but yield both a value and a format.
+Alef-style casts to complex types are allowed.
+Lists admit the following operators, with
+subscripts counted from 0.
+.IP
+.BI head " list
+.br
+.BI tail " list
+.br
+.BI append " list", " element
+.br
+.BI delete " list", " subscript
+.PP
+Format codes are the same as in
+.IR db (10.1).
+Formats may be attached to (unary) expressions with
+.BR \e ,
+e.g.
+.BR (32*7)\eD .
+There are two indirection operators,
+.B *
+to address a core image,
+.B @
+to address a text file.
+The type and format of the result are determined by the format of the operand,
+whose type must be integer.
+.PP
+Statements are
+.IP
+.BI if " expr " then " statement " "\fR[ \fPelse\fI statement \fR]
+.br
+.BI while " expr " do " statement
+.br
+.BI loop " expr" , " expr " do " statement
+.br
+.BI defn " name" ( args ") {" " statement \fP}
+.br
+.BI local " name
+.br
+.BI return " expr
+.br
+.BR whatis " [ \fI name \fP]
+.PP
+Here is a partial list of functions; see the manual for a complete list.
+.TF asm(address)
+.TP
+.B stk()
+Print a stack trace for current process.
+.TP
+.B lstk()
+Print a stack trace with values of local variables.
+.TP
+.B gpr()
+Print general registers.
+Registers can also be accessed by name, for example
+.BR *R0 .
+.TP
+.B spr()
+Print special registers such as program counter and stack pointer.
+.TP
+.B fpr()
+Print floating-point registers.
+.TP
+.B regs()
+Same as
+.BR spr();gpr() .
+.TP
+.BI fmt( expr , format )
+Expression
+.I expr
+with format given by the character value of expression
+.IR format .
+.TP
+.BI src( address )
+Print 10 lines of source around the program address.
+.TP
+.BI Bsrc( address )
+Get the source line for the program address
+into a window of a running
+.IR sam (10.1)
+and select it.
+.TP
+.BI line( address )
+Print source line nearest to the program address.
+.TP
+.B source()
+List current source directories.
+.TP
+.BI addsrcdir( string )
+Add a source directory to the list.
+.TP
+.BI filepc( where )
+Convert a string of the form
+.IB sourcefile : linenumber
+to a machine address.
+.TP
+.BI pcfile( address )
+Convert a machine address to a source file name.
+.TP
+.BI pcline( address )
+Convert a machine address to a source line number.
+.TP
+.BI bptab()
+List breakpoints set in the current process.
+.TP
+.BI bpset( address )
+Set a breakpoint in the current process at the given address.
+.TP
+.BI bpdel( address )
+Delete a breakpoint from the current process.
+.TP
+.B cont()
+Continue execution of current process and wait for it to stop.
+.TP
+.B step()
+Execute a single machine instruction in the current process.
+.TP
+.B func()
+Step repeatedly until after a function return.
+.TP
+.BI stopped( pid )
+This replaceable function is called automatically when the given process
+stops.
+It normally prints the program counter and returns to the prompt.
+.TP
+.BI asm( address )
+Disassemble 30 machine instructions beginning at the given address.
+.TP
+.BI mem( address , string )
+Print a block of memory
+interpreted according to a string of format codes.
+.TP
+.BI dump( address , n , string\fP)
+Like
+.BR mem (),
+repeated for
+.I n
+consecutive blocks.
+.TP
+.BI print( expr , ... )
+Print the values of the expressions.
+.TP
+.BI newproc( arguments )
+Start a new process with arguments given as a string
+and halt at the first instruction.
+.TP
+.B new()
+Like
+.IR newproc (),
+but take arguments (except
+.BR argv[0] )
+from string variable
+.BR progargs .
+.TP
+.B win()
+Like
+.IR new (),
+but run the process in a separate window.
+.TP
+.BI start( pid )
+Start a stopped process.
+.TP
+.BI kill( pid )
+Kill the given process.
+.TP
+.BI setproc( pid )
+Make the given process current.
+.TP
+.BI rc( string )
+Escape to the shell,
+.IR rc (10.1),
+to execute the command string.
+.SH EXAMPLES
+Start to debug
+.BR /bin/ls ;
+set some breakpoints; run up to the first one:
+.IP
+.EX
+% acid /bin/ls
+/bin/ls: mips plan 9 executable
+/lib/acid/port
+/lib/acid/mips
+acid: new()
+70094: system call _main ADD $-0x14,R29
+70094: breakpoint main+0x4 MOVW R31,0x0(R29)
+acid: pid
+70094
+acid: argv0 = **main:argv\es
+acid: whatis argv0
+integer variable format s
+acid: *argv0
+/bin/ls
+acid: bpset(ls)
+acid: cont()
+70094: breakpoint ls ADD $-0x16c8,R29
+acid:
+.EE
+.PP
+Display elements of a linked list of structures:
+.IP
+.EX
+complex Str { 'D' 0 val; 'X' 4 next; };
+complex Str s;
+s = *headstr;
+while s != 0 do{
+ print(s.val, "\en");
+ s = s.next;
+}
+.EE
+.PP
+Note the use of the
+.B .
+operator instead of
+.BR -> .
+.PP
+Display an array of bytes declared in C as
+.BR "char array[]" .
+.IP
+.EX
+*(array\es)
+.EE
+.PP
+This example gives
+.B array
+string format, then prints the string beginning at the address (in
+.I acid
+notation)
+.BR *array .
+.SH FILES
+.B /proc/*/text
+.br
+.B /proc/*/mem
+.br
+.B /proc/*/ctl
+.br
+.B /proc/*/note
+.br
+.B /lib/acid/$objtype
+.br
+.B /lib/acid/port
+.br
+.B $home/lib/acid
+.SH SOURCE
+.B /utils/acid
+.SH "SEE ALSO"
+.IR 2a (10.1),
+.IR 2c (10.1),
+.IR 2l (10.1),
+.IR alef (10.1),
+.IR mk (10.1),
+.IR db (10.1)
+.br
+Phil Winterbottom,
+``Acid Manual''.
+.SH DIAGNOSTICS
+At termination, kill commands are proposed
+for processes that are still active.
+.SH BUGS
+There is no way to redirect the standard input and standard output
+of a new process.
+.br
+Source line selection near the beginning of a file may pick
+an adjacent file.
+.br
+With the extant stepping commands, one cannot step through instructions
+outside the text segment and it is hard to debug across process forks.
diff --git a/man/10/allocb b/man/10/allocb
new file mode 100644
index 00000000..4690ab35
--- /dev/null
+++ b/man/10/allocb
@@ -0,0 +1,314 @@
+.TH ALLOCB 10.2
+.SH NAME
+allocb, iallocb, freeb, freeblist, BLEN, blocklen, concatblock, copyblock, trimblock, packblock, padblock, pullblock, pullupblock, adjustblock, checkb \- data block management
+.SH SYNOPSIS
+.ta \w'\fLBlock* 'u
+.B
+Block* allocb(int size)
+.PP
+.B
+Block* iallocb(int size)
+.PP
+.B
+void freeb(Block *b)
+.PP
+.B
+void freeblist(Block *b)
+.PP
+.B
+long BLEN(Block *b)
+.PP
+.B
+int blocklen(Block *b)
+.PP
+.B
+Block* concatblock(Block *b)
+.PP
+.B
+Block* copyblock(Block *b, int n)
+.PP
+.B
+Block* trimblock(Block *b, int offset, int n)
+.PP
+.B
+Block* packblock(Block *b)
+.PP
+.B
+Block* padblock(Block *b, int n)
+.PP
+.B
+int pullblock(Block **bph, int n)
+.PP
+.B
+Block* pullupblock(Block *b, int n)
+.PP
+.B
+Block* adjustblock(Block *b, int n)
+.PP
+.B
+void checkb(Block *b, char *msg)
+.SH DESCRIPTION
+A
+.B Block
+provides a receptacle for data:
+.IP
+.EX
+.DT
+typedef
+struct Block
+{
+ Block* next;
+ Block* list;
+ uchar* rp; /* first unconsumed byte */
+ uchar* wp; /* first empty byte */
+ uchar* lim; /* 1 past the end of the buffer */
+ uchar* base; /* start of the buffer */
+ void (*free)(Block*);
+ ulong flag;
+} Block;
+.EE
+.PP
+Each
+.B Block
+has an associated buffer, located at
+.BR base ,
+and accessed via
+.B wp
+when filling the buffer, or
+.B rp
+when fetching data from it.
+Each pointer should be incremented to reflect the amount of data written or read.
+A
+.B Block
+is empty when
+.B rp
+reaches
+.BR wp .
+The pointer
+.B lim
+bounds the allocated space.
+Some operations described below accept lists of
+.BR Block s,
+which are
+chained via their
+.B next
+pointers, with a null pointer ending the list.
+.B Blocks
+are usually intended for a
+.B Queue
+(see
+.IR qio (10.2)),
+but can be used independently.
+.PP
+A
+.B Block
+and its buffer are normally allocated by one call to
+.IR malloc (10.2)
+and aligned on an 8 byte (\fLBY2V\fP) boundary.
+Some devices with particular allocation constraints
+(eg, requiring certain addresses for DMA) might allocate their own
+.B Block
+and buffer;
+.B free
+must then point to a function that can deallocate the specially allocated
+.BR Block .
+.PP
+Many
+.B Block
+operations cannot be used in interrupt handlers
+because they either
+.IR sleep (10.2)
+or raise an
+.IR error (10.2).
+Of operations that allocate blocks, only
+.IR iallocb
+is usable.
+.PP
+.I Allocb
+allocates a
+.B Block
+of at least
+.IR size
+bytes.
+The block
+is initially empty:
+.B rp
+and
+.B wp
+point to the start of the data.
+If it cannot allocate memory,
+.I allocb
+raises an
+.IR error (10.2);
+it cannot be used by an interrupt handler.
+.PP
+.IR Iallocb
+is similar to
+.IR allocb
+but is intended for use by interrupt handlers,
+and returns a null pointer if no memory is available.
+It also limits its allocation to a quota allocated at system initialisation to interrupt-time buffering.
+.PP
+.I Freeb
+frees a single
+.B Block
+(and its buffer).
+.PP
+.I Freeblist
+frees the whole
+list of blocks headed by
+.IR b .
+.PP
+.I BLEN
+returns the number of unread bytes in a single block
+.IR b ;
+it is implemented as a macro.
+.PP
+.I Blocklen
+returns the number of bytes of unread data in the whole list of blocks headed by
+.IR b .
+.PP
+.I Concatblock
+returns
+.I b
+if it is not a list, and otherwise
+returns a single
+.B Block
+containing all the data in the list of blocks
+.IR b ,
+which it frees.
+.PP
+.I Copyblock
+by contrast returns a single
+.B Block
+containing a copy of the first
+.I n
+bytes of data in the block list
+.IR b ,
+padding with zeroes if the list contained less than
+.I n
+bytes.
+The list
+.I b
+is unchanged.
+.PP
+.I Padblock
+can pad a single
+.B Block
+at either end, to reserve space for protocol headers or trailers.
+If
+.IR n ≥ 0 ,
+it inserts
+.I n
+bytes at the start of the block,
+setting the read pointer
+.B rp
+to point to the new space.
+If
+.IR n < 0 ,
+it adds
+.I n
+bytes at the end of the block,
+leaving the write pointer
+.B wp
+pointing at the new space.
+In both cases, it allocates a new
+.B Block
+if necessary, freeing the old, and
+it always returns a pointer to the resulting
+.BR Block .
+.PP
+.I Trimblock
+trims the list
+.I b
+to contain no more than
+.I n
+bytes starting at
+.I offset
+bytes into the data of the original list.
+It returns a new list, freeing unneeded parts of the old.
+If no data remains, it returns a null pointer.
+.PP
+.I Packblock
+examines each
+.B Block
+in the list
+.IR b ,
+reallocating any block in the list that has four times more available space than actual data.
+It returns a pointer to the revised list.
+.PP
+.I Pullblock
+discards up to
+.I n
+bytes from the start of the list headed by
+.BI * bph \f1.\f0
+Unneeded blocks are freed.
+.I Pullblock
+sets
+.BI * bph
+to point to the new list head
+and returns the number of bytes discarded (which might be less than
+.IR n ).
+It is used by transport protocols to discard ack'd data at
+the head of a retransmission queue.
+.PP
+.I Pullupblock
+rearranges the data in the list of blocks
+.I b
+to ensure that there are at least
+.I n
+bytes of contiguous data in the first block,
+and returns a pointer to the new list head.
+It frees any blocks that it empties.
+It returns a null pointer if there is not enough data in the list.
+.PP
+.I Adjustblock
+ensures that the block
+.I b
+has at least
+.I n
+bytes of data, reallocating or padding with zero if necessary.
+It returns a pointer to the new
+.BR Block .
+(If
+.I n
+is negative, it frees the block and returns a null pointer.)
+.PP
+.I Checkb
+does some consistency checking of
+the state of
+.IR b ;
+a
+.IR panic (10.2)
+results if things look grim.
+It is intended for internal use by the queue I/O routines (see
+.IR qio (10.2))
+but could be used elsewhere.
+.PP
+The only functions that can be called at interrupt level are
+.IR iallocb ,
+.IR freeb ,
+.IR freeblist ,
+.IR BLEN ,
+.IR blocklen ,
+.IR trimblock
+and
+.IR pullupblock .
+The others allocate memory and can potentially block.
+.SH DIAGNOSTICS
+Many functions directly or indirectly can raise an
+.IR error (10.2),
+and callers must therefore provide for proper error recovery
+as described therein to prevent memory leaks and other bugs.
+Except for
+.IR iallocb ,
+any functions that allocate new blocks or lists
+are unsuitable for use by interrupt handlers.
+.IR Iallocb
+returns a null pointer when it runs out of memory.
+.SH SOURCE
+.B /os/port/qio.c
+.br
+.B /emu/port/qio.c
+.SH SEE ALSO
+.IR qio (10.2)
diff --git a/man/10/ar b/man/10/ar
new file mode 100644
index 00000000..2c28f550
--- /dev/null
+++ b/man/10/ar
@@ -0,0 +1,98 @@
+.TH AR 10.6
+.SH NAME
+ar \- archive (library) file format
+.SH SYNOPSIS
+.B #include <ar.h>
+.SH DESCRIPTION
+The archive command
+.IR iar (10.1)
+is used to combine several files into
+one.
+Archives are used mainly as libraries to be searched
+by the loaders
+.IR 2l (10.1)
+.I et al.
+.PP
+A file produced by
+.I ar
+has a magic string at the start,
+followed by the constituent files, each preceded by a file header.
+The magic number and header layout as described in the
+include file are:
+.IP
+.EX
+.ec %
+#define ARMAG "!<arch>\n"
+#define SARMAG 8
+
+#define ARFMAG "`\n"
+
+struct ar_hdr {
+ char name[16];
+ char date[12];
+ char uid[6];
+ char gid[6];
+ char mode[8];
+ char size[10];
+ char fmag[2];
+};
+#define SAR_HDR 60
+.ec \
+.EE
+.LP
+The
+.B name
+is a blank-padded string.
+The
+.L fmag
+field contains
+.L ARFMAG
+to help verify the presence of a header.
+The other fields are left-adjusted, blank-padded numbers.
+They are decimal except for
+.LR mode ,
+which is octal.
+The date is the modification date of the file (see
+.IR sys-stat (2))
+at the time of its insertion into the archive.
+The mode is the low 9 bits of the file permission mode.
+The length of the header is
+.LR SAR_HDR .
+Because the
+.L ar_hdr
+structure is padded in an architecture-dependent manner,
+the structure should never be read or written as a unit;
+instead, each field should be read or written independently.
+.PP
+Each file begins on an even (0 mod 2) boundary;
+a newline is inserted between files if necessary.
+Nevertheless
+.B size
+reflects the
+actual size of the file exclusive of padding.
+.PP
+When all members of an archive are object files of
+the same architecture,
+.B ar
+automatically adds an extra file, named
+.BR __.SYMDEF ,
+as the first member of the archive. This file
+contains an index used by the loaders to locate all
+externally defined text and data symbols in the archive.
+.PP
+There is no provision for empty areas in an archive
+file.
+.SH "SEE ALSO"
+.IR iar (10.1),
+.IR 2l (10.1),
+.IR inm (10.1),
+.IR sys-stat (2)
+.SH BUGS
+The
+.B uid
+and
+.B gid
+fields are unused.
+They provide compatibility with Unix
+.I ar
+format.
diff --git a/man/10/atoi b/man/10/atoi
new file mode 100644
index 00000000..6281ac2e
--- /dev/null
+++ b/man/10/atoi
@@ -0,0 +1,127 @@
+.TH ATOI 10.2
+.SH NAME
+atoi, atol, charstod, strtod, strtol, strtoul, strtoll \- convert text to numbers
+.SH SYNOPSIS
+.nf
+.ta \w'\fLdouble 'u
+.B
+int atoi(char *nptr)
+.PP
+.B
+long atol(char *nptr)
+.PP
+.B
+double charstod(int (*f)(void *), void *a)
+.PP
+.B
+double strtod(char *nptr, char **rptr)
+.PP
+.B
+long strtol(char *nptr, char **rptr, int base)
+.PP
+.B
+ulong strtoul(char *nptr, char **rptr, int base)
+.PP
+.B
+vlong strtoll(char *nptr, char **rptr, int base)
+.fi
+.SH DESCRIPTION
+.IR Atoi
+and
+.I atol
+convert a string pointed to by
+.I nptr
+to integer, and long integer
+representation respectively.
+The first unrecognized character ends the string.
+Leading C escapes are understood, as in
+.I strtol
+with
+.I base
+zero.
+.PP
+.I Atoi
+and
+.I atol
+recognize an optional string of tabs and spaces,
+then an optional sign, then a string of
+decimal digits.
+.PP
+.IR Strtod ,
+.IR strtol ,
+.IR strtoul ,
+and
+.I strtoll
+behave similarly to
+.I atol
+and, if
+.I rptr
+is not zero, set
+.I *rptr
+to point to the input character
+immediately after the string converted.
+.PP
+.I Strtod
+recognizes an optional string of tabs and spaces,
+then an optional sign, then
+a string of digits optionally containing a decimal
+point, then an optional
+.L e
+or
+.L E
+followed
+by an optionally signed integer.
+.PP
+.IR Strtol ,
+.I strtoul
+and
+.I strtoll
+interpret the digit string in the specified
+.IR base ,
+from 2 to 36,
+each digit being less than the base.
+Digits with value over 9 are represented by letters,
+a-z or A-Z.
+If
+.I base
+is 0, the input is interpreted as an integral constant in
+the style of C (with no suffixed type indicators):
+numbers are octal if they begin with
+.LR 0 ,
+hexadecimal if they begin with
+.L 0x
+or
+.LR 0X ,
+otherwise decimal.
+.I Strtoul
+does not recognize signs.
+.PP
+.I Charstod
+interprets floating point numbers in the same syntax as
+.IR strtod ,
+but it gets successive characters by calling
+.BR (*\fIf\fP)(\f2a\f5) .
+The last call to
+.I f
+terminates the scan, so it must have returned a character that
+is not a legal continuation of a number.
+Therefore, it may be necessary to back up the input stream one character
+after calling
+.IR charstod .
+.SH SOURCE
+.B /libkern/atol.c
+.br
+.B /libkern/charstod.c
+.br
+.B /libkern/strtod.c
+.br
+.B /libkern/strtol.c
+.br
+.B /libkern/strtoul.c
+.br
+.B /libkern/utils.c
+.SH DIAGNOSTICS
+Zero is returned if the beginning of the input string is not
+interpretable as a number; even in this case,
+.I rptr
+will be updated.
diff --git a/man/10/c2l b/man/10/c2l
new file mode 100644
index 00000000..63f134d2
--- /dev/null
+++ b/man/10/c2l
@@ -0,0 +1,231 @@
+.TH C2L 10.1
+.SH NAME
+c2l \- C to Limbo translator
+.SH SYNOPSIS
+.B c2l
+[
+.I option ...
+]
+.I file
+.SH DESCRIPTION
+.I C2l
+translates the named C
+.I file
+into Limbo. The translated code should be almost always syntactically correct
+but will certainly never be semantically correct as certain constructs in C
+(strings for example) are almost impossible to convert automatically into Limbo.
+Otherwise it tries to do a good job of translating the C constructs that have some
+sort of equivalence in Limbo. The C ternary
+.B ?:
+operator is replaced where possible.
+C library calls are mapped to calls to the Limbo system module, maths module or
+the provided Limbo libc modules. Some library calls, such as malloc, are instead
+mapped directly into Limbo wherever possible.
+.PP
+Once a translation has been made, running the
+.IR limbo (1)
+compiler on the resulting output should pick out the areas where hand
+editing is required.
+.PP
+.I C2l
+normally puts all mapped C code (plus that from included files) into a
+single .b file.
+.PP
+The options to
+.I c2l
+are:
+.TP
+.B -p
+Use an ANSI preprocessor in place of the internal one.
+.TP
+.BI -D name=def
+.br
+.ns
+.TP
+.BI -D name
+Define the
+.I name
+to the preprocessor,
+as if by
+.LR #define .
+If no definition is given, the name is defined as
+.LR 1 .
+.TP
+.BI -I dir
+An
+.L #include
+file whose name does not begin with
+slash
+or is enclosed in double quotes
+is always
+sought first in the directory
+of the
+.I file
+argument. If this fails, or the name is enclosed in
+.BR <> ,
+it is then sought
+in directories named in
+.B -I
+options,
+then in
+.BR /sys/include ,
+and finally in
+.BR /$objtype/include .
+.TP
+.B -m
+Put the mapped code of any included
+.B .h
+files into its corresponding
+.B .m
+file instead of
+the
+.B .b
+file.
+.TP
+.B -i
+Send the mapped code of any included
+.B .h
+files to
+.BR /dev/null .
+.TP
+.B -l
+Send the mapped code of any non-local included
+.B .h
+files to
+.BR /dev/null .
+.TP
+.B -c
+Just generate code corresponding to the C code ie don't include any prologue
+or epilogue code such as an implement header, include declarations, module
+declarations or an init function.
+.TP
+.B -v
+Outputs any warnings to standard error as well as putting them in the output source.
+.TP
+.B -s
+Map C strings to NUL-terminated arrays of bytes in Limbo. This just about preserves
+the semantics of strings and makes the process of hand editing much easier. It is
+useful as a first attempt at translation. In this case the module
+.B /module/libc0.m
+is used in place of the standard one
+.B /module/libc.m.
+.TP
+.B -S
+Map
+.B "char*"
+in C to string in Limbo. Incompatible with the
+.B -s
+option.
+.TP
+.B -M
+Indicates this file is the one containing the C main program. Used with the
+.B -q
+option below when
+.I c2l
+does not always know this until it's too late.
+.TP
+.B -q
+This reduces the number of passes that
+.I c2l
+makes over the C code. It makes it faster but more liable to miss some
+transformations. Cyclic data structures might not be detected.
+.TP
+.B -a
+For functions which are passed the address of a scalar typed (ie not a structure
+or union) expression as a parameter, pass the expression itself and
+rewrite the function and all calls of it to return the expression. For example :-
+.PP
+.EX
+ int
+ f(int x, int *y)
+ {
+ *y = x*x*x;
+ return x*(*y);
+ }
+
+ void
+ g()
+ {
+ int p3, p4;
+
+ p4 = f(1729, &p3);
+ }
+.EE
+.PP
+ becomes
+.PP
+.EX
+ f(x: int, y: int): (int, int)
+ {
+ y = x*x*x;
+ return (x*y, y);
+ }
+
+ g()
+ {
+ p3, p4: int;
+
+ (p4, p3) = f(1729, p3);
+ }
+.EE
+.PP
+.I C2l
+runs the preprocessor on the C code before starting translation. As
+a special case it will convert definitions of constants into Limbo constant declarations.
+It makes no attempt to convert any definitions into function declarations.
+.PP
+Identifier names that clash with Limbo keywords have letter
+.B x
+appended so, for example,
+a structure member called
+.B type
+would become
+.BR typex .
+.PP
+Warning messages preceded by the acronym TBA (to be addressed) are issued for
+NUL bytes in strings, ... as an argument, array indices in declarations, use of void type, use of unions, bit fields, use of address operator, negative array
+indices, element specifiers, initial values in Limbo modules, labels, gotos and case
+statement fall through.
+.PP
+The C types
+.B char
+and
+.B "unsigned char"
+are mapped to the Limbo
+.B byte
+type.
+The C types short, unsigned short, int, unsigned int, long and unsigned long
+are mapped to the Limbo int type. The C types long long and unsigned long long
+are mapped to the Limbo big type. Finally the C types float and double are mapped
+to the Limbo real type.
+.PP
+Anonymous C structures and unions map to a name of the form <module>_adt_<num> where module is the name of the module which is, in turn, derived from the file name. Anonymous member names in strucures and unions have a
+name of the form anon_<num>. Finally,temporary variables generated by
+.I c2l
+have a name of the form tmp_<num>. In all cases <num> is a unique identifier.
+.SH SOURCE
+.TF /utils/c2l
+.TP
+.B /module/libc.m
+.TP
+.B /module/libc0.m
+.TP
+.B /appl/lib/libc.b
+.TP
+.B /appl/lib/libc0.b
+.TP
+.SH "SEE ALSO"
+.IR 2c (10.1),
+.IR limbo (1)
+.SH BUGS
+.I C2l
+is not a pretty printer. It has its own idea of how Limbo should be laid out.
+.PP
+.I C2l
+may well crash if given invalid C code.
+.PP
+.I c2l -a
+does not always do all possible conversions.
+
+
+
diff --git a/man/10/conf b/man/10/conf
new file mode 100644
index 00000000..134a3038
--- /dev/null
+++ b/man/10/conf
@@ -0,0 +1,335 @@
+.TH CONF 10.6
+.SH NAME
+conf \- native and hosted kernel configuration file
+.SH DESCRIPTION
+Native and hosted Inferno kernels are built for a given target
+.I platform
+in the host environment in directory
+.BI /os/ platform
+or
+.BI /emu/ platform .
+Existing
+platforms include
+.B pc
+and
+.B ipaq
+for native kernels and
+.BR Plan9 ,
+.BR Linux ,
+.B Nt
+(for all versions of Windows),
+and
+.BR Solaris ,
+amongst others.
+Each
+.I platform
+can have different kernels with different configurations.
+A given configuration is built in the platform's directory using the
+.IR mk (10.1)
+command:
+.IP
+.EX
+mk 'CONF=\fIconf\fP'
+.EE
+.PP
+where
+.I conf
+is a text file that specifies drivers, protocols and other parameters for that
+particular kernel:
+a parts list.
+The result of a successful
+.I mk
+is
+an executable or bootable file with a name determined by the
+.IR platform 's
+.BR mkfile ,
+typically
+.BI i conf
+for all native platforms,
+.BI $O. conf
+for Plan 9, Unix and clones,
+and
+.BI i conf .exe
+for Windows.
+.PP
+A kernel configuration file has several sections of the form
+.IP
+.EX
+.I "label"
+.IR " item" " [ " "subitem ..." " ]"
+\& ...
+.EE
+.PP
+Each section begins with a
+.I label
+at the start of a line, which names a configuration
+category, followed by
+a list of each
+.I item
+to select from that category,
+one line per item, with white space (ie, blank or tab) at the start of the line.
+An
+.I item
+line can optionally list one or more
+.I subitems
+that must be included in the kernel to support it.
+A line that starts with a
+.L #
+is a comment.
+Empty lines are ignored.
+.PP
+.I Labels
+are chosen from the following set, listed in the order
+in which they conventionally appear in a configuration file:
+.TF etherxx
+.TP
+.B dev
+Device drivers
+.TP
+.B ip
+IP protocols (native kernels only) taken from
+.B ../ip
+.TP
+.B link
+Hardware-specific parts of device drivers.
+.TP
+.B misc
+Architecture-specific files; specific VGA and SCSI interfaces
+.TP
+.B lib
+Libraries to link with the kernel
+.TP
+.B mod
+Builtin Dis modules
+.TP
+.B port
+Portable components (other than drivers) from
+.B ../port
+.TP
+.B code
+C code and declarations to include as-is in the generated configuration file
+.TP
+.B init
+Dis init program
+.TP
+.B root
+List of files and directories to put in the
+.IR root (3)
+file system
+.PD
+.PP
+When an
+.I item
+is listed
+under a given
+.I label
+it causes a corresponding component to be included in the kernel.
+The details depend on the
+.IR label ,
+as discussed below.
+Each
+.I subitem
+represents a kernel subcomponent required by the corresponding
+.IR item .
+Both items and subitems can be either portable (platform-independent)
+or platform-specific.
+The source file for a given item or subitem
+is sought in the platform-directory
+(for platform-specific code), and
+in directories
+.BR ../port
+and
+.BR ../ip ,
+under control of the platform's
+.BR mkfile
+and
+.B ../port/portmkfile
+(which is included by
+.BR mkfile ).
+Resulting object files are left in the
+.I platform
+directory.
+.PP
+Outside the
+.B dev
+section,
+each item and subitem
+.I x
+causes the kernel image to include the code compiled from
+.IB x .c ,
+(or
+.IB x .s
+or
+.IB x .S
+for assembly-language support),
+or
+.IB portdir / x .c ,
+where
+.I portdir
+is one of the portable directories mentioned above.
+In the
+.B dev
+section, an item
+.I x
+corresponds instead to the driver source file
+.BI dev x .c
+in the current (platform-specific)
+directory or a portable driver
+.IB portdir /dev x .c .
+Subitems are handled as in any other section.
+Typically they are auxiliary files that are needed by the associated driver.
+.PP
+For instance, in a native kernel
+the portable driver for the
+.B draw
+device uses platform-specific code from
+.BR screen.c .
+That can be represented as follows:
+.IP
+.EX
+dev
+ draw screen
+.EE
+.PP
+Each item
+.I x
+in the
+.B ip
+section
+corresponds to a protocol implementation compiled from
+.BI ../ip/ x .c .
+Any subitems
+are dealt with in the same way as in the
+.B dev
+section.
+.PP
+The
+.B link
+section provides a way for hardware-specific
+parts of drivers to link at runtime to the hardware-invariant part of a device
+drivers.
+For each item
+.IR x ,
+the kernel will call the function
+.IB x link
+during its initialisation.
+Typically that function makes itself known to the device driver by
+calling a function provided by that driver,
+passing the address of a interface-specific data structure or linkage table.
+For example,
+.B ethersmc
+is an interface-specific component:
+.IP
+.EX
+link
+ \fR...\fP
+ ethersmc
+.EE
+.PP
+and its source file
+.B ethersmc.c
+provides a function
+.B ethersmclink
+that
+calls
+.B addethercard
+in the interface-invariant part of the driver,
+.BR devether.c :
+.IP
+.EX
+void
+ethersmclink(void)
+{
+ addethercard("smc91cXX", reset);
+}
+.EE
+.PP
+Similarly, during kernel initialisation, for each item
+.I x
+in the
+.B mod
+section, the kernel calls the function
+.IB x init ,
+to initialise the corresponding built-in Limbo module.
+.PP
+The
+.B init
+section selects the first Dis program run by the system.
+For native kernels, a given item
+.I x
+refers to
+.BI ../init/ x .dis ,
+which is automatically built from
+.BI ../init/ x .b .
+For hosted kernels,
+.B emuinit
+is normally used, referring to
+.BR /dis/emuinit.dis .
+.PP
+The
+.B lib
+section lists the libraries to include when linking the kernel,
+in an order that satisfies any dependencies amongst them.
+Each item
+.I x
+corresponds to
+.BI /$SYSTARG/$OBJTYPE/lib x .a ,
+a target-specific library
+produced by compiling the C source code in
+.BI /lib item,
+where
+.B SYSTARG
+and
+.B OBJTYPE
+are set in
+.B mkfile
+to the target system and object types.
+.PP
+An item in the
+.B root
+section
+has one of the forms:
+.IP
+.EX
+.I name
+.I "name source"
+.EE
+.PP
+where
+.I name
+and
+.I source
+are both absolute path names rooted at the Inferno source tree.
+The kernel's initial root file system (see
+.IR root (3))
+will contain a file or directory with the given
+.IR name .
+.I Name
+must exist in the Inferno root, or an existing
+.I source
+file must be named.
+In either case,
+if the existing name refers to a file, the file in the root file system will have that file's current contents.
+If it is a directory, the root file file system will have a directory with that name,
+but the directory will contain only those names listed in
+the configuration file as belonging to that directory.
+.I Source
+is often
+.L /
+to force a target
+.I name
+to be a directory.
+.SH FILES
+.B /emu/port/mkdevc
+.br
+.B /emu/port/mkdevlist
+.br
+.B /emu/port/mkroot
+.br
+.B /os/port/mkdevc
+.br
+.B /os/port/mkdevlist
+.br
+.B /os/port/mkroot
+.SH SEE ALSO
+.IR mk (10.1)
diff --git a/man/10/delay b/man/10/delay
new file mode 100644
index 00000000..72665837
--- /dev/null
+++ b/man/10/delay
@@ -0,0 +1,36 @@
+.TH DELAY 10.2
+.SH NAME
+delay, microdelay, addclock0link \- small delays, clock interrupts
+.SH SYNOPSIS
+.ta \w'\fLvoid 'u
+.B
+void delay(int n)
+.PP
+.B
+void microdelay(int n)
+.PP
+.B
+void addclock0link(void(*clockf)(void))
+.SH DESCRIPTION
+.I Delay
+busy waits for
+.I n
+milliseconds, forced to be at least one millisecond.
+.PP
+.I Microdelay
+is similar, but busy waits for
+.IR n
+microseconds.
+.PP
+For delays on the order of clock ticks,
+.I tsleep
+(see
+.IR sleep (10.2))
+provides a better alternative to the busy waiting of these routines.
+.PP
+.I Addclock0link
+adds
+.I clockf
+to a list of functions to be executed at each clock interrupt.
+.SH SEE ALSO
+.IR sleep (10.2)
diff --git a/man/10/dev b/man/10/dev
new file mode 100644
index 00000000..15bf16cb
--- /dev/null
+++ b/man/10/dev
@@ -0,0 +1,435 @@
+.TH DEV 10.2
+.SH NAME
+Dev \- device driver interface
+.SH SYNOPSIS
+.EX
+struct Dev
+{
+ int dc;
+ char* name;
+
+ void (*reset)(void); /* native only */
+ void (*init)(void);
+ void (*shutdown)(void); /* native */
+ Chan* (*attach)(char *spec);
+ Walkqid* (*walk)(Chan *c, Chan *nc, char **name, int nname);
+ int (*stat)(Chan *c, uchar *db, int dbsize);
+ Chan* (*open)(Chan *c, int mode);
+ void (*create)(Chan *c, char *name, int mode, ulong perm);
+ void (*close)(Chan *c);
+ long (*read)(Chan *c, void *buf, long nbytes, vlong offset);
+ Block* (*bread)(Chan *c, long nbytes, ulong offset);
+ long (*write)(Chan *c, void*, long, vlong offset);
+ long (*bwrite)(Chan *c, Block *b, ulong offset);
+ void (*remove)(Chan *c);
+ int (*wstat)(Chan *c, uchar *db, int dbsize);
+ void (*power)(int on); /* native only */
+ int (*config)(int on, char *spec, DevConf *cf); /* native */
+};
+.EE
+.SH DESCRIPTION
+Every device driver serves a unique name space that represents to the corresponding device(s).
+Applications act on the space using the operations of
+.IR sys-bind (2),
+.IR sys-open (2),
+.IR sys-read (2),
+.IR sys-stat (2),
+and other system calls.
+Within the kernel, the
+.B Dev
+structure defines the interface between the kernel and a device driver for
+all operations on that driver's name space.
+.PP
+.B Dev
+identifies the driver, and lists a set of C functions that are the driver's operations.
+Most are operations on the
+.B Chan
+type that is the kernel representation of a file or directory active in a name space.
+The kernel converts system calls acting on file descriptors into calls to a device's
+.B Dev
+operations acting on channel values.
+All channel values presented through the
+.B Dev
+interface are associated with the corresponding device driver:
+for channel
+.IR c ,
+.IB c ->type
+specifies that driver.
+Within the driver, the
+.IB c ->qid.path
+of a channel
+.I c
+identifies a file in the driver's name space, or even a client-specific instance of a file
+(eg, for multiplexors such as
+.IR ip (3)).
+The interpretation of the
+.B path
+is completely determined by the driver.
+.PP
+A device driver in the source file
+.BI dev x .c
+exports an initialised instance of
+.BI "Dev " x devtab .
+For instance,
+.B devcons.c
+contains the global initialiser:
+.IP
+.EX
+Dev consdevtab = {
+ 'c',
+ "cons",
+
+ devreset,
+ consinit,
+ devshutdown,
+ consattach,
+ conswalk,
+ consstat,
+ consopen,
+ devcreate,
+ consclose,
+ consread,
+ devbread,
+ conswrite,
+ devbwrite,
+ devremove,
+ devwstat,
+};
+.EE
+.PP
+The kernel accesses the driver only through its
+.B Dev
+structure, and consequently entry points such as
+.BR consinit ,
+.BR consread ,
+etc. can (and should) be declared
+.BR static ,
+and thus local to the file.
+.PP
+The following elements of
+.B Dev
+identify the driver:
+.TP
+.B dc
+The device's type, represented by a Unicode character (`rune') that must be unique
+amongst those in a given kernel (and ideally for a given platform).
+Its value is the value of
+.B Dir.dtype
+in the result of a
+.IR sys-stat (2)
+applied to any file in the device.
+.TP
+.B name
+The name that identifies the driver in a kernel configuration file and in
+.B /dev/drivers
+(see
+.IR cons (3)).
+.PP
+All the other entries are functions.
+In many cases, the values given in a device's
+.B Dev
+will be the default operations provided by
+.IR devattach (10.2).
+.TP
+.B reset()
+Called once during system initialisation by the native
+kernel's
+.B main
+after initialising all supporting subsystems, including memory allocation, traps, screen, MMU (if used),
+but with interrupts disabled, and before any kernel process environment has been established.
+Typically used on some platforms to force some devices into a sane state
+before interrupts are enabled.
+.TP
+.B init()
+Called once during system initialisation in the context of the first kernel process,
+with interrupts enabled, before the virtual machine has been started.
+.TP
+.B shutdown()
+Called once in native kernels during system shut down.
+Used on only a few platforms to force a device into a state that will allow it
+to function correctly during and after a soft reboot (eg, without doing a full system hardware reset).
+.TP
+.BI attach( spec )
+Called on each new attach to the device (eg, a reference to
+.BI # c
+by
+.IR sys-bind (2)).
+.I Spec
+is the string following the device character and before a subsequent
+.RB ` / '
+in the bind request.
+It is the empty string for most devies.
+If the attach is successful,
+.B attach
+should return a
+.B Chan
+the refers to the root of the tree served by the device driver.
+Normally, it will suffice to return the value of
+.IR devattach (10.2).
+.TP
+.BI walk( c\fP,\fP\ nc\fP,\fP\ name\fP,\fP\ nname )
+Walks existing channel
+.I c
+from its current position in the device tree to that specified by the
+path represented by
+.BR name[0] ,
+\&...
+.BR name[nname-1] .
+The driver must interpret
+.RB ` .. '
+as a walk from the current position one level up towards the root of the device tree.
+The result is represented by a dynamically-allocated
+.B Walkqid
+value,
+with contents as described in
+.IR devattach (10.2).
+Most drivers simply pass parameters on to
+.B devwalk
+in
+.IR devattach (10.2)
+and return its result.
+.TP
+.BI stat( c\fP,\fP\ db\fP,\fP\ nbytes )
+Fill
+.I db
+with
+.IR stat (5)
+data describing the file referenced by
+.IR c .
+.I Nbytes
+gives the size of
+.IR db ;
+if the data will not fit, return the value specified for
+.B convD2M
+in
+.IR styx (10.2).
+Most drivers simply pass parameters on to
+.B devstat
+in
+.IR devattach (10.2);
+a few fill a local copy of a
+.B Dir
+structure, and call
+.B convD2M
+to store the machine-independent representation in
+.IR db .
+.TP
+.BI open( c\fP,\fP\ mode )
+Open the file represented by
+.B Chan
+.IR c ,
+in the given
+.I mode
+(see
+.IR sys-open (2)),
+and if successful, return a
+.B Chan
+value representing the result
+(usually
+.IR c ).
+Many drivers simply apply
+.B devopen
+of
+.IR devattach (10.2).
+Exclusive use drivers might check and increment a reference count.
+.TP
+.BI create( c\fP,\fP\ name\fP,\fP\ mode\fP,\fP\ perm )
+.I C
+should be a directory.
+Create a new file
+.I name
+in that directory, with permissions
+.IR perm ,
+opened with the given
+.IR mode .
+If successful, make
+.I c
+refer to the newly created file.
+Most drivers return an error on all creation attempts,
+by specifying
+.B devcreate
+of
+.IR devattach (10.2)
+in the
+.B Dev
+table.
+.TP
+.BI close( c )
+Close channel
+.IR c .
+This must be implemented by all drivers; there is no default,
+although the function often is a no-op.
+Exclusive use drivers might decrement a reference count.
+.TP
+.BI read( c\fP,\fP\ buf\fP,\fP\ nbytes\fP,\fP\ offset )
+Implement a
+.IR sys-read (2)
+of
+.I nbytes
+of data from the given
+.I offset
+in file
+.IR c ,
+and if successful, place the data in
+.IR buf ,
+and return the number of bytes read,
+which must be no greater than
+.IR nbytes .
+Devices sometimes ignore the
+.IR offset .
+All device drivers must implement
+.BR read ;
+there is no default.
+Note that if
+.I c
+is a directory, the data has an array of
+.IR stat (5)
+data listing the directory contents, in the format prescribed by
+.IR read (5).
+Most drivers have
+.B devdirread
+of
+.IR devattach (10.2)
+do the work when
+.I c
+is the root directory of the device's tree.
+.TP
+.BI bread( c\fP,\fP\ nbytes\fP,\fP\ offset )
+Implement a
+.IR sys-read (2)
+of
+.I nbytes
+of data from the given offset in file
+.IR c ,
+and if successful return the data in a
+.B Block
+(see
+.IR allocb (10.2)
+and
+.IR qio (10.2)).
+Most drivers use the default
+.B devbread
+provided by
+.IR devattach(10.2),
+and nearly all ignore the
+.I offset
+in any case.
+Drivers that manipulate Blocks internally, such as
+.IR ip (3),
+.IR ssl (3)
+and similar protocol devices,
+and drivers that are likely to provide data to those devices,
+will provide a
+.B devbread
+implementation so as to reduce the number of times the data is copied.
+.TP
+.BI write( c\fP,\fP\ buf\fP,\fP\ nbytes\fP,\fP\ offset )
+Implement a write of
+.I nbytes
+of data from
+.I buf
+to file
+.IR c ,
+which must not be a directory,
+starting at the given byte
+.IR offset .
+Return the number of bytes actually written.
+There is no default, but drivers that do not
+implement writes to any of their files can simply call
+.B error(Eperm)
+to signal an error.
+.TP
+.BI bwrite( c\fP,\fP\ b\fP,\fP\ offset )
+Similar to the
+.B write
+entry point, but the data is contained in a
+.B Block
+.I b
+(see
+.IR allocb (10.2)).
+.I B
+should be freed before return, whether the driver signals an error or not.
+Most drivers use the default
+.B devbwrite
+from
+.IR devattach (10.2),
+which calls the driver's
+.B write
+entry point using the data in
+.IR b .
+Drivers that manipulate Blocks internally, such as
+.IR ip (3),
+.IR ssl (3)
+and similar protocol devices,
+will provide a
+.B devbwrite
+implementation so as to avoid copying the data needlessly.
+.TP
+.BI remove( c )
+Remove the file referenced by
+.IR c .
+Most drivers raise an error by using the default
+.B devremove
+from
+.IR devattach (10.2).
+.TP
+.BI wstat( c\fP,\fP\ db\fP,\fP\ dbsize )
+Change the attributes of file
+.IR c ,
+using the
+.IR stat (5)
+data in buffer
+.IR db ,
+which is
+.I dbsize
+bytes long.
+Usually a driver will use
+.B convM2D
+of
+.IR styx (10.2)
+to convert the data to a
+.B Dir
+structure, then apply the rules of
+.IR stat (5)
+to decide which attributes are to be changed (and whether the change is allowed).
+Most drivers simply return an error on all
+.B wstat
+requests by using the default
+.B devwstat
+from
+.IR devattach (10.2).
+.TP
+.BI power( on )
+Reserved for use in native kernels, to allow the kernel
+to power the device on and off for power-saving;
+.I on
+is non-zero if the device is being powered up, and
+zero if it is being powered down.
+The device driver should save the device state if necessary.
+Leave the
+.B Dev
+entry null for now.
+.TP
+.BI config( on\fP,\fP\ spec\fP,\fP\ cf )
+Reserved for use in native kernels to allow a device
+to be configured on and off dynamically.
+Leave the
+.B Dev
+entry null for now.
+.PD
+.PP
+The elements
+.IR reset ,
+.IR shutdown ,
+.IR power ,
+and
+.IR config
+are currently present only in the native kernels.
+.SH SEE ALSO
+.IR intro (2),
+.IR intro (5),
+.IR allocb (10.2),
+.IR devattach (10.2),
+.IR newchan (10.2),
+.IR qio (10.2)
+
diff --git a/man/10/devattach b/man/10/devattach
new file mode 100644
index 00000000..718fe9b8
--- /dev/null
+++ b/man/10/devattach
@@ -0,0 +1,701 @@
+.TH DEVATTACH 10.2
+.SH NAME
+devattach, devclone, devdir, devgen, devwalk, devdirread, devstat, devopen, devbread, devbwrite, devcreate, devremove, devwstat, devreset, devinit, devshutdown, openmode \- common device driver support
+.SH SYNOPSIS
+.nf
+.ta \w'\fLBlock* 'u +10n
+.B
+typedef int
+.B
+Devgen(Chan *c, char *name, Dirtab *tab, int ntab, int i, Dir *dp)
+.PP
+.B
+Chan* devattach(int tc, char *spec)
+.PP
+.B
+Chan* devclone(Chan *c)
+.PP
+.B
+void devdir(Chan *c, Qid qid, char *n, long length,
+.B
+ char *user, long perm, Dir *dp)
+.PP
+.B
+int devgen(Chan *c, char *name, Dirtab *tab, int ntab,
+.B
+ int i, Dir *dp)
+.PP
+.B
+Walkqid* devwalk(Chan *c, Chan *nc, char **name, int nname,
+.B
+ Dirtab *tab, int ntab, Devgen *gen)
+.PP
+.B
+void devstat(Chan *c, uchar *db, int n, Dirtab *tab,
+.B
+ int ntab, Devgen *gen)
+.PP
+.B
+long devdirread(Chan *c, char *d, long n, Dirtab *tab,
+.B
+ int ntab, Devgen *gen)
+.PP
+.B
+Chan* devopen(Chan *c, int omode, Dirtab *tab,
+.B
+ int ntab, Devgen *gen)
+.PP
+.B
+Block* devbread(Chan *c, long n, ulong offset)
+.PP
+.B
+long devbwrite(Chan *c, Block *bp, ulong offset)
+.PP
+.B
+void devcreate(Chan*, char*, int, ulong)
+.PP
+.B
+void devremove(Chan*)
+.PP
+.B
+void devwstat(Chan*, uchar*, int)
+.PP
+.B
+void devreset(void)
+.PP
+.B
+void devinit(void)
+.PP
+.B
+void devshutdown(void)
+.PP
+.B
+int openmode(ulong mode)
+.SH DESCRIPTION
+Device drivers call these functions to carry out essential tasks and default actions.
+They do most of the name space management
+for a driver that serves a simple name space
+(eg, data and control files),
+leaving the driver to concentrate on the device-specific details
+of the I/O requests.
+More complex drivers also make good use of them at the leaves
+of their name space, and to help manage the
+.B Chan
+structures correctly.
+.PP
+A device has an associated
+.IR type ,
+represented as a Unicode character (`rune') that identifies the device
+inside and outside the kernel.
+It appears as the value of the
+.B type
+field in the
+.B Dir
+resulting from a
+.IR sys-stat (2)
+of any file provided by the device.
+A device is named outside the kernel using
+a path name starting with
+.B #
+followed by the device character
+(eg,
+.B c
+in
+.B #c
+for the console).
+Any subsequent characters before
+the next '/' or end of string is the `device specifier',
+interpreted solely by the device itself.
+.PP
+.I Devattach
+returns a new channel representing
+the root of the file tree
+corresponding to device type
+.IR tc ,
+with device specifier
+.IR spec .
+It is normally called by a driver's
+.I attach
+function (see
+.IR dev (10.2)).
+The
+.B qid
+for the new channel is
+.BR "(Qid){0,0,QTDIR}" ,
+suitable for a root directory for many devices, but
+a device driver is free to change it (provided the
+.B QTDIR
+bit remains in the
+.BR Qid.type ).
+.PP
+.I Devclone
+returns a new channel that is a copy of
+.IR c .
+An attempt to clone an open channel causes a
+.IR panic (10.2).
+.PP
+The
+.L Dir
+structure is shown below:
+.IP
+.EX
+typedef
+struct Dir
+{
+ /* system-modified data */
+ ushort type; /* server type */
+ uint dev; /* server subtype */
+ /* file data */
+ Qid qid; /* unique id from server */
+ ulong mode; /* permissions */
+ ulong atime; /* last read time */
+ ulong mtime; /* last write time */
+ vlong length; /* file length */
+ char *name; /* last element of path */
+ char *uid; /* owner name */
+ char *gid; /* group name */
+ char *muid; /* last modifier name */
+} Dir;
+.EE
+.PP
+This
+.B Dir
+structure corresponds directly to the Limbo
+.B Dir
+adt described in
+.IR sys-stat (2).
+.PP
+Given a channel and assorted other information,
+.I devdir
+initialises a Dir structure at
+.IR dp .
+.I Devdir
+supplies the following data itself:
+.RS
+.TF length
+.TP
+.B atime
+last access time (set to current time)
+.TP
+.B mtime
+last modification time (set to kernel creation date)
+.TP
+.B gid
+group name (set to
+.IR eve (10.2))
+.TP
+.B length
+length in bytes (set to zero, which
+is normal for most devices)
+.RE
+.PD
+.PP
+Note that
+.I devdir
+assigns the values of
+.I name
+and
+.I user
+directly to fields of
+.BI * dp,
+and consequently those values must remain valid until the last use of
+.BI * dp.
+(Sometimes that requires the use of an auxiliary buffer, such as
+.BR up->genbuf .)
+If channel
+.I c
+corresponds to a file descriptor on which Styx is served,
+.I devdir
+sets both the flag bit
+.B QTMOUNT
+in
+.IB dp ->qid.type
+and the flag bit
+.B DMMOUNT
+in
+.IB dp ->mode
+(see
+.I export
+in
+.IR sys-dial (2)
+and
+.I mount
+in
+.IR sys-bind (2)).
+.PP
+A simple name space can be represented in a driver by an array of
+.B Dirtab
+structures.
+The array is typically static when the names and permissions
+are static, but can be dynamically allocated and initialised if required.
+The structure of
+.B Dirtab
+is shown below:
+.IP
+.EX
+typedef
+struct Dirtab
+{
+ char name[KNAMELEN];
+ Qid qid;
+ vlong length;
+ long perm;
+} Dirtab;
+.EE
+.PP
+The name
+.RB ` . '
+.I must
+appear as the first entry in a
+.B Dirtab
+if the default
+.I devgen
+function is used.
+On the other hand, the name
+.RB ` .. '
+must never appear in a
+.B Dirtab
+table.
+Drivers that support a directory hierarchy must walk up the hierarchy towards
+the root when their
+.I walk
+function receives
+.RB ` .. '
+as a file name component.
+The name
+.RB ` . '
+is never seen by a driver.
+.PP
+The
+.IR devdirread ,
+.IR devopen ,
+.IR devstat ,
+and
+.IR devwalk
+functions all take a
+.I gen
+function argument,
+of type
+.BR Devgen ,
+which they invoke to retrieve the items in
+a
+.B Chan
+that represents a directory.
+.I Gen
+takes a channel
+.I c
+(a directory),
+a file
+.I name
+(which is nil except during
+.IR devwalk ),
+an array of
+.B Dirtab
+structures
+.I tab
+of length
+.IR ntab ,
+and a table index
+.IR i .
+The functions calling
+.I gen
+expect it to place the
+.IR i 'th
+entry in the directory into
+.IR \f5*\fPdp .
+It should return 1
+if the call was successful,
+-1 if
+.I i
+is beyond the index of the last directory entry,
+or 0 if there is no entry at
+.IR i ,
+but there are entries beyond it.
+When
+.I i
+has the special value
+.B DEVDOTDOT
+then
+.I gen
+should set
+.IR \f5*\fPdp
+to reflect the parent of
+.IR c ;
+if
+.I c
+is a one-level device directory, then `..' is equivalent to `.'.
+Custom implementations of
+.I gen
+often ignore
+.IR devtab ,
+and instead return their own dynamically generated
+set of directory entries from some other source.
+Exceptionally, during
+.I devwalk
+a non-nil
+.I name
+is provided: it is the name being looked up, and a device-specific
+.I gen
+can short-circuit the search by returning -1 if the name does not exist,
+or filling in
+.IR \f5*\fPdp
+and returning 1 if it does exist.
+.PP
+The function
+.I devgen
+is compatible with
+.BR Devgen ;
+it returns the
+.IR i 'th
+entry in
+.IR devtab ,
+and can be used to provide a simple, static
+set of directory entries.
+.PP
+.I Devwalk
+walks channel
+.I c
+to the file in the device named by the path encoded in
+.IR name ,
+which is an array of strings of length
+.IR nname .
+It provides the interface to
+.IR walk (5)
+within the kernel, and that specification must be well understood to appreciate
+all the nuances of its interface.
+Fortunately, in nearly all device drivers, a device's
+.I walk
+function typically passes its parameters on to
+.I devwalk
+(adding the device's own
+.B Dirtab
+array as the the value of
+.IR tab ),
+and simply returning the result of
+.IR devwalk .
+.PP
+.I Devwalk
+walks
+.I c
+using the given set of names, and if the walk is successful, the
+channel
+.I nc
+will refer to the result of the walk
+(specifically,
+.IB nc ->qid
+is set to the Qid for the file).
+If
+.I nc
+is nil,
+.I devwalk
+will allocate a new channel itself, that is initially a clone of
+.IR c .
+As in
+.IR walk (5),
+.I devwalk
+can return a partial result,
+represented by
+a dynamically allocated value of the following structure:
+.IP
+.EX
+struct Walkqid
+{
+ Chan *clone;
+ int nqid;
+ Qid qid[1]; /* actually nname in length */
+};
+.EE
+.PP
+The value must be freed after use.
+For each element of
+.I name ,
+.I devwalk
+passes
+the
+.I tab
+parameter to
+.I gen
+together with the currently-sought element of
+.IR name .
+If the first element is not found,
+.I devwalk
+returns nil; otherwise, it returns a
+.B Walkqid
+value in which
+.B nqid
+elements of the array
+.B qid
+are set to the qids (see
+.IR intro (5))
+of each valid element of
+.IR name .
+If all
+.I nname
+elements were successfully traversed, then
+.B nqid
+will have the value
+.IR nname ,
+and
+.B clone
+will refer to the result of the walk,
+which is either
+.I nc
+if given, or
+the new channel allocated by
+.IR devwalk .
+Otherwise, at least one element succeeded and
+.B nqid
+is less than
+.I nname
+and
+.B clone
+is nil.
+On an error or incomplete walk,
+the error string is set to the error that stopped the walk (eg,
+.B Enonexist
+or
+.BR Enotdir ).
+.PP
+.I Devstat
+fills the array of bytes
+.I db
+with data in the format produced by
+.IR stat (5)
+that describes the file
+referenced by channel
+.IR c ,
+which must have a corresponding entry
+returned by
+.IR gen
+(ie, an entry with matching
+.BR Qid.path ).
+If
+.I c
+is a communications channel connecting a Styx server to a current mount point,
+the
+.B DMMOUNT
+bit is set in the resulting
+.BR Dir.mode ,
+and
+.B QTMOUNT
+is set in
+.BR Dir.qid.type .
+As in
+.IR stat (5),
+the length of the data written to
+.I db
+varies; if more than
+.I n
+bytes are needed,
+.I devstat
+raises the
+.IR error (10.2)
+.BR Ebadarg .
+Otherwise, it returns the number of bytes in
+.I db
+actually used.
+.PP
+If an entry with the desired qid is not found in the table, but
+.I c
+corresponds to a directory
+(ie,
+.B QTDIR
+is set in
+.IR c\f5->qid.type\fP ),
+it is taken to be a
+.I stat
+of a notional directory containing the files listed in
+.IR tab .
+.I Dirstat
+then builds the corresponding Dir structure:
+its
+.B Dir.name
+is taken from
+.IR c\f5->path->elem\fP ;
+the length is
+.BI DIRLEN*nelem(tab) ;
+and
+.B Dir.perm
+is 0555 (read-execute for all).
+.PP
+.I Devdirread
+calls
+.I gen
+to obtain successive
+.B Dir
+structures representing entries in the open directory
+.IR c .
+These are converted to standard format (see
+.I convD2M
+in
+.IR styx (10.2))
+and placed in the buffer
+.IR b .
+It returns the number of bytes in the result.
+At most
+.I n
+bytes will be returned, in multiples of
+.BR DIRLEN .
+Because the kernel maintains the current offset in
+.IR c ,
+successive calls to
+.I devdirread
+return successive directory components.
+.PP
+.I Devopen
+is called to check and complete a request to open channel
+.I c
+for I/O according to
+.IR omode
+(the open mode of
+.IR sys-open (2)).
+It calls
+.I gen
+to obtain successive directory entries
+which it searches
+for a Qid matching that of
+.IR c ,
+and ensures that the current user has permission to open
+.I c
+with the given mode,
+.IR omode ,
+and that the mode itself is valid
+(see
+.I openmode
+below).
+Permission is checked against the permission in the
+matching entry.
+If no matching Qid is found, it is assumed
+that the notional parent directory of the files represented in
+.I tab
+is to be opened.
+Such a directory is deemed to have mode
+0555, allowing access by any user.
+A directory can only be opened for reading
+.RB ( OREAD ).
+.I Devopen
+returns the channel
+.I c
+on success.
+Last, it sets the bit
+.B COPEN
+in
+.B Chan.flag
+to mark
+.I c
+as open.
+This convention can always be relied upon by the driver's
+.I close
+function to tell if an open succeeded.
+On the otherhand,
+if the open request was unsuccessful,
+.I devopen
+raises an appropriate
+.IR error (10.2)
+and does not return.
+.PP
+.I Devbread
+returns a
+.B Block
+(see
+.IR allocb (10.2))
+containing up to
+.I n
+bytes read,
+using
+.BI "devtab[" c "->type]->read" ,
+from
+.I c
+starting at the given
+.IR offset .
+The read pointer in the returned
+.B Block
+points to the start of the data;
+the write pointer points to the next available byte.
+.PP
+.I Devbwrite
+writes the data in
+.B Block
+.I bp
+to the file
+.I c
+at the given
+.IR offset ,
+using the write function
+.BI "devtab[" c "->type]->write" .
+It then frees the block list
+.I bp
+before
+returning the number of bytes written.
+.PP
+Most built-in devices do not allow
+.IR create ,
+.IR remove
+or
+.I wstat
+on their files.
+.IR Devcreate ,
+.I devremove
+and
+.I devwstat
+are stubs that raise an
+.IR error (10.2),
+.BR Eperm .
+They can be named directly in a device driver's device
+switch (the
+.B Dev
+structure in
+.BR /os/port/portdat.h :
+see
+.IR dev (10.2)).
+.PP
+.IR Devreset ,
+.I devinit
+and
+.I devshutdown
+are also stubs;
+they do nothing.
+A device driver puts them in its
+.B Dev
+structure when it need take no action on device reset, initialisation, or shut down.
+.PP
+.I Openmode
+is used by a driver that does not use
+.IR devopen ,
+to check the open mode it receives in its open
+routine.
+.I Openmode
+returns mode
+.IR o ,
+the mode parameter to
+.IR sys-open (2)
+or
+.IR sys-create ,
+shorn of
+.BR OTRUNC
+and similar options,
+and reduced to one of
+.BR OREAD ,
+.BR OWRITE
+or
+.BR ORDWR .
+In particular,
+.B OEXEC
+becomes
+.B OREAD
+within the kernel.
+.I Openmode
+raises an
+.IR error (10.2)
+.B Ebadarg
+instead of returning, if
+.I o
+is an invalid mode (eg, reserved bits set).
+.SH SOURCE
+.B /emu/port/dev.c
+.br
+.B /os/port/dev.c
+.SH SEE ALSO
+.IR allocb (10.2),
+.IR eve (10.2),
+.IR qio (10.2)
diff --git a/man/10/dmainit b/man/10/dmainit
new file mode 100644
index 00000000..f0786c33
--- /dev/null
+++ b/man/10/dmainit
@@ -0,0 +1,86 @@
+.TH DMAINIT 10.2 x86
+.SH NAME
+dmainit, dmasetup, dmadone, dmaend, dmacount \- platform-specific DMA support
+.SH SYNOPSIS
+.ta \w'\fLushort 'u
+.B
+void dmainit(int chan)
+.PP
+.B
+long dmasetup(int chan, void *va, long len, int isread)
+.PP
+.B
+int dmadone(int chan)
+.PP
+.B
+void dmaend(int chan)
+.PP
+.B
+int dmacount(int chan)
+.PP
+.SH DESCRIPTION
+These functions manage DMA on a bus that uses ISA-style DMA controllers.
+They were originally devised for the x86 platform, but the same interface, and similar code,
+is used by other platforms that use similar controllers.
+They compensate as best they can for the limitations of older DMA implementations
+(eg, alignment, boundary and length restrictions).
+There are 8 DMA channels:
+0 to 3 are byte-oriented; 4 to 7 are word-oriented (16-bit words).
+.PP
+.I Dmainit
+must be called early in a driver's initialisation to prepare
+.I chan
+for use.
+Amongst other things, it allocates a page-sized buffer to help circumvent hardware
+restrictions on DMA addressing.
+.PP
+.I Dmasetup
+prepares DMA channel
+.IR chan
+for a transfer between a device configured to use it
+and the virtual address
+.IR va .
+(The transfer is started by issuing a command to the device.)
+If
+.I va
+lies outside the kernel address space,
+the transfer crosses a 64k boundary,
+or exceeds the 16 Mbyte limit imposed by some DMA controllers,
+the transfer will be split into page-sized transfers using the buffer previously allocated by
+.IR dmainit .
+If
+.I isread
+is true (non-zero), data is to be transferred from
+.I chan
+to
+.IR va ;
+if false, data is transferred from
+.I va
+to
+.IR chan .
+In all cases,
+.I dmasetup
+returns the number of bytes to be transferred.
+That value (rather than
+.IR len )
+must be given to the device in the read or write request that starts the transfer.
+.PP
+.I Dmadone
+returns true (non-zero) if
+.I chan
+is idle.
+.PP
+.I Dmaend
+must be called at the end of every DMA operation.
+It disables
+.IR chan ,
+preventing further access to the previously associated memory and,
+if a low-memory buffer was required for input, transfers its contents
+to the appropriate part of the target buffer.
+.PP
+.I Dmacount
+returns the number of bytes that were last transferred by channel
+.IR chan .
+The count is always even for word-oriented DMA channels.
+.SH SOURCE
+.B /os/pc/dma.c
diff --git a/man/10/dynld b/man/10/dynld
new file mode 100644
index 00000000..62971752
--- /dev/null
+++ b/man/10/dynld
@@ -0,0 +1,287 @@
+.TH DYNLD 10.2
+.SH NAME
+dynfindsym, dynfreeimport, dynloadfd, dynloadgen, dynobjfree, dyntabsize \- load object file dynamically
+.SH SYNOPSIS
+.B #include <lib9.h>
+.br
+.B #include <a.out.h>
+.br
+.B #include <dynld.h>
+.PP
+.ta \w'\fLDynsym*** 'u
+.B
+Dynsym* dynfindsym(char *name, Dynsym *syms, int nsym)
+.PP
+.B
+Dynobj* dynloadfd(int fd, Dynsym *exports, int nexport,
+.br
+.B
+ ulong maxsize)
+.PP
+.B
+Dynobj* dynloadgen(void *file, long (*read)(void*,void*,long),
+.br
+.B
+ vlong (*seek)(void*,vlong,int), void (*err)(char*),
+.br
+.B
+ Dynsym *exports, int nexport, ulong maxsize)
+.PP
+.B
+void* dynimport(Dynobj *o, char *name, ulong sig)
+.PP
+.B
+void dynfreeimport(Dynobj *o)
+.PP
+.B
+void dynobjfree(Dynobj *o)
+.PP
+.B
+int dyntabsize(Dynsym *t)
+.PP
+.B
+extern Dynsym _exporttab[];
+.DT
+.SH DESCRIPTION
+These functions allow a process to load further code and data
+into the currently executing image.
+A dynamically-loadable file, called a
+.I module
+here, is a variant of the
+.IR a.out (10.6)
+executable format with some extra components.
+The loader for the architecture
+(see
+.IR 2l (1))
+creates a module file from component object file(s) when given the
+.B -u
+option.
+A module contains text and data sections, an import table, an export table,
+and relocation data.
+The import table lists the symbols the module needs from the loading program;
+the export table lists symbols the module provides when loaded.
+A program that loads a module provides a table of its own symbols to match
+the symbols in the module's import table.
+.PP
+A symbol entry in a symbol table names a global function or data item, and has an associated
+.I signature
+value representing the type of the corresponding function or data in the source code.
+The
+.B Dynsym
+structure defines a symbol:
+.IP
+.EX
+typedef struct {
+ ulong sig;
+ ulong addr;
+ char* name;
+} Dynsym;
+.EE
+.PP
+The structure is known to the loaders
+.IR 2l (1).
+.I Name
+is the linkage name of the function or data.
+.I Addr
+is its address, which is relative to the start of the module before loading,
+and an address in the current address space after loading.
+The signature
+.I sig
+is the value produced by the C compiler's
+.B signof
+operator applied to the type.
+Symbol tables must be sorted by
+.IR name .
+.PP
+An executable that wishes to load modules will normally be linked using the
+.B -x
+option to the appropriate loader
+.IR 2l (1).
+The resulting executable contains an export table
+.B _exporttab
+that lists all the exported symbols of the program (by default, all external symbols).
+A nil name marks the end of the table.
+See
+.IR 2l (1)
+for details.
+The table can be given to the functions below to allow a loaded module
+to access those symbols.
+.PP
+A loaded module is described by a
+.B Dynobj
+structure:
+.IP
+.EX
+typedef struct {
+ ulong size; /* total size in bytes */
+ ulong text; /* bytes of text */
+ ulong data; /* bytes of data */
+ ulong bss; /* bytes of bss */
+ uchar* base; /* start of text, data, bss */
+ int nexport;
+ Dynsym* export; /* export table */
+ int nimport;
+ Dynsym** import; /* import table */
+} Dynobj;
+.EE
+.PP
+Several fields give sizes of the module's components, as noted in comments above.
+.I Base
+gives the address at which the module has been loaded.
+All its internal
+references have been adjusted where needed to reflect its current address.
+.I Export
+points to a symbol table listing the symbols exported by the module;
+.I nexport
+gives the table's length.
+.I Import
+points to a list of symbols imported by the module;
+note that each entry actually points to an entry in a symbol table
+provided by the program that loaded the module (see below).
+.I Nimport
+gives the import table's length.
+If the import table is not required, call
+.I dynfreeimport
+on the module pointer to free it.
+.PP
+.I Dynfindysm
+looks up the entry for the given
+.I name
+in symbol table
+.I syms
+(of length
+.IR nsym ).
+It returns a pointer to the entry if found; nil otherwise.
+The symbol table must be sorted by name in ascending order.
+.PP
+.I Dyntabsize
+returns the length of symbol table
+.IR t ,
+defined to be the number of
+.B Dynsym
+values starting at
+.I t
+that have non-nil
+.I name
+fields.
+It is used to find the length of
+.BR _exporttab .
+.PP
+.I Dynloadfd
+loads a module from the file open for reading on
+.IR fd ,
+and returns the resulting module pointer on success,
+or nil on error.
+If
+.I maxsize
+is non-zero
+the size of the dynamically-loaded module's code and data
+is limited to
+.I maxsize
+bytes.
+.I Exports
+is an array of
+.I nexport
+symbols in the current program that can be imported by the current module.
+It uses
+.IR read (2)
+and
+.IR seek (2)
+to access
+.IR fd ,
+and calls
+.I werrstr
+(see
+.IR errstr (2))
+to set the error string if necessary.
+.PP
+.I Dynloadgen
+is a more general function that can load a module from an
+arbitrary source, not just an open file descriptor.
+(In particular, it can be
+called by the kernel using functions internal to the kernel
+instead of making system calls.)
+.IR Exports ,
+.I nexport
+and
+.I maxsize
+are just as for
+.IR dynloadfd .
+.I File
+is a pointer to a structure defined by the caller that represents the file
+containing the module.
+It is passed to
+.I read
+and
+.IR seek .
+.I Read
+is invoked as
+.BI (*read)( file , buf ,\ \fInbytes\fP)\fR.\fP
+.I Read
+should read
+.I nbytes
+of data from
+.I file
+into
+.I buf
+and return the number of bytes transferred.
+It should return -1 on error.
+.I Seek
+is invoked as
+.BI (*seek)( file , n ,\ \fItype\fP)
+where
+.I n
+and
+.I type
+are just as for
+.IR seek (2);
+it should seek to the requested offset in
+.IR file ,
+or return -1 on error.
+.I Dynloadgen
+returns a pointer to the loaded module on success.
+On error,
+it returns nil after calling its
+.I err
+parameter to set the error string.
+.PP
+.I Dynimport
+returns a pointer to the value of the symbol
+.I name
+in loaded module
+.IR o ,
+or
+.I nil
+if
+.I o
+does not export a symbol with the given
+.IR name .
+If
+.I sig
+is non-zero, the exported symbol's signature must equal
+.IR sig ,
+or
+.I dynimport
+again returns nil.
+For example:
+.IP
+.EX
+Dev *d;
+d = dynimport(obj, "XXXdevtab", signof(*d));
+if(d == nil)
+ error("not a dynamically-loadable driver");
+.EE
+.PP
+.I Dynobjfree
+frees the module
+.IR o .
+There is no reference counting: it is the caller's responsibility to decide whether
+a module is no longer needed.
+.SH SEE ALSO
+.IR 2l (10.1),
+.\".IR mach (2),
+.IR a.out (10.6)
+.SH DIAGNOSTICS
+Functions that return pointers return nil on error.
+.I Dynloadfd
+sets the error string and returns nil.
diff --git a/man/10/error b/man/10/error
new file mode 100644
index 00000000..ca177d94
--- /dev/null
+++ b/man/10/error
@@ -0,0 +1,175 @@
+.TH ERROR 10.2
+.SH NAME
+error, nexterror, poperror, waserror \- error handling functions
+.SH SYNOPSIS
+.ta \w'\fLchar* 'u
+.B
+void error(char*)
+.PP
+.B
+void nexterror(void)
+.PP
+.B
+void poperror(void)
+.PP
+.B
+int waserror(void)
+.SH DESCRIPTION
+The kernel handles error conditions using non-local gotos,
+similar to
+.IR setjmp / longjmp
+in ANSI C,
+but using a stack of error labels to implement nested exception handling.
+This simplifies many of the internal interfaces by eliminating the need
+for returning and checking error codes at every level of the call stack,
+at the cost of requiring kernel routines to adhere to a strict discipline.
+.PP
+Each kernel process
+(see
+.IR kproc (10.2))
+has in its defining
+.B Proc
+structure a stack of labels,
+currently 32 elements deep.
+A kernel function that must perform a clean up or recovery action on an error
+makes a stylised call to
+.IR waserror ,
+.IR nexterror
+and
+.IR poperror :
+.IP
+.EX
+.DT
+if(waserror()){
+ /* recovery action */
+ nexterror();
+}
+/* normal action */
+poperror();
+.EE
+.PP
+When called in the normal course of events,
+.I waserror
+registers an error handling block by pushing its label onto the stack,
+and returns zero.
+The return value of
+.I waserror
+should be tested as shown above.
+If non-zero (true), the calling function should perform the needed
+error recovery, ended by a call to
+.I nexterror
+to transfer control to the next location on the error stack.
+Typical recovery actions include deallocating memory, unlocking resources, and
+resetting state variables.
+.PP
+Within the recovery block,
+after handling an error condition, there must normally
+be a call to
+.I nexterror
+to transfer control to any error recovery lower down in the stack.
+The main exception is in the outermost function in a process,
+which must not call
+.I nexterror
+(there being nothing further on the stack), but calls
+.I pexit
+(see
+.IR kproc (10.2))
+instead,
+to terminate the process.
+.PP
+When the need to recover a particular resource has passed,
+a function that has called
+.I waserror
+must
+remove the corresponding label from the stack by calling
+.IR poperror .
+This
+must
+be done before returning from the function; otherwise, a subsequent call to
+.I error
+will return to an obsolete activation record, with unpredictable but unpleasant consequences.
+.PP
+.I Error
+copies the given error message, which is limited to
+.B ERRMAX
+bytes, into the
+.B Osenv.errstr
+of the current process,
+enables interrupts by calling
+.I spllo
+.RI ( native
+only),
+and finally calls
+.I nexterror
+to start invoking the recovery procedures currently stacked by
+.IR waserror .
+The files
+.B /os/port/error.h
+and
+.B /emu/port/error.h
+offer a wide selection of predefined error messages, suitable for almost any occasion.
+The message set by the most recent call to
+.I error
+can be obtained within the kernel by examining
+.B up->env->error
+and in an application, by using the
+.L %r
+directive of
+.IR sys-print (2).
+.PP
+A complex function can have nested error handlers.
+A
+.I waserror
+block will follow the acquisition of a resource, releasing it
+on error before calling
+.I nexterror,
+and a
+.I poperror
+will precede its release in the normal case.
+For example:
+.IP
+.EX
+.DT
+void
+outer(Thing *t)
+{
+ qlock(t);
+ if(waserror()){ /* A */
+ qunlock(t);
+ nexterror();
+ }
+ m = mallocz(READSTR, 0);
+ if(m == nil)
+ error(Enomem);
+ if(waserror()){ /* B */
+ free(m);
+ nexterror(); /* invokes A */
+ }
+ inner(t);
+ poperror(); /* pops B */
+ free(m);
+ poperror(); /* pops A */
+ qunlock(t);
+}
+.sp 1v
+void
+inner(Thing *t)
+{
+ if(t->bad)
+ error(Egreg); /* error() call returns to B */
+ t->valid++;
+}
+.EE
+.SH SOURCE
+.B /os/port/proc.c
+.br
+.B /emu/port/main.c
+.SH CAVEATS
+The description above has many instances of
+.IR should ,
+.IR will ,
+.I must
+and
+.IR "must not" .
+.SH SEE ALSO
+.IR panic (10.2)
diff --git a/man/10/eve b/man/10/eve
new file mode 100644
index 00000000..8a20b77f
--- /dev/null
+++ b/man/10/eve
@@ -0,0 +1,42 @@
+.TH EVE 10.2
+.SH NAME
+eve, iseve \- privileged user
+.SH SYNOPSIS
+.ta \w'\fLchar* 'u
+.B
+char eve[NAMELEN] = "inferno";
+.PP
+.B
+int iseve(void)
+.SH DESCRIPTION
+.I Eve
+is a null-terminated string containing the name of the privileged user, often called
+the `host owner', in
+the Inferno system.
+The default identity in native systems is
+.LR inferno ,
+and in hosted Inferno it is the user who started
+.IR emu (1).
+The initial process created by system initialisation is given the
+.I eve
+identity.
+.PP
+.I Iseve
+returns true if the current user is
+.IR eve .
+Several drivers use
+.I iseve
+to check the caller's identity
+before granting permission to perform certain actions.
+For example, the console driver allows only the user
+.I eve
+to write a new identity into the
+.B /dev/user
+file.
+The privileges are strictly local and do not extend into the network
+(in particular, to file servers).
+.PP
+Note that the comparison performed by
+.I iseve
+is case-sensitive, even when running hosted on systems where
+usernames are case-insensitive.
diff --git a/man/10/getfields b/man/10/getfields
new file mode 100644
index 00000000..291ebce5
--- /dev/null
+++ b/man/10/getfields
@@ -0,0 +1,76 @@
+.TH GETFIELDS 10.2
+.SH NAME
+getfields, tokenize \- break a string into fields
+.SH SYNOPSIS
+.ta \w'\fLchar* \fP'u
+.B
+int getfields(char *str, char **args, int maxargs, int multiflag,
+.br
+.B
+ char *delims)
+.PP
+.B
+int tokenize(char *str, char **args, int maxargs)
+.SH DESCRIPTION
+.I Getfields
+breaks the null-terminated
+.SM UTF
+string
+.I str
+into at most
+.I maxargs
+null-terminated fields and places pointers to the start of these fields in the array
+.IR args .
+Some of the bytes in
+.I str
+are overwritten.
+If there are more than
+.I maxargs
+fields,
+only the first
+.I maxargs
+fields will be set.
+.I Delims
+is a
+.SM UTF
+string defining a set of delimiters.
+.PP
+If
+.I multiflag
+is zero,
+adjacent fields are separated by exactly one delimiter.
+A string containing
+.I n
+delimiter characters
+contains
+.IR n +1
+fields.
+If the
+.I multiflag
+argument is not zero,
+a field is a non-empty string of non-delimiters.
+.PP
+Getfields
+return the number of tokens processed.
+.PP
+.I Tokenize
+is the same as
+.I getfields
+with
+.I multiflag
+non-zero and
+.I delims
+\f5"\et\er\en "\fP,
+except that fields may be quoted using single quotes, in the manner
+of
+the command interpreter.
+.SH SOURCE
+.B /libkern/getfields.c
+.br
+.B /libkern/tokenize.c
+.br
+.B /lib9/getfields.c
+.br
+.B /lib9/tokenize.c
+.SH SEE ALSO
+.IR strcat (10.2)
diff --git a/man/10/iar b/man/10/iar
new file mode 100644
index 00000000..7d319c78
--- /dev/null
+++ b/man/10/iar
@@ -0,0 +1,183 @@
+.TH IAR 10.1
+.SH NAME
+iar \- archive and library maintainer
+.SH SYNOPSIS
+.B iar
+.I key
+[
+.I posname
+]
+.I afile
+[
+.I file ...
+]
+.SH DESCRIPTION
+.I Iar
+maintains groups of files
+combined into a single archive file,
+.IR afile .
+The main use of
+.I iar
+is to create and update library files for the loaders
+.IR 2l (10.1),
+etc.
+It can be used, though, for any similar purpose.
+.PP
+.I Key
+is one character from the set
+.BR drqtpmx ,
+optionally concatenated with
+one or more of
+.BR vuaibclo .
+The
+.I files
+are constituents of the archive
+.IR afile .
+The meanings of the
+.I key
+characters are:
+.TP
+.B d
+Delete
+.I files
+from the archive file.
+.TP
+.B r
+Replace
+.I files
+in the archive file, or add them if missing.
+Optional modifiers are
+.RS
+.PD0
+.TP
+.B u
+Replace only files with
+modified dates later than that of
+the archive.
+.TP
+.B a
+Place new files after
+.I posname
+in the archive rather than at the end.
+.TP
+.BR b " or " i
+Place new files before
+.I posname
+in the archive.
+.RE
+.PD
+.TP
+.B q
+Quick. Append
+.I files
+to the end of the archive without checking for duplicates.
+Avoids quadratic behavior in
+.LR "for (i in *.v) ar r lib.a $i" .
+.TP
+.B t
+List a table of contents of the archive.
+If names are given, only those files are listed.
+.TP
+.B p
+Print the named files in the archive.
+.TP
+.B m
+Move the named files to the end or elsewhere,
+specified as with
+.LR r .
+.TP
+.B o
+Preserve the access and modification times of files
+extracted with the
+.B x
+command.
+.TP
+.B x
+Extract the named files.
+If no names are given, all files in the archive are
+extracted.
+In neither case does
+.B x
+alter the archive file.
+.TP
+.B v
+Verbose.
+Give a file-by-file
+description of the making of a
+new archive file from the old archive and the constituent files.
+With
+.BR p ,
+precede each file with a name.
+With
+.BR t ,
+give a long listing of all information about the files,
+somewhat like a listing by
+.IR ls (1),
+showing
+.br
+.ns
+.IP
+.B
+ mode uid/gid size date name
+.TP
+.B c
+Create.
+Normally
+.I iar
+will create a new archive when
+.I afile
+does not exist, and give a warning.
+Option
+.B c
+discards any old contents and suppresses the warning.
+.TP
+.B l
+Local.
+Normally
+.I iar
+places its temporary files in the directory
+.BR /tmp .
+This option causes them to be placed in the local directory.
+.PP
+When a
+.BR d ,
+.BR r ,
+or
+.BR m
+.I key
+is specified and all members of the archive are valid object files for
+the same architecture,
+.I iar
+inserts a table of contents, required by the loaders, at
+the front of the library.
+The table of contents is
+rebuilt whenever the archive is modified, except
+when the
+.B q
+.I key
+is specified or when the table of contents is
+explicitly moved or deleted.
+.SH EXAMPLE
+.TP
+.L
+iar cr lib.a *.v
+Replace the contents of library
+.L lib.a
+with the object files in the current directory.
+.SH FILES
+.TF /tmp/vxxxx
+.TP
+.B /tmp/v*
+temporaries
+.SH SOURCE
+.B /utils/iar
+.SH "SEE ALSO"
+.IR 2l (10.1),
+.IR ar (10.6)
+.SH BUGS
+If the same file is mentioned twice in an argument list,
+it may be put in the archive twice.
+.br
+The file format used by this command is taken from UNIX, and
+makes some invalid assumptions,
+for instance that user IDs are numeric.
diff --git a/man/10/inb b/man/10/inb
new file mode 100644
index 00000000..5e30d496
--- /dev/null
+++ b/man/10/inb
@@ -0,0 +1,84 @@
+.TH INB 10.2 x86
+.SH NAME
+inb, ins, inl, outb, outs, outl, insb, inss, insl, outsb, outss, outsl \- programmed I/O
+.SH SYNOPSIS
+.ta \w'\fLushort 'u
+.B
+int inb(int port)
+.PP
+.B
+ushort ins(int port)
+.PP
+.B
+ulong inl(int port)
+.PP
+.B
+void outb(int port, int value)
+.PP
+.B
+void outs(int port, ushort value)
+.PP
+.B
+void outl(int port, ulong value)
+.PP
+.B
+void insb(int port, void *address, int count)
+.PP
+.B
+void inss(int port, void *address, int count)
+.PP
+.B
+void insl(int port, void *address, int count)
+.PP
+.B
+void outsb(int port, void *address, int count)
+.PP
+.B
+void outss(int port, void *address, int count)
+.PP
+.B
+void outsl(int port, void *address, int count)
+.SH DESCRIPTION
+The
+.I x86
+implementation provides functions to allow kernel code
+written in C to access the I/O address space.
+On several other architectures such as the PowerPC and Strongarm,
+the platform-dependent code provides similar functions to access
+devices with an I/O space interface, even when that is memory mapped, to encourage portability of device drivers.
+.PP
+.IR Inb ,
+.I ins
+and
+.I inl
+apply the corresponding hardware instruction to fetch the next byte, short or long
+from the I/O
+.IR port .
+.IR Outb ,
+.I outs
+and
+.I outl
+output a
+.I value
+to the I/O
+.IR port .
+.PP
+The remaining functions transfer
+.I count
+bytes, shorts, or longs using programmed I/O between a memory
+.I address
+and
+.IR port .
+Functions
+.BI ins x
+copy values into memory; functions
+.BI outs x
+copy values from memory.
+The
+.I count
+is in elements, not bytes.
+.SH SOURCE
+.B /os/pc/l.s
+.SH SEE ALSO
+.IR dma (10.2),
+.IR isaconfig (10.2)
diff --git a/man/10/inm b/man/10/inm
new file mode 100644
index 00000000..61d86f65
--- /dev/null
+++ b/man/10/inm
@@ -0,0 +1,102 @@
+.TH INM 10.1
+.SH NAME
+inm \- Inferno name list (symbol table)
+.SH SYNOPSIS
+.B inm
+[
+.B -aghnsu
+]
+.I file ...
+.SH DESCRIPTION
+.I Inm
+prints the name list of each executable or object
+.I file
+in the argument list.
+If the
+.I file
+is an archive
+(see
+.IR iar (10.1)),
+the name list of each file in the archive is printed.
+If more than one file is given in the argument list,
+the name of each file is printed at the beginning of each line.
+.PP
+Each symbol name is preceded by its hexadecimal
+value (blanks if undefined)
+and one of the letters
+.TP
+.B T
+text segment symbol
+.PD0
+.TP
+.B t
+static text segment symbol
+.TP
+.B L
+leaf function text segment symbol
+.TP
+.B l
+static leaf function text segment symbol
+.TP
+.B D
+data segment symbol
+.TP
+.B d
+static data segment symbol
+.TP
+.B B
+bss segment symbol
+.TP
+.B b
+static bss segment symbol
+.TP
+.B a
+automatic (local) variable symbol
+.TP
+.B p
+function parameter symbol
+.TP
+.B z
+source file name
+.TP
+.B Z
+source file line offset
+.TP
+.B f
+source file name components
+.PD
+.PP
+The output is sorted alphabetically.
+.PP
+Options are:
+.TP
+.B -a
+Print all symbols; normally only user-defined text, data,
+and bss segment symbols are printed.
+.TP
+.B -g
+Print only global
+.RB ( T ,
+.BR L ,
+.BR D ,
+.BR B )
+symbols.
+.TP
+.B -h
+Do not print file name headers with output lines.
+.TP
+.B -n
+Sort according to the address of the symbols.
+.TP
+.B -s
+Don't sort; print in symbol-table order.
+.TP
+.B -u
+Print only undefined symbols.
+.SH SOURCE
+.B /utils/nm
+.SH SEE ALSO
+.IR iar (10.1),
+.IR 2l (10.1),
+.IR acid (10.1),
+.IR a.out (10.6)
diff --git a/man/10/intrenable b/man/10/intrenable
new file mode 100644
index 00000000..a6d508e3
--- /dev/null
+++ b/man/10/intrenable
@@ -0,0 +1,106 @@
+.TH INTRENABLE 10.2
+.SH NAME
+intrenable, intrdisable \- enable (disable) an interrupt handler
+.SH SYNOPSIS
+.ta \w'\fLvoid* 'u
+.B
+void intrenable(int v, void (*f)(Ureg*, void*), void* a, int tbdf, char *name)
+.PP
+.B
+void intrdisable(int v, void (*f)(Ureg*, void*), void* a, int tbdf, char *name)
+.SH DESCRIPTION
+.I Intrenable
+registers
+.I f
+to be called by the kernel's interrupt controller driver each time
+an interrupt denoted by
+.I v
+occurs, and unmasks the corresponding interrupt in the interrupt controller.
+The encoding of
+.I v
+is platform-dependent; it is often an interrupt vector number, but
+can be more complex.
+.I Tbdf
+is a platform-dependent value that might further qualify
+.IR v .
+It might for instance
+denote the type of bus, bus instance, device number and function
+(following the PCI device indexing scheme), hence its name,
+but can have platform-dependent meaning.
+.I Name
+is a string that should uniquely identify the corresponding device (eg, \f5"uart0"\fP);
+again it is usually platform-dependent.
+.I Intrenable
+supports sharing of interrupt levels when the hardware does.
+.PP
+Almost invariably
+.I f
+is a function defined in a device driver to carry out the device-specific work associated with a given interrupt.
+The pointer
+.I a
+is passed to
+.IR f ;
+typically it points to the driver's data for a given device or controller.
+It also passes
+.I f
+a
+.B Ureg*
+value that
+contains the registers saved by the interrupt handler (the
+contents are platform specific;
+see the platform's include file
+.BR "ureg.h" ).
+.PP
+.I F
+is invoked by underlying code in the kernel that is invoked directly from the hardware vectors.
+It is therefore not running in any process (see
+.IR kproc (10.2);
+indeed, on many platforms
+the current process pointer
+.RB ( up )
+will be nil.
+There are many restrictions on kernel functions running outside a process, but a fundamental one is that
+they must not
+.IR sleep (10.2),
+although they often call
+.B wakeup
+to signal the occurrence of an event associated with the interrupt.
+.IR Qio (10.2)
+and other manual pages note which functions are safe for
+.I f
+to call.
+.PP
+The interrupt controller driver does whatever is
+required to acknowledge or dismiss the interrupt signal in the interrupt controller,
+before calling
+.IR f ,
+for edge-triggered interrupts,
+and after calling
+.IR f
+for level-triggered ones.
+.I F
+is responsible for deal with the cause of the interrupt in the device, including any
+acknowledgement required in the device, before it returns.
+.PP
+.I Intrdisable
+removes any registration previously made by
+.I intrenable
+with matching parameters, and if no other
+interrupt is active on
+.IR v ,
+it masks the interrupt in the controller.
+Device drivers that are not dynamically configured tend to call
+.I intrenable
+during reset or initialisation (see
+.IR dev (10.2)),
+but can call it at any appropriate time, and
+instead of calling
+.I intrdisable
+they can simply enable or disable interrupts in the device as required.
+.SH SOURCE
+.B /os/*/trap.c
+.SH SEE ALSO
+.IR malloc (10.2),
+.IR qio (10.2),
+.IR sleep (10.2),
+.IR splhi (10.2)
diff --git a/man/10/kbdputc b/man/10/kbdputc
new file mode 100644
index 00000000..08fe3830
--- /dev/null
+++ b/man/10/kbdputc
@@ -0,0 +1,105 @@
+.TH KBDPUTC 10.2
+.SH NAME
+kbdputc, kbdrepeat, kbdclock, kbdq \- keyboard interface to \fIcons\fP(3)
+.SH SYNOPSIS
+.ta \w'\f5extern\ \ \f1'u
+.B
+#include "keyboard.h"
+.PP
+.B
+void kbdputc(Queue *q, int c)
+.PP
+.B
+void kbdrepeat(int on)
+.PP
+.B
+void kbdclock(void)
+.PP
+.B
+extern Queue *kbdq;
+.SH DESCRIPTION
+This is the internal interface between
+.B /dev/keyboard
+of
+.IR cons (3)
+and the architecture-dependent keyboard driver.
+Before calling any of these functions,
+the global variable
+.B kbdq
+must be initialised;
+.IR cons (3)
+does not initialise it.
+This is usually done during system initialisation by the keyboard driver's
+.I kbdinit
+function ,
+as follows:
+.IP
+.EX
+kbdq = qopen(4*1024, 0, 0, 0);
+qnoblock(kbdq, 1);
+.EE
+.PP
+.I Kbdputc
+puts a 16-bit Unicode character
+.I c
+(ie, a `rune')
+on the given
+.IR q ,
+as a sequence of bytes in UTF-8 encoding
+(see
+.IR utf (6)).
+If
+.I c
+is the special value
+.B Latin
+(defined by
+.BR keyboard.h ),
+.I kbdputc
+starts collecting characters, looking for the typeable representations of
+Unicode characters defined by
+.IR keyboard (6);
+at the end of a complete such sequence,
+.I kbdputc
+queues the UTF-8 encoding of the corresponding Unicode character.
+It is up to the keyboard driver to map a suitable physical keyboard character
+(or combination of characters) to the code
+.BR Latin .
+.PP
+Drivers that need to implement repeat of keypresses in software
+should call
+.IP
+.EX
+addclock0link(kbdclock);
+.EE
+.PP
+at the end of
+.IR kbdinit ,
+to cause
+.I kbdclock
+to be called each clock tick.
+.I Kbdrepeat
+can then be called to enable
+.RI ( on
+is non-zero)
+or disable it
+.RI ( on
+is zero).
+When repeat is on,
+.I kbdclock
+(when called) will periodically call
+.BI "kbdputc(" kbdq , c )
+where
+.I c
+is the last rune given to
+.IR kbdputc .
+The driver is responsible for enabling and disabling repeat appropriately;
+for instance, function keys and certainly
+.B Latin
+should typically not be repeated.
+.SH SOURCE
+.B /os/*/kbd*.c
+.SH SEE ALSO
+.IR cons (3),
+.IR utf (6),
+.IR qio (10.2)
+
diff --git a/man/10/kproc b/man/10/kproc
new file mode 100644
index 00000000..eff495c2
--- /dev/null
+++ b/man/10/kproc
@@ -0,0 +1,142 @@
+.TH KPROC 10.2
+.SH NAME
+kproc, setpri, swiproc, pexit \- kernel process creation, priority change, interrupt and termination
+.SH SYNOPSIS
+.ta \w'\fLchar* 'u
+.B
+void kproc(char *name, void (*func)(void*), void *arg, int flags);
+.PP
+.B
+int setpri(int pri);
+.PP
+.B
+void swiproc(Proc *p, int interp);
+.PP
+.B
+void pexit(char*, int);
+.SH DESCRIPTION
+.I Kproc
+creates a new Inferno kernel process
+to run the function
+.IR func ,
+which is invoked as
+.BR "(*func)(arg)" .
+The string
+.I name
+is copied into the
+.B text
+field of the
+.B Proc
+structure of the new process; although the value is not visible to Limbo
+applications, it can appear in system messages written to the console.
+The process is made runnable; it
+will run when selected by the scheduler.
+.PP
+The new process always acquires the following attributes from the creating process:
+.IP
+owner (Inferno user name)
+.br
+host user and group IDs (in
+.I emu
+only)
+.br
+floating-point attributes
+.PP
+Several resources can be shared with the creating process on request, as determined by
+.IR flags ,
+which is the logical OR
+of a subset of the following:
+.TF KPDUPENVG
+.TP
+.B KPDUPPG
+If set, the new process shares the caller's process group,
+which includes its process group ID
+(for
+.IR killgrp ),
+name space (mounts, root and current directory),
+and PIN for
+.B /dev/pin
+(see
+.IR cons (3)).
+.TP
+.B KPDUPFDG
+If set, the new process shares the caller's file descriptor group;
+otherwise, it has no file descriptor group, and (if it intends to open files) must call
+.IR newfgrp (10.2)
+to obtain an empty file descriptor group.
+.TP
+.B KPDUPENVG
+If set, the new process shares the caller's environment group
+(currently applies in
+.I emu
+only).
+.TP
+.B KPDUP
+Equivalent to all of the above.
+.PD
+.PP
+If a particular option is not set, the new process will have a
+.B nil
+reference for the corresponding resource.
+.PP
+.I Setpri
+sets the priority of the calling process to
+.I pri
+and returns its previous priority level.
+If a (now) higher priority process is ready to run, the system will reschedule.
+The available priority levels are shown below,
+arranged from highest to lowest priority,
+with examples of the type of processes intended to use them:
+.TF PriBackground
+.TP
+.B PriLock
+The highest priority, used by
+.IR lock (10.2)
+for a process entering a critical section
+.TP
+.B PriRealtime
+Intended for processes supporting applications with real-time constraints, such as video telephony.
+.TP
+.B PriHicodec
+MPEG codec
+.TP
+.B PriLocodec
+Audio codec
+.TP
+.B PriHi
+Any task with keen time constraints.
+.TP
+.B PriNormal
+The priority of most processes in the system.
+.TP
+.B PriLo
+.TP
+.B PriBackground
+.PD
+.PP
+.I Swiproc
+sends a software interrupt to process
+.IR p ,
+causing it to wake from
+.IR sleep (10.2)
+with an
+.IR error (10.2)
+`interrupted'.
+Unless
+.I interp
+is non-zero (ie, the Dis interpreter is the caller), the process is also marked `killed'.
+.PP
+An Inferno process terminates only when it calls
+.IR pexit ,
+thereby terminating itself.
+There is no mechanism for one process to force the termination of another,
+although it can send a software interrupt using
+.IR swiproc .
+The arguments to
+.I pexit
+are ignored in Inferno, but are included for compatibility
+with kernel components of Plan 9; use
+.IP
+.EX
+pexit("", 0);
+.EE
diff --git a/man/10/kprof b/man/10/kprof
new file mode 100644
index 00000000..4df39888
--- /dev/null
+++ b/man/10/kprof
@@ -0,0 +1,34 @@
+.TH KPROF 10.1
+.SH NAME
+kprof \- display kernel profiling data
+.SH SYNOPSIS
+.B kprof
+.I kernel
+.I kpdata
+.SH DESCRIPTION
+.I Kprof
+presents the data accumulated by the kernel
+profiling device,
+.IR kprof (3) .
+The symbol table is taken from the file
+.IR kernel ,
+the executable file of the operating system kernel that
+was profiled.
+The data file
+.I kpdata
+is usually a copy of
+.BR /dev/kpdata
+from the device running the profiling kernel.
+.PP
+The symbol table
+is read and correlated with the
+profile data.
+For each symbol, the time (in milliseconds)
+spent executing between that symbol
+and the next
+is printed (in decreasing order),
+together with the percentage of the total time.
+.SH SOURCE
+.B /utils/kprof
+.SH SEE ALSO
+.IR kprof (3)
diff --git a/man/10/ksize b/man/10/ksize
new file mode 100644
index 00000000..824200b2
--- /dev/null
+++ b/man/10/ksize
@@ -0,0 +1,29 @@
+.TH KSIZE 10.1
+.SH NAME
+ksize \- print size of kernel images
+.SH SYNOPSIS
+.B ksize
+[
+.I file ...
+]
+.SH DESCRIPTION
+.I Ksize
+prints the size of the segments for each of the argument executable files
+(default
+.BR 8.out ).
+The format is
+.IP
+.IB textsize t
++
+.IB datasize d
++
+.IB bsssize b
+=
+.I total
+.PP
+where the numbers are in bytes.
+.SH SOURCE
+.B /utils/ksize
+.SH "SEE ALSO
+.IR kstrip (10.1),
+.IR a.out (10.6)
diff --git a/man/10/kstrip b/man/10/kstrip
new file mode 100644
index 00000000..3346c622
--- /dev/null
+++ b/man/10/kstrip
@@ -0,0 +1,32 @@
+.TH KSTRIP 10.1
+.SH NAME
+kstrip \- remove symbols from kernel images
+.SH SYNOPSIS
+.B kstrip
+.I file ...
+.PP
+.B kstrip
+.B -o
+.I ofile
+.I file
+.SH DESCRIPTION
+.I Kstrip
+removes symbol table segments from executable files,
+rewriting the files in place.
+Stripping a file requires write permission on the file
+and the directory it is in.
+.PP
+If the
+.B -o
+flag is given,
+the single input file
+.I file
+is stripped and the result written to
+.IR ofile .
+.I File
+is unchanged.
+.SH SOURCE
+.B /utils/kstrip
+.SH "SEE ALSO"
+.IR ksize (10.1),
+.IR a.out (10.6)
diff --git a/man/10/lock b/man/10/lock
new file mode 100644
index 00000000..9c9e04cd
--- /dev/null
+++ b/man/10/lock
@@ -0,0 +1,110 @@
+.TH LOCK 10.2
+.SH NAME
+lock, canlock, ilock, iunlock, unlock \- spin locks
+.SH SYNOPSIS
+.ta \w'\fLvoid 'u
+.B
+void lock(Lock *l)
+.PP
+.B
+int canlock(Lock *l)
+.PP
+.B
+void unlock(Lock *l)
+.PP
+.B
+void ilock(Lock *l)
+.PP
+.B
+void iunlock(Lock *l)
+.SH DESCRIPTION
+These primitives control access to shared
+resources using spin locks.
+They in turn are used to build higher-level synchronisation mechanisms
+such as those described in
+.IR sleep (10.2),
+.IR qlock (10.2)
+and
+.IR qio (10.2).
+They should be used only to protect short critical sections
+that update shared data structures.
+.PP
+.I Lock
+loops repeatedly attempting acquire the spin lock
+.I l
+until it succeeds.
+.I Lock
+should not be used to lock a structure shared with an interrupt handler
+unless interrupts are disabled by
+.IR splhi (10.2)
+before attempting the lock;
+it is better to use
+.IR ilock ,
+below.
+.PP
+.I Canlock
+is non-blocking.
+Only one attempt is made for the lock.
+It returns non-zero if the lock was successfully acquired; 0 otherwise.
+.PP
+.I Unlock
+releases the lock
+.IR l .
+A lock must be unlocked only by the locking process.
+.PP
+When called by a process, the functions above temporarily boost its priority
+to the highest priority,
+.BR PriLock ;
+its original priority is restored at the end of the critical section by
+.IR unlock .
+On a uniprocessor, if
+.I l
+is unavailable,
+.I lock
+can reschedule unless interrupts are disabled before entering
+.I lock
+or there is no current process (eg, when executing the scheduler).
+.PP
+.I Ilock
+disables interrupts before attempting to acquire the lock.
+It should be used to lock a resource shared between a process and an interrupt handler.
+On a uniprocessor, disabling interrupts is sufficient to exclude an interrupt handler
+from the critical section,
+and on a multiprocessor the spin lock excludes an interrupt handler running on another processor.
+.I Ilock
+never reschedules the caller, nor must a caller allow itself to be rescheduled
+(eg, by calling
+.IR sleep (10.2))
+before releasing the lock.
+.PP
+.I Iunlock
+releases a lock previously got by
+.IR ilock .
+.SH DIAGNOSTICS
+The lock functions
+guard against the possibility of never acquiring the lock by capping the number of lock attempts.
+If the limit is reached, a message of
+the following form is written on the console:
+.IP
+.EX
+lock loop on \fIlock-address\fP key \fIkey-value\fP pc \fIcaller-pc\fP held by pc \fIlock-pc\fP
+.EE
+.PP
+Most lock loops represent deadlocks caused by failing to unlock a resource,
+attempting to lock (eg, by recursive call) a resource already held by the process,
+inconsistent locking and unlocking of nested resources, using a spin-lock
+to guard code that reschedules, using
+.I lock
+not
+.I ilock
+to interlock with an interrupt routine, and similar blunders.
+.SH SOURCE
+.B /os/port/taslock.c
+.br
+.B /os/*/l.s
+.br
+.B /emu/port/lock.c
+.br
+.B /emu/*/os.c
+.SH SEE ALSO
+.IR qlock (10.2)
diff --git a/man/10/malloc b/man/10/malloc
new file mode 100644
index 00000000..d79ccc45
--- /dev/null
+++ b/man/10/malloc
@@ -0,0 +1,81 @@
+.TH MALLOC 10.2
+.SH NAME
+malloc, mallocz, smalloc, free, realloc, calloc \- kernel memory allocators
+.SH SYNOPSIS
+.ta \w'\fLvoid* 'u
+.B
+void* malloc(ulong size)
+.PP
+.B
+void* mallocz(ulong size, int clr)
+.PP
+.B
+void* smalloc(ulong size)
+.PP
+.B
+void* realloc(void *p, ulong size)
+.PP
+.B
+void* calloc(ulong n, ulong szelem)
+.PP
+.B
+void free(void *p)
+.SH DESCRIPTION
+These functions allocate memory from the
+.B mainmem
+memory pool.
+All but
+.I smalloc
+(which sleeps)
+may safely be called by interrupt handlers.
+.PP
+.I Malloc
+returns a pointer to a block of at least
+.I size
+bytes, initialised to zero.
+The result is aligned on a 32-bit boundary.
+.I Mallocz
+is similar, but only clears the memory if
+.I clr
+is non-zero.
+.PP
+.I Smalloc
+returns a pointer to a block of
+.I size
+bytes, initialised to zero.
+If the memory is not immediately available,
+.I smalloc
+retries every 100 milliseconds until the memory is acquired.
+.PP
+.I Calloc
+returns a pointer to a block of memory of at least
+.I "n*szelem"
+bytes, initialised to zero.
+.PP
+.I Realloc
+changes the size of the block pointed to by
+.I p
+to
+.I size
+bytes,
+if possible without moving the data,
+and returns a pointer to the block.
+The contents are unchanged up to the lesser of old and new sizes,
+and any new space allocated is initialised to zero.
+If
+.I p
+is a null pointer,
+.I realloc
+returns the equivalent of
+.BR "malloc(size)" .
+.PP
+The argument to
+.I free
+is a pointer to a block of memory allocated by one of the routines above, which
+is returned to the allocation pool, or a null pointer, which is ignored.
+.SH DIAGNOSTICS
+All functions except
+.I smalloc
+return a null pointer if space is unavailable.
+.SH SEE ALSO
+.IR xalloc (10.2)
diff --git a/man/10/memory b/man/10/memory
new file mode 100644
index 00000000..0b11e7ed
--- /dev/null
+++ b/man/10/memory
@@ -0,0 +1,117 @@
+.TH MEMORY 10.2
+.SH NAME
+memccpy, memchr, memcmp, memcpy, memmove, memset \- memory operations
+.SH SYNOPSIS
+.ta \w'\fLvoid* 'u
+.B
+void* memccpy(void *s1, void *s2, int c, long n)
+.PP
+.B
+void* memchr(void *s, int c, long n)
+.PP
+.B
+int memcmp(void *s1, void *s2, long n)
+.PP
+.B
+void* memcpy(void *s1, void *s2, long n)
+.PP
+.B
+void* memmove(void *s1, void *s2, long n)
+.PP
+.B
+void* memset(void *s, int c, long n)
+.SH DESCRIPTION
+These functions operate efficiently on memory areas
+(arrays of bytes bounded by a count, not terminated by a zero byte).
+They do not check for the overflow of any receiving memory area.
+.PP
+.I Memccpy
+copies bytes from memory area
+.I s2
+into
+.IR s1 ,
+stopping after the first occurrence of byte
+.I c
+has been copied, or after
+.I n
+bytes have been copied, whichever comes first.
+It returns a pointer to the byte after
+the copy of
+.I c
+in
+.IR s1 ,
+or zero if
+.I c
+was not found in the first
+.I n
+bytes of
+.IR s2 .
+.PP
+.I Memchr
+returns a pointer to the first
+occurrence of byte
+.I c
+in the first
+.I n
+bytes of memory area
+.IR s,
+or zero if
+.I c
+does not occur.
+.PP
+.I Memcmp
+compares its arguments, looking at the first
+.I n
+bytes only, and returns an integer
+less than, equal to, or greater than 0,
+according as
+.I s1
+is lexicographically less than, equal to, or
+greater than
+.IR s2 .
+The comparison is bytewise unsigned.
+.PP
+.I Memmove
+copies
+.I n
+bytes from memory area
+.I s2
+to
+.IR s1 .
+It returns
+.IR s1 .
+It is guaranteed to work if
+.I s1
+and
+.IR s2
+overlap.
+.PP
+In the Inferno kernel
+.I memcpy
+is equivalent to
+.IR memmove .
+(In ANSI C, by contrast,
+.I memcpy
+does not account for overlapping memory regions.)
+.PP
+.I Memset
+sets the first
+.I n
+bytes in memory area
+.I s
+to the value of the least significant byte of
+.IR c .
+It returns
+.IR s .
+.SH DIAGNOSTICS
+If
+.I memcpy
+and
+.I memmove
+are handed negative counts, they abort.
+.SH SOURCE
+.BR /libkern/mem*.c
+.br
+.BR /libkern/mem*-\fIobjtype\fP.s
+.SH SEE ALSO
+.IR strcat (10.2)
diff --git a/man/10/mk b/man/10/mk
new file mode 100644
index 00000000..de5dc6d7
--- /dev/null
+++ b/man/10/mk
@@ -0,0 +1,668 @@
+.TH MK 10.1
+.SH NAME
+mk \- maintain (make) related files
+.SH SYNOPSIS
+.B mk
+[
+.B -f
+.I mkfile
+] ...
+[
+.I option ...
+]
+[
+.I target ...
+]
+.SH DESCRIPTION
+.I Mk
+uses the dependency rules specified in
+.I mkfile
+to control the update (usually by compilation) of
+.I targets
+(usually files)
+from the source files upon which they depend.
+The
+.I mkfile
+(default
+.LR mkfile )
+contains a
+.I rule
+for each target that identifies the files and other
+targets upon which it depends and an
+.IR rc (10.1)
+script, a
+.IR recipe ,
+to update the target.
+The script is run if the target does not exist
+or if it is older than any of the files it depends on.
+.I Mkfile
+may also contain
+.I meta-rules
+that define actions for updating implicit targets.
+If no
+.I target
+is specified, the target of the first rule (not meta-rule) in
+.I mkfile
+is updated.
+.PP
+The environment variable
+.B $NPROC
+determines how many targets may be updated simultaneously;
+Plan 9 sets
+.B $NPROC
+automatically to the number of CPUs on the current machine.
+.PP
+Options are:
+.TP \w'\fL-d[egp]\ 'u
+.B -a
+Assume all targets to be out of date.
+Thus, everything is updated.
+.PD 0
+.TP
+.BR -d [ egp ]
+Produce debugging output
+.RB ( p
+is for parsing,
+.B g
+for graph building,
+.B e
+for execution).
+.TP
+.B -e
+Explain why each target is made.
+.TP
+.B -i
+Force any missing intermediate targets to be made.
+.TP
+.B -k
+Do as much work as possible in the face of errors.
+.TP
+.B -n
+Print, but do not execute, the commands
+needed to update the targets.
+.TP
+.B -s
+Make the command line arguments sequentially rather than in parallel.
+.TP
+.B -t
+Touch (update the modified date of) file targets, without
+executing any recipes.
+.TP
+.BI -w target1 , target2,...
+Pretend the modify time for each
+.I target
+is the current time; useful in conjunction with
+.B -n
+to learn what updates would be triggered by
+modifying the
+.IR targets .
+.PD
+.SS The \fLmkfile\fP
+A
+.I mkfile
+consists of
+.I assignments
+(described under `Environment') and
+.IR rules .
+A rule contains
+.I targets
+and a
+.IR tail .
+A target is a literal string
+and is normally a file name.
+The tail contains zero or more
+.I prerequisites
+and an optional
+.IR recipe ,
+which is an
+.B rc
+script.
+Each line of the recipe must begin with white space.
+A rule takes the form
+.IP
+.EX
+target: prereq1 prereq2
+ rc \f2recipe using\fP prereq1, prereq2 \f2to build\fP target
+.EE
+.PP
+When the recipe is executed,
+the first character on every line is elided.
+.PP
+After the colon on the target line, a rule may specify
+.IR attributes ,
+described below.
+.PP
+A
+.I meta-rule
+has a target of the form
+.IB A % B
+where
+.I A
+and
+.I B
+are (possibly empty) strings.
+A meta-rule acts as a rule for any potential target whose
+name matches
+.IB A % B
+with
+.B %
+replaced by an arbitrary string, called the
+.IR stem .
+In interpreting a meta-rule,
+the stem is substituted for all occurrences of
+.B %
+in the prerequisite names.
+In the recipe of a meta-rule, the environment variable
+.B $stem
+contains the string matched by the
+.BR % .
+For example, a meta-rule to compile a C program using
+.IR 2c (10.1)
+might be:
+.IP
+.EX
+%.2: %.c
+ 2c $stem.c
+ 2l -o $stem $stem.2
+.EE
+.PP
+Meta-rules may contain an ampersand
+.B &
+rather than a percent sign
+.BR % .
+A
+.B %
+matches a maximal length string of any characters;
+an
+.B &
+matches a maximal length string of any characters except period
+or slash.
+.PP
+The text of the
+.I mkfile
+is processed as follows.
+Lines beginning with
+.B <
+followed by a file name are replaced by the contents of the named
+file.
+Blank lines and comments, which run from unquoted
+.B #
+characters to the following newline, are deleted.
+The character sequence backslash-newline is deleted,
+so long lines in
+.I mkfile
+may be folded.
+Non-recipe lines are processed by substituting for
+.BI `{ command }
+the output of the
+.I command
+when run by
+.IR rc .
+References to variables are replaced by the variables' values.
+Special characters may be quoted using single quotes
+.BR \&''
+as in
+.IR rc (10.1).
+.PP
+Assignments and rules are distinguished by
+the first unquoted occurrence of
+.B :
+(rule)
+or
+.B =
+(assignment).
+.PP
+A later rule may modify or override an existing rule under the
+following conditions:
+.TP
+\-
+If the targets of the rules exactly match and one rule
+contains only a prerequisite clause and no recipe, the
+clause is added to the prerequisites of the other rule.
+If either or both targets are virtual, the recipe is
+always executed.
+.TP
+\-
+If the targets of the rules match exactly and the
+prerequisites do not match and both rules
+contain recipes,
+.I mk
+reports an ``ambiguous recipe'' error.
+.TP
+\-
+If the target and prerequisites of both rules match exactly,
+the second rule overrides the first.
+.SS Environment
+Rules may make use of
+.B rc
+environment variables.
+A legal reference of the form
+.B $OBJ
+or
+.B ${name}
+is expanded as in
+.IR rc (10.1).
+A reference of the form
+.BI ${name: A % B = C\fL%\fID\fL}\fR,
+where
+.I A, B, C, D
+are (possibly empty) strings,
+has the value formed by expanding
+.B $name
+and substituting
+.I C
+for
+.I A
+and
+.I D
+for
+.I B
+in each word in
+.B $name
+that matches pattern
+.IB A % B\f1.
+.PP
+Variables can be set by
+assignments of the form
+.I
+ var\fL=\fR[\fIattr\fL=\fR]\fIvalue\fR
+.br
+Blanks in the
+.I value
+break it into words, as in
+.I rc
+but without the surrounding parentheses.
+Such variables are exported
+to the environment of
+recipes as they are executed, unless
+.BR U ,
+the only legal attribute
+.IR attr ,
+is present.
+The initial value of a variable is
+taken from (in increasing order of precedence)
+the default values below,
+.I mk's
+environment, the
+.IR mkfiles ,
+and any command line assignment as an argument to
+.IR mk .
+A variable assignment argument overrides the first (but not any subsequent)
+assignment to that variable.
+The variable
+.B MKFLAGS
+contains all the option arguments (arguments starting with
+.L -
+or containing
+.LR = )
+and
+.B MKARGS
+contains all the targets in the call to
+.IR mk .
+.PP
+It is recommended that mkfiles start with
+.IP
+.EX
+</$objtype/mkfile
+.EE
+.PP
+to set
+.BR CC ,
+.BR LD ,
+.BR AS ,
+.BR O ,
+.BR ALEF ,
+.BR YACC ,
+and
+.B MK
+to values appropriate to the target architecture (see the examples below).
+.PP
+Dynamic information may be included in the mkfile by using a line of the form
+.I
+ \fR<| \fIcommand\fR \fIargs\fR
+.br
+This runs the command
+.I command
+with the given arguments
+.I args
+and pipes its standard output to
+.I mk
+to be included as part of the mkfile. For instance, the file
+.B /os/sa1100/mkfile
+uses this technique
+to run a shell command with an awk script and a configuration file as arguments in order for
+the
+.I awk
+script to process the file and output a set of variables and their values.
+.SS Execution
+.PP
+During execution,
+.I mk
+determines which targets must be updated, and in what order,
+to build the
+.I names
+specified on the command line.
+It then runs the associated recipes.
+.PP
+A target is considered up to date if it has no prerequisites or
+if all its prerequisites are up to date and it is newer
+than all its prerequisites.
+Once the recipe for a target has executed, the target is
+considered up to date.
+.PP
+The date stamp
+used to determine if a target is up to date is computed
+differently for different types of targets.
+If a target is
+.I virtual
+(the target of a rule with the
+.B V
+attribute),
+its date stamp is initially zero; when the target is
+updated the date stamp is set to
+the most recent date stamp of its prerequisites.
+Otherwise, if a target does not exist as a file,
+its date stamp is set to the most recent date stamp of its prerequisites,
+or zero if it has no prerequisites.
+Otherwise, the target is the name of a file and
+the target's date stamp is always that file's modification date.
+The date stamp is computed when the target is needed in
+the execution of a rule; it is not a static value.
+.PP
+Nonexistent targets that have prerequisites
+and are themselves prerequisites are treated specially.
+Such a target
+.I t
+is given the date stamp of its most recent prerequisite
+and if this causes all the targets which have
+.I t
+as a prerequisite to be up to date,
+.I t
+is considered up to date.
+Otherwise,
+.I t
+is made in the normal fashion.
+The
+.B -i
+flag overrides this special treatment.
+.PP
+Files may be made in any order that respects
+the preceding restrictions.
+.PP
+A recipe is executed by supplying the recipe as standard input to
+the command
+.B
+ $SHELL -e -I
+.br
+where the
+.I SHELL
+variable is the appropriate shell on the current platform - typically
+.B /bin/sh
+or
+.B /bin/rc.
+The appropriate value is automatically supplied in the Inferno build environment.
+The
+.B -e
+is omitted if the
+.B E
+attribute is set.
+The environment is augmented by the following variables:
+.TP 14
+.B $alltarget
+all the targets of this rule.
+.TP
+.B $newprereq
+the prerequisites that caused this rule to execute.
+.TP
+.B $nproc
+the process slot for this recipe.
+It satisfies
+.RB 0≤ $nproc < $NPROC .
+.TP
+.B $pid
+the process id for the
+.I mk
+executing the recipe.
+.TP
+.B $prereq
+all the prerequisites for this rule.
+.TP
+.B $stem
+if this is a meta-rule,
+.B $stem
+is the string that matched
+.B %
+or
+.BR & .
+Otherwise, it is empty.
+For regular expression meta-rules (see below), the variables
+.LR stem0 ", ...,"
+.L stem9
+are set to the corresponding subexpressions.
+.TP
+.B $target
+the targets for this rule that need to be remade.
+.PP
+These variables are available only during the execution of a recipe,
+not while evaluating the
+.IR mkfile .
+.PP
+Unless the rule has the
+.B Q
+attribute,
+the recipe is printed prior to execution
+with recognizable environment variables expanded.
+Commands returning error status
+cause
+.I mk
+to terminate.
+.PP
+Recipes and backquoted
+.B rc
+commands in places such as assignments
+execute in a copy of
+.I mk's
+environment; changes they make to
+environment variables are not visible from
+.IR mk .
+.PP
+Variable substitution in a rule is done when
+the rule is read; variable substitution in the recipe is done
+when the recipe is executed. For example:
+.IP
+.EX
+bar=a.c
+foo: $bar
+ $CC -o foo $bar
+bar=b.c
+.EE
+.PP
+will compile
+.B b.c
+into
+.BR foo ,
+if
+.B a.c
+is newer than
+.BR foo .
+.SS Aggregates
+Names of the form
+.IR a ( b )
+refer to member
+.I b
+of the aggregate
+.IR a .
+Currently, the only aggregates supported are
+.IR ar (10.1)
+archives.
+.SS Attributes
+The colon separating the target from the prerequisites
+may be
+immediately followed by
+.I attributes
+and another colon.
+The attributes are:
+.TP
+.B <
+The standard output of the recipe is read by
+.I mk
+as an additional
+.IR mkfile .
+.PD 0
+.TP
+.B D
+If the recipe exits with a non-null status, the target is deleted.
+.TP
+.B E
+Continue execution if the recipe draws errors.
+.TP
+.B N
+If there is no recipe, the target has its time updated.
+.TP
+.B n
+The rule is a meta-rule that cannot be a target of a virtual rule.
+Only files match the pattern in the target.
+.TP
+.B P
+The characters after the
+.B P
+until the terminating
+.B :
+are taken as a program name.
+It will be invoked as
+.B "rc -c prog 'arg1' 'arg2'"
+and should return a null exit status
+if and only if arg1 is not out of date with respect to arg2.
+Date stamps are still propagated in the normal way.
+.TP
+.B Q
+The recipe is not printed prior to execution.
+.TP
+.B R
+The rule is a meta-rule using regular expressions.
+In the rule,
+.B %
+has no special meaning.
+The target is interpreted as a regular expression as defined in
+.IR regexp (6).
+The prerequisites may contain references
+to subexpressions in form
+.BI \e n\f1,
+as in the substitute command of
+.IR sed (10.1).
+.TP
+.B U
+The targets are considered to have been updated
+even if the recipe did not do so.
+.TP
+.B V
+The targets of this rule are marked as virtual.
+They are distinct from files of the same name.
+.PD
+.SH EXAMPLES
+A simple mkfile to compile a program:
+.IP
+.EX
+</$objtype/mkfile
+
+prog: a.$O b.$O c.$O
+ $LD $CFLAGS -o $target $prereq
+
+%.$O: %.c
+ $CC $stem.c
+.EE
+.PP
+Override flag settings in the mkfile:
+.IP
+.EX
+% mk target 'CFLAGS=-S -w'
+.EE
+.PP
+To get the prerequisites for an aggregate:
+.IP
+.EX
+% membername 'libc.a(read.2)' 'libc.a(write.2)'
+read.2 write.2
+.EE
+.PP
+Maintain a library:
+.IP
+.EX
+libc.a(%.$O):N: %.$O
+libc.a: libc.a(abs.$O) libc.a(access.$O) libc.a(alarm.$O) ...
+ names=`{membername $newprereq}
+ ar r libc.a $names && rm $names
+.EE
+.PP
+String expression variables to derive names from a master list:
+.IP
+.EX
+NAMES=alloc arc bquote builtins expand main match mk var word
+OBJ=${NAMES:%=%.$O}
+.EE
+.PP
+Regular expression meta-rules:
+.IP
+.EX
+([^/]*)/(.*)\e.o:R: \e1/\e2.c
+ cd $stem1; $CC $CFLAGS $stem2.c
+.EE
+.PP
+A correct way to deal with
+.IR yacc (10.1)
+grammars.
+The file
+.B lex.c
+includes the file
+.B x.tab.h
+rather than
+.B y.tab.h
+in order to reflect changes in content, not just modification time.
+.IP
+.EX
+lex.o: x.tab.h
+x.tab.h: y.tab.h
+ cmp -s x.tab.h y.tab.h || cp y.tab.h x.tab.h
+y.tab.c y.tab.h: gram.y
+ $YACC -d gram.y
+.EE
+.PP
+The above example could also use the
+.B P
+attribute for the
+.B x.tab.h
+rule:
+.IP
+.EX
+x.tab.h:Pcmp -s: y.tab.h
+ cp y.tab.h x.tab.h
+.EE
+.SH SOURCE
+.B /utils/mk
+.SH SEE ALSO
+.IR rc (10.1),
+.IR regexp (6)
+.br
+A. Hume,
+``Mk: a Successor to Make''.
+.br
+Bob Flandrena,
+``Plan 9 Mkfiles''.
+.SH BUGS
+Identical recipes for regular expression meta-rules only have one target.
+.br
+Seemingly appropriate input like
+.B CFLAGS=-DHZ=60
+is parsed as an erroneous attribute; correct it by inserting
+a space after the first
+.LR = .
+.br
+The recipes printed by
+.I mk
+before being passed to
+.I rc
+for execution are sometimes erroneously expanded
+for printing. Don't trust what's printed; rely
+on what
+.I rc
+does.
diff --git a/man/10/ms2 b/man/10/ms2
new file mode 100644
index 00000000..6a0d23af
--- /dev/null
+++ b/man/10/ms2
@@ -0,0 +1,58 @@
+.TH MS2 10.1
+.SH NAME
+ms2 \- convert executable or raw file to Motorola S record format
+.SH SYNOPSIS
+.B ms2
+[
+.I option ...
+]
+.I infile
+.SH DESCRIPTION
+.IR ms2
+converts the
+.I infile
+onto the standard output in Motorola S record format. If the
+.B -b
+option is not given, the
+.I infile
+is presumed to be an executable, and the header and symbol
+table stripped. If the
+.B -b
+option is given, the file is treated as raw binary.
+The options are:
+.TP 1i
+.BI -d
+Encode the data segment only.
+.TP
+.BI -s
+Omit the end record, presumably to accomodate poorly implemented
+decoders.
+.TP
+.BI -T addr
+.TP
+.BI -A addr
+Set the address of the text segment, i.e. the first record output.
+.B -a
+is an older, deprecated option.
+.TP
+.BI -R n
+.TP
+.BI -p n
+Set the page size in use by the linker.
+.B -p
+is an older, deprecated option.
+.TP
+.BI -b
+The
+.I infile
+is binary. Ignores the
+.B -R
+and
+.B -d
+options.
+.TP
+.BI -S addr
+Sets the entry address output in the end record.
+.PP
+.SH SOURCE
+.IR 5cv (10.1)
diff --git a/man/10/newchan b/man/10/newchan
new file mode 100644
index 00000000..69346d46
--- /dev/null
+++ b/man/10/newchan
@@ -0,0 +1,227 @@
+.TH NEWCHAN 10.2
+.SH NAME
+newchan, chanfree, cclose, eqqid, eqchan, isdir, fdtochan, namec \- channel operations
+.SH SYNOPSIS
+.ta \w'\fLChan* 'u
+.B
+Chan* newchan(void)
+.PP
+.B
+void chanfree(Chan *c)
+.PP
+.B
+int eqqid(Qid a, Qid b)
+.PP
+.B
+int eqchan(Chan *a, Chan *b, int pathonly)
+.PP
+.B
+void isdir(Chan *c)
+.PP
+.B
+Chan* fdtochan(Fgrp *f, int fd, int mode, int chkmnt, int iref)
+.PP
+.B
+Chan* namec(char *pathname, int amode, int omode, ulong perm)
+.PP
+.B
+void cclose(Chan *c)
+.SH DESCRIPTION
+A value of type
+.B Chan
+represents a kernel channel for I/O and name space operations.
+It has the following public structure:
+.IP
+.EX
+typedef struct Chan{
+ ushort type; /* driver name */
+ ulong dev; /* instance number */
+ ushort mode; /* open mode */
+ ushort flag; /* COPEN set once opened */
+ ulong offset; /* current file offset */
+ Qid qid; /* unique id (path, vers) */
+ Cname* name; /* name by which it was accessed */
+.EE
+.PP
+.I Newchan
+returns a pointer to a newly allocated channel (sleeping if necessary until memory is available).
+Device drivers do not normally call
+.IR newchan
+directly, but instead allocate channels using either
+.IR devattach ,
+when a process attaches to the device's root,
+or
+.IR devclone ,
+when an existing channel is cloned;
+see
+.IR devattach (10.2).
+.PP
+.I Chanfree
+frees the channel structure
+.I c
+for reuse.
+.PP
+.I Eqqid
+returns 1 if
+.B Qid
+values
+.I a
+and
+.I b
+are equal
+(ie,
+both their
+.B path
+and
+.B vers
+members are equal);
+it returns 0 otherwise.
+.PP
+.I Eqchan
+returns 1 if
+.I a
+and
+.I b
+have the same
+.BR qid ,
+.BR type
+and
+.BR dev
+members
+(ie, they represent the same file);
+it returns 0 otherwise.
+If
+.I pathonly
+is non-zero, the comparison of the two
+.B qid
+members compares only their
+.B path
+values,
+ignoring the version field
+.BR vers .
+.PP
+.I Isdir
+checks that a given channel
+.I c
+is a directory.
+If so, it returns;
+otherwise, it generates an
+.IR error (10.2),
+.BR Enotdir .
+.PP
+The
+.B Fgrp
+structure represents an array of open files, each
+represented by a
+.BR Chan ,
+indexed by integer file descriptors.
+A given
+.B Fgrp
+can be shared between processes.
+.PP
+.I Fdtochan
+returns a pointer to the
+.B Chan
+corresponding to file descriptor
+.I fd
+in file descriptor group
+.I f
+(almost invariably
+.BR up->env->fgrp ,
+the file descriptor group for the current process).
+If
+.I mode
+is a valid mode for
+.IR sys-open (2),
+typically
+.BR OREAD ,
+.B OWRITE
+or
+.BR ORDWR ,
+it must correspond to the mode with which
+.I fd
+was originally opened; if
+.I mode
+is
+.BR -1 ,
+no check is made.
+If
+.I chkmnt
+is non-zero,
+.I c
+must not be a channel in use by the mount driver
+.IR mnt (3).
+On successful return, if
+.I iref
+is non-zero, the channel's reference count has been incremented.
+.I Fdtochan
+calls
+.IR error (10.2)
+if it detects invalid uses, in particular an invalid file descriptor
+.IR fd .
+.PP
+.I Namec
+looks up a
+.I pathname
+in the current name space and returns a channel.
+.I Amode
+determines the mode of look up, and must be one of the constants below:
+.TF Aaccess
+.PD
+.TP
+.B Aaccess
+Access file for information, as in the stat command or call.
+.TP
+.B Atodir
+Access file as directory (the
+.B CHDIR
+bit of its
+.B qid.path
+must be set).
+.TP
+.B Aopen
+Access for I/O.
+.TP
+.B Amount
+Access directory to be mounted upon.
+.TP
+.B Acreate
+File is to be created.
+.PP
+If
+.I amode
+is
+.B Aopen
+or
+.BR Acreate ,
+.I omode
+should be a mode suitable for
+.IR sys-open (2);
+if
+.BR Acreate ,
+.I perm
+should be valid file permissions.
+In all other cases,
+.I omode
+and
+.I perm
+can be zero.
+.PP
+.I Cclose
+decrements the reference count on
+.IR c ;
+if no further references remain, it
+calls the corresponding device's
+.B Dev.close
+to close the channel, and frees
+.IR c .
+.SH DIAGNOSTICS
+Most functions call
+.IR error (10.2)
+on any sort of error.
+.SH SOURCE
+.B /os/port/chan.c
+.br
+.B /emu/port/chan.c
+.SH SEE ALSO
+.IR ref (10.2)
diff --git a/man/10/ntsrv b/man/10/ntsrv
new file mode 100644
index 00000000..d49b48a2
--- /dev/null
+++ b/man/10/ntsrv
@@ -0,0 +1,69 @@
+.TH NTSRV 10.1 Windows
+.SH NAME
+ntsrv \- start hosted Inferno as Windows service
+.SH SYNOPSIS
+.B ntsrv
+.B add
+.IR "svcname rootdir cmd" " [" arg " ... ]"
+.PP
+.B ntsrv
+.B del
+.I svcname
+.SH DESCRIPTION
+.I Ntsrv
+is a command (for Windows only) that allows hosted Inferno
+to run automatically as a Windows service, under Windows 2000 and XP.
+For Windows NT, use the command
+.BR ntsrv4 ,
+which otherwise has identical interface.
+.I Svcname
+is the (proposed) Windows service name;
+.I rootdir
+is the root of the Inferno directory tree,
+including the drive letter.
+Once added, a service can be controlled using the Windows service manager:
+it may be stopped, started, or have its attributes changed.
+.I Svcname
+is set to start automatically when Windows starts up.
+Services run by default under the local Windows `System' identity.
+All Windows processes and threads the service creates (eg, using
+.IR cmd (3))
+are destroyed when the service is stopped.
+There may be many different services, each with a distinct
+.IR svcname .
+.PP
+.I Ntsrv 's
+first parameter tells it what to do:
+.TP
+.B add
+Add a new service
+.I svcname
+that when started will invoke
+.IR emu (1)
+to run the Inferno command
+.I cmd
+with any additional arguments.
+.TP
+.B del
+Delete an existing service
+.IR svcname .
+.PP
+.I Ntsrv
+requires the directory
+.IR rootdir /Nt/386/bin
+to contain both
+.B emu.exe
+(ie,
+.IR emu (1))
+and
+.B ntsrv.exe
+itself.
+.SH FILES
+.TF c:/inferno/Nt/386/bin
+.TP
+.IB rootdir /Nt/386/bin
+Windows host executables
+.SH SOURCE
+.B /utils/ntsrv
+.SH SEE ALSO
+.IR emu (1)
diff --git a/man/10/odbc b/man/10/odbc
new file mode 100644
index 00000000..fac39877
--- /dev/null
+++ b/man/10/odbc
@@ -0,0 +1,266 @@
+.TH ODBC 10.4
+.SH NAME
+ODBC \- A Windows ODBC file server
+.SH SYNOPSIS
+.B odbc.exe
+[
+.B -d
+] [
+.BI -p " port"
+]
+.SH DESCRIPTION
+.I Odbc
+is a file server that runs under Windows and
+exports a Styx namespace
+(see
+.IR intro (5)).
+An Inferno process that mounts the namespace
+can use it to manipulate Windows ODBC databases.
+.PP
+The
+.B -d
+option causes
+.I odbc
+to print debugging information.
+.PP
+The
+.B -p
+option gives the port number to listen on for connections. The default is 6700.
+.SS Name space
+.I Odbc
+presents the following name space:
+.PP
+.nf
+.BI /nclients
+.BI /db
+.BI /db/new
+.BI /db/ n
+.BI /db/ n /cmd
+.BI /db/ n /ctl
+.BI /db/ n /data
+.BI /db/ n /error
+.BI /db/ n /format
+.BI /db/ n /sources
+.BI /db/ n /status
+.fi
+.PP
+The top level read-only file
+.B nclients
+contains the current number of active clients on the server.
+.PP
+The top level
+.B db
+directory contains a
+.B new
+file and subdirectories numbered
+.B n
+from zero to the maximum number of
+configured conversations.
+.PP
+Opening the
+.B new
+file reserves a conversation, represented
+by one of the numbered directories. The resulting file descriptor will be open
+on the control file,
+.BR ctl ,
+of the newly allocated conversation.
+Reading the
+.B ctl
+file returns a text string representing the
+number of the conversation.
+A conversation is used to converse with the server - in ODBC terms
+it is equivalent to obtaining a connection handle. This is the level at
+which ODBC transactions are managed.
+.PP
+A conversation is controlled by writing text strings to the
+associated
+.B ctl
+file. ODBC commands may be sent to the
+server by writing them, as text strings, to the
+.B cmd
+file.
+For commands that return a record set, the results may be read
+from the
+.B data
+file; each read returning a single record.
+If a command results in an error, the write to the
+.B cmd
+file
+will fail. The full ODBC error message can be obtained by reading
+the
+.B error
+file.
+A conversation remains open while at least one of the
+.BR ctl ,
+.B cmd
+or
+.B data
+files remains open.
+.PP
+The following commands can be written to the
+.B ctl
+file:
+.TP
+.B connect " datasource" " [user!auth]"
+Connect to the ODBC datasource using the username and authentication, if given.
+.TP
+.B disconnect
+Disconnect from the datasource.
+.TP
+.B fixed
+Reads from the
+.B data
+file will return data in a fixed format. The format can
+be read from the
+.B format
+file after writing the command to the
+.B cmd
+file and before reading the data from the
+.B data
+file.
+.TP
+.B float " [fs< [rs<]]"
+Reads from the data file will return data using the character
+.B fs
+to separate fields and the character
+.B rs
+to separate records.
+The default values for
+.B fs and
+.B rs
+are the pipe symbol '|'
+and the newline character.
+.TP
+.B trans " begin"
+Enter ODBC manual-commit mode for transactions. A transaction will
+not complete until one of
+.B trans commit
+or
+.B trans rollback
+is written to the
+.B ctl
+file.
+.TP
+.B trans " auto"
+Enter ODBC auto-commit mode for transactions (the default).
+Each database statement is wrapped by a transaction that is automatically
+commited when the statement is executed.
+.TP
+.B trans " commit"
+Commit a transaction when in manual-commit mode.
+.TP
+.B trans " rollback"
+Rollback a transation when in manual-commit mode.
+.PP
+Once a conversation has been established and transaction mode and
+output formats determined the
+.B cmd
+file is
+used to send ODBC commands to the server.
+The following commands can be written to the
+.B cmd
+file:
+.TP
+.B tables
+The result of calling the ODBC API function SQLTables is returned
+in the
+.B data
+file.
+.TP
+.B columns " tablename"
+The result of calling the ODBC API function SQLColumns with the
+given
+.B tablename
+as a parameter is returned in the
+.B data
+file.
+.TP
+.B any " ODBC" " command"
+Any ODBC command written to the
+.B cmd
+file is passed
+to the ODBC API function SQLExecDirect. This most commonly includes
+select, update, insert, and delete
+commands.
+.PP
+The
+.B format
+file is used to determine column names and how to extract
+individual columns from the record read from the
+.B data
+file when using
+fixed format output. A read of it gives
+a single record read returning one line
+for each column in the result data. Each line has three components separated
+by a single space: a number giving the character position of the start of the field
+in the result data, a number giving the character position one beyond the
+end of the field in the result data, and the field name.
+.PP
+The result of database enquiries can be read from the
+.B data
+file.
+After writing a command that returns data to the
+.B cmd
+file,
+reads from the
+.B data
+file will return the results one record at a time.
+When the last record has been read the following read will return zero
+bytes indicating the end of the data.
+.PP
+The read-only file
+.B sources
+gives a newline separated list of sources. Each line consists
+of the source name and the source type separated by a colon.
+.PP
+The read-only file
+.B status
+return the status of the current conversation.
+.SH EXAMPLE
+For example, the Inferno shell can be used to retrieve
+values from a database. The shell commands:
+.PP
+.EX
+mount -A tcp!localhost!6700 /n/remote
+{
+ d=/n/remote/db/`{cat}
+ echo -n 'float' > $d/ctl
+ echo -n 'connect cellar' > $d/ctl
+ echo -n 'select name from wine' > $d/cmd
+ cat $d/data
+} < /n/remote/db/new
+.EE
+.PP
+produces the output:
+.PP
+.EX
+Chardonnay
+Jo. Riesling
+Fume Blanc
+Wh. Burgundy
+Gewurztraminer
+Cab. Sauvignon
+Pinot Noir
+Zinfandel
+Gamay
+.EE
+.PP
+Here the server has been started on the local machine, listening on port
+6700 for network connections.
+The braced block and the redirection from
+.B /n/remote/db/new
+reserve a conversation with the server and ensures that it remains open
+for the duration of the execution of the set of commands within the block.
+The
+.B -A
+option to mount is used because this server can not
+authenticate a connection.
+.SH SOURCE
+.B /tools/odbc/odbc.c
+.SH SEE ALSO
+.IR bind (1),
+.IR sys-bind (2),
+.IR intro (5),
+.IR db (7),
+.IR dbsrv (7),
+.IR svc (8)
diff --git a/man/10/panic b/man/10/panic
new file mode 100644
index 00000000..6de7fe4b
--- /dev/null
+++ b/man/10/panic
@@ -0,0 +1,25 @@
+.TH PANIC 10.2
+.SH NAME
+panic \- abandon hope
+.SH SYNOPSIS
+.ta \w'\fLchar* 'u
+.B
+void panic(char *fmt, ...)
+.SH DESCRIPTION
+.I Panic
+writes a message to the console and
+causes the system to give up the ghost.
+It enables interrupts, dumps the kernel stack,
+and halts the current processor;
+if more than one, others will gradually come to a halt.
+Depending on configuration settings, the platform-dependent
+.I exit
+might reboot the system.
+The format
+.I fmt
+and associated arguments are the same as those for
+.IR print (10.2).
+.I Panic
+adds a prefix
+.L "panic: "
+and a trailing newline.
diff --git a/man/10/parsecmd b/man/10/parsecmd
new file mode 100644
index 00000000..a9598773
--- /dev/null
+++ b/man/10/parsecmd
@@ -0,0 +1,68 @@
+.TH PARSECMD 10.2
+.SH NAME
+parsecmd \- parse device commands
+.SH SYNOPSIS
+.ta \w'\fLCmdbuf* 'u
+.B
+Cmdbuf* parsecmd(char *a, int n)
+.SH DESCRIPTION
+.I Parsecmd
+is an interface to
+.I tokenize
+(see
+.IR getfields (10.2)),
+that safely parses a command, with blank-separated fields, as might be
+written to a device's
+.B ctl
+file.
+The buffer
+.I a
+and count
+.I n
+can be those passed to the driver's
+.I write
+function.
+.I Parsecmd
+converts the byte array (which might not be null-terminated) to a null-terminated string,
+trimming any trailing new line,
+before invoking
+.I tokenize
+to break the string into arguments, interpreting blank and tab as field separators
+when they are not quoted
+(in the style of
+.IR sh (1)).
+It returns a pointer to a dynamically-allocated
+.B Cmdbuf
+structure,
+which holds a copy of the string as
+modified by
+.IR parsefields ,
+and the resulting fields; it is defined as follows:
+.IP
+.EX
+.ta 6n +\w'char* 'u
+typedef
+struct Cmdbuf
+{
+ char buf[128];
+ char *f[16];
+ int nf;
+} Cmdbuf;
+.EE
+.PP
+The array
+.B f
+holds the field pointers;
+.B nf
+gives the number of fields.
+.B Cmdbuf
+is allocated by
+.I smalloc
+(see
+.IR malloc (10.2)),
+and the caller is responsible for freeing it using
+.IR free .
+.SH SOURCE
+.B /os/port/parse.c
+.br
+.B /emu/port/dev.c
diff --git a/man/10/plan9.ini b/man/10/plan9.ini
new file mode 100644
index 00000000..71e8559d
--- /dev/null
+++ b/man/10/plan9.ini
@@ -0,0 +1,789 @@
+.TH PLAN9.INI 10.6
+.SH NAME
+plan9.ini \- configuration file for PCs
+.SH SYNOPSIS
+.I none
+.SH DESCRIPTION
+When booting Inferno on a PC, the Plan 9 bootstrap programs
+are used, hence the references to Plan 9 below.
+The DOS program
+.IR 9load (10.8)
+first reads a DOS file
+containing configuration information from the boot disk.
+This file,
+.BR plan9.ini ,
+looks like a shell script containing lines of the form
+.PP
+.EX
+ name=\f2value\fP
+.EE
+.LP
+each of which defines a kernel or device parameter.
+.PP
+For devices, the generic format of
+.I value
+is
+.PP
+.EX
+ type=TYPE [port=N] [irq=N] [mem=N] [size=N] [dma=N] [ea=N]
+.EE
+.LP
+specifying the controller type,
+the base I/O port of the interface, its interrupt
+level, the physical starting address of any mapped memory,
+the length in bytes of that memory, the DMA channel,
+and for Ethernets an override of the physical network address.
+Not all elements are relevant to all devices; the relevant values
+and their defaults are defined below in the description of each device.
+.PP
+The file is used by
+.B 9load
+and the kernel to configure the hardware available.
+The information it contains is also passed to the boot
+process, and subsequently other programs,
+as environment variables
+(see also
+.B osinit.dis
+in
+.IR root (3)).
+However, values whose names begin with an asterisk
+.B *
+are used by the kernel and are not converted into environment variables.
+.PP
+The following sections describe how variables are used.
+.SS \fLetherX=value\fP
+This defines an Ethernet interface.
+.IR X ,
+a unique monotonically increasing number beginning at 0,
+identifies an Ethernet card to be probed at system boot.
+Probing stops when a card is found or there is no line for
+.BR etherX+1 .
+After probing as directed by the
+.BI ether X
+lines, any remaining ethernet cards that can be automatically
+detected are added.
+Almost all cards can be automatically detected.
+For debugging purposes, automatic probing can
+be disabled by specifying the line
+.BR *noetherprobe= .
+This automatic probing is only done by the kernel, not by
+.IR 9load (10.8).
+Thus, if you want to load a kernel over the ethernet, you need
+to specify an
+.B ether0
+line so that
+.I 9load
+can find the ethernet card, even if the kernel would
+have automatically detected it.
+.PP
+Some cards are software configurable and do not require all options.
+Unspecified options default to the factory defaults.
+.PP
+Known types are
+.TP
+.B ne2000
+Not software configurable. 16-bit card.
+Defaults are
+.EX
+ port=0x300 irq=2 mem=0x04000 size=0x4000
+.EE
+The option (no value)
+.B nodummyrr
+is needed on some (near) clones to turn off a dummy remote read in the driver.
+.TP
+.B amd79c970
+The AMD PCnet PCI Ethernet Adapter (AM79C970).
+(This is the ethernet adapter used by VMware.)
+Completely configurable, no options need be given.
+.TP
+.B wd8003
+Includes WD8013 and SMC Elite and Elite Ultra cards. There are varying degrees
+of software configurability. Cards may be in either 8-bit or 16-bit slots.
+Defaults are
+.EX
+ port=0x280 irq=3 mem=0xD0000 size=0x2000
+.EE
+BUG: On many machines only the 16 bit card works.
+.TP
+.B elnk3
+The 3COM Etherlink III series of cards including the 5x9, 59x, and 905 and 905B.
+Completely configurable, no options need be given.
+The media may be specified by setting
+.B media=
+to the value
+.BR 10BaseT ,
+.BR 10Base2 ,
+.BR 100BaseTX ,
+.BR 100BaseFX ,
+.BR aui ,
+and
+.BR mii .
+If you need to force full duplex, because for example the Ethernet switch does not negotiate correctly,
+just name the word (no value)
+.B fullduplex
+or
+.BR 100BASE-TXFD .
+Similarly, to force 100Mbit operation, specify
+.BR force100 .
+Port 0x110 is used for the little ISA configuration dance.
+.TP
+.B 3c589
+The 3COM 3C589 series PCMCIA cards, including the
+3C562 and the 589E.
+There is no support for the modem on the 3C562.
+Completely configurable, no options need be given.
+Defaults are
+.EX
+ port=0x240 irq=10
+.EE
+The media may be specified as
+.B media=10BaseT
+or
+.BR media=10Base2 .
+.TP
+.B ec2t
+The Linksys Combo PCMCIA EthernetCard (EC2T),
+EtherFast 10/100 PCMCIA cards (PCMPC100) and integrated controllers (PCM100),
+the Netgear FA410TX 10/100 PCMCIA card
+and the Accton EtherPair-PCMCIA (EN2216).
+Completely configurable, no options need be given.
+Defaults are
+.EX
+ port=0x300 irq=9
+.EE
+These cards are NE2000 clones.
+Other NE2000 compatible PCMCIA cards may be tried
+with the option
+.EX
+ id=string
+.EE
+where
+.B string
+is a unique identifier string contained in the attribute
+memory of the card (see
+.IR pcmcia (8));
+unlike most options in
+.BR plan9.ini ,
+this string is case-sensitive.
+The option
+.B dummyrr=[01]
+can be used to turn off (0) or on (1) a dummy remote read in the driver
+in such cases,
+depending on how NE2000 compatible they are.
+.TP
+.B i82557
+Cards using the Intel 8255[789] Fast Ethernet PCI Bus LAN Controller such as the
+Intel EtherExpress PRO/100B.
+Completely configurable, no options need be given.
+If you need to force the media, specify
+one of the options (no value)
+.BR 10BASE-T ,
+.BR 10BASE-2 ,
+.BR 10BASE-5 ,
+.BR 100BASE-TX ,
+.BR 10BASE-TFD ,
+.BR 100BASE-TXFD ,
+.BR 100BASE-T4 ,
+.BR 100BASE-FX ,
+or
+.BR 100BASE-FXFD .
+.TP
+.B 2114x
+Cards using the Digital Equipment (now Intel) 2114x PCI Fast Ethernet Adapter Controller,
+for example the Netgear FA310.
+Completely configurable, no options need be given.
+Media can be specified the same was as for the
+.BR i82557 .
+Some cards using the
+.B PNIC
+and
+.B PNIC2
+near-clone chips may also work.
+.\" .TP
+.\" .B ga620
+.\" Netgear GA620 and GA620T Gigabit Ethernet cards,
+.\" and other cards using the Alteon Acenic chip such as the
+.\" Alteon Acenic fiber and copper cards,
+.\" the DEC DEGPA-SA and the SGI Acenic.
+.\" Completely configurable.
+.TP
+.B wavelan
+Lucent Wavelan (Orinoco) IEEE 802.11b
+and compatible PCMCIA cards.
+Compatible cards include the Dell TrueMobile 1150
+and the Linksys Instant Wireless Network PC Card.
+Port and IRQ defaults are 0x180 and 3 respectively.
+
+These cards take a number of unique options to aid in
+identifying the card correctly on the 802.11b network.
+The network may be
+.I "ad hoc"
+or
+.I managed
+(i.e. use an access point):
+.EX
+ mode=[adhoc, managed]
+.EE
+and defaults to
+.IR managed .
+The 802.11b network to attach to
+.RI ( managed
+mode)
+or identify as
+.RI ( "ad hoc"
+mode),
+is specified by
+.EX
+ essid=string
+.EE
+and defaults to a null string.
+The card station name is given by
+.EX
+ station=string
+.EE
+and defaults to
+.IR "Plan 9 STA" .
+The channel to use is given by
+.EX
+ channel=number
+.EE
+where
+.I number
+lies in the range 1 to 16 inclusive;
+the channel is normally negotiated automatically.
+
+If the card is capable of encryption,
+the following options may be used:
+.EX
+ crypt=[off, on]
+.EE
+and defaults to
+.IR on .
+.EX
+ key\fIN\fP=string
+.EE
+sets the encryption key
+.I n
+(where
+.I n
+is in the range 1 to 4 inclusive) to
+.IR string ;
+this will also set the transmit key to
+.I n
+(see below).
+.EX
+ txkey=number
+.EE
+sets the transmit key to use to be
+.I number
+in the range 1 to 4 inclusive.
+If it is desired to exclude or include unencrypted packets
+.EX
+ clear=[off, on]
+.EE
+configures reception and defaults to inclusion.
+
+The defaults are intended to match the common case of
+a managed network with encryption and a typical entry would
+only require, for example
+.EX
+ essid=left-armpit key2=fishcalledraawaru
+.EE
+if the port and IRQ defaults are used.
+These options may be set after boot by writing to the device's
+.I ctl
+file using a space as the separator between option and value, e.g.
+.EX
+ echo 'key2 fishcalledraawaru' > /net/ether0/0/ctl
+.EE
+.TP
+.B wavelanpci
+PCI ethernet adapters that use the same Wavelan
+programming interface.
+Currently the only tested cards are those based on the
+Intersil Prism 2.5 chipset.
+.TP
+.B 83815
+National Semiconductor DP83815-based adapters, notably
+the Netgear FA311, Netgear FA312, and various SiS built-in
+controllers such as the SiS900.
+On the SiS controllers, the ethernet address is not detected properly;
+specify it with an
+.B ea=
+attribute.
+.\" .TP
+.\" .B 83820
+.\" National Semiconductor DP83820-based gigabit ethernet adapters, notably
+.\" the D-Link DGE-500T.
+.TP
+.B rtl8139
+The Realtek 8139.
+.TP
+.B 82543gc
+The Intel RS-82543GC gigabit ethernet controller,
+as found on the Intel PRO/1000[FT] server adapter.
+The older non-[FT] cards based on the 82542 (LSI L2A1157)
+chip are not supported, although support would probably be
+easy to add.
+.TP
+.B smc91cxx
+SMC 91cXX chip-based PCMCIA adapters, notably the SMC EtherEZ card.
+.TP
+.B sink
+A
+.B /dev/null
+for ethernet packets \(em the interface discards sent
+packets and never receives any.
+This is used to provide a test bed for
+some experimental ethernet bridging software.
+.SS \fLusbX=type=uhci port=xxx irq=xxx\fP
+This specifies the settings for a USB UHCI controller.
+Like the ethernet controllers, USB controllers are autodetected
+after scanning for the ones listed in
+.IR plan9.ini .
+Thus, most systems will not need a
+.B usbX
+line.
+Also like the ethernet controllers, USB autoprobing can be
+disabled by specifying the line
+.BR *nousbprobe= .
+.SS \fLscsiX=value\fP
+This defines a SCSI interface which cannot be automatically detected
+by the kernel.
+.PP
+Known types are
+.TP
+.B aha1542
+The Adaptec 154x series of controllers (and clones).
+Almost completely configurable, only the
+.EX
+ port=0x300
+.EE
+option need be given.
+.PP
+NCR/Symbios/LSI Logic 53c8xx-based adapters
+and Mylex MultiMaster (Buslogic BT-*) adapters are
+automatically detected and need no entries.
+.PP
+By default, the NCR 53c8xx driver searches for up to 32 controllers.
+This can be changed by setting the variable
+.BR *maxsd53c8xx .
+.PP
+By default the Mylex driver resets SCSI cards by using
+both the hard reset and SCSI bus reset flags in the driver interface.
+If a variable
+.BR *noscsireset
+is defined, the SCSI bus reset flag is omitted.
+.SS Uarts
+Plan 9 automatically configures COM1 and COM2, if found,
+as
+.B eia0
+(port 0x3F8, IRQ4)
+and
+.B eia1
+(port 0x2F8, IRQ3)
+respectively.
+These devices can be disabled by adding a line:
+.EX
+ eia\fIX\fP=disabled
+.EE
+This is typically done in order to reuse the IRQ for
+another device.
+.PP
+The system used to support various serial concentrators,
+including the TTC 8 serial line card and various models
+in the Star Gate Avanstar series of intelligent serial boards.
+These are no longer supported; the much simpler
+Perle PCI-Fast4, PCI-Fast8, and PCI-Fast16 controllers
+have taken their places.
+These latter cards are automatically detected
+and need no configuration lines.
+.PP
+The line
+.B serial=type=com
+can be used to specify settings for a PCMCIA modem.
+.SS \fLmouseport=value\fP
+This specifies where the mouse is attached.
+.I Value
+can be
+.TP
+.B ps2
+the PS2 mouse/keyboard port. The BIOS setup procedure
+should be used to configure the machine appropriately.
+.TP
+.B ps2intellimouse
+an Intellimouse on the PS2 port.
+.TP
+.B 0
+for COM1
+.TP
+.B 1
+for COM2
+.SS \fLmodemport=value\fP
+Picks the UART line to call out on.
+This is used when connecting to a file server over
+an async line.
+.I Value
+is the number of the port.
+.SS \fLpccard0=disabled\fP
+Disable probing for and automatic configuration of PC card controllers.
+.SS \fLpcmciaX=type=XXX irq=value\fP
+If the default IRQ for the
+PCMCIA
+is correct, this entry can be omitted. The value of
+.B type
+is ignored.
+.SS \fLpcmcia0=disabled\fP
+Disable probing for and automatic configuration of PCMCIA controllers.
+.SS \fLconsole=value params\fP
+This is used to specify the console device.
+The default
+value is
+.BR cga ;
+a number
+.B 0
+or
+.B 1
+specifies
+.I COM1
+or
+.I COM2
+respectively.
+A serial console is initially configured with the
+.IR eia (3)
+configuration string
+.B b9600
+.B l8
+.B pn
+.BR s1 ,
+specifying 9600 baud,
+8 bit bytes, no parity, and one stop bit.
+If
+.I params
+is given, it will be used to further
+configure the uart.
+Notice that there is no
+.B =
+sign in the
+.I params
+syntax.
+For example,
+.EX
+ console=0 b19200 po
+.EE
+would use COM1 at 19,200 baud
+with odd parity.
+.SS \fLbootfile=value\fP
+This is used to direct the actions of
+.IR 9load (10.8)
+by naming the device and file from which to load the kernel.
+.SS \fLpartition=value\fP
+This defines the partition table
+.IR 9load (10.8)
+will examine to find disk partitioning information.
+By default, a partition table in a Plan 9 partition
+is consulted; if no such table is found, an old-Plan 9
+partition table on the next-to-last or last sector
+of the disk is consulted.
+A value of
+.B new
+consults only the first table,
+.B old
+only the second.
+.SS \fL*maxmem=value\fP
+This defines the maximum physical address that the system will scan when sizing memory.
+By default the operating system will scan up to 768 megabytes, but setting
+.B *maxmem
+will limit the scan.
+If the system has more than 768 megabytes, you must set
+.B *maxmem
+for the kernel to find it.
+.B *maxmem
+must be less than 1.75 gigabytes.
+.SS \fL*kernelpercent=value\fP
+This defines what percentage of available memory is reserved for the kernel allocation pool.
+The remainder is left for user processes. The default
+.I value
+is
+.B 30
+on CPU servers,
+.B 60
+on terminals with less than 16MB of memory,
+and
+.B 40
+on terminals with memories of 16MB or more.
+Terminals use more kernel memory because
+.IR draw (3)
+maintains its graphic images in kernel memory.
+This deprecated option is rarely necessary in newer kernels.
+.SS \fL*nomce=value\fP
+If machine check exceptions are supported by the processor,
+then they are enabled by default.
+Setting this variable to
+.B 1
+causes them to be disabled even when available.
+.SS \fL*nomp=\fP
+A multiprocessor machine will enable all processors by default.
+Setting
+.B *nomp
+restricts the kernel to starting only one processor and using the
+traditional interrupt controller.
+.SS \fL*ncpu=value\fP
+Setting
+.B *ncpu
+restricts the kernel to starting at most
+.I value
+processors.
+.SS \fL*pcimaxbno=value\fP
+This puts a limit on the maximum bus number probed
+on a PCI bus (default 255).
+For example, a
+.I value
+of 1 should suffice on a 'standard' motherboard with an AGP slot.
+This, and
+.B *pcimaxdno
+below are rarely used and only on troublesome or suspect hardware.
+.SS \fL*pcimaxdno=value\fP
+This puts a limit on the maximum device number probed
+on a PCI bus (default 31).
+.SS \fL*nopcirouting=\fP
+Disable pci routing during boot. May solve interrupt routing
+problems on certain machines.
+.\" .SS \fL*nobios=\fP
+.\" what does this do? something with pci
+.SS \fLioexclude=value\fP
+Specifies a list of ranges I/O ports to exclude from use by drivers.
+Ranges are inclusive on both ends and separated by commas.
+For example:
+.EX
+ ioexclude=0x330-0x337,0x430-0x43F
+.EE
+.SS \fLapm0=\fP
+This enables the ``advanced power management'' interface
+as described in
+.IR apm (3).
+....and
+.....IR apm (8).
+The main feature of the interface is the ability to watch
+battery life.
+....battery life (see
+.....IR stats (8)).
+It is not on by default because it causes problems on some laptops.
+.SS \fLmonitor=value\fP
+.SS \fLvgasize=value\fP
+These are used not by the kernel but by system initialisation.
+.SS \fL*dpms=value\fP
+This is used to specify the screen blanking behavior of the MGA4xx
+video driver.
+Values are
+.BR standby ,
+.BR suspend ,
+and
+.BR off .
+The first two specify differing levels of power saving;
+the third turns the monitor off completely.
+.SS \fLnvr=value\fP
+This is used by a file server kernel to locate a file holding information
+to configure the file system.
+The file cannot live on a SCSI disk.
+The default is
+.B fd!0!plan9.nvr
+(sic),
+unless
+.B bootfile
+is set, in which case it is
+.B plan9.nvr
+on the same disk as
+.BR bootfile .
+The syntax is either
+.BI fd! unit ! name
+or
+.BI hd! unit ! name
+where
+.I unit
+is the numeric unit id.
+This variant syntax is a vestige of the file server kernel's origins.
+.SS \fLaudioX=value\fP
+This defines a sound interface.
+.PP
+Known types are
+.TP
+.B sb16
+Sound Blaster 16.
+.TP
+.B ess1688
+A Sound Blaster clone.
+.PP
+The DMA channel may be any of 5, 6, or 7.
+The defaults are
+.EX
+ port=0x220 irq=7 dma=5
+.EE
+.SS \fLfs=a.b.c.d\fP
+.SS \fLauth=a.b.c.d\fP
+These specify the IP address of the file and authentication server
+to use when mounting a network-provided root file system.
+They are used only if the addresses cannot be determined via DHCP.
+.SH Multiple Configurations
+.PP
+A
+.B plan9.ini
+file may contain multiple configurations,
+each within a block beginning with a line
+.EX
+ [tag]
+.EE
+A special block with the tag
+.B menu
+gives a list of blocks from which the user may
+interactively select the contents of
+.BR plan9.ini .
+There may also be multiple blocks with the tag
+.B common
+which will be included in all selections;
+if any lines appear in
+.B plan9.ini
+before the first block,
+they are treated as a
+.B common
+block.
+.LP
+Within the
+.B menu
+block the following configuration lines are allowed:
+.SS \fLmenuitem=tag[, description]
+The block identified by
+.B tag
+will appear in the presented menu.
+The menu entry will consist of the
+.B tag
+unless the optional
+.B description
+is given.
+.SS \fLmenudefault=tag[, timeout]
+Identifies a default block to be given in the
+menu selection prompt.
+If the optional
+.B timeout
+is given (in seconds),
+the default block will be selected if there is no user
+input within the timeout period.
+.SS \fLmenuconsole=value[, baud]
+Selects a serial console upon which to present the menu
+as no
+.B console
+or
+.B baud
+configuration information will have been processed yet
+(the
+.B plan9.ini
+contents are still to be decided...).
+.LP
+In response to the menu being printed,
+the user is prompted to select a menu item from the list.
+If the numeric response is followed by a
+.BR p ,
+the selected configuration is printed and the menu presented
+again.
+.LP
+The line
+.EX
+ menuitem=tag
+.EE
+is prefixed to the selected configuration as an aid to
+user-level initialization scripts.
+.SH EXAMPLES
+.PP
+A representative
+.BR plan9.ini :
+.IP
+.EX
+% cat /n/c:/plan9.ini
+ether0=type=3C509
+mouseport=ps2
+modemport=1
+serial0=type=generic port=0x3E8 irq=5
+monitor=445x
+vgasize=1600x1200x8
+%
+.EE
+.PP
+Minimum CONFIG.SYS and AUTOEXEC.BAT files to use
+COM2 as a console:
+.IP
+.EX
+% cat /n/c:/config.sys
+SHELL=COMMAND.COM COM2 /P
+% cat /n/c:/autoexec.bat
+@ECHO OFF
+PROMPT $p$g
+PATH C:\eDOS;C:\eBIN
+mode com2:96,n,8,1,p
+SET TEMP=C:\eTMP
+%
+.EE
+.PP
+Simple
+.B plan9.ini
+with multiple configurations:
+.IP
+.EX
+[menu]
+menuitem=vga, Plan 9 with VGA
+menuitem=novga, Plan 9 no automatic VGA
+menudefault=vga
+
+[vga]
+monitor=multisync135
+vgasize=1024x768x8
+
+[novga]
+
+[common]
+ether0=type=i82557
+audio0=type=sb16 port=0x220 irq=5 dma=1
+.EE
+.PP
+With this, the following menu will be presented on boot:
+.IP
+.EX
+Plan 9 Startup Menu:
+====================
+ 1. Plan 9 with VGA
+ 2. Plan 9 no automatic VGA
+Selection[default==1]:
+.EE
+.PP
+Selecting item 1 generates the following
+.B plan9.ini
+to be used by the remainder of the bootstrap process:
+.IP
+.EX
+menuitem=vga
+monitor=multisync135
+vgasize=1024x768x8
+ether0=type=i82557
+audio0=type=sb16 port=0x220 irq=5 dma=1
+.EE
+.PP
+and selecting item 2:
+.IP
+.EX
+menuitem=novga
+ether0=type=i82557
+audio0=type=sb16 port=0x220 irq=5 dma=1
+.EE
+.SH "SEE ALSO"
+.IR root (3),
+.IR 9load (10.8)
+.SH BUGS
+Being able to set the console device to other than a
+display is marginally useful on file servers; MS-DOS
+and the programs which run under it are so tightly bound
+to the display that it is necessary to have a display if any
+setup or reconfiguration programs need to be run.
+Also, the delay before any messages appear at boot time
+is disconcerting, as any error messages from the BIOS
+are lost.
+.PP
+This idea is at best an interesting experiment that needs another iteration.
diff --git a/man/10/print b/man/10/print
new file mode 100644
index 00000000..aadbbad8
--- /dev/null
+++ b/man/10/print
@@ -0,0 +1,402 @@
+.TH PRINT 10.2
+.SH NAME
+print, fprint, sprint, snprint, seprint, smprint, vfprint, vsnprint, vseprint, vsmprint \- print formatted output
+.SH SYNOPSIS
+.ta \w'\fLchar* 'u
+.B
+int print(char *format, ...)
+.PP
+.B
+int fprint(int fd, char *format, ...)
+.PP
+.B
+int sprint(char *s, char *format, ...)
+.PP
+.B
+int snprint(char *s, int len, char *format, ...)
+.PP
+.B
+char* seprint(char *s, char *e, char *format, ...)
+.PP
+.B
+char* smprint(char *format, ...)
+.PP
+.B
+int vfprint(int fd, char *format, va_list v)
+.PP
+.B
+int vsnprint(char *s, int len, char *format, va_list v)
+.PP
+.B
+char* vseprint(char *s, char *e, char *format, va_list v)
+.PP
+.B
+char* vsmprint(char *format, va_list v)
+.SH DESCRIPTION
+.I Print
+writes text to the standard output.
+.I Fprint
+writes to the named output
+file descriptor;
+a buffered form
+is described in
+.IR bio (2).
+.I Sprint
+places text
+followed by the NUL character
+.RB ( \e0 )
+in consecutive bytes starting at
+.IR s ;
+it is the user's responsibility to ensure that
+enough storage is available.
+Each function returns the number of bytes
+transmitted (not including the NUL
+in the case of
+.IR sprint ),
+or
+a negative value if an output error was encountered.
+.PP
+.I Snprint
+is like
+.IR sprint ,
+but will not place more than
+.I len
+bytes in
+.IR s .
+Its result is always NUL-terminated and holds the maximal
+number of complete UTF-8 characters that can fit.
+.I Seprint
+is like
+.IR snprint ,
+except that the end is indicated by a pointer
+.I e
+rather than a count and the return value points to the terminating NUL of the
+resulting string.
+.I Smprint
+is like
+.IR sprint ,
+except that it prints into and returns a string of the required length, which is
+allocated by
+.IR malloc (10.2).
+.PP
+Finally, the routines
+.IR vfprint ,
+.IR vsnprint ,
+.I vseprint
+and
+.I vsmprint
+are like their
+.BR v-less
+relatives except they take as arguments a
+.B va_list
+parameter, so they can be called within a variadic function.
+The Example section shows a representative usage.
+.PP
+Each of these functions
+converts, formats, and prints its
+trailing arguments
+under control of a
+.IR format
+string.
+The
+format
+contains two types of objects:
+plain characters, which are simply copied to the
+output stream,
+and conversion specifications,
+each of which results in fetching of
+zero or more
+arguments.
+The results are undefined if there are arguments of the
+wrong type or too few
+arguments for the format.
+If the format is exhausted while
+arguments remain, the excess
+is ignored.
+.PP
+Each conversion specification has the following format:
+.IP
+.B "% [flags] verb
+.PP
+The verb is a single character and each flag is a single character or a
+(decimal) numeric string.
+Up to two numeric strings may be used;
+the first is called
+.IR width ,
+the second
+.IR precision .
+A period can be used to separate them, and if the period is
+present then
+.I width
+and
+.I precision
+are taken to be zero if missing, otherwise they are `omitted'.
+Either or both of the numbers may be replaced with the character
+.BR * ,
+meaning that the actual number will be obtained from the argument list
+as an integer.
+The flags and numbers are arguments to
+the
+.I verb
+described below.
+.PP
+The numeric verbs
+.BR d ,
+.BR o ,
+.BR b ,
+.BR x ,
+and
+.B X
+format their arguments in decimal,
+octal, binary, hexadecimal, and upper case hexadecimal.
+Each interprets the flags
+.BR 0 ,
+.BR h ,
+.BR hh ,
+.BR l ,
+.BR u ,
+.BR + ,
+.BR - ,
+.BR , ,
+and
+.B #
+to mean pad with zeros,
+short, byte, long, unsigned, always print a sign, left justified, commas every three digits,
+and alternate format.
+Also, a space character in the flag
+position is like
+.BR + ,
+but prints a space instead of a plus sign for non-negative values.
+If neither
+short nor long is specified,
+then the argument is an
+.BR int .
+If unsigned is specified,
+then the argument is interpreted as a
+positive number and no sign is output.
+If two
+.B l
+flags are given,
+then the argument is interpreted as a
+.B vlong
+(usually an 8-byte, sometimes a 4-byte integer).
+If
+.I precision
+is not omitted, the number is padded on the left with zeros
+until at least
+.I precision
+digits appear.
+Then, if alternate format is specified,
+for
+.B o
+conversion, the number is preceded by a
+.B 0
+if it doesn't already begin with one;
+for
+.B x
+conversion, the number is preceded by
+.BR 0x ;
+for
+.B X
+conversion, the number is preceded by
+.BR 0X .
+Finally, if
+.I width
+is not omitted, the number is padded on the left (or right, if
+left justification is specified) with enough blanks to
+make the field at least
+.I width
+characters long.
+.PP
+The floating point verbs
+.BR f ,
+.BR e ,
+.BR E ,
+.BR g ,
+and
+.B G
+take a
+.B double
+argument.
+Each interprets the flags
+.BR + ,
+.BR - ,
+and
+.B #
+to mean
+always print a sign,
+left justified,
+and
+alternate format.
+.I Width
+is the minimum field width and,
+if the converted value takes up less than
+.I width
+characters, it is padded on the left (or right, if `left justified')
+with spaces.
+.I Precision
+is the number of digits that are converted after the decimal place for
+.BR e ,
+.BR E ,
+and
+.B f
+conversions,
+and
+.I precision
+is the maximum number of significant digits for
+.B g
+and
+.B G
+conversions.
+The
+.B f
+verb produces output of the form
+.RB [ - ] digits [ .digits\fR].
+.B E
+conversion appends an exponent
+.BR E [ - ] digits ,
+and
+.B e
+conversion appends an exponent
+.BR e [ - ] digits .
+The
+.B g
+verb will output the argument in either
+.B e
+or
+.B f
+with the goal of producing the smallest output.
+Also, trailing zeros are omitted from the fraction part of
+the output, and a trailing decimal point appears only if it is followed
+by a digit.
+The
+.B G
+verb is similar, but uses
+.B E
+format instead of
+.BR e .
+When alternate format is specified, the result will always contain a decimal point,
+and for
+.B g
+and
+.B G
+conversions, trailing zeros are not removed.
+.PP
+The
+.B s
+verb copies a string
+(pointer to
+.BR char )
+to the output.
+The number of characters copied
+.RI ( n )
+is the minimum
+of the size of the string and
+.IR precision .
+These
+.I n
+characters are justified within a field of
+.I width
+characters as described above.
+The
+.B S
+verb is similar, but it interprets its pointer as an array
+of runes (see
+.IR utf (6));
+the runes are converted to
+.SM UTF
+before output.
+.PP
+The
+.B c
+verb copies a single
+.B char
+(promoted to
+.BR int )
+justified within a field of
+.I width
+characters as described above.
+The
+.B C
+verb is similar, but works on runes.
+.PP
+The
+.B p
+verb formats a pointer value.
+At the moment, it is a synonym for
+.BR ux ,
+but that will change once pointers and integers are different sizes.
+.PP
+The
+.B r
+verb takes no arguments; it copies the error string returned by a call to
+the emulated environment's
+`system calls'.
+It must not be used within the kernels.
+....PP
+...Custom verbs may be installed using
+....IR fmtinstall (2).
+.SH EXAMPLE
+This function prints an error message with a variable
+number of arguments and then quits.
+.IP
+.EX
+.ta 6n +6n +6n
+void fatal(char *msg, ...)
+{
+ char buf[1024], *out;
+ va_list arg;
+
+ out = vseprint(buf, buf+sizeof(buf), "Fatal error: ");
+ va_start(arg, msg);
+ out = vseprint(out, buf+sizeof(buf), msg, arg);
+ va_end(arg);
+ write(2, buf, out-buf);
+ exits("fatal error");
+}
+.EE
+.SH SOURCE
+.B /lib9/fmt*
+.br
+.B /libkern/fmt*
+.SH SEE ALSO
+.IR utf (6)
+.SH DIAGNOSTICS
+Routines that write to a file descriptor or call
+.IR malloc
+set
+.IR errstr .
+.SH BUGS
+The formatting is close to that specified for ANSI
+.IR fprintf (2);
+the main difference is that
+.B b
+is not in ANSI and
+.B u
+is a flag here instead of a verb.
+Also, and distinctly not a bug,
+.I print
+and friends generate
+.SM UTF
+rather than
+.SM ASCII.
+.PP
+There is no
+.BR runeprint ,
+.BR runefprint ,
+etc. because runes are byte-order dependent and should not be written directly to a file; use the
+UTF output of
+.I print
+or
+.I fprint
+instead.
+Also,
+.I sprint
+is deprecated for safety reasons; use
+.IR snprint ,
+.IR seprint ,
+or
+.I smprint
+instead.
+Safety also precludes the existence of
+.IR runesprint .
diff --git a/man/10/qio b/man/10/qio
new file mode 100644
index 00000000..c0a88869
--- /dev/null
+++ b/man/10/qio
@@ -0,0 +1,482 @@
+.TH QIO 10.2
+.SH NAME
+qio: qget, qdiscard, qconsume, qpass, qproduce, qcopy, qopen, qbread, qread, qbwrite, qwrite, qiwrite, qfree, qclose, qhangup, qreopen, qlen, qwindow, qcanread, qsetlimit, qnoblock, qflush, qfull \- queued I/O for devices
+.SH SYNOPSIS
+.ta \w'\fLQueue* 'u
+.B
+Queue* qopen(int limit,int msg, void (*kick)(void*),void *arg)
+.PP
+.B
+void qhangup(Queue *q, char *reason)
+.PP
+.B
+void qclose(Queue *q)
+.PP
+.B
+void qreopen(Queue *q)
+.PP
+.B
+void qfree(Queue *q)
+.PP
+.B
+long qbwrite(Queue *q, Block *b)
+.PP
+.B
+long qwrite(Queue *q, void *buf, int len)
+.PP
+.B
+int qpass(Queue *q, Block *b)
+.PP
+.B
+int qpassnolim(Queue *q, Block *b)
+.PP
+.B
+int qproduce(Queue *q, void *buf, int len)
+.PP
+.B
+int qiwrite(Queue *q, void *buf, int len)
+.PP
+.B
+Block* qbread(Queue *q, int len)
+.PP
+.B
+long qread(Queue *q, void *buf, int len)
+.PP
+.B
+Block* qcopy(Queue *q, int len, ulong offset)
+.PP
+.B
+Block* qget(Queue *q)
+.PP
+.B
+int qconsume(Queue *q, void *buf, int len)
+.PP
+.B
+int qdiscard(Queue *q, int len)
+.PP
+.B
+void qflush(Queue *q)
+.PP
+.B
+int qlen(Queue *q)
+.PP
+.B
+int qwindow(Queue *q)
+.PP
+.B
+int qcanread(Queue *q)
+.PP
+.B
+void qsetlimit(Queue *q, int limit)
+.PP
+.B
+void qnoblock(Queue *q, int nonblock)
+.PP
+.B
+int qfull(Queue *q);
+.SH DESCRIPTION
+This suite of functions provides serial data buffering for device drivers.
+Data is stored in a
+.B Queue
+structure as a sequence of variable-sized
+.BR Blocks ;
+see
+.IR allocb (10.2).
+.PP
+.I Qopen
+initialises and returns a pointer to a new
+.BR Queue ,
+configuring it according to the following parameters:
+.TF limit
+.PD
+.TP
+.I limit
+Set the queue limit (high water mark) in bytes.
+.TP
+.I msg
+Set message mode if non-zero; otherwise, stream mode (discussed below).
+.TP
+.I kick
+Optional flow-control function called by
+.I qbread
+to restart writers, and by
+.I qbwrite
+(also
+.IR qiwrite )
+to restart readers.
+.TP
+.I arg
+Argument to pass to
+.I kick
+.PP
+.I Qhangup
+marks
+.I q
+as `hung up'
+for the given
+.IR reason
+.RB ( Ehungup
+by default).
+Subsequent attempts to write to the queue raise an
+.IR error (10.2).
+.I Qhangup
+does not flush the queue: subsequent read requests are
+handled normally until the queue empties.
+.I Qread
+and the other functions then return their conventional values
+for a hungup stream: 0, -1 or a null pointer, depending on the function.
+After a few such attempts by any process, an
+.IR error (10.2)
+is raised (typically
+.BR Ehungup )
+on each subsequent read.
+.PP
+If queued data is left unread, and not flushed by
+.I qflush
+or
+.IR qclose ,
+the data will again be readable following a subsequent
+.IR qreopen .
+.PP
+.I Qclose
+also marks a given
+.I q
+as `hung up',
+but removes and frees any queued data Blocks.
+.I Qclose
+ignores calls when
+.I q
+is null.
+.PP
+.I Qreopen
+makes a closed or hung up queue available for use again.
+The queue's data limit is reset to the
+.I limit
+value given when the queue was first created by
+.IR qopen ,
+cancelling the effect of any previous call to
+.IR qsetlimit .
+.PP
+.I Qfree
+closes
+.I q
+with
+.I qclose
+and frees it.
+The caller must ensure that no references remain;
+these functions do not keep a reference count.
+.SS "Flow control"
+The queue I/O routines provide a flow control mechanism to coordinate producers and consumers.
+Each queue has a limit on the number of bytes queued, its `high water mark',
+initially set when the queue is created, but adjustable by
+.IR qsetlimit ,
+below.
+The low water mark is not set explicitly:
+it is always half the current queue limit.
+When the high water mark is exceeded, writes normally block until a reader drains the
+queue below its low water mark; the writer is then allowed to proceed.
+Conversely, readers normally block when the queue is empty, until a writer
+arrives with data, or the queue is closed.
+.PP
+A queue can be given a
+.I kick
+function when the queue is created by
+.IR qopen .
+The function is invoked by
+.IR qread
+and
+.IR qbread ,
+to prod an output routine when the queue falls below the low-water mark, and by
+.IR qwrite ,
+.IR qbwrite
+and
+.IR qiwrite ,
+to notify a reader that a queue is no longer empty.
+Because
+.I kick
+is called from the reading (or writing) process, or an interrupt handler, it
+must not block.
+.PP
+Interrupt handlers must not
+.IR sleep (10.2),
+and are therefore restricted to using only the non-blocking functions described below.
+.SS "Stream mode and message mode"
+In stream mode,
+no read will return more than one
+block
+of data, but
+a read can split a block that contains more data than requested, leaving the remainder
+in a new block at the front of the Queue.
+Writes of more than the maximum
+.B Block
+size (currently 128k bytes)
+are split into as many Blocks as required, each written separately to the queue,
+in order, but with possible flow-control between them.
+The queue is locked meanwhile, however, so that data from other writers is not intermingled.
+.PP
+In message mode, by contrast, a read will return at most
+one block's worth of data, but the remainder of a partially-read block will be discarded,
+not returned to the queue.
+If a write count exceeds the maximum
+.B Block
+size, the excess data is discarded:
+at most a single block can be queued.
+.PP
+The mode of the queue should be taken into account in the descriptions below
+of the following functions:
+.IR qwrite ,
+.IR qiwrite ,
+.IR qbread
+and
+.IR qconsume .
+No other functions are aware of the distinction.
+.SS "Write operations (flow controlled)"
+.I Qwrite
+copies
+.I len
+bytes of data from
+.I buf
+into one or more
+.B Blocks
+which it places on the
+.IR q .
+.I Qwrite
+always returns
+.IR len .
+It can implement message mode.
+.PP
+.I Qbwrite
+places the single Block
+.I b
+on the tail of
+.IR q ,
+waking any sleeping reader.
+If the queue is full, the
+writing process blocks until a reader
+has reduced the queued data to
+the low-water mark;
+if the queue is non-blocking
+(see
+.I qnoblock
+below),
+the data is discarded without notice.
+.I Qbwrite
+normally returns
+.IR len ,
+but raises an
+.IR error (10.2)
+if the queue is closed (see
+.I qhangup
+and
+.IR qclose ).
+The block
+.I b
+is always freed.
+Note that
+.I b
+can be empty (zero-length), to punctuate the data in a queue.
+.I Qbwrite
+cannot handle a list of Blocks;
+.I qpass
+must be used instead.
+.SS Non-blocking writes
+.PP
+.I Qproduce
+returns -1immediately if
+.I q
+is full.
+Otherwise, it queues
+.I len
+bytes of data from
+.I buf
+in a single
+.B Block
+on
+.I q
+and returns the number of bytes written.
+.PP
+.I Qpass
+attempts to place the list of Blocks headed by
+.I b
+on
+.IR q ,
+returning the number of bytes written if successful.
+If
+.I q
+was full, it
+frees the Block list
+.I b
+and returns -1.
+.PP
+.I Qpassnolim
+puts the Block list
+.I b
+on
+.I q
+regardless of flow control; it returns the number of bytes in the list
+.IR b .
+.PP
+.I Qiwrite
+is a variant of
+.I qwrite
+used exclusively by the kernel print function,
+to allow printing by interrupt handlers;
+.I qiwrite
+could be used with care by other routines, but
+.IR qproduce
+is preferable.
+.I Qiwrite
+writes the
+.I len
+bytes of data at
+.I buf
+into the
+.I q
+without regard to flow control;
+the writer never blocks.
+The queue is assumed to be open.
+.I Qiwrite
+always returns
+.IR len .
+It can implement message mode.
+.SS "Read operations (flow controlled)"
+.I Qbread
+blocks until data arrives on
+.IR q ,
+then
+returns the first
+.BR Block ;
+it limits the data returned
+to
+.I len
+bytes (in the manner depending on the mode of
+.IR q ).
+It returns a null pointer if the queue has hung up.
+.PP
+.I Qread
+reads a Block of up to
+.I len
+bytes from
+.I q
+using
+.IR qbread ,
+and copies the data in the Block into
+.IR buf ,
+then frees the Block and returns
+the number of bytes read.
+.I Qread
+returns 0 on end of file or error (hangup).
+It can implement message mode.
+.PP
+.I Qcopy
+returns a Block with a copy of data from the queue (the data remains on the queue).
+The copy begins
+.I offset
+bytes into the queue's data and proceeds until
+.I len
+bytes have been copied or no more data remains.
+The Block's read and write pointers delimit the data copied into it.
+.I Qcopy
+can be used by a reliable transport protocol to copy a packet for transmission,
+leaving the data queued for possible retransmission, if unacknowledged.
+.SS Non-blocking reads
+.PP
+.I Qconsume
+returns -1 immediately if
+.I q
+is empty.
+Otherwise, it
+copies up to
+.I len
+bytes from the first
+.B Block
+on the queue into
+.IR buf ,
+returning the number of bytes copied.
+It can implement message mode.
+.PP
+.I Qget
+returns a null pointer immediately if
+.I q
+is empty or closed.
+Otherwise, it
+returns the first
+.B Block
+on the queue.
+.SS "Discard and flush"
+.I Qdiscard
+removes the first
+.I len
+data bytes from
+.IR q ;
+it returns the number of bytes actually discarded, in case
+the queue is shorter than
+.IR len .
+If the queue drains below the low-water mark,
+.I qdiscard
+wakes any sleeping writers.
+Since it does not block,
+.I qdiscard
+can safely be called from interrupt handlers.
+It is useful in transport protocol drivers to remove data from the queue
+once acknowledged.
+.PP
+.I Qflush
+discards all data waiting on
+.IR q ,
+waking any waiting writer.
+.SS "Queue status"
+The following functions return a Queue's status.
+Note that between a call to one of these functions and another operation,
+the state can change if a driver allows concurrent access by
+either another process or an interrupt handler.
+.PP
+.I Qlen
+returns the number of bytes queued on
+.IR q .
+.PP
+.I Qwindow
+returns the number of bytes that can be written before reaching the queue's high-water mark.
+A return of 0 means that a write operation will certainly block;
+a non-zero return gives no guarantees (see
+.IR qfull ,
+below).
+.PP
+.I Qcanread
+returns 1 if any data queued is queued. A subsequent read operation will not block.
+.PP
+.I Qfull
+returns non-zero if
+.I q
+is flow-controlled and a write would block or a non-blocking write would return an error.
+(Note that the implementation allows
+.I qwindow
+to return non-zero yet
+.I qfull
+to return true.)
+.SS "Queue control"
+.I Qsetlimit
+sets the high water mark for the queue to
+.IR limit .
+Note that
+.I qopen
+saves the initial queue limit.
+If the queue is closed and reopened (by
+.IR qreopen )
+that initial limit is restored.
+.PP
+.I Qnoblock
+sets or resets non-blocking mode.
+If
+.I nonblock
+is non-zero,
+the queue becomes non-blocking, and
+data written to a queue beyond its high water mark is discarded
+by calls that would otherwise block.
+.SH SOURCE
+.B /os/port/qio.c
+.br
+.B /emu/port/qio.c
+.SH SEE ALSO
+.IR allocb (10.2),
+.IR ref (10.2)
diff --git a/man/10/qlock b/man/10/qlock
new file mode 100644
index 00000000..155b4dd9
--- /dev/null
+++ b/man/10/qlock
@@ -0,0 +1,106 @@
+.TH QLOCK 10.2
+.SH NAME
+qlock, qunlock, canqlock, rlock, runlock, wlock, wunlock \- serial synchronisation
+.SH SYNOPSIS
+.ta \w'\fLvoid 'u
+.B
+void qlock(QLock *l)
+.PP
+.B
+void qunlock(QLock *l)
+.PP
+.B
+int canqlock(QLock *l)
+.PP
+.B
+void rlock(RWlock *l)
+.PP
+.B
+void runlock(RWlock *l)
+.PP
+.B
+int canrlock(RWlock *l)
+.PP
+.B
+void wlock(RWlock *l)
+.PP
+.B
+void wunlock(RWlock *l)
+.SH DESCRIPTION
+The primitive locking functions described in
+.IR lock (10.2)
+guarantee mutual exclusion, but they implement spin locks,
+and should not be used if the process might
+.IR sleep (10.2)
+within a critical section.
+The following functions serialise access to a resource by forming an orderly
+queue of processes.
+.PP
+Each resource to be controlled is given an associated
+.B QLock
+structure; it is usually most straightforward to put the
+.B QLock
+in the structure that represents the resource.
+It must be initialised to zero before use
+(as guaranteed for global variables and for structures allocated by
+.IR malloc ).
+.PP
+On return from
+.IR qlock ,
+the process has acquired the lock
+.IR l ,
+and can assume exclusive access to the associated resource.
+If the lock is not immediately available, the requesting process is placed on a
+FIFO queue of processes that have requested the lock.
+Processes on this list are blocked in the
+.L Queueing
+state.
+.PP
+.I Qunlock
+unlocks
+.I l
+and schedules the first process queued for it (if any).
+.PP
+.I Canqlock
+is a non-blocking form of
+.IR qlock .
+It tries to obtain the lock
+.I l
+and returns true if successful, and 0 otherwise;
+it always returns immediately.
+.PP
+.B RWlock
+is a form of lock for resources that have distinct readers and writers.
+It allows concurrent readers but gives each writer exclusive access.
+A caller announces its read or write intentions by choice of lock (and unlock) function;
+the system assumes the caller will not modify a structure accessed under read lock.
+.PP
+.I Rlock
+acquires
+.I l
+for reading.
+The holder can read but agrees not to modify the resource.
+There may be several concurrent readers.
+.I Canrlock
+is non-blocking: it returns non-zero if it successfully acquired the lock immediately,
+and 0 if the resource was unavailable.
+.PP
+.I Runlock
+returns a read lock;
+the last reader out enables the first writer waiting (if any).
+.PP
+.I Wlock
+acquires a write lock.
+The holder of such a lock may assume exclusive access to the resource,
+and is allowed to modify it.
+.PP
+.I Wunlock
+returns a write lock.
+The next pending process, whether reader or writer, is scheduled.
+.SH SOURCE
+.B /os/port/qlock.c
+.br
+.B /os/emu/port/lock.c
+.SH SEE ALSO
+.IR lock (10.2),
+.IR splhi (10.2)
diff --git a/man/10/readnum b/man/10/readnum
new file mode 100644
index 00000000..64103cac
--- /dev/null
+++ b/man/10/readnum
@@ -0,0 +1,60 @@
+.TH READNUM 10.2
+.SH NAME
+readnum, readstr \- return values from read from device
+.SH SYNOPSIS
+.ta \w'\fLchar* 'u
+.B
+int readstr(ulong off, char *buf, ulong n, char *str)
+.PP
+.B
+int readnum(ulong off, char *buf, ulong n, ulong val, int size)
+.SH DESCRIPTION
+.I Readstr
+and
+.I readnum
+simplify the return of strings and numbers from device
+.I read
+routines,
+because they deal with any buffering and boundary cases.
+Several parameters to the read call are often handed on directly
+to these functions:
+the file offset, as
+.IR off ;
+the address of the user's buffer, as
+.IR buf ;
+and the number of bytes requested, as
+.IR n .
+Both functions return the number of bytes they have stored in
+.IR buf ,
+and which can often be returned directly from the device read routine.
+.PP
+.I Readstr
+satisfies a read by copying data into
+.I buf
+from the NUL-terminated string in
+.IR str .
+The data transferred is selected and limited by
+.IR off ,
+.I n
+and the length of
+.IR str .
+.PP
+.I Readnum
+converts the unsigned integer
+.I val
+to a decimal representation in
+.IR buf .
+The value is right-justified in a field of
+.IR size "-1"
+places and is followed by a blank.
+.I Size
+can be the global constant
+.L NUMSIZE
+for 32-bit integers;
+the largest
+.I size
+allowed is 64 bytes.
+.SH SOURCE
+.B /os/port/devcons.c
+.br
+.B /emu/port/devcon.c
diff --git a/man/10/ref b/man/10/ref
new file mode 100644
index 00000000..9a363f8c
--- /dev/null
+++ b/man/10/ref
@@ -0,0 +1,61 @@
+.TH REF 10.2
+.SH NAME
+Ref, incref, decref \- reference counts
+.SH SYNOPSIS
+.ta \w'\fLchar* 'u
+.PP
+.B
+int incref(Ref *r)
+.PP
+.B
+int decref(Ref *r)
+.SH DESCRIPTION
+A
+.B Ref
+structure holds a reference count for a data structure:
+.IP
+.EX
+typedef struct
+struct Ref
+{
+ Lock;
+ long ref;
+} Ref;
+.EE
+.PP
+The reference count proper is found in
+.BR ref ;
+the
+.B Lock
+prevents concurrent updates
+(see
+.IR lock (10.2)).
+.PP
+.I Incref
+atomically increments the reference count
+.IR r ,
+and returns the new count.
+.PP
+.I Decref
+atomically decrements the reference count
+.IR r ,
+and returns the new count.
+.SH EXAMPLES
+Release a structure containing a
+.B Ref
+on last use.
+.IP
+.EX
+if(decref(s) == 0)
+ free(s);
+.EE
+.SH DIAGNOSTICS
+.I Decref
+will
+.IR panic (10.2)
+if the count goes negative,
+revealing a reference counting bug.
+.SH SOURCE
+.B /os/port/chan.c
+.br
+.B /emu/port/chan.c
diff --git a/man/10/rune b/man/10/rune
new file mode 100644
index 00000000..8c3b6324
--- /dev/null
+++ b/man/10/rune
@@ -0,0 +1,150 @@
+.TH RUNE 10.2
+.SH NAME
+runetochar, chartorune, runelen, fullrune, utflen, utfrune, utfrrune, utfutf \- rune/UTF conversion
+.SH SYNOPSIS
+.ta \w'\fLchar*xx'u
+.PP
+.B
+int runetochar(char *s, Rune *r)
+.PP
+.B
+int chartorune(Rune *r, char *s)
+.PP
+.B
+int runelen(long r)
+.PP
+.B
+int fullrune(char *s, int n)
+.PP
+.B
+int utflen(char *s)
+.PP
+.B
+char* utfrune(char *s, long c)
+.PP
+.B
+char* utfrrune(char *s, long c)
+.PP
+.B
+char* utfutf(char *s1, char *s2)
+.SH DESCRIPTION
+These routines convert to and from a
+.SM UTF
+byte stream and runes.
+.PP
+.I Runetochar
+copies one rune at
+.I r
+to at most
+.B UTFmax
+bytes starting at
+.I s
+and returns the number of bytes copied.
+.BR UTFmax ,
+defined as
+.B 3
+in
+.BR <libc.h> ,
+is the maximum number of bytes required to represent a rune.
+.PP
+.I Chartorune
+copies at most
+.B UTFmax
+bytes starting at
+.I s
+to one rune at
+.I r
+and returns the number of bytes copied.
+If the input is not exactly in
+.SM UTF
+format,
+.I chartorune
+will convert to 0x80 and return 1.
+.PP
+.I Runelen
+returns the number of bytes
+required to convert
+.I r
+into
+.SM UTF.
+.PP
+.I Fullrune
+returns 1 if the string
+.I s
+of length
+.I n
+is long enough to be decoded by
+.I chartorune
+and 0 otherwise.
+This does not guarantee that the string
+contains a legal
+.SM UTF
+encoding.
+This routine is used by programs that
+obtain input a byte at
+a time and need to know when a full rune
+has arrived.
+.PP
+The following routines are analogous to the
+corresponding string routines with
+.B utf
+substituted for
+.B str
+and
+.B rune
+substituted for
+.BR chr .
+.PP
+.I Utflen
+returns the number of runes that
+are represented by the
+.SM UTF
+string
+.IR s .
+.PP
+.I Utfrune
+.RI ( utfrrune )
+returns a pointer to the first (last)
+occurrence of rune
+.I c
+in the
+.SM UTF
+string
+.IR s ,
+or 0 if
+.I c
+does not occur in the string.
+The NUL byte terminating a string is considered to
+be part of the string
+.IR s .
+.PP
+.I Utfutf
+returns a pointer to the first occurrence of
+the
+.SM UTF
+string
+.I s2
+as a
+.SM UTF
+substring of
+.IR s1 ,
+or 0 if there is none.
+If
+.I s2
+is the null string,
+.I utfutf
+returns
+.IR s1 .
+.SH SOURCE
+.B /libkern/rune.c
+.br
+.B /libkern/runestrlen.c
+.br
+.B /libkern/utflen.c
+.br
+.B /libkern/utfrrune.c
+.br
+.B /libkern/utfrune.c
+.SH SEE ALSO
+.IR convcs (2),
+.IR utf (6)
diff --git a/man/10/seconds b/man/10/seconds
new file mode 100644
index 00000000..aeec3268
--- /dev/null
+++ b/man/10/seconds
@@ -0,0 +1,64 @@
+.TH SECONDS 10.2
+.SH NAME
+seconds, ticks, HZ, MS2HZ, MS2TK, TK2MS, TK2SEC \- kernel times and time conversions
+.SH SYNOPSIS
+.ta \w'\fL#define 'u
+.B
+long seconds(void)
+.PP
+.B
+ulong ticks(void)
+.PP
+.EX
+#define HZ ...
+#define MS2HZ(t) ...
+#define TK2SEC(t) ...
+#define TK2MS(t) ...
+#define MS2TK(m) ...
+.EE
+.SH DESCRIPTION
+.I Seconds
+returns the system's idea of the current time as the number of seconds
+since the start of the epoch
+(00:00:00 GMT, January 1, 1970).
+.PP
+.I Ticks
+returns the number of system-dependent clock ticks since system boot.
+.PP
+The system clock frequency is platform-dependent.
+Several symbolic constants and macro functions are defined by
+the file
+.B mem.h
+to convert between different time units:
+.TF TK2SEC(t)
+.PD
+.TP
+.B HZ
+The number of clock ticks per second.
+.TP
+.B MS2HZ
+Milliseconds per clock tick.
+.TP
+.BI TK2SEC( t )
+Convert
+.I t
+clock ticks to seconds and return the result (truncating not rounding).
+.TP
+.BI TK2MS( t )
+Convert
+.I t
+clock ticks to milliseconds and return the result.
+.TP
+.BI MS2TK( m )
+Convert
+.I m
+milliseconds to clock ticks and return the result (truncating).
+.PP
+The functions are often used to calculate delays for timing functions,
+for instance:
+.IP
+.EX
+if(atactlrwait(dp->cp, DHmagic, 0, MS2TK(100))){
+ ...
+}
+.EE
diff --git a/man/10/sleep b/man/10/sleep
new file mode 100644
index 00000000..d823d99a
--- /dev/null
+++ b/man/10/sleep
@@ -0,0 +1,125 @@
+.TH SLEEP 10.2
+.SH NAME
+sleep, wakeup, tsleep, return0 \- process synchronisation
+.SH SYNOPSIS
+.ta \w'\fLvoid 'u
+.B
+void sleep(Rendez *r, int (*f)(void*), void *arg)
+.PP
+.B
+void wakeup(Rendez *r)
+.PP
+.B
+void tsleep(Rendez *r, int (*f)(void*), void *arg, int ms)
+.PP
+.B
+int return0(void *arg)
+.PP
+.SH DESCRIPTION
+A process running in the kernel can use these functions to
+synchronise with an interrupt handler or another kernel process.
+In particular, they are used by device drivers to wait for an event to be signalled on
+receipt of an interrupt.
+(In practice, they are most often used indirectly, through
+.IR qio (10.2)
+for instance.)
+.PP
+The caller of
+.I sleep
+and a caller of
+.I wakeup
+share a
+.B Rendez
+structure, to provide a rendezvous point between them
+to synchronise on an event.
+.I Sleep
+uses a condition function
+.I f
+that returns true if the event has occurred.
+.PP
+.I Sleep
+evaluates
+.IB f ( arg ).
+If true, the event has happened and
+.I sleep
+returns immediately.
+Otherwise,
+.I sleep
+blocks on the event variable
+.IR r ,
+awaiting
+.IR wakeup .
+.PP
+.I Wakeup
+is called by either a process or an interrupt handler to wake any process
+sleeping at
+.IR r ,
+signifying that the corresponding condition is true (the event has occurred).
+It has no effect if there is no sleeping process.
+.PP
+.I Tsleep
+is similar to
+.IR sleep ,
+except that if the condition
+.IB f ( arg )
+is false and the caller does sleep,
+and nothing else wakes it within
+.I ms
+millliseconds,
+the system will wake it.
+.IR Tsleep 's
+caller must check its environment to decide whether timeout or the event
+occurred.
+The timing provided by
+.I tsleep
+is imprecise, but adequate in practice for the normal use of protecting against
+lost interrupts and otherwise unresponsive devices or software.
+.PP
+.I Return0
+ignores its arguments and returns zero. It is commonly used as
+the predicate
+.I f
+in a call to
+.I tsleep
+to obtain a time delay, using a
+.B Rendez
+variable
+.B sleep
+in the
+.B Proc
+structure, for example:
+.IP
+.B tsleep(&up->sleep, return0, nil, 10);
+.PP
+Both
+.I sleep
+and
+.I tsleep
+can be interrupted by
+.IR swiproc
+(see
+.IR kproc (10.2)),
+causing a non-local goto through a call to
+.IR error (10.2).
+.SH DIAGNOSTICS
+There can be at most one process waiting on a
+.BR Rendez ,
+and if two processes collide, the system will
+.IR panic (10.2)
+.RB (`` "double sleep" '').
+Access to a
+.B Rendez
+must therefore be serialised by some other mechanism, usually
+.IR qlock (10.2).
+.SH SOURCE
+.B /os/port/proc.c
+.br
+.B /emu/port/proc.c
+.SH SEE ALSO
+.IR lock (10.2),
+.IR qlock (10.2),
+.IR delay (10.2)
+.br
+``Process Sleep and Wakeup on a Shared-memory Multiprocessor'',
+in
+.I "Plan 9 Programmer's Manual: Volume 2".
diff --git a/man/10/splhi b/man/10/splhi
new file mode 100644
index 00000000..9ac9cb3f
--- /dev/null
+++ b/man/10/splhi
@@ -0,0 +1,55 @@
+.TH SPLHI 10.2
+.SH NAME
+splhi, spllo, splx, islo \- enable and disable interrupts
+.SH SYNOPSIS
+.ta \w'\fLvoid 'u
+.B
+int spllo(void)
+.PP
+.B
+int splhi(void)
+.PP
+.B
+void splx(int x)
+.PP
+.B
+int islo(void)
+.SH DESCRIPTION
+These primitives enable and disable maskable interrupts on the current
+processor.
+Generally, device drivers should use
+.I ilock
+(see
+.IR lock (10.2)),
+.IR sleep (10.2),
+or the functions in
+.IR qio (10.2)
+to control interaction between processes and interrupt handlers.
+Those routines (but not these) provide correct synchronisation on multiprocessors.
+.PP
+.I Spllo
+enables interrupts and returns a flag representing the previous interrupt enable state.
+It must not normally be called from interrupt level.
+.PP
+.I Splhi
+disables all maskable interrupts and returns the previous interrupt enable state.
+The period during which interrupts are disabled had best be short,
+or real-time applications will suffer.
+.PP
+.I Splx
+restores the interrupt enable state
+state to
+.IR x ,
+which must be a value returned
+by a previous call to
+.I splhi
+or
+.IR spllo .
+.PP
+.I Islo
+returns true (non-zero) if interrupts are currently enabled, and 0 otherwise.
+.SH SEE ALSO
+.IR lock (10.2),
+.IR qio (10.2),
+.IR sleep (10.2),
+.IR intrenable (10.2)
diff --git a/man/10/srclist b/man/10/srclist
new file mode 100644
index 00000000..199711b0
--- /dev/null
+++ b/man/10/srclist
@@ -0,0 +1,41 @@
+.TH SRCLIST 10.1
+.SH NAME
+srclist \- list source files used to build an executable
+.SH SYNOPSIS
+.B srclist
+[
+.B -ce
+] [
+.BI -r " rootdir"
+\&...
+]
+.I executable
+.SH DESCRIPTION
+.I Srclist
+prints on standard output, one per line, the names of source files used to build
+the given
+.IR executable ,
+which should be
+in
+.IR a.out (10.6)
+format.
+.PP
+By default, all source file names are listed.
+The
+.B -c
+option restricts the output to names ending
+.RB ` .c '.
+The
+.B -e
+option restricts the output to file names that currently exist.
+Each
+.B -r
+option adds a new root directory
+.I rootdir
+to an internal list.
+Only the names of source files that appear below one of the root directories
+will be printed.
+.SH SOURCE
+.B /utils/srclist
+.SH SEE ALSO
+.IR inm (10.1)
diff --git a/man/10/strcat b/man/10/strcat
new file mode 100644
index 00000000..6a1f9fd8
--- /dev/null
+++ b/man/10/strcat
@@ -0,0 +1,170 @@
+.TH STRCAT 10.2
+.SH NAME
+strcat, strcmp, strncmp, strcpy, strncpy, strlen, strchr, strrchr, strdup, strstr \- string operations
+.SH SYNOPSIS
+.ta \w'\fLchar* \fP'u
+.B
+char* strcat(char *s1, char *s2)
+.PP
+.B
+int strcmp(char *s1, char *s2)
+.PP
+.B
+int strncmp(char *s1, char *s2, long n)
+.PP
+.B
+char* strcpy(char *s1, char *s2)
+.PP
+.B
+char* strncpy(char *s1, char *s2, long n)
+.PP
+.B
+long strlen(char *s)
+.PP
+.B
+char* strchr(char *s, char c)
+.PP
+.B
+char* strrchr(char *s, char c)
+.PP
+.B
+char* strdup(char *s)
+.PP
+.B
+char* strstr(char *s1, char *s2)
+.SH DESCRIPTION
+The arguments
+.I s1, s2
+and
+.I s
+point to null-terminated strings.
+The functions
+.IR strcat ,
+.IR strcpy ,
+and
+.I strncpy
+all alter
+.IR s1 .
+These functions do not check for overflow of
+the array pointed to by
+.IR s1 .
+.PP
+.I Strcat
+appends a copy of string
+.I s2
+to the end of string
+.IR s1 ,
+and
+returns a pointer to the null-terminated result.
+.PP
+.I Strcmp
+compares its arguments and returns an integer
+less than, equal to, or greater than 0,
+according as
+.I s1
+is lexicographically less than, equal to, or
+greater than
+.IR s2 .
+.I Strncmp
+makes the same comparison but examines at most
+.I n
+bytes.
+The comparisons are made with unsigned bytes.
+.PP
+.I Strcpy
+copies string
+.I s2
+to
+.IR s1 ,
+stopping after the null byte has been copied.
+.I Strncpy
+copies exactly
+.I n
+bytes,
+truncating
+.I s2
+or adding
+null bytes to
+.I s1
+if necessary.
+The result will not be null-terminated if the length
+of
+.I s2
+is
+.I n
+or more.
+Each function returns
+.IR s1 .
+.PP
+.I Strlen
+returns the number of bytes in
+.IR s ,
+not including the terminating null byte.
+.PP
+.I Strchr
+.RI ( strrchr )
+returns a pointer to the first (last)
+occurrence of byte
+.I c
+in string
+.IR s ,
+or
+.L 0
+if
+.I c
+does not occur in the string.
+The null byte terminating a string is considered to
+be part of the string.
+.PP
+.I Strdup
+returns a pointer to a distinct copy of the null-terminated string
+.I s
+in space obtained from
+.IR malloc (10.2)
+or
+.L 0
+if no space can be obtained.
+.PP
+.I Strstr
+returns a pointer to the first occurrence of
+.I s2
+as a substring of
+.IR s1 ,
+or 0 if there is none.
+If
+.I s2
+is the null string,
+.I strstr
+returns
+.IR s1 .
+.SH SOURCE
+.B /libkern/str*.c
+.br
+.B /libkern/str*-\fIobjtype\fP.c
+.br
+.B /lib9/strdup.c
+.SH SEE ALSO
+.IR memory (10.2),
+.IR rune (10.2)
+.SH BUGS
+These routines know nothing about
+.SM UTF.
+Use the routines in
+.IR rune (10.2)
+as appropriate.
+Note, however, that the definition of UTF guarantees that
+.I strcmp
+compares UTF strings correctly.
+.PP
+The outcome of overlapping moves varies among implementations.
+.PP
+Note the absence of ANSI C's
+.IR strncat ,
+.IR strpbrk ,
+.IR strspn ,
+.IR strcspn
+and
+.IR strtok ,
+but the presence of
+.IR strdup .
+...strtod.c strtol.c strtoul.c strtoll.c
diff --git a/man/10/styx b/man/10/styx
new file mode 100644
index 00000000..cbf9bdda
--- /dev/null
+++ b/man/10/styx
@@ -0,0 +1,364 @@
+.TH STYX 10.2
+.SH NAME
+Fcall, convS2M, convD2M, convM2S, convM2D, fcallfmt, dirfmt, dirmodefmt, statcheck, sizeS2M, sizeD2M \- interface to Inferno File protocol
+.SH SYNOPSIS
+.B #include <lib9.h>
+.br
+.br
+.B #include <styx.h>
+.PP
+.B
+uint convS2M(Fcall *f, uchar *ap, uint nap)
+.PP
+.B
+uint convD2M(Dir *d, uchar *ap, uint nap)
+.PP
+.B
+uint convM2S(uchar *ap, uint nap, Fcall *f)
+.PP
+.B
+uint convM2D(uchar *ap, uint nap, Dir *d, char *strs)
+.PP
+.B
+int dirfmt(Fmt*)
+.PP
+.B
+int fcallfmt(Fmt*)
+.PP
+.B
+int dirmodefmt(Fmt*)
+.PP
+.B
+int statcheck(uchar *buf, uint nbuf)
+.PP
+.B
+uint sizeS2M(Fcall *f)
+.PP
+.B
+uint sizeD2M(Dir *d)
+.SH DESCRIPTION
+These
+routines convert messages in the machine-independent format of
+the Inferno file protocol,
+Styx (which is equivalent to the Plan 9 protocol 9P2000),
+to and from a more convenient form,
+an
+.B Fcall
+structure:
+.PP
+.EX
+.if n .ta 4n +6n +5n +6n +18n +4n
+.if t .ta \w'xxxx'u +\w'short 'u +\w'xxxx'u +\w'ushort 'u +\w'ticket[TICKETLEN]; 'u +\w'/* 'u
+#define MAXWELEM 16
+
+typedef
+struct Fcall
+{
+ uchar type;
+ u32int fid;
+ ushort tag;
+ union {
+ struct {
+ u32int msize; /* Tversion, Rversion */
+ char *version; /* Tversion, Rversion */
+ };
+ struct {
+ ushort oldtag; /* Tflush */
+ };
+ struct {
+ char *ename; /* Rerror */
+ };
+ struct {
+ Qid qid; /* Rattach, Ropen, Rcreate */
+ u32int iounit; /* Ropen, Rcreate */
+ };
+ struct {
+ Qid aqid; /* Rauth */
+ };
+ struct {
+ u32int afid; /* Tauth, Tattach */
+ char *uname; /* Tauth, Tattach */
+ char *aname; /* Tauth, Tattach */
+ };
+ struct {
+ u32int perm; /* Tcreate */
+ char *name; /* Tcreate */
+ uchar mode; /* Tcreate, Topen */
+ };
+ struct {
+ u32int newfid; /* Twalk */
+ ushort nwname; /* Twalk */
+ char *wname[MAXWELEM]; /* Twalk */
+ };
+ struct {
+ ushort nwqid; /* Rwalk */
+ Qid wqid[MAXWELEM]; /* Rwalk */
+ };
+ struct {
+ vlong offset; /* Tread, Twrite */
+ u32int count; /* Tread, Twrite, Rread */
+ char *data; /* Twrite, Rread */
+ };
+ struct {
+ ushort nstat; /* Twstat, Rstat */
+ uchar *stat; /* Twstat, Rstat */
+ };
+ };
+} Fcall;
+.EE
+.EX
+
+/* these are implemented as macros */
+
+uchar GBIT8(uchar*)
+ushort GBIT16(uchar*)
+ulong GBIT32(uchar*)
+vlong GBIT64(uchar*)
+
+void PBIT8(uchar*, uchar)
+void PBIT16(uchar*, ushort)
+void PBIT32(uchar*, ulong)
+void PBIT64(uchar*, vlong)
+
+#define BIT8SZ 1
+#define BIT16SZ 2
+#define BIT32SZ 4
+#define BIT64SZ 8
+.EE
+.PP
+This structure is defined in
+.BR <styx.h> .
+See section 5
+for a full description of Styx messages and their encoding.
+For all message types, the
+.B type
+field of an
+.B Fcall
+holds one of
+.BR Tversion ,
+.BR Rversion ,
+.BR Tattach ,
+.BR Rattach ,
+etc. (defined in an enumerated type in
+.BR <styx.h> ).
+.B Fid
+is used by most messages, and
+.B tag
+is used by all messages.
+The other fields are used selectively by the message types
+given in comments.
+.PP
+.I ConvM2S
+takes a Styx message at
+.I ap
+of length
+.IR nap ,
+and uses it to fill in
+.B Fcall
+structure
+.IR f .
+If the passed message
+including any data for
+.B Twrite
+and
+.B Rread
+messages
+is formatted properly,
+the return value is the number of bytes the message occupied in the buffer
+.IR ap ,
+which will always be less than or equal to
+.IR nap ;
+otherwise it is 0.
+For
+.B Twrite
+and
+.B Tread
+messages,
+.B data
+is set to a pointer into the argument message,
+not a copy.
+.PP
+.I ConvS2M
+does the reverse conversion, turning
+.I f
+into a message starting at
+.IR ap .
+The length of the resulting message is returned.
+For
+.B Twrite
+and
+.B Rread
+messages,
+.B count
+bytes starting at
+.B data
+are copied into the message.
+.PP
+The constant
+.B IOHDRSZ
+is a suitable amount of buffer to reserve for storing
+the Styx header;
+the data portion of a
+.B Twrite
+or
+.B Rread
+will be no more than the buffer size negotiated in the
+.BR Tversion/Rversion
+exchange, minus
+.BR IOHDRSZ .
+.PP
+The routine
+.I sizeS2M
+returns the number of bytes required to store the machine-independent representation of the
+.B Fcall
+structure
+.IR f ,
+including its initial 32-bit size field.
+In other words, it reports the number of bytes produced
+by a successful call to
+.IR convS2M .
+.PP
+Another structure is
+.BR Dir ,
+used by C functions in much the same way as the Limbo versions
+described in
+.IR sys-stat (2).
+.I ConvM2D
+converts the machine-independent form starting at
+.I ap
+into
+.IR d
+and returns the length of the machine-independent encoding.
+The strings in the returned
+.B Dir
+structure are stored at successive locations starting at
+.BR strs .
+Usually
+.B strs
+will point to storage immediately after the
+.B Dir
+itself.
+It can also be a
+.B nil
+pointer, in which case the string pointers in the returned
+.B Dir
+are all
+.BR nil ;
+however, the return value still includes their length.
+.PP
+.I ConvD2M
+does the reverse translation,
+also returning the length of the encoding.
+If the buffer is too short, the return value will be
+.B BIT16SZ
+and the correct size will be returned in the first
+.B BIT16SZ
+bytes.
+(If the buffer is less than
+.BR BIT16SZ ,
+the return value is zero; therefore a correct test for
+complete packing of the message is that the return value is
+greater than
+.BR BIT16SZ ).
+The macro
+.B GBIT16
+can be used to extract the correct value.
+The related macros with different sizes retrieve the corresponding-sized quantities.
+.B PBIT16
+and its brethren place values in messages.
+With the exception of handling short buffers in
+.IR convD2M ,
+these macros are not usually needed except by internal routines.
+.PP
+Analogous to
+.IR sizeS2M ,
+.I sizeD2M
+returns the number of bytes required to store the machine-independent representation of the
+.B Dir
+structure
+.IR d ,
+including its initial 16-bit size field.
+.PP
+The routine
+.B statcheck
+checks whether the
+.I nbuf
+bytes of
+.I buf
+contain a validly formatted machine-independent
+.B Dir
+entry.
+It checks that the sizes of all the elements of the the entry sum to exactly
+.IR nbuf ,
+which is a simple but effective test of validity.
+.I Nbuf
+and
+.I buf
+should include the second two-byte (16-bit) length field that precedes the entry when
+formatted in a Styx message (see
+.IR stat (5));
+in other words,
+.I nbuf
+is 2 plus the sum of the sizes of the entry itself.
+.I Statcheck
+also verifies that the length field has the correct value (that is,
+.IB nbuf -2\f1).
+It returns
+.B 0
+for a valid entry and
+.B -1
+for an incorrectly formatted entry.
+.PP
+.IR Dirfmt ,
+.IR fcallfmt ,
+and
+.I dirmodefmt
+are formatting routines, suitable for
+.IR fmtinstall (10.2).
+They convert
+.BR Dir* ,
+.BR Fcall* ,
+and
+.BR long
+values into string representations of the directory buffer,
+.B Fcall
+buffer,
+or file mode value.
+.I Fcallfmt
+assumes that
+.I dirfmt
+has been installed with format letter
+.L D
+and
+.I dirmodefmt
+with format letter
+.LR M .
+They currently cannot be used in the kernels because they clash
+with the use of format
+.L D
+for Dis instructions.
+.SH SOURCE
+.B /lib9/convM2D.c
+.br
+.B /lib9/convM2D.c
+.br
+.B /lib9/convM2S.c
+.br
+.B /lib9/convS2M.c
+.br
+.B /lib9/fcallfmt.c
+.br
+.B /libkern/convM2D.c
+.br
+.B /libkern/convM2D.c
+.br
+.B /libkern/convM2S.c
+.br
+.B /libkern/convS2M.c
+.br
+.B /libkern/fcallfmt.c
+.SH SEE ALSO
+.IR intro (2),
+.IR styx (2),
+.IR sys-stat (2),
+.IR intro (5)
diff --git a/man/10/styxserver b/man/10/styxserver
new file mode 100644
index 00000000..d0a8d321
--- /dev/null
+++ b/man/10/styxserver
@@ -0,0 +1,611 @@
+.TH STYXSERVER 10.2
+.SH NAME
+Styxserver \- C Styx server library
+.SH SYNOPSIS
+.EX
+#define Qroot 0
+
+#define MSGMAX ((((8192+128)*2)+3) & ~3)
+
+extern char Enomem[]; /* out of memory */
+extern char Eperm[]; /* permission denied */
+extern char Enodev[]; /* no free devices */
+extern char Ehungup[]; /* i/o on hungup channel */
+extern char Eexist[]; /* file exists */
+extern char Enonexist[]; /* file does not exist */
+extern char Ebadcmd[]; /* bad command */
+extern char Ebadarg[]; /* bad arguments */
+
+typedef uvlong Path;
+typedef struct Styxserver Styxserver;
+typedef struct Styxops Styxops;
+typedef struct Styxfile Styxfile;
+typedef struct Client Client;
+
+struct Styxserver
+{
+ Styxops *ops;
+ Path qidgen;
+ int connfd;
+ Client *clients;
+ Client *curc;
+ Styxfile *root;
+ Styxfile **ftab;
+ void *priv; /* private */
+};
+
+struct Client
+{
+ Styxserver *server;
+ Client *next;
+ int fd;
+ char msg[MSGMAX];
+ uint nread; /* valid bytes in msg (including nc)*/
+ int nc; /* bytes consumed from front of msg by convM2S */
+ char data[MSGMAX]; /* Tread/Rread data */
+ int state;
+ Fid *fids;
+ char *uname; /* uid */
+ char *aname; /* attach name */
+ void *u;
+};
+
+struct Styxops
+{
+ char *(*newclient)(Client *c);
+ char *(*freeclient)(Client *c);
+
+ char *(*attach)(char *uname, char *aname);
+ char *(*walk)(Qid *qid, char *name);
+ char *(*open)(Qid *qid, int mode);
+ char *(*create)(Qid *qid, char *name, int perm, int mode);
+ char *(*read)(Qid qid, char *buf, ulong *n, vlong offset);
+ char *(*write)(Qid qid, char *buf, ulong *n, vlong offset);
+ char *(*close)(Qid qid, int mode);
+ char *(*remove)(Qid qid);
+ char *(*stat)(Qid qid, Dir *d);
+ char *(*wstat)(Qid qid, Dir *d);
+};
+
+struct Styxfile
+{
+ Dir d;
+ Styxfile *parent;
+ Styxfile *child;
+ Styxfile *sibling;
+ Styxfile *next;
+ int ref;
+ int open;
+ void *u;
+};
+
+char *styxinit(Styxserver *server, Styxops *ops, char *port, int perm, int needfile);
+char *styxwait(Styxserver *server);
+char *styxprocess(Styxserver *server);
+char *styxend(Styxserver *server);
+
+Client *styxclient(Styxserver *server);
+
+Styxfile *styxaddfile(Styxserver *server, Path pqid, Path qid, char *name,
+ int mode, char *owner);
+Styxfile *styxadddir(Styxserver *server, Path pqid, Path qid, char *name,
+ int mode, char *owner);
+int styxrmfile(Styxserver *server, Path qid);
+Styxfile *styxfindfile(Styxserver *server, Path qid);
+
+int styxperm(Styxfile *file, char *uid, int mode);
+long styxreadstr(ulong off, char *buf, ulong n, char *str);
+Qid styxqid(int path, int isdir);
+void *styxmalloc(int bytes);
+void styxfree(void *p);
+void styxdebug(void);
+.EE
+.SH DESCRIPTION
+The C Styx server library provides a small suite of functions to enable the
+production of a file server based on the Inferno Styx protocol. The following
+elements define the primary routines in the interface:
+.TP
+.BI styxinit(server\fP,\fP\ ops\fP,\fP\ port\fP,\fP\ perm\fP,\fP\ needfile )
+Initializes the interface given a pointer to a Styxserver structure
+.I server
+, a callback table of operations
+.I ops
+, a port number
+.I port
+to announce the file service on
+and the permissions
+.I perm
+on the root directory. The default permission is 0555 (read and execute for user,
+group and others) if the latter is specified as -1. If the last argument
+.I needfile
+is set to true, the styx library will check that each path number it deals with
+has a corresponding file associated with it and, if it hasn't, it will issue a
+"file does not exist" message automatically. In case of an error, the error message is
+returned, otherwise nil is returned to indicate success.
+.TP
+.BI styxwait(server )
+Waits for communication from a client. Return value as above.
+.TP
+.BI styxprocess(server )
+Processes the client message after a successful call to
+.I styxwait .
+This may result in calls to the functions in the table provided to
+.I styxinit .
+Return value as above.
+.TP
+.BI styxend(server )
+End all file service. Return value as above.
+.TP
+.BI styxclient(server )
+Returns the client whose request is currently being processed.
+.PP
+The next set of functions allow the creation of a file system structure based
+upon the
+.I Styxfile
+structure. This contains a Dir structure
+.I d
+describing the properties of the file
+(defined in lib9.h) and pointers to other files in the file tree:
+.I parent
+,
+.I child
+,
+.I sibling
+and
+.I next .
+The
+.I ref
+field
+counts current references to the file. The
+.I open
+field counts the current number of opens on the file. Finally the
+.I u
+field allows further fields to be tagged onto each file. It is not
+used by the Styx server library.
+.PP
+Each file must have a unique path number in the server. The root of
+the tree
+.I Qroot
+always has path number zero. It's corresponding file is created during library initialization
+and placed in the
+.I root
+field of the server structure. All other files must be supplied with a path number
+to identify them. Files are created/deleted as follows:
+.TP
+.BI styxaddfile(server\fP,\fP\ ppath\fP,\fP\ path\fP,\fP\ name\fP,\fP\ mode\fP,\fP\ owner )
+Add a new file (ie non-directory) with the given path
+.I path
+, name
+.I name
+, mode
+.I mode
+and owner
+.I owner
+to the directory identified by the path
+.I ppath .
+If
+.I path
+is -1 the library will generate a unique path number instead.
+Returns nil if the parent file with path
+.I ppath
+does not exist, if the parent is not a directory, if the path number
+.I path
+already is assigned to a file or if the parent already contains a file of name
+.I name .
+.TP
+.BI styxadddir(server\fP,\fP\ ppath\fP,\fP\ path\fP,\fP\ name\fP,\fP\ mode\fP,\fP\ owner )
+Add a new directory with the given path
+.I path
+, name
+.I name
+, mode
+.I mode
+and owner
+.I owner
+to the directory identified by the path
+.I ppath .
+Returns nil in the same circumstances as
+.I styxaddfile .
+.TP
+.BI styxrmfile(server\fP,\fP\ path )
+Remove the file or directory with path
+.I path
+from the file server tree. If the file is a directory, it's contents will be recursively
+removed. If the file does not exist, -1 is returned, otherwise 0 is returned for
+success.
+.TP
+.BI styxfindfile(server\fP,\fP\ path )
+Return the file structure corresponding to the file or directory with path
+.I path .
+Nil is returned if the file does not exist.
+.PP
+If the file system is created in this way the Styx library will check read/write/execute
+permissions, check for invalid uses of files and check that path numbers exist
+in the file system (see
+.I styxinit
+for the latter). If it's not feasible to do this (for instance if there is a more suitable
+way of describing the file system in question), then all file checking must be
+done as part of the callback functions below.
+.PP
+The library provides a callback mechanism so that the implementer of the
+file server can take corresponding action when a particular request is made
+of the server. All of these functions may return an error message which will
+be communicated back to the client. Otherwise they should return nil to
+indicate the success of the operation. Any of these functions may be nil in which case the library
+performs a default operation which will be described below. These routines use
+the
+.I Qid
+structure defined in lib9.h to describe files. This structure contains the path number(
+.I path
+), a version number(
+.I vers
+) typically zero and a type(
+.I type
+) which indicates whether the file is a directory, append-only etc.
+.TP
+.BI newclient(c )
+Called whenever a new client connects to the server. The Client structure
+.I c
+contains mainly private data but the
+.I uname
+field contains a user name and the
+.I aname
+field an attach name if required. The
+.I u
+field may be used to tag further data onto each client. It is not used by
+the Styx server library.
+.TP
+.BI freeclient(c )
+Called whenever a client disconnects from the server.
+.TP
+.BI attach(uname\fP,\fP\ aname )
+Called when a client user first mounts the file server. The
+.I uname
+is the user id and
+.I aname
+is typically the file tree to access if the server provides a choice.
+The default action is to allow the attach to the root of the file system.
+.TP
+.BI walk(qid\fP,\fP\ name )
+In a directory represented by
+.I qid
+, find a file member whose name is that given and place it's Qid in
+.I qid .
+The default action is to perform the walk using any directory structure provided.
+.TP
+.BI open(qid\fP,\fP\ mode )
+Open the file represented by
+.I qid
+with mode
+.I mode .
+The latter may be one of OREAD, OWRITE, ORDWR etc (see lib9.h). If the Qid
+of the newly opened file is different from that given (a file server may understand
+the opening of a file called "new" say to signify the creation of a directory whose
+Qid is returned instead) place it's Qid in
+.I qid .
+The default action is to nominally allow the open.
+.TP
+.BI create(qid\fP,\fP\ name\fP,\fP\ perm\fP,\fP\ mode )
+Create a file in the directory given by
+.I qid
+with name
+.I name
+, permissions
+.I perm
+and mode
+.I mode .
+Place the Qid of the newly created file in
+.I qid .
+The default action is to issue a permission denied message.
+.TP
+.BI read(qid\fP,\fP\ buf\fP,\fP\ n\fP,\fP\ offset )
+Read
+.I n
+bytes of the file represented by
+.I qid
+at offset
+.I offset
+and place the result in
+.I buf.
+ Place in
+.I n
+the actual number of bytes read.
+The default action is to read directories but to issue permission denied on ordinary
+files.
+.TP
+.BI write(qid\fP,\fP\ buf\fP,\fP\ n\fP,\fP\ offset )
+Write
+.I n
+bytes to the file represented by
+.I qid
+at offset
+.I offset
+from the buffer
+.I buf.
+ Place in
+.I n
+the actual number of bytes written.
+The default action is to issue permission denied.
+.TP
+.BI close(qid\fP,\fP\ mode )
+Close the file represented by
+.I qid .
+The mode it was originally opened with is given by
+.I mode .
+The default action is to allow the close.
+.TP
+.BI remove(qid )
+Remove the file represented by
+.I qid .
+The default action is to issue a permission denied message.
+.TP
+.BI stat(qid\fP,\fP\ d )
+Place the information for the file represented by
+.I qid
+in the Dir structure(see lib9.h)
+.I d .
+The default action is to allow the stat using any information in the file tree.
+.TP
+.BI wstat(qid\fP,\fP\ d )
+Update the information for the file represented by
+.I qid
+according to the Dir structure
+.I d .
+The default action is to disallow this with a permission denied message.
+.PP
+A small number of utility functions are provided:
+.TP
+.BI styxperm(file\fP,\fP\ uid\fP,\fP\ mode )
+Does the file/directory
+.I file
+allow the user
+.I uid
+the permission given by
+.I mode .
+For example use
+.I OREAD
+for read permission,
+.I OWRITE
+for write permission and
+.I ORDWR
+for both.
+.TP
+.BI styxreadstr(off\fP,\fP\ buf\fP,\fP\ n\fP,\fP\ str )
+Read
+.I n
+bytes of data from the string
+.I str
+at offset
+.I off
+and place the result in
+.I buf .
+Returns the actual number of bytes read.
+.TP
+.BI styxqid(path\fP,\fP\ isdir )
+Returns a typical Qid structure with the given path number
+.I path
+and whether the Qid is for a directory
+.I isdir .
+.TP
+.BI styxmalloc(n )
+Allocate
+.I n
+bytes of memory and return it.
+.TP
+.BI styxfree(p )
+Free the memory pointed to by
+.I p .
+.TP
+.BI styxdebug()
+Print out some of the actions of the server.
+.SH EXAMPLE
+.PP
+A very small file server example is illustrated. First the include files and globals.
+.PP
+.EX
+ #include <lib9.h>
+ #include "styxserver.h"
+
+ int nq;
+ Styxserver *server;
+.EE
+.PP
+The main processing loop:
+.PP
+.EX
+ main(int argc, char **argv)
+ {
+ Styxserver s;
+
+ server = &s;
+ styxinit(&s, &ops, "6701", 100, 0555, 0);
+ myinit(&s);
+ for(;;) {
+ styxwait(&s);
+ styxprocess(&s);
+ }
+ return 0;
+ }
+.EE
+.PP
+Here the port number is 6701 and the root file permissions are 0555 - no write
+permission for anyone which implies that files and directories cannot be
+created in the root directory.
+.PP
+The creation of the directory tree:
+.PP
+.EX
+ myinit(Styxserver *s)
+ {
+ styxaddfile(s, Qroot, 1, "fred", 0664, "inferno");
+ styxaddfile(s, Qroot, 2, "joe", 0664, "inferno");
+ styxadddir(s, Qroot, 3, "adir", 0775, "inferno");
+ styxaddfile(s, 3, 4, "bill", 0664, "inferno");
+ styxadddir(s, Qroot, 5, "new", 0775, "inferno");
+ styxadddir(s, 5, 6, "cdir", 0775, "inferno");
+ styxaddfile(s, 6, 7, "cfile", 0664, "inferno");
+ nq = 8;
+ }
+.EE
+.PP
+This creates two files
+.I fred
+and
+.I joe
+and two directories
+.I adir
+and
+.I new
+at the top level.
+.I adir
+contains a file called
+.I bill
+and
+.I new
+contains a directory called
+.I cdir
+which contains a file called
+.I cfile .
+Note that each new path number is unique.
+.PP
+The callback functions:
+.PP
+.EX
+ Styxops ops = {
+ nil, /* newclient */
+ nil, /* freeclient */
+
+ nil, /* attach */
+ nil, /* walk */
+ nil, /* open */
+ mycreate, /* create */
+ myread, /* read */
+ nil, /* write */
+ nil, /* close */
+ myremove, /* remove */
+ nil, /* stat */
+ nil, /* wstat */
+ };
+.EE
+.PP
+Here we choose the defaults most of the time.
+.PP
+The supplied callback routines:
+.PP
+.EX
+ char *
+ mycreate(Qid *qid, char *name, int perm, int mode)
+ {
+ int isdir;
+ Styxfile *f;
+
+ isdir = perm&DMDIR;
+ if(isdir)
+ f = styxadddir(server, qid->path, nq++, name , perm, "inferno");
+ else
+ f = styxaddfile(server, qid->path, nq++, name, perm, "inferno");
+ if(f == nil)
+ return Eexist;
+ *qid = f->d.qid;
+ return nil;
+ }
+
+ char *
+ myremove(Qid qid)
+ {
+ Styxfile *f;
+
+ f = styxfindfile(server, qid.path);
+ if(f != nil && (f->d.qid.type&QTDIR) && f->child != nil)
+ return "directory not empty";
+
+ if(styxrmfile(server, qid.path) < 0)
+ return Enonexist;
+ return nil;
+ }
+
+ char *
+ myread(Qid qid, char *d, ulong *n, vlong offset)
+ {
+ if(qid.path != 1){
+ *n = 0;
+ return nil;
+ }
+ *n = styxreadstr(offset, d, *n, "abcdeghijklmn");
+ return nil;
+ }
+.EE
+.PP
+Permission checking for walk (need execute permission on directory), open (the
+given mode must be compatible with the file permissions), create and remove (both of
+which need write permission on directory) is done automatically whenever
+possible. The functions
+.I mycreate
+and
+.I myremove
+below therefore can omit these checks.
+.PP
+The function
+.I mycreate
+simply creates a directory or file and
+if the file cannot be added to the directory tree it returns a 'file exists' error string.
+It sets the Qid for the newly created file before returning.
+.PP
+The function
+.I myremove
+first checks to see if the file represents a non-empty directory, in which case it
+disallows it's removal. Otherwise it
+removes the file if it can find it and returns a 'file does not exist' error string if it
+can't.
+.PP
+The function
+.I myread
+considers all files to be empty except for
+.I fred
+which notionally contains
+.I abcdefghijklmn .
+Note that the number of bytes read is returned in the argument
+.I n .
+.PP
+Once this file server is running, the root can be accessed by doing for example
+.PP
+.EX
+ mount -A tcp!<address>!6701 /n/remote
+.EE
+.PP
+under Inferno. Here
+.I <address>
+is the address of the machine running the file server (or the loopback address
+127.0.0.1 if it's all on one machine). The
+.I -A
+option is used to prevent authentication which is not supported at the moment.
+Then we can do
+.PP
+.EX
+ cd /n/remote
+ ls
+ adir
+ fred
+ joe
+ new
+ ...
+.EE
+.PP
+For a more complicated file server see /tools/styxtest/styxtest.c.
+.PP
+The file /tools/styxtest/mkfile shows how to compile and link the file server
+sources.
+.SH SOURCE
+.B /Nt/386/include/lib9.h
+.br
+.B /tools/libstyx/styxserver.h
+.br
+.B /tools/libstyx/styxserver.c
+.br
+.B /tools/styxtest/styxtest.c
+.br
+.B /tools/styxtest/styxtest0.c
+.SH BUGS
+Currently the library is available under Windows, Linux and Solaris only.
+.br
+Authentication is not supported.
diff --git a/man/10/xalloc b/man/10/xalloc
new file mode 100644
index 00000000..d22ea9cb
--- /dev/null
+++ b/man/10/xalloc
@@ -0,0 +1,70 @@
+.TH XALLOC 10.2
+.SH NAME
+xalloc, xspanalloc, xfree \- basic memory management
+.SH SYNOPSIS
+.ta \w'\fLvoid* 'u
+.B
+void* xalloc(ulong size)
+.PP
+.B
+void* xspanalloc(ulong size, int align, ulong span)
+.PP
+.B
+void xfree(void *p)
+.SH DESCRIPTION
+.I Xalloc
+and
+.I xfree
+are primitives used by higher-level memory allocators in the kernel,
+such as
+.IR malloc (10.2).
+They are not intended for use directly by most kernel routines.
+The main exceptions are routines that permanently allocate large structures,
+or need the special alignment properties guaranteed by
+.IR xspanalloc .
+.PP
+.I Xalloc
+returns a pointer to a range of size bytes of memory. The memory will be zero filled and aligned on a 8 byte
+.RB ( BY2V )
+address. If the memory is not available,
+.B xalloc
+returns a null pointer.
+.PP
+.I Xspanalloc
+allocates memory given alignment and spanning constraints.
+The block returned will contain
+.I size
+bytes, aligned on a boundary that is
+.BI "0 mod" " align,"
+in such a way that the memory in the block does not
+span an address that is
+.BI "0 mod" " span."
+.I Xspanalloc
+is intended for use
+allocating hardware data structures (eg, page tables) or I/O buffers
+that must satisfy specific alignment restrictions.
+If
+.I xspanalloc
+cannot allocate memory to satisfy the given constraints, it will
+.IR panic (10.2).
+The technique it uses can sometimes cause memory to be wasted.
+Consequently,
+.I xspanalloc
+should be used sparingly.
+.PP
+.I Xfree
+frees the block of memory at
+.IR p ,
+which must be an address previously returned by
+.I xalloc
+(not
+.IR xspanalloc ).
+.SS Allocation status
+Some memory allocation statistics are written to the console in response to
+the debugging sequence
+.LR "control-T control-T x" .
+The output includes the total free space, the number of free holes,
+and a summary of active holes.
+Each line shows `address top size'.
+.SH SEE ALSO
+.IR malloc (10.2)