1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165
|
Description of kernel-supoorted swapping of FreeCOM
-- 2001/01/21 ska
===> Please also read VSPAWN.TXT.
This sort of swap is incompatible with XMS-Only swap!
=== Preface
This technique is an experimental implementation of a general purpose
swap technique applyable to FreeCOM that does not require any special
support of the kernel.
It will therefore not support swapping in any circumstances and is intended
to work as a "boot-through" shell for memory hungry programs, which
normally don't require no function of a resident shell.
=== Supported Swappings
The swapping is activated via the CALL command in this way:
C> CALL /S prg [{ args }]
The /S switch forces the swapping mechanism to be activated on executation
of the next command.
Swapping is NOT supported in:
- secondary shells or other programs,
- pipes, e.g. CALL /S prg1 | prg2, nor prg1 | CALL /s prg2 ,
- conjunction with redirections, e.g. CALL /s prg <input
- batch files,
- called batch files accessing any shell functions or patch the master
environment.
Swapping does not preserve the history.
=== How to use KSSF?
In CONFIG.SYS:
SHELL=C:\KSSF.COM C:\COMMAND.COM /E:2048 /P
From command line:
CALL /S KSSF.COM c:\command.com /e:2048
[[The CALL /S will force the previously loaded FreeCOM to swap;
don't use it if you doesn't use FreeCOM.]]
You can even nest KSSFs.
Doing so KSSF and FreeCOM associate together very tidly, you will need
to spawn FreeCOM via KSSF whenever you want to use the Swapping Support
from within the spawned shell.
Always use the absolute path to the shell.
You cannot change the path to the shell once KSSF has been loded.
=== Implementation
The code of the kernel spawning process 0 (the primary shell) has been
extended as loop. When process 0 finishes, the kernel checks a special
internal variable, if this one points to a valid argument structure,
the program mentioned herein is executed as process 0 and, then, FreeCOM
is re-invoked. The only information passed from FreeCOM to the new process
are the command line and the environment, no file descriptors are preserved!
See below about Critical Error handler and ^Break handler.
The argument structure contains the following information:
#pragma -a- /* byte aligned members of structure */
typedef struct {
uint16 envSegm; /* segment to be passed forth as environment */
char far *prg; /* program to be executed */
char far *cmdline; /* command line arguments of program */
char far *shell; /* absolute path to shell to be executed */
/* ... internal information for FreeCOM */
}
envSegm is to be passed as environment segment to both the program and the
re-invoked shell.
The code to spawn process 0 passes NULL for both fcb1 and fcb2 pointers,
neither is any support for both programs.
The command line is empty for the re-invoked shell.
If prg is equal to NULL, no external program is to be invoked.
If shell is equal to NULL, the shell is not to be invoked --> shut down
computer.
The argument structure is made known to the system via an interrupt call,
here are the specs:
DOS-4B-FD: Set Segment of Argument Structure
AH = 0x4B
AL = 0xFD
BX = segment
DX = 0x4446 == 'FD' (magic number)
Return:
Carry == 1 on error (see below)
Carry == 0 on success
BX := _previous_ segment
DOS-4B-FE: Get Segment of Argument Structure
AH = 0x4B
AL = 0xFE
DX = 0x4446 == 'FD' (magic number)
Return:
Carry == 1 on error (see below)
if AX == 5 (Access Denied) --> BX := current segment
Carry == 0 on success
BX := current segment
Note:
If DEBUG was enabled during compilation of KSSF && Carry == 0,
AX := PID of KSSF
Only one process may use these functions, any other process gets the
error 1 (invalid function). Therefore the primary shell MUST invoke
DOS-4B-F? to lock this function for other processes.
Secondary shells may use DOS-4B-FE/Carry/AX==5 to detect a context
of the primary shell and re-use it's critical error handler.
If segment == 0, no segment has been assigned so far.
The kernel interpretes this situation as prg == NULL && shell == NULL.
FreeCOM performs a swap-out request as follows:
+ Parse a "CALL /S prg argument" as "CALL prg arguments", but enable the
flag swapOnExec.
+ Eventually the interpreter reaches the "exec()" function, that
executes an external command. At this point all the remaining command
line has been broken into the external program's name and it's command
line.
If at this point the flag "swapOnExec" is true, the argument structure
is prepared and FreeCOM terminates with a DOS-4C API command.
+ Whenever FreeCOM is to read "the next input line" from whichever media
is currently active, the flag is deactived, thus unless the CALL/S
command is immediately followed by an external program, this switch is
ignored completely.
Because the shell provides two core functions, the Critical Error
handler and the ^Break handler, which are not always included within
every program, both handlers must be installed residently even if the
primary copy of FreeCOM unloads on a swap request. That's why both
handlers are installed when FreeCOM loads the first time and FreeCOM's
own previous handlers are settings are tweaked in such way that when
FreeCOM terminates for swapping, the addresses of the installed handlers
are copied back into the system and, thus, furtherly re-used for both
the external program and the re-invoked shell.
FreeCOM knows two variants of the Critical Error handler:
Type 1: displays the known menu Abort/Retry/Ignore/Fail.
Type 2: is installed when the primary copy had been invoked with the /F
switch == AutoFail. In this case the handler will automatically return
"Fail" for all and any Critical Error.
This variant is much smaller (about 5 bytes rather than approx. 390 bytes),
but may cause unexpected and unretraceable behaviour.
FreeCOM installs a ^Break handler, that will always "Abort" the program.
This is required in order to make the handler independed on the context,
in which it is triggered, aka if within FreeCOM or a spawned program.
In most circumstances the external program spawned by a swaped-out
FreeCOM will get the same PID as FreeCOM itself.
|