changeset 1074:2038f48c78e4

A new article on how to write extension modules
author roug
date Mon, 31 Mar 2003 18:53:23 +0000
parents 43ea8e02cd96
children 1e3b13dfb976
files docs/articles/articles.docbook docs/articles/bootprocess.article docs/articles/extensionmodule.article docs/articles/makefile
diffstat 4 files changed, 498 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- a/docs/articles/articles.docbook	Mon Mar 31 18:52:30 2003 +0000
+++ b/docs/articles/articles.docbook	Mon Mar 31 18:53:23 2003 +0000
@@ -1,10 +1,12 @@
 <?xml version="1.0" ?>
 <!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
    "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd" [
-  <!ENTITY tutorial     SYSTEM "tutorial.article">
+  <!ENTITY bootprocess  SYSTEM "bootprocess.article">
+  <!ENTITY ded          SYSTEM "ded.article">
   <!ENTITY diskcrash    SYSTEM "diskcrash.article">
-  <!ENTITY ded          SYSTEM "ded.article">
+  <!ENTITY extmodule    SYSTEM "extensionmodule.article">
   <!ENTITY os9software  SYSTEM "os9software.article">
+  <!ENTITY tutorial     SYSTEM "tutorial.article">
  ]>
 <book id="articles" lang="en">
 <part label="Part One" id="part1">
@@ -19,6 +21,7 @@
 <partintro>
 <para>How to administer OS9</para>
 </partintro>
+&bootprocess;
 &diskcrash;
 &ded;
 </part>
@@ -28,5 +31,6 @@
 <para>How to program OS9</para>
 </partintro>
 &os9software;
+&extmodule;
 </part>
 </book>
--- a/docs/articles/bootprocess.article	Mon Mar 31 18:52:30 2003 +0000
+++ b/docs/articles/bootprocess.article	Mon Mar 31 18:53:23 2003 +0000
@@ -1,6 +1,3 @@
-<?xml version="1.0" ?>
-<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
-   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 <!--
     The author has not been contacted about adding this article to the
     documentation set.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/articles/extensionmodule.article	Mon Mar 31 18:53:23 2003 +0000
