On at 2022-07-12 20:01 +0200, Jose Senna wrote:
  Bret Johnson said:
  > The way it works is to make a "copy" of
  > itself at the top of conventional memory,
  > terminates itself (using a normal DOS
  > terminate process, which includes deleting
  > the original PSP), and then continues
  > running from the "copy". The "copy" decides
  > where the best place in memory is to load
  > the TSR (which can even be in one or more
  > "memory holes" left by some other program
  > or in upper memory),allocates appropriate
  > memory block(s), and then installs itself
  > in the allocated memory.


   But when it terminates, the system would
  not return to the parent of the utility,
  (COMMAND or whatever called the utility) ?
  So, how can the copy continue running
  after termination  ?

Good question! As I independently invented this method, I will answer quickly. You can read my reference implementation in my TSR example [1]. Basically, it creates a new PSP (the system structure that makes up a DOS process) in a temporary memory block, then bends that memory block to "belong to itself" (as memory blocks used for PSPs usually do). This means that when we terminate with service 4Ch, the temporary allocation is not freed because it doesn't belong to the original process.

The actual "jump" over to the new temporary process is achieved by twisting the parent process field and the Parent Return Address (aka interrupt 22h) of the original process. Their original contents (which refer to the shell or whatever other process EXECed our program) are transferred into the new temporary PSP, so that upon its termination it will actually return to the shell. The old original PSP is instead modified to refer to the new PSP as its parent, and the original PSP's PRA is also modified to jump into the code of the relocated process. (Additionally, there is a field in the *parent* PSP which indicates what stack to use when returning from DOS process termination to the parent.)

In part this was inspired by FreeDOS Debug (and before this actual shells for DOS, too, I believe even MS-DOS COMMAND.COM does this). It sets up its parent as itself, and its PRA to return into its own resident code. DOS detects the special condition of a self-parented process in its termination handling, and will not free memory nor close the file handles in this case. (Just as for service 31h TSR termination actually, it also neither frees memory nor closes handles, as I mentioned in my longer reply earlier.) That allows the shell (and the debugger, which touts itself a kind of shell [2]) to retain control after it was aborted with Control-C or upon a critical error when "Abort" was selected.

Regards,
ecm


[1]: https://hg.pushbx.org/ecm/tsr/file/daca203fa216/transien.asm#l988
[2]: https://hg.pushbx.org/ecm/ldebug/file/d8d009634290/source/debug.asm#l1319


_______________________________________________
Freedos-devel mailing list
Freedos-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/freedos-devel

Reply via email to