1 Copyright (c) 1999 Massachusetts Institute of Technology
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; either version 3 of the License, or (at
6 your option) any later version.
8 This program is distributed in the hope that it will be useful, but
9 WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 General Public License for more details.
13 You should have received a copy of the GNU General Public License
14 along with this program; if not, write to the Free Software
15 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
16 ------------------------------
18 PROGRAMMING TECHNOLOGY DIVISION DOCUMENT SYS.xx.yy
21 IDENTIFICATIONî______________
23 The JOB/BOJ Device: A Mechanism for Implementing
26 Marc S. Seriff, Jack Haverty, Richard Stallman (MIT-AI)
31 INTRODUCTIONî____________
33 It is occasionally desirable to extend the ITS system to allow
35 for the use of non-standard I/O devices. A very desirable feature
37 would be to allow user-level programs to make use of the newly defined
39 devices with out modification of the user-level programs. For this
41 reason the JOB/BOJ device was implemented.
43 When a job (call it the user) attempts an OPEN for a file whose
45 name is "JOB: <
\b-dir>
\b-; <
\b-fn1>
\b- <
\b-fn2>
\b-", the system creates a
47 new job, called the BOJ device handler, or BDH (this is a terrible
49 name; it USES the BOJ device and HANDLES the JOB device), and attempts
51 to load the file "DSK: <
\b-dir>
\b-; <
\b-fn1>
\b- <
\b-fn2>
\b-" into that job.
53 If the load fails, the OPEN will fail. If this load succeeds, the
55 OPEN, as well as all further I/O operations on the user's JOB channel
57 will be referred to the BDH for execution. At that point, it will be
59 up to the BDH to decide whether or not the open should fail. In order
61 to get a handle on information about the user's open, The BDH opens
63 one or more channels to the "BOJ" device. The system will insure that
65 the BDH's BOJ channel is logically linked to the user's JOB channel.
67 The following diagram illustrates what happens:
74 | User |------
\bv
\b\b__________
\b\b\b------>| BDH |
75 |__________| | | ---X
\bO--- | | |_________|
77 ____| |_____
\b|_____| |____
79 The JOB channel | The BOJ channel
85 Once the BDH has successfully opened the BOJ channel, it will be
87 notified (via an I/O channel interrupt) every time the user attempts
89 an I/O operation on the JOB channel. The BDH may then examine the
91 data that is made available to it about the I/O operation and may
93 simulate the operation for the user. In this way, BDHs can be written
95 to give anything the appearance of a disk, tape or other specific type
99 USING THE JOB DEVICEî_____ ___ ___ ______
101 Programs that use the JOB device should not be required to make
103 special provisions. A BDH should, in general, be written so that the
105 non-standard device will behave exactly like some standard device. In
107 other words, a user program may open a JOB device using a standard
109 open and may then execute any legal I/O operation.
111 A file name with something other than "JOB" for a device code can
113 be made to act like a JOB device in one of two ways. The first way
115 should be used for devices that are not generally applicable or are
117 expected to be used only for a short time. To use this method simply
119 use translates (using MONIT, DDT or directly via system calls) to
121 inform the system which file should be used as a BDH. For instance,
123 if we translate all file names of the form "XXX:" into the file name
127 "JOB:ABC;TS RUNXXX", then the system will use the file "DSK:ABC;TS
129 RUNXXX" as the BDH for any file name whose device code is "XXX".
131 The other method is much simpler and is designed for non-standard
133 devices that are to be made available to the entire user community.
135 When an OPEN is attempted on a device whose name the system does not
137 recognize, the system will examine the "DEVICE;" directory for a file
139 whose first name is "JOBDEV" and whose second name is the unrecognized
141 device name. If such a file exists, then the contents of that file
143 will be loaded by the system and used as the BDH for the user's OPEN.
145 USING THE BOJ DEVICE - THE BOJ DEVICE HANDLERî_____ ___ ___ ______ _ ___ ___ ______ _______
147 The BDH is the workhorse in the JOB/BOJ device scheme. It is
149 required to interpret all of the user's I/O operations. It must do
151 everything to make the non-standard device that it represents appear
153 standard. The system provides five .CALLs to give the BDH some of the
155 required communcation with the user.
157 The first thing that the BDH should do when he is loaded and
159 started by the system is to execute an OPEN on the BOJ device. This
161 establishs a logical link between the user and the BDH. The BDH may
163 enable a channel interrupt on the BOJ channel, in order to be informed
165 whenever the user attempts an I/O operation.
167 It should be noted that the ITS system allows for the possibility
169 of a full duplex connection between the user and the BDH (i.e. a
171 channel in each direction). If a user attempts an open for reading
173 and an open for writing on the same device, then the system will
175 present both opens to the same activation of the BDH. Should this be
177 undesirable for a particular BDH, that BDH should use an open mode
179 with the 3.4 bit set (10 in the left half) each time it attempts to
185 JOBCAL SYSTEM CALLî______ ______ ____
187 The first .CALL that will be discussed is the JOBCAL. This call
189 enables the BDH to find out what I/O operation the user has attempted
191 to execute. It has the following calling sequence:
199 [<
\b-BOJ channel number>
\b-]
201 SETZ [-<
\b-n>
\b-,,<
\b-data>
\b-]
204 This .CALL, as well as the other three discussed below, will fail to
206 skip if any of the following conditions hold:
208 1. <
\b-BOJ channel number>
\b- is an illegal channel number.
210 2. <
\b-BOJ channel number>
\b- is not open on the BOJ device.
212 3. the user job does not exist or as has closed his channel.
214 4. the user job is no longer attempting to execute the I/O
217 <
\b-opcode>
\b- should be an address into which information about
219 the I/O operation requested will be placed. This word contains three
221 sections. The right half of the word contains an integer indicating
223 which operation was attempted. The following table indicates what the
225 various integers mean:
230 CODE OPERATIONî ____ _________
236 2 STATUS (currently unused)
240 4 RCHST (complete status)
244 6 FDELE (for delete or rename while not open)
246 7 FDELE (for rename while open)
250 It is up to the BDH to insure that these I/O operations perform as
252 they would for standard ITS devices.
254 The top three bits (4.9-4.7) of the op-code word contain the mode
256 in which user is attempting to open his channel. This is only
258 meaningful for op-code 0, OPEN. If either of the next two bits (4.6
260 and 4.5) are non-zero, then the user is requesting that a channel be
262 closed. As was mentioned above, the system allows the connection
264 between user and BDH to be full dumplex. If the 4.6 bit of the opcode
266 is set, then the user is requesting that his input channel be closed,
268 while the 4.5 bit requests a close of the user's output channel. It
270 is possible to get an opcode in which both bits are set. In the case
272 the BDH should perform the obvious task of closing both channels.
274 Most I/O operations require more information than just the name
276 of the operation. The third argument to JOBCAL tells the system where
278 any additional information that is available should be placed.
280 <
\b-n>
\b- is the largest number of words that the BDH is willing to
284 accept (it should normally be 12). <
\b-data>
\b- is the address where
286 the first word of the information should be placed. What information
288 is placed in this buffer is determined by the I/O operation being
292 If the op-code (in the right half of the op-code word) is less
294 than 8, then five words will be written into the buffer (beginning at
296 <
\b-data>
\b-) in response to the JOBCAL. The meanings of the words are
298 given in the following table:
303 WORD OPERATIONS MEANINGî____ __________ _______
305 1 IOT (1) Meaningful only for block IOTs.
306 This word will contain the user's
307 IOT pointer. The left half of this
308 word will be the negative of the
309 number of words that the user wants.
311 1 ACCESS (5) The address within the virtual file
312 that is open from (or to) which the
313 next IOT should be done. The first
314 word of the virtual file is word
317 1 FDELE (6 or 7) Zero implies delete requested.
318 Non-zero means that a rename is
319 requested. This word is the name
320 (in sixbit) to be used as the new
323 2 OPEN (0) or FDELE (6) First name of the file that the user
324 is attempting to open, rename or
327 3 OPEN (0) or FDELE (6) Second name of the file that the
328 user is attempting to open, rename
331 4 OPEN (0) or FDELE (6) Name of directory to be used for
332 open, rename or delete.
334 5 OPEN (0) or FDELE (6) Name of device to be used for open,
337 6 OPEN (0) The full 18 bit open mode (right
340 6 FDELE (6 or 7) Zero implies delete. Non-zero means
341 that a rename is requested. This
342 word is the name (in sixbit) to be
343 used as the new second file name.
345 If the op-code returned by JOBCAL is 8, then the user has
347 attempted some I/O operation not recognized by the systems JOB/BOJ
349 device code (this does not mean that the operation is illegal). Inî ___
351 this case, more information is written into the BDH's buffer (up to
353 twelve words). The first of the data words will be the SIXBIT name of
357 the operation being performed. (This will normally be the name of the
359 .CALL executed by the user - see Appendix 1 for a list of
361 possiblities.) The second word will contain all of the flags that the
363 user has set using the "flag" feature of the .CALL UUO. The third
365 word will be an integer indicating how many input (to the system)
367 arguments the user supplied in his .CALL. It should be noted that if
369 this integer is larger than <
\b-n>
\b-+3, then some information will be
371 lost. The values of the input arguments will appear in the remainder
373 of the words in the buffer. Remember that, in almost all cases, the
375 first of the input arguments will be the user's channel number.
377 JOBRET SYSTEM CALLî______ ______ ____
379 Once the BDH has interpreted the user's request for execution of
381 an I/O operation, the BDH must have some way of responding to the
383 user. This is provided with the JOBRET .CALL. This .CALL serves
387 1. to unblock the user who is waiting for completion of his
388 I/O request (possibly causing the request to skip)
390 2. to set lossage codes in the user's status words (e.g. for
393 3. to return information requested by the user's I/O
396 The format of this CALL is as follows:
404 [<
\b-BOJ channel number>
\b-]
406 SETZ [-<
\b-n>
\b-,,<
\b-data>
\b-]
409 where <
\b-return>
\b- satisfies requirements 1 and 2 above. If
413 <
\b-return>
\b- is zero, then the user's I/O call will not skip or set
415 status bits. If <
\b-return>
\b- is of the form <
\b-i>
\b-,,<
\b-j>
\b- , then
417 <
\b-i>
\b- will be placed in the "open-loss" field of the status word for
419 the user's channel and the user's I/O call will skip <
\b-j>
\b- times. A
421 list of all currently recognized open loss codes can be found in
425 If the user's I/O call requested data, then the BDH can supply
427 this data by supplying the third argument to the JOBRET call. The
429 system will use the <
\b-n>
\b- words beginning at location <
\b-data>
\b- as
431 the values for the return arguments in the user's call.
433 SETIOC AND JOBINT -- INTERRUPT SYSTEM CALLSî______ ___ ______ __ _________ ______ _____
435 There are two interrupt oriented functions that the BDH must
437 perform and there are CALLs available to perform them. The first is
439 to notify the user when he has done something catastrophic. The user
441 should be notified of his error by causing the system to awaken him
443 with an I/O channel error. This done with the SETIOC call, as
448 ... ; error return (standard reasons
449 + illegal IOCERR code)
454 [<
\b-BOJ channel number>
\b-]
455 SETZ [<
\b-IOCERR code>
\b-]
458 where <
\b-IOCERR code>
\b- is an integer identifying the reason for the
460 error. This integer should be chosen from the list that can be found
462 in Appendix 2. Since BDHs are written to handle non-standard devices,
464 these error codes will quite often not apply. Simply choose the code
470 Occassionally, the BDH must notify the user of a non-catastrophic
472 situation (e.g. the arrival of data). The JOBINT call allows the BDH
474 to give the user a second-word I/O channel interrupt, as follows:
482 SETZ [<
\b-BOJ channel number>
\b-]
485 JOBSTS SYSTEM CALLî______ ______ ____
487 Finally, the BDH must have some way to notify the system what the
489 status of the pseudo-device is. For this purpose, the JOBSTS call is
491 available. Its calling sequence is as follows:
499 [<
\b-BOJ channel number>
\b-]
500 SETZ [<
\b-new status>
\b-]
503 The right half of <
\b-new status>
\b- will be given to anyone requesting
505 the status of the user's channel until another JOBSTS is done. It
507 should be remembered that the low order six bits (1.1-1.6) should
509 contain the device code of the pseudo-device. Unless, you know what
511 you are doing, this should always be 22 octal.
513 DATA TRANSFERS - HOW TO IOTî____ _________ _ ___ __ ___
515 Since the main purposes of I/O devices is transfer of
517 information, let us look at how the BDH manages to respond to the
519 user's IOTs. The method for doing this is very simply. If we think
521 back to the diagram presented early in this memo, we will remember
525 that the BOJ and JOB channels (i.e. the channels belonging to the BDH
527 and the user, respectively) are logically connected. The full meaning
529 of this now becomes clear. If the JOB channel is open for input and
531 the BOJ channel is open for output, then anything that BDH outputs on
533 the BOJ channel will be available to the user as input on the JOB
535 channel. (For this reason, the BDH must insure that he opens the BOJî ____
537 channel in the opposite direction from the user's JOB channel even if
539 this requires opening the BOJ channel a second time in the correct
543 There are two features of which the BDH implementer should be
545 aware when writing the I/O sections of the BDH. Let us assume for the
547 discussion here, that the user has the JOB channel open for reading
549 and that the BDH has the BOJ channel open for writing. Let us also
551 assume that the user is currently hung attempting to read 100 words on
555 First it should be noted that the BDH does not have to respond toî ___
557 this request with a single transfer of 100 words. The system will act
559 as an mediator between different transfer sizes. The BDH can respond
561 to the user's request for 100 words in several ways:
563 1. He can send all 100 words in small pieces (e.g. 10
565 transfers of 10 words each.
567 2. He can send all 100 words in a single transfer.
569 3. He can send more than 100 words. In this case, the BDH
571 will remain hung in his IOT until the user has read all of
573 the data that the BDH is attempting to send. (If this is
575 undesirable, set the 3.5 in the BOJ open mode. This will
577 cause BOJ IOTs to unhang whenever the user's IOT is
581 satisfied. When that happens, the BOJ IOT pointer will
583 have been counted out only partially; the RH will point to
585 the first word not transfered)
587 4. He may send less than 100 words. In this case, the BDH
589 must manually awaken the user as described below.
591 The user, who is hung awaiting his 100 words, will stay hung until he
593 has received all 100 words. Suppose, however, that the BDH only
595 wishes to send 50 words (e.g. the last 50 words of the virtual file).
597 To do this, he can send the 50 words normally, but must then use the
599 JOBRET call (described above) to awaken the user. JOBRET should be
601 called with the BOJ channel number as the first argument, zero as the
603 second argument and no third argument. Secondly, the BDH implementer
605 must be aware that the ITS system guarantees that IOTs to a channel
607 open in block mode, will never generate an I/O channel error. In
609 other words, the following algorithm should be followed:
611 1. If the user requests n words and there are n words or more
613 left in the "file", give him n words.
615 2. If the user requests n words and there are only m words
617 (n>m), give him m words and manually awaken him (using
621 3. If the user requests n words and there are no words left,
623 then give him nothing and manually awaken him (using
627 HINTS TO BDH IMPLEMENTERSî_____ __ ___ ____________
629 The following hints should ease the task of BDH implementers a
631 little. It is hoped that anyone who attempts to a BDH implementation
633 will add his harshly acquired knowledge to this section of this memo.
637 1. Remember that the BDH is essentially a disowned job and should
639 attempt to log out after a close has been requested.
641 2. Be very leery of logging out for any reason other than a requested
643 CLOSE. In particular:
645 a. if a JOBCAL fails, only log out if a request for OPEN has not
649 b. when you generate an I/O channel error for the user, only log
651 out if the error is irrecoverable. Remember that he can
653 correct an access beyond end-of-file by doing an access before
655 attempting another IOT.
657 c. if he requests an I/O operation that you do not recognize,
659 generate a "mode not available" error (via JOBRET) and wait
661 for his next request.
663 d. if you decide, for your own reasons, to make the initial open
665 fail, you should log out.
667 THE OJB DEVICE -- AN AID FOR DEBUGGING THE BDHî___ ___ ______ __ __ ___ ___ _________ ___ ___
669 One of the problems with debugging BDH programs is that when the
671 JOB device is used, it is loaded into a newly created job. That job is
673 not inferior to any DDT, and there is no way to put breakpoints in it
675 before it starts. The OJB device makes it possible to run the BDH
679 The OJB device acts just like the JOB device except during the
681 initial open. When the JOB device would be creating and loading a new
683 job, the OJB device is looking for an existing job whose UNAME and
685 JNAME are the same as the filenames specified in the open. If such a
687 job is found, it is connected to the job opening the OJB device
689 through a standard JOB-BOJ pipeline. If such a job does not exist,
693 the open of the OJB device fails. In order to protect innocent jobs
695 from being hacked in this matter, the job opened on the OJB device is
697 required to have set its OPTOJB bit (this is bit 4.2 in the .OPTION
699 varisble, settable with .SUSET). Also, it must not already be a BDH,
701 for the system cannot consider one job to be a BDH through two
703 connections at once. If either of those conditions is not met, the
705 OJB open WAITS until they are.
707 To remove a possible timing screw, a BOJ device open by a job
709 that is not a BDH, which usually fails, will wait instead for the job
711 to become a BDH if the job's OPTOJB bit is set.
713 The procedure for using the OJB device for debugging is:
716 1. create a job to use for the BDH (call it J, in this example).
718 2. run (in another job) the program which would normally open
720 the JOB device, but tell it (perhaps by means of a translation) to use
722 the OJB device instead. This program's function is to issue system
724 calls so that the BDH's responses to them can be tested.
726 Since the OPTOJB bit of job J is now 0, when this program reaches
728 the OJB open it will hang.
730 3. ^Z that program, and ^P it. it will go back to hanging in the
732 open of the OJB device.
734 4. switch to job J, load in the BDH program. This RESET's the
736 job so that if it had been a BDH before, it will not be one now.
738 5. turn on the OPTOJB bit by depositing from DDT in .OPTION.
740 The conditions for a successful OJB open by job JJ have now been met,
742 so that job will make some headway, turning job J into a BDH and
744 waiting for job J to issue a JOBRET.
748 6. it is now possible to start running job J, with breakpoints
750 as desired, to step through the code for handling the initial open.
752 It is unlikely, but theoretically possible, for J to execute its BOJ
754 open before JJ gets around to turning J into a BDH. In this case, J
756 will wait for JJ to do so.
758 7. if it becomes necessary to try again after discovering a bug,
760 go back to step 2. The OJB open will hang up this time not because
762 the OPTOJB bit is off (since it is still 1) but because J is already a
764 BDH. Loading J in step 4 will make J cease to be a BDH but also turn
766 off the OPTOJB bit, so JJ will still be waiting.
768 8. it is possible for job JJ to be "PCLSR'ed" or backed up out
770 of its open while job J is being traced through the handling of the
772 initial open. For example, job JJ might receive a real-time
774 interrupt. If that happens, J will cease to be a BDH. This will not
776 interfere with the tracing of J until the next BOJ device system call
778 is executed; that call will probably fail. It is impossible to
780 continue after such an occurrence, so the jobs must be restarted by
782 returning to step 2. Of course, if there are no breakpoints before
784 the first JOBRET, this is very unlikely to happen.
786 9. if the initial open has been handled successfully, to go on
788 to debug handling of other system calls, simply tell JJ to execute
790 them with J stopped while JJ is being told, then ^Z^P JJ and go back
794 10. the usual .LOGOUT in the BDH program will be a no-op when the
796 program is run as an inferior in this manner, so it should be followed
799 \f\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0