@@ -0,0 +1,490 @@
+<article>
+<articleinfo>
+<title>OS-9 System Extension Modules</title>
+<author><firstname>Boisy</firstname>
+<othername role="mi">G</othername>
+<surname>Pitre</surname>
+</author>
+</articleinfo>
+<para>
+The technical information, especially in the OS-9 Level Two manuals,
+is brimming with details and information that can unlock a wealth
+of understanding about how OS-9 works.  Unfortunately, some of this
+information can be hard to digest without proper background and some
+help along the way.  This series of articles is intended to take a
+close look at the internals of OS-9/6809, both Level One and Level Two.
+So along with this article, grab your OS-9 Technical Manual, sit down
+in a comfortable chair or recliner, grab a beverage, relax and let's
+delve into the deep waters!
+</para>
+<section><title>Assemble Your Gear</title>
+<para>
+For successful comprehension of the topics presented
+in this and future articles, I recommend that you have the following
+items handy:
+</para>
+<itemizedlist>
+<listitem><para>
+OS-9 Level Two Technical Reference Manual <emphasis>or</emphasis>
+</para></listitem>
+<listitem><para>
+OS-9 Level One Technical Information Manual (light blue book) and the
+OS-9 Addendum Upgrade to Version 02.00.00 Manual
+</para></listitem>
+<listitem><para>
+A printout of the <literal>os9defs</literal> file for your respective operating system.
+This file can be found
+in the DEFS directory of the OS-9 Level One Version 02.00.00
+System Master (OS-9 Level One) or the DEFS directory of
+the OS-9 Development System (OS-9 Level Two).
+</para></listitem>
+</itemizedlist>
+<para>
+In this article, we will look at a rarely explored, yet intriguing OS-9
+topic: system extensions, a.k.a. P2 modules. When performing an <literal>mdir</literal>
+command, you have no doubt seen modules with names like <literal>OS9p1</literal> and <literal>OS9p2</literal>
+in OS-9 Level Two (or <literal>OS9</literal> and <literal>OS9p2</literal> in OS-9 Level One).  These modules
+are essentially the OS-9 operating system itself; they contain the
+code for the system calls that are documented in the OS-9 Technical
+Reference documentation.  In the case of OS-9 Level One, the modules <literal>OS9</literal>
+and <literal>OS9p2</literal> are located in the boot track of your boot disk (track 34).
+In OS-9 Level Two, <literal>OS9p1</literal> (equivalent to the <literal>OS9</literal> module in Level One) is
+found in the boot track while <literal>OS9p2</literal> is located in the bootfile.  Both of
+the modules are of module type <literal>Systm</literal> and define the basic behavior
+and structure of OS-9.  Even the module IOMan is a system extension,
+containing code for the I/O calls in the operating system.
+</para><para>
+While drivers and file managers have been the most common area to expand
+the capabilities of OS-9, they are pretty much limited to expanding the
+functionality of I/O.  What system extensions allow you to do is even more
+powerful: they can add new system calls or even replace existing ones.
+Such functionality allows you to change the behavior of OS-9 in a very
+fundamental way.  Of course, with such power, caution must be exercised.
+It is not wise to radically modify the behavior of an existing system
+call; such an action could break compatibility with existing applications.
+</para><para>
+What we aim to do in this article is not to replace an existing system
+call, but rather to add a new system call by looking at the example
+provided in Tandy's OS-9 Level Two documentation.  Although the example
+is written for OS-9 Level Two, we will look at how it can be changed
+to run under OS-9 Level One as well.  But first, let's get a little
+background on system calls and how they are constructed in OS-9.
+</para>
+</section>
+<section><title>The System Call</title>
+<para>
+As an operating system, OS-9 provides system level
+functions, or system calls to applications.  These system calls give
+applications a base by which they can operate consistently and without
+fear of incompatibility from one OS-9 system to the next.  The system
+call in OS-9/6809 evaluates to an SWI2 instruction on the 6809, which
+is a software interrupt.  Suffice it to say that when this instruction
+is encountered by the CPU, control is routed to OS-9, which interprets
+and performs the system call on behalf of the calling process.
+</para><para>
+While system calls are generally hidden by wrapper functions or procedures
+in high-level languages such as Basic09 and C, we can see the system call
+in its native form by looking at 6809 assembly language.  Consider the
+following assembly source fragment:
+</para>
+<programlisting>
+      lda   #1 
+      leax  mess,pcr 
+      ldy   #5 
+      os9   I$Write 
+      rts 
+mess  fcc   "Hello" 
+</programlisting>
+<para> 
+In the middle of what appears to be normal 6809 assembly language
+source code is a mnemonic called <literal>os9</literal>.  This is a pseudo mnemonic, since
+Motorola did not place an <literal>os9</literal> instruction in the 6809 instruction set.
+The OS-9 assembler actually recognizes this pseudo mnemonic as a special
+case, along with the <literal>I$Write</literal> string, and translates the above piece of
+code into:
+</para>
+<programlisting>
+      lda   #1 
+      leax  mess,pcr
+      ldy   #5
+      swi2
+      fcb   $8A
+      rts
+mess  fcc "Hello"
+</programlisting>
+<para>
+The $8A which follows the <literal>swi2</literal> instruction is the constant representation
+of the I/O system call <literal>I$Write</literal>.  Since the <literal>swi2</literal> instruction calls into
+the OS-9 kernel, the code in the kernel looks for the byte following
+the <literal>swi2</literal> instruction in the module (the $8A) and interprets that as
+the system call code.  Using that code, OS-9 jumps to the appropriate
+routine in order to execute the <literal>I$Write</literal>.
+</para><para>
+Since the system call code following the swi2 instruction is a byte,
+in theory this would allow OS-9 to have up to 256 different system calls
+that can be executed on behalf of an application. Under OS-9 Level Two,
+this is the case; however under OS-9 Level One there are restrictions
+placed on exactly which codes are available.  The following tables show
+the range of system call codes.
+</para>
+<table frame="all">
+<title>OS-9 Level One System Call Ranges</title>
+<tgroup cols="2">
+<thead>
+<row>
+  <entry>System call range</entry>
+  <entry>Function</entry>
+</row>
+</thead>
+<tbody>
+<row>
+    <entry>$00-$27</entry>
+    <entry>User mode system call codes</entry>
+</row>
+<row>
+    <entry>$29-$34</entry>
+    <entry>Privileged system mode call codes</entry>
+</row>
+<row>
+    <entry>$80-$8F</entry>
+    <entry>I/O system call codes</entry>
+</row>
+</tbody>
+</tgroup>
+</table>
+
+<table frame="all">
+<title>OS-9 Level Two System Call Ranges</title>
+<tgroup cols="2">
+<thead>
+<row>
+  <entry>System call range</entry>
+  <entry>Function</entry>
+</row>
+</thead>
+<tbody>
+<row>
+    <entry>$00-$7F</entry>
+    <entry>User mode system call codes</entry>
+</row>
+<row>
+    <entry>$80-$8F</entry>
+    <entry>I/O system call codes</entry>
+</row>
+<row>
+    <entry>$90-$FF</entry>
+    <entry>Privileged mode system call codes</entry>
+</row>
+</tbody>
+</tgroup>
+</table>
+<para> 
+The idea behind <emphasis>User mode</emphasis> vs. <emphasis>System mode</emphasis>
+is to allow two different points
+of execution for the same system call, depending on whether the calling
+process is running in user state or system state.  OS-9 controls this
+by maintaining two system call tables: one for user state and one for
+system state.  When installing a system call, as we'll soon see, we can
+specify whether our system call should only be called from system state
+(hence only updating the system table) or from both user and system state
+(updating both the user and system tables).
+</para><para>
+An example of a system call that can be executed in both user and
+privileged modes is the <literal>F$Load</literal> function code (pp. 8-25 in the OS-9 Level
+Two Technical Reference manual; pp. 106 in the OS-9 Level
+One Technical Information manual).  Since <literal>F$Load</literal> can be called from a user
+state process as well as from a driver or other module running in system
+state, OS-9 installs this system call in both the user and system tables.
+On the other hand, a privileged mode system call such as <literal>F$AProc</literal> (Level
+Two: pp. 8-74; Level One: pp. 141) can only be called from system state
+and therefore a user state process attempting to call it will receive
+an error.
+</para><para>
+Notice that in both OS-9 Level One and OS-9 Level Two, codes $80-$8F are
+reserved for I/O system call codes.  When the OS-9 kernel receives one of
+these codes, it passes the code along to <literal>IOMan</literal> for processing.  I/O system
+calls cannot be added since they are under the control of <literal>IOMan</literal>.
+</para><para>
+Installing a new system call involves selecting a free system call code,
+determining whether the call will be accessible from both user/system
+state or from system state only, and building a table in assembly language
+that will be used to install the system call.  Interestingly enough,
+the method of installing a system call is by calling a system call!
+It's called <literal>F$SSvc</literal> and is documented in your respective OS-9 Technical
+manual.
+</para>
+</section>
+<section>
+<title>Installing a System Call in OS-9 Level Two</title>
+<para>
+The source code in Listing
+1 is the system extension module, os9p3.a, which contains the code
+to install the system call, as well as the system call code itself.
+Incidentally, this is virtually the same code that is found in the OS-9
+Level Two Technical Reference Manual on pp. 2-2 to 2-4.  I've eliminated
+the comments for brevity since they are already in your manual, as well
+as changed the <literal>use</literal> directive.  Instead of including <literal>/dd/defs/os9defs</literal>, I
+include <literal>/dd/defs/os9defs.l2</literal>.  The reason for this is that I do compiling
+of both OS-9 Level One and OS-9 Level Two modules on my CoCo 3 development
+system.  Since the OS-9 definitions are different for each operating
+system, I have renamed their respective <literal>os9defs</literal> files with an extension
+indicating which operating system they belong to. Even if you just develop
+for one operating system or the other, I strongly suggest following the
+same naming convention; it will save you headaches in the long run.
+</para><para>
+This module, called <literal>OS9p3</literal>, installs the <literal>F$SAYHI</literal> system call.  A process
+making this call can either pass a pointer to a string of up to 40 bytes
+(carriage return terminated) in register X, or set X to 0, in which case
+the system call will print a default message.  In either case, the message
+goes to the calling process' standard error path.  While not very useful,
+this system call is a good example of how to write a system extension.
+</para><para>
+The asm program is used to assemble this source code file.  Notice that
+the entry point for the module is the label <literal>Cold</literal>, where Y is set to the
+address of the service table, <literal>SvcTbl</literal>.  Each entry in this table contains
+three bytes.  The first is the system call code that we have selected
+from a range that Microware says is safe to use for new system calls,
+and the remaining two are the address of the first instruction of the
+system call.  The table, which can contain any number of entries, is
+terminated by byte $80.  After setting Y to the address of the service
+table, a system call to <literal>F$SSvc</literal> is made, which takes the table pointed
+to by Y and installs the system calls.
+</para><para>
+The code for the <literal>F$SAYHI</literal> system call in listing 1 is for OS-9 Level
+Two only.  It determines whether or not a valid string pointer has been
+passed in register X.  If indeed the caller has passed a valid pointer,
+then control is routed to the label <literal>SayHi6</literal> where Y is loaded with the
+maximum byte count and the process descriptor of the calling process is
+used to obtain the system path number of the process' standard error
+in register A.  The separation of user and system state paths is an
+important concept to understand; however, we will discuss it in detail
+in another article.  For now, let's continue analyzing the code.
+</para><para>
+The <literal>I$WritLn</literal> system call then prints the string at register X to the
+caller's standard error path.  If on the other hand, register X contains
+a zero, then room is made on the caller's stack for the default message,
+which is then copied into the caller's address space using the <literal>F$Move</literal>
+system call.  The moving of the default message from the system address
+space to the caller's address space is necessary due to the separation
+of a process' address space in OS-9 Level Two.
+</para><para>
+Once the module has been compiled, it should be included in your OS-9
+Level Two bootfile.  Reboot with the new bootfile, and the <literal>OS9p2</literal> module
+will find <literal>OS9p3</literal> then jump into the execution offset (the <literal>Cold</literal> label
+in this case).  This will install the <literal>F$SAYHI</literal> system call and make it
+available for programs immediately.
+</para>
+</section>
+<section>
+<title>Installing a System Call in OS-9 Level One</title>
+<para>
+Listing 2 is similar to the
+code in Listing 1, except that the code to move the default message
+from system space to the caller's address space has been removed.  Also,
+the code to install the system call has changed, and the module type is
+not of type <literal>Systm</literal>, but instead of type <literal>Prgrm</literal>.  This is due to the lack
+of separation of address space in Level One, which makes writing system
+extension modules much easier than in Level Two.
+</para><para>
+The common address space between the system and all processes in OS-9
+Level One also makes the <literal>F$SSvc</literal> system call available from user state
+as well as from system state.  Unlike OS-9 Level Two, where the system
+extension module must be placed in the bootfile, installing a system
+extension in OS-9 Level One takes a different approach.  Placing a
+module called <literal>OS9p3</literal> in an OS-9 Level One bootfile will NOT cause the
+system extension to be called because there are no provisions for that
+in the kernel.  Instead, system extensions are installed by creating a
+module of type <literal>Prog</literal> that contains both code to install the system call
+and the system call itself.  Installing the system call entails executing
+the module from the command line.
+</para><para>
+Besides the <literal>sayhi.a</literal> source in listing 2, another example of the this
+is the <literal>Printerr</literal> command that comes with OS-9 Level One.  This is a
+program that actually installs a newer version of the <literal>F$PErr</literal> system call.
+To install the new system call, you simply run <literal>Printerr</literal> from the command
+line.  It then installs the call and exits.  There is an advantage to
+OS-9 Level One's approach to installing system calls: it can be done
+at run-time without making a new bootfile and rebooting the system.
+However, additional care must be taken not to unlink the <literal>Printerr</literal> module
+from memory.  Why?  Because the code for the replacement <literal>F$PErr</literal> call is
+in that module, and if the module is unlinked, the memory it occupied
+is made available subsequent reallocation and at some point, a system
+crash will ensue.
+</para>
+</section>
+<section>
+<title>Exercising Our New System Call</title>
+<para>
+Listing 3 is a small assembly language
+program, <literal>tsayhi</literal>,  which calls the <literal>F$SAYHI</literal> routine.  It will work fine
+under both OS-9 Level One and Level Two.  If you fork the <literal>tsayhi</literal> program
+without any parameters, then the <literal>F$SAYHI</literal> system call is called with
+register X set to $0000, which will cause the system call to print the
+default message.  Otherwise, you can pass a message on the command line
+as a parameter and up to 40 of the message's characters will be printed
+to the standard error path.
+</para>
+</section>
+<section>
+<title>Summary</title>
+<para>
+Extension modules give us an effective way of altering the
+behavior of OS-9 by allowing us to add a new system call or modify the
+behavior of an existing one.  Writing extension modules requires an
+extremely good understanding of the internals of OS-9.  The particulars
+of writing a system extension vary under OS- 9 Level One and Level Two
+primarily due to the differences between memory addressing.
+</para>
+
+<example><title>Source for os9p3.a for OS-9 Level Two</title>
+<programlisting>
+Type     set   Systm+Objct 
+Revs     set   ReEnt+1 
+         mod   OS9End, OS9Name,Type,Revs,Cold,256 
+OS9Name  fcs   "OS9p3" 
+ 
+         fcb   1                       edition number 
+ 
+         ifp1 
+         use   /dd/defs/os9defs.l2 
+         endc 
+ 
+level    equ   2 
+         opt   -c 
+         opt   f 
+ 
+* routine cold 
+Cold     leay  SvcTbl,pcr 
+         os9   F$SSvc 
+         rts 
+ 
+F$SAYHI  equ   $25 
+ 
+SvcTbl   equ   * 
+         fcb   F$SAYHI 
+         fdb   SayHi-*-2 
+         fcb   $80 
+ 
+ 
+SayHi    ldx   R$X,u 
+         bne   SayHi6 
+         ldy   D.Proc 
+         ldu   P$SP,y 
+         leau  -40,u 
+         lda   D.SysTsk 
+         ldb   P$TASK,y 
+         ldy   #40 
+         leax  Hello,pcr 
+         os9   F$Move 
+         leax  0,u 
+SayHi6   ldy   #40 
+         ldu   D.Proc 
+         lda   P$PATH+2,u 
+         os9   I$WritLn 
+         rts 
+ 
+Hello    fcc   "Hello there user." 
+         fcb   $0D 
+ 
+         emod 
+ 
+OS9End   equ   * 
+
+         end 
+</programlisting>
+</example>
+<example><title>Source for sayhi.a for OS-9 Level One</title>
+<programlisting>
+Type     set   Prgrm+Objct 
+Revs     set   ReEnt+1 
+         mod   OS9End, OS9Name,Type,Revs,Cold,256 
+OS9Name  fcs   "SayHi" 
+ 
+         fcb   1                       edition number 
+ 
+         ifp1 
+         use   /dd/defs/os9defs.l1 
+         endc 
+ 
+level    equ   1 
+         opt   -c 
+         opt   f 
+ 
+* routine cold 
+Cold     equ   * 
+* The following three instructions are important.  They cause the link 
+* count of this module to increase by 1.  This insures that the module 
+* stays in memory, even if forked from disk. 
+         leax  OS9Name,pcr 
+         clra 
+         os9   F$Link 
+ 
+         leay  SvcTbl,pcr 
+         os9   F$SSvc 
+         bcs   Exit 
+         clrb 
+Exit     os9   F$Exit 
+ 
+F$SAYHI  equ   $25 
+ 
+SvcTbl   equ   * 
+         fcb   F$SAYHI 
+         fdb   SayHi-*-2 
+         fcb   $80 
+ 
+* Entry point to F$SAYHI system call 
+SayHi    ldx   R$X,u 
+         bne   SayHi6 
+         leax  Hello,pcr 
+SayHi6   ldy   #40 
+         ldu   D.Proc 
+         lda   P$PATH+2,u 
+         os9   I$WritLn 
+         rts 
+ 
+Hello    fcc   "Hello there user." 
+         fcb   $0D 
+ 
+         emod 
+OS9End   equ   * 
+         end 
+</programlisting> 
+</example>
+<example><title>Source for tsayhi.a</title>
+<programlisting> 
+Type     set   Prgrm+Objct 
+Revs     set   ReEnt+1 
+         mod   OS9End, OS9Name,Type,Revs,start,256 
+OS9Name  fcs   "TSayHi" 
+ 
+         fcb   1                       edition number 
+ 
+         ifp1 
+         use   /dd/defs/os9defs 
+         endc 
+ 
+level    equ   2 
+         opt   -c 
+         opt   f 
+ 
+F$SAYHI  equ   $25 
+ 
+* routine cold 
+start    equ   * 
+         lda   ,x 
+         cmpa  #$0D 
+         bne   SayHi 
+         ldx   #$0000 
+SayHi    os9   F$SAYHI 
+         bcs   error 
+         clrb 
+error    os9   F$Exit 
+ 
+         emod 
+ 
+OS9End   equ   * 
+         end 
+</programlisting> 
+</example>
+</section>
+</article>
--- a/docs/articles/makefile	Mon Mar 31 18:52:30 2003 +0000
+++ b/docs/articles/makefile	Mon Mar 31 18:53:23 2003 +0000
@@ -1,4 +1,5 @@
 pdf: articles.pdf
 
-articles.pdf: os9software.article diskcrash.article
+articles.pdf: articles.docbook bootprocess.article ded.article diskcrash.article \
+            os9software.article tutorial.article extensionmodule.article
 	docbook2pdf articles.docbook