This format has several advantages:
* The CONFIG block need not be moved.
* The entire compressed image (depacker and payload) need
not be moved another time before the UPX depacker's own
operation.
* The CONFIG block always lives at 00602h, and the kernel
need not be aware whether it was compressed for detecting
which CONFIG block to use.
* Support for compressed images beyond 64 KiB for free.
(The assembly define TEST_FILL_INIT_TEXT can be passed in
NASMENV to test this support with 32 KiB of LFSR output.)
* A subsequent commit will shorten the stub to 64 bytes,
compared to the prior 32 + 45 = 77 bytes, with no loss
of features. (The packed payload is a bit shorter too.)
* The new stub also sets ds and es to the segment value
that would point to the DOS/EXE process's PSP. This is
apparently not used by the UPX depacker but could be in
a future or past version, or if another packer is used.
Some assembly tricks:
* SMC instead of checking the XMS driver address
in the DOS DS stub,
* SMC so that the address goes right into a
`call far immediate` instruction,
* use `repe cmpsw` to compare multiple words (saves
space over the individual word compares),
* near calls to far functions use push cs to build
a far-call stack frame,
* segments 0 and FFFFh generated by segment arithmetic
instead of loading from memory,
* common case (A20 already enabled) made to be the case
where the conditional branch just falls through, which
may be slightly better.
A crash was introduced by the prior commit, ee255d2. I
tested that the kernel still did build with gcc, but I
failed to test whether it also still runs. Turns out that
apparently changing the pointers to static made it so gcc
put the structure into the init data segment and
implicitly called memcpy to put it on the stack. That's
wrong, however. We depend on #define to convert all calls
in init to the init text copies of memcpy etc. The
implicit call by gcc however attempts to call the HMA text
copy of memcpy which happens to be at another offset.
The fix is to make the entire array of structs static so
that memory for it is allocated only in the init data
segment, not on the stack. This seems to work for both
gcc and OpenWatcom (no warnings, it builds, it runs).
CONFIG takes precedence and is by default initialised
to the empty string, that is, skipped. ALTCONFIG is
used to specify the 'alternative' filename and defaults
to fdconfig.sys. Finally, OLDCONFIG defaults to the
config.sys filename.
The protocol for this extension is based on what lDebug
already does given the PROTOCOL=FREEDOS with the switch
CMDLINE=1 (which was originally defined for the lDOS and
RxDOS load protocols). Therefore the stack frame mirrors
that of the lDOS protocol.
Also adds a CheckDebugger byte to the CONFIG block and
support for reading and writing this setting in the
SYS CONFIG program. Default is 0 (no check assume absent).
Here we depend on the signal instruction that is patched
by exeflat to indicate whether we were compressed. This
replaces the prior check that detected the UPX help data
solely by checking the CONFIG signature at 05E2h.
This commit does not change the behaviour of the code
as it already did the right thing. However, it notes
that that should happen. (This is DR DOS compatible.
For example, SHSUCDX depends on DR DOS setting this
segment so that it can keep track of the DOS DS
across it being relocated. We do not yet relocate it
but keeping a reference here is still useful.)
Fixes problem with GCC-ia16 compiled share not allowing open of files.
It seems that the TCC 2.01 compiled version was fortunate in that DS
happened to be correct when the interrupt was called, but this was
not the case for the GCC ia16 compiled version.
It's an analogue of this patch by @stsp for FDPP.
https://github.com/dosemu2/fdpp/commit/5b52510b
Delete and Rename should not be able to remove an open file,
so check share's open file table first. Behaviour is now identical
to MS-DOS 6.22.
Note: Uses a new subfunction of the FreeDOS share multiplex
interrupt int2f/0x10a6 called is_file_open()
A similar patch was applied to FDPP at
https://github.com/dosemu2/fdpp/commit/691721f1
Fixes dosemu2 tests:
test_fat_ds3_share_open_rename_fcb
test_fat_ds3_share_open_rename_ds2
test_fat_ds3_share_open_delete_ds2
test_fat_ds3_share_open_delete_fcb
original commit notes 'Fix an error at opening a character device prefixed with invalid drive letter (e.g. "@:NUL") (some application use it for opening character device driver)', need to test case but breaks TRUENAME asis
After comparison with DR-DOS 7.01 and MS-DOS 6.22 over at Dosemu2 it
was seen that rmdir of a directory having the _A_RDONLY bit set should
succeed. This patch makes that change.
For reference the test report can be found in the fdpp issue
https://github.com/dosemu2/fdpp/issues/161. An identical patch has
been applied there.
This changes the interface between reloc_call_int2f_handler
(int2f.asm) and int2F_12_handler( ) (inthndlr.c) so that
- int2F_12_handler( ) will not try to output values to its
caller by passing "back" input parameter values
- reloc_call_int2f_handler will switch to an internal
stack before calling int2F_12_handler( ), so that SS ==
DGROUP as expected by the latter.
This partly addresses https://github.com/FDOS/kernel/issues/11 .
(The call to syscall_MUX14( ) in int2f.asm seems to have
similar issues, and should probably also be updated.)
DOS provides the interrupt 2f/12xx functions for use by
filesystem redirectors in order that they do not need to access
structures and variables using undocumented methods. Interrupt
2f/1217 is a function used by a redirector to get the CDS entry
corresponding to a drive without iterating the CDS array found
via SYSVARS LOL.
FreeDOS currently validates the flags in CDS entry before
deciding whether to return the entry to the caller. This behaviour
prevents a redirector receiving the CDS entry corresponding to
an as yet unassigned drive so preventing any new drive mapping.
I've tested the following flavours of DOS and only FreeDOS
does this.
# DOS variants returning new CDS entries okay
DR-DOS
6.00-930319 7.00 7.01 7.02-971119 7.02-980123 7.03 8.00
MS-DOS
3.10 3.20 3.21 3.30-Nec 3.30 3.31 4.01 5.00 6.00 6.20 6.21 6.22
7.00 7.10
PC-DOS
3.00-Compaq 3.00 3.10-850307 3.10-850422 3.10-Compaq 3.20-851230
3.20-860221 3.30 3.31-Compaq 4.00 4.01 5.00 5.02 6.10 6.30 7.00
7.10 7.2K
# DOS variants that return error rather than new CDS entry
FR-DOS
1.00 1.10 1.20
This patch introduces an unvalidated version of get_cds() and calls
it only for the int2f/1217h call, other uses remain as before.
- Upon creation, initialize the PSP version field
to os_setver_minor / os_setver_major.
- When calling Function 30h, return the contents
of the current PSP's version field to the caller.
Some ancient NE programs set exMinAlloc to 0xffff to signify
that they should not be run as normal MZ programs at all:
00000000 4d 5a 40 00 01 00 00 00 04 00 ff ff ff ff 00 00
00000010 00 00 00 00 00 00 00 00 40 00 00 00 00 00 00 00
00000020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00000030 00 00 00 00 00 00 00 00 00 00 00 00 40 00 00 00
00000040 4e 45 04 00 9b 00 07 00 00 00 00 00 06 40 02 00
...
The kernel should reject these programs, rather than try to
run them (and crash the system).
Two variables named 'result' were defined, at the outer level a
UBYTE to hold the function return value and the inner a COUNT to
hold returns from 'truename()'. The overall function return value
was always FCB_SUCCESS due to shadowing, however removing the
inner variable definition as a fix does not work due to sign
issues and intermixing of the variable uses, so rename the inner
variable.
Tested this patch using FDPP platform
1/ Simple rename of file with conditions for success (ok)
2/ Simple rename of file with conditions for failure - source missing (ok)
3/ Simple rename of file with conditions for failure - target exists (ok)
Fixes#16
GCC has -mrtd but the args are pushed in reverse versus PASCAL. So asm
routines have to use macros to obtain the stack arguments.
For the complex call_nls assembly, revert the arguments in C using a
preprocessor macro.
Using DOSTEXT(x) accesses x in LGROUP and DOSDATA(x) in DGROUP.
This is necessary since ia16-elf-gcc does not understand data
in far segments.
For non-macro'ed symbols, FP_SEG needs to be replaced by explicit
segment references.
Because ia16-elf-gcc and the GNU linker do not understand OMF we
need to use ELF everywhere.
This also means we cannot use "wrt", "seg" and "call/jmp far".
Most wrt's are superfluous, and seg and call/jmp far can be
replaced by explicit ?GROUP references (to be defined in the
linker script).
LBA_to_CHS() uses geometry taken from BIOS, but LBA_Transfer()
was using the geometry from VBR. This caused "count" variable
to underflow over unsigned long, then corrupting the entire
DOS memory with the large read.
This patch makes LBA_to_CHS() to return the geometry to caller,
so that the calculus do always match.
Thanks to @ecm-pushbx and @andrewbird for helping to
nail this down.