@Section(OVERVIEW) The first section of this chapter describes the Interface to the system kernel (in terms of the kernel service requests and operand formats), as well as the structure of the system (i.e. which system processes are assumed by the kernel to exist), and how user processes are expected to communicate with each other and with systems server processes in particular. The filestore provides useful system informations via a number of special files. You will find a list of all these files and some general information about them in section @ref(SystemFiles). @NewPage @Section(MULTI PROCESS OPERATING SYSTEM FOR THE APM) The APM hardware environment is such that multiple processors coexist on a shared bus and communicate principally through common memory. Accordingly, the operating system kernel supports interprocess communication primarily via shared memory, synchronisation being achieved by means of counting semaphores. Although we currently only have single-processor machines, the kernel has been designed with multiple processors in mind and in due course processes excuting on different processors will be able to communicate exactly as if they were executing on the same processor. In a global (i.e. multi-processor) sense, the only functions performed by the kernel are @Begin(Itemize) the primitive synchronisation operations, and dealing with the creation and deletion of processes. @End(Itemize) Over and above this, processor-local kernels are responsible for maintaining proper links with other local kernels and for providing a framework for the deployment of local interrupt handlers. They may (and indeed the M68000 local kernel does) present an interface to local processes which is a slight enhancement of the simple semaphore mechanism, in particular to facilitate the rather special form of communication areas and system objects) and memory management are not performed by the kernel itself, but by specialist server processes. The current M68000 local kernel implements client-server communication by means of request messages called IRPs (term taken from VAX/VMS: I/O Request Packets) which are put on service queues called IRQs (I/O request queues). @Begin(group) @SubSection(Kernel Services) @Paragraph(WAIT)@Index(WAIT) @IndexSecondary(Primary="Kernel", Secondary="WAIT") @Begin(description) Perform a "P" operation on a semaphore (TRAP 6). Parameter @\A0: address of semaphore descriptor. Result @\None. @Hinge Description @\Decrement the value field of the semaphore by one, suspend the calling process if that value is now negative, by enqueueing its PCB on the queue field of the semaphore. @End(Description) @End(Group) @Begin(Group) @Paragraph(SIGNAL)@Index(SIGNAL) @IndexSecondary(Primary="Kernel", Secondary="SIGNAL") @Begin(description) Perform a "V" operation on a semaphore (TRAP 5). Parameter @\A0: address of a semaphore descriptor. Result @\None. @Hinge Description @\Increment the value field of the semaphore by one, if that value is now negative (indicating that at least one process is waiting on the queue of this semaphore) and transfer the head of the semaphore queue to the run queue. The calling process will be pre-empted if its priority is less than that of the signalled process. @End(Description) @End(Group) @Begin(Group) @Paragraph(PON)@Index(PON) @IndexSecondary(Primary="Kernel", Secondary="PON") @Begin(Description) Put a request packet onto a service queue (TRAP 3). Parameter @\A0: address of an IRP. Result @\None. @Hinge Description @\This service is used by client processes only. The IRP is enqueued on the service queue identified by the IRQ field of the IRP. The IRP is made "pending", it is inserted into a list linking all the pending IRPs PONned by the calling process. A signal operation is performed on the semaphore associated with the IRQ. @End(Description) @End(Group) @Begin(Group) @Paragraph(POFF)@Index(POFF) @IndexSecondary(Primary="Kernel", Secondary="POFF") @Begin(Description) Take a request packet off a service queue (TRAP 4). Parameter @\A0: address of an IRQ. Result @\A0: address of an IRP. @Hinge Description @\This service is used by server processes only. A wait operation is performed on the semaphore associated with the IRQ, then the head of the IRQ is removed from the IRQ and this IRP (which was pending) is transferred from the pending-list of the requesting process to that process's active-list. @End(Description) @End(Group) @Begin(Group) @Paragraph(COMPLETE)@Index(COMPLETE) @IndexSecondary(Primary="Kernel", Secondary="COMPLETE") @Begin(Description) Notify completion of a service request (TRAP 8). Parameter @\A0: address of an IRP. Result @\None. @Hinge Description @\This service is used by server processes only. The IRP is removed from the active list of the requesting process. A signal operation is performed on the semaphore associated with the IRP. @End(Description) @End(Group) @Begin(Group) @Paragraph(ACCEPT)@Index(ACCEPT) @IndexSecondary(Primary="Kernel", Secondary="ACCEPT") @Begin(Description) Notify completion of a service request (TRAP 9). Parameter @\A0: address of an IRP. Result @\None. @Hinge Description @\This service is used by server processes only, to acknowledge the opening of a long-term transaction. The IRP is removed from the active list of the requesting process and transferred to the debt-list of that process. The IRP will eventually be re-submitted to the server when the requesting process dies, in order to enable the server to shut down the long-term transaction which has just been established, and to relinquish any resources it holds on behalf of that process. A signal operation is performed on the semaphore associated with the IRP. @End(Description) @End(Group) @Begin(Group) @Paragraph(CREATE)@Index(CREATE) @IndexSecondary(Primary="Kernel", Secondary="CREATE") @Begin(Description) Create a new process (TRAP 7). Parameter @\A0: address of a PCB template. Result @\A0: address of the PCB of the created process. @Hinge Description @\A request is made to the memory manager for space for the new PCB. The bulk of the template PCB is copied into the new PCB (with a few exceptions, see below under PCB layout). The new PCB is then linked into the list of all known processes and put onto the run queue. The calling process will be pre-empted if its priority is less than that of the new process. @End(Description) @End(Group) @Begin(Group) @Paragraph(KILL)@Index(KILL) @Begin(Description) @IndexSecondary(Primary="Kernel", Secondary="KILL") Delete a process (TRAP 11). Parameter @\A0: address of a PCB. Result @\None. @Hinge Description @\The specified process (which may or may not be the calling process) is killed. This is achieved by setting a bit, called black spot, in the victim's PCB marking it for death, removing it from any wait queue in which it might be, transferring it to its run queue and invoking its local scheduler. When the process is scheduled, its local kernel will arrange for it to @Begin(Enumerate) cancel all pending IRPs, wait for all active IRPs to complete or be accepted, re-submit and wait for completion of all debt-IRPs, remove its PCB from the list of known processes, and finally return its space to the memory manager. @End(Enumerate) @End(Description) @End(Group) @Begin(Group) @Paragraph(SETPRIO)@Index(SETPRIO) @IndexSecondary(Primary="Kernel", Secondary="SETPRIO") @Begin(Description) Change priority of a process (TRAP 10). Parameter @\A0: address of a PCB and D0: new 32-bit priority value. Result @\None. @Hinge Description @\The priority of the specified process (which may or may not be the calling process) is changed to the given value. Certain local housekeeping may be necessary if the target process is on a run queue and its position within that queue has to be adjusted. The M68000 local kernel disregards the high-order 5 bits of the priority value. Of the remaining 27, the high-order 3 become the hardware IPL (interrupt priority level) of the process, the remaining 24 have no significance in hardware. All 32 are used to determine the process's position in run queues. @End(Description) @End(Group) @Begin(Group) @Paragraph(INSTALL)@Index(INSTALL) @IndexSecondary(Primary="Kernel", Secondary="INSTALL") @Begin(Description) Install an interrupt handler (TRAP 13). Parameter @\A0: address of an interrupt handler block and D0: interrupt vector number in range 0-7, corresponding to the M68000 auto-vectors). Result @\None. @Hinge Description @\The specified handler is chained into the list of all those handlers which are invoked whenever an interrupt with the specified vector occurs. The KICK field of the handler block is set up appropriately. @End(Description) @End(Group) @Begin(Group) @Paragraph(REMOVE)@Index(REMOVE) @IndexSecondary(Primary="Kernel", Secondary="REMOVE") @Begin(Description) Remove an interrupt handler (TRAP 14). Parameter @\A0: address of an interrupt handler block. Result @\None @Hinge Description @\The specified handler is unchained from its list. @End(Description) @End(Group) @Begin(Group) @Paragraph(ME)@Index(ME) @IndexSecondary(Primary="Kernel", Secondary="ME") @Begin(Description) Acquire PCB address (TRAP 12,0). Parameter @\None. Result @\address of a PCB. @Hinge Description @\The address of the PCB of the calling process is returned. @End(Description) @End(Group) @Begin(Group) @Paragraph(CPUTIME)@Index(CPUTIME) @IndexSecondary(Primary="Kernel", Secondary="CPUTIME") @Begin(Description) (TRAP 12,4) Parameter @\None. Result @\D0: milliseconds. @Hinge Description @\The amount of time the CPU has been spending on behalf of the calling process is returned. It will be slightly inaccurate because the time spent in interrupt handlers is charged to the interrupted process. This service and the one below are kernel sevices because of the intricate way the clock works and the way it is tied in to the local scheduler (for the purpose of time-slicing). @End(Description) @End(Group) @Begin(Group) @Paragraph(REALTIME)@Index(REALTIME) @IndexSecondary(Primary="Kernel", Secondary="REALTIME") @Begin(Description) (TRAP 12, 8) Parameter @\None. Result @\D0: milliseconds. @Hinge Description @\The time since the system was last loaded is returned. @End(Description) @End(Group) @Begin(Group) @Paragraph(NAMEQ) @Begin(Description) Find address of Name Manager's IRQ (TRAP 12,12). Parameter @\None. Result @\D0: address of an IRQ. @Hinge Description @\The text name manager, for obvious reasons, cannot be referenced by text name, and so this service is used to acquire the address of its request queue. @End(Description) @End(Group) @Begin(Group) @Paragraph(SPACEQ)@Index(SPACEQ) @IndexSecondary(Primary="Kernel", Secondary="SPACEQ") @Begin(Description) Find address of Space Manager's IRQ (TRAP 12,6) Parameter @\None. Result @\D0: addres of an IRQ. @Hinge Description @\The Kernel must know where the space manager's request queue is (it needs it for CREATE and KILL). In fact, both the name manager's and space manager's IRQs are known by the kernel before they are known by their respective servers, and both servers use the NAMEQ and SPACEQ services, respectively, to establish where their queues are so that they may POFF on them. The space manager has a requirement to do this without recourse to the name manager, because the name manager needs to request its work space from the space manager. @End(Description) @End(Group) @Begin(Group) @Paragraph(EXVEC)@Index(EXVEC) @IndexSecondary(Primary="Kernel", Secondary="EXVEC") @Begin(Description) Find default exception vector table (TRAP 12,20). Parameter @\None. Result @\address of a 32-longword table of exception vectors. @Hinge Description @\Local processes contain a pointer to a table of exception vectors, allowing them to field themselves exceptions such as address errors, privilege violations, and traps. The EXVEC service returns the address of a default vector table, which should be plugged into template PCBs by processes whishing to create others. @End(Description) @End(Group) @SubSection(Kernel Descriptor Layouts) @IndexSecondary(Primary="Kernel", Secondary="Descriptor layouts") @Begin(FileExample, LeftMargin +0) @IndexSecondary(Primary="Kernel", Secondary="General queue descriptor") @b[General queue descriptor] Size: 2 longwords. 0: address of first element (head) of queue. 4: address of last element (tail) of queue. @End(FileExample) Queues of system objects are all held as doubly-linked lists, with each item itself containing a general queue descriptor, of which the first longword (0) points at (that of) the previous item. The main descriptor of the queue is simultaneoulsy the predecessor of the head and the successor of the descriptor points at the descriptor itself. @Paragraph(Semaphore Descriptor) @IndexSecondary(Primary="Kernel", Secondary="Semaphore descriptor") @Begin(Description, LeftMargin +8, Indent -8) @b[Size] @\4 longwords. @b[0,4] @\Queue of waiting PCBs. @b[8] @\Token for text name of this semaphore. @b[12] @\Semaphore value. @End(Description) A negative semaphore value is the (negation of the) number of PCBs waiting on this semaphore's queue. A (strictly) positive value is the number of "P" operations that may be performed on the semaphore without suspending the calling process. @Paragraph(Run Queue Descriptor) @IndexSecondary(Primary="Kernel", Secondary="Run queue descriptor") @Begin(Description, LeftMargin +8, Indent -8) @b[Size] @\4 longwords. @b[0,4] @\Queue of waiting PCBs. @b[8] @\Token for text name of this run queue. @b[12] @\Kick address. @End(Description) The kick address is that of a processor interrupt register, writing to which causes invocation of a local scheduler by means of an interrupt. This makes it possible for processes to signal other processes on a different processor. @Paragraph(IO Request Queue Descriptor) @IndexSecondary(Primary="Kernel", Secondary="IO Request queue descriptor") @Begin(Description, LeftMargin +8, Indent -8) @b[Size] @\4 longwords. @b[0,4] @\Queue of pending IRPs. @b[8] @\Token for text name of this IRQ. @b[12] @\Address of associated semaphore. @End(Description) The associated semaphore is signalled every time a new IRP is placed on the queue by some PON operation. @Paragraph(IO Request Packet Descriptor) @IndexSecondary(Primary="Kernel", Secondary="IO Request packet descriptor") @Begin(Description, LeftMargin +8, Indent -8) @b[Size] @\12 longwords or more. @b[0,4] @\Queue descriptor for linking on IRQ. @b[8] @\Address of target IRQ. @b[12,16] @\Queue descriptor for linking on pending/active/debt lists. @b[20] @\Address of requesting process's PCB (inserted by kernel on PON). @b[24] @\Parameter 0 of the request (by convention a function code). @b[28-44] @\Parameters 1-4 of the request. @b[48+] @\(if present) further parameters. @End(Description) @NewPage @Section(FILES GIVING INFORMATION ABOUT THE SYSTEM) @Label(SystemFiles)@Index(System files) @SeeAlso(Primary="Files",Other="System files") The filestore provides useful systems information via a number of special "files". These are indistinguishable from real files to the user but are generated "on-the-fly" by the filestore. Most are "read-only" . The system manager administration program maintains two databases giving information about owners of directories and APMs. These live in MANAGR:ADMIN.DAT and MANAGR:NS.DAT respectively. The second of these is strictly experimental. @SubSection($:UNOS)@Index(UNOS) @IndexSecondary(Primary="SYSTEM Files", Secondary="UNOS") @Begin(FileExample, Group, LeftMargin +0) @b[Bytes Field Comments] 3 User number (UNO) decimal 4 "Context". Usually = filestore port. decimal. See (1) 2 2 User Station hex 3 User port if meaningful decimal. See (2) 7 User name if meaningful right-justified. See (2) 1 Privileged indication ('!') 7 Directory name right-justified 2 14 Date and time user logged on DD/MM/YY HH:MM 2 14 Date and time UNO was last used " 2 14 Date and time XNO last used by this UNO " 1 78 Total Fixed format (1) For locally connected terminals Context = Qsart port + 256. Certain internally created processes have context -2 (e.g. file copies) (2) User station and port are blank for UNO = 0 [ANON], non-ether contexts or -ve contexts. i.e. where station and port are meaningless. @End(FileExample) The SSE routine FS GET USER INFO unpacks $:UNOS into a recordarray on the heap. @NewPage @SubSection($:PORTS)@Index(PORTS) @IndexSecondary(Primary="SYSTEM Files", Secondary="PORTS") @Begin(FileExample, Group, LeftMargin +0) @b[Bytes Field Comments] 3 Filestore port ("Context") Decimal 4 User Station Hex 3 User port 2 14 Date and time port was attached DD/MM/YY HH:MM 2 14 Date and time port last used " 1 43 Total Fixed format @End(FileExample) The SSE routine FS GET PORT INFO unpacks $:PORTS into a recordarray on the heap. @SubSection($:XNOS)@Index(XNO) @IndexSecondary(Primary="SYSTEM Files", Secondary="XNO") @Begin(FileExample, Group, LeftMargin +0) @b[Bytes Field Comments] 3 XNO 3 UNO associated with this XNO 3 Filestore port ("Context") 1 21 File name or "Special File" 5 Next file block to be read or written * starts at 1 5 Next block of extent * starts at 0 6 Next disc block to be read * 3 Current extent * 1 "/" * 3 Extents in file * 1 5 Blocks in file 2 14 Time XNO was last active 1 1-3 "R" (read operations) &/or "W" (write operations) "L" (last block has gone) See (3) 1 78-80 Total (3) Any or all of these may be present. Files opened MOD have R & W set. @End(FileExample) @NewPage @SubSection($:DIRECTORIES)@Index(DIRECTORIES) @IndexSecondary(Primary="SYSTEM Files", Secondary="DIRECTORIES") @Begin(FileExample, Group, LeftMargin +0) @b[Bytes Field Comments] 4 Cache Slot 3 8 Directory owner left-justified 1 "(" 1 partition 1 "." 3 user directory number 1 ")" 5 Reference count See (4) 5 5 Time Stamp "** Written **" 1 Total (4) Reference count = No of entities referencing this directory: 1/Logged on user + 1/Default + 1/XNO referencing this file + a few for internal use. @End(FileExample) @SubSection($:BITMAP.)@Index(BITMAP) @IndexSecondary(Primary="SYSTEM Files", Secondary="BITMAP") @Begin(FileExample, LeftMargin +0) There is one of these for each filestore partition . (0 <= <= max partition) 8000 Bitmap of available pages on the filestore disc. 0 = free; 1 = allocated @End(FileExample) @SubSection($:TRACE)@Index(TRACE) @IndexSecondary(Primary="SYSTEM Files", Secondary="TRACE") @Begin(FileExample, Group, LeftMargin +0) @b[Bytes Field Comments] 4 Index of first trace record 4 "Context" * 4 In (=0) | Out (=1) * 56 Text * String (55) 4 Index of last trace record @End(FileExample) The file has TBUFFS entries (see system:config.inc) each of format (the fields marked '*') with a leading first entry pointer and trailing last entry pointer. @SubSection($:BOOTAREA)@Index(BOOTAREA) @IndexSecondary(Primary="SYSTEM Files", Secondary="BOOTAREA") This is the filestore bootstrap area i.e. the file from which the filestore bootstraps itself. The file is included here for completeness as it is of no value to machines other than the filestores. It is read and write protected againts all non-privileged users. This file must be opened MOD to enable it to be accessed via DA-type operations. @SubSection(:DIRECTORY)@Index(DIRECTORY) @IndexSecondary(Primary="SYSTEM Files", Secondary="DIRECTORY") There is one of these for each user . The file consists of a complete list of the accessible files of the directory, one per line in date order (Last file first). Lines are of varying length and terminate with a linefeed. @SubSection(MANAGR:ADMIN.DAT)@Index(ADMIN) @IndexSecondary(Primary="SYSTEM Files", Secondary="ADMIN") This is an indexed sequential file of 128-byte records comprising a header record followed by one record for each top-level directory. Directory records are sorted in increasing alphabetical order. @Begin(FileExample, Group, LeftMargin +0) @b[Header Record] @b[Bytes] 4 Number of directory records in file (not counting header) 104 Index into file. This is an integerarray A('A'-'Z') Entries are record numbers, counting from the header (= 0) and indicate the point from which a search should start. 10 Spare @End(FileExample) @b[Directory Records] @Begin(FileExample, Group, LeftMargin +0) @b[Bytes] 8 Directory ID String (7) 36 {Prenames String (35) 16 {Surname String (15) or.. 52 {Description String (51) 16 Supervisor String (15) 2 Group Shortinteger 2 Bitmap of F'stores this no. is on. Shortinteger 10 Creation Date String (9) 10 Date after which directory may be deleted String (9) 28 Mail Address of owner or supervisor String (27) @End(FileExample) The Description option is used for systems directories. All "Description" strings start with '!'. The Dates are strings with one extra byte for alignment. @Begin(FileExample, Group, LeftMargin +0) Groups: 0: Unknown 1: Essential systems directories 2: Additional Systems directories 3: Staff 4: Postgrads 5: CS4 6: CS3 7: CS2 8: CS1 9: IS1 10: Visitors 11: Public directories 12: Other Departments 13: ERCC Bit 15: "Trusted" bit Bit 14: "Ex-" bit Bit 13: Laser printer bit Bit 12: Female Bit @End(FileExample) @Begin(FileExample, Group, LeftMargin +0) FS accredit bits Bit 0: alpha Bit 1: bravo Bit 2: charlie Bit 3: portable Bit 4: vax Bit 5: old @End(FileExample) The Include file MANAGR:ADDEFS.INC contains specifications for the above record formats. MANAGR:ADMIN.INC contains the routines FIND DIR and SHOW DIR which access the database. @SubSection(MANAGR:NS.DAT)@Index(ADMIN) @IndexSecondary(Primary="SYSTEM Files", Secondary="ADMIN") This file is a pair of tables, indexed by station number giving a short and long description of the APM at the specified station number. The short table is intended for quick name <-> address translation and the long one is a database for housekeeping and general reference. The table comprises 128 8-byte fields followed by 128 64-byte fields. All "strings" are stored as bytearrays padded to right with characters <= ' ' with no length byte. (To save space) The 8-byte fields are simply the station short names in station number order. APMs are designated by names starting with an '@' character. The 64-byte fields are records of type NS LFM (specified in MANAGR:NSDEFS.INC) in station number order. @Begin(FileExample, Group, LeftMargin +0) @b[Bytes Field Comments] 1 "In" or "On" designation See (5) 1 "Room" designation See (5) 31 Long text name of station Bytearray padded 1 Case Number See (6) 8 Spare 4 Supplementary address information (eg Room number) Bytearray padded 18 Backplane Map. See (7) 64 Total (5) These fields taken with the long text name give a "user-friendly" description of the location. "In"/"On" takes values.. 'I' In 'O' On 'A' At ' ' No special description "Room" takes values.. 'R' to indicate the description refers to someone's room 'T' to indicate it is the something-or-other ' ' No special description Examples: 'I''R' John Butler -> In John Butler's Room 'O''T' Test Rig -> On the Test Rig @End(FileExample) @Begin(FileExample, Group, LeftMargin +0) (6) Note to systems staff - This field may cause alignment problems if moved. (7) The backplane map should indicate what is in each of the 16 backplane slots plus an indication of what mouse and display is being used. Position is irrelevant. Each entry can take the value.. 'A' 0.5 Mb Memory Board 'B' 1.0 Mb Memory Board 'C' Processor Board (8 MHz) 'D' Processor Board (10 MHz) 'E' Ethernet Board 'G' Level 1 Graphics 'H' Level 1.5 Graphics 'J' Level 2 Graphics 'L' 2.0 Mb Memory Board 'M' Mouse 'X' MIT Graphics Monitor 'Y' DJR/MIT Monitor @End(FileExample) MANAGR:NS.INC contains a set of routines for accessing the file. It is suggested that all NS.DAT access be channeled through these routines (adding new ones if necessary) so the file format can be changed without too much difficulty.