This shows you the differences between two versions of the page.
| — |
blog:pushbx:2026:0516_dr-dos_v9_trial [2026-05-16 20:40:11 +0200 May Sat] (current) ecm created |
||
|---|---|---|---|
| Line 1: | Line 1: | ||
| + | ====== DR-DOS v9 trial ====== | ||
| + | |||
| + | I tried out the most recent build of DR-DOS v9 recently. In case you're unaware, [[https:// | ||
| + | |||
| + | ===== ===== | ||
| + | |||
| + | The most recent revision was "9.0 rev 648 - 2026-05-02" | ||
| + | |||
| + | Since, version "9.0 rev 692 - 2026-05-16" | ||
| + | |||
| + | |||
| + | ===== The bug report ===== | ||
| + | |||
| + | ==== Subject ==== | ||
| + | |||
| + | DOS corrupts .exe file during load after the image' | ||
| + | |||
| + | ==== Version ==== | ||
| + | |||
| + | DR DOS (R) 9.0 rev 648 | ||
| + | |||
| + | ==== Hardware/ | ||
| + | |||
| + | QEMU emulator version 5.2.0 (Debian 1: | ||
| + | |||
| + | ==== Provide as much detail as possible about the bug ==== | ||
| + | |||
| + | It appears that large MZ .exe files aren't fully loaded by DOS, or corrupted in some way. A test program is provided in https:// | ||
| + | |||
| + | '' | ||
| + | |||
| + | This requires NASM, dosemu2 and a DOS, WarpLink, and the warplink.sh script from https:// | ||
| + | |||
| + | The expected return is no output, return code 0. On DR-DOS v9 rev 648, instead the address 0948:382 (corresponding to linear 9802h = 38914, subtract 2 as '' | ||
| + | |||
| + | Debugging using application mode lDebug wasn't possible as the debugger itself is too large and runs afoul of this bug. Debugging using bootloadable lDebug, with a loader extension that reserves memory at segment 8000h used by drbios.sys, later setting a breakpoint on the int 21h handler for function 4Bh, then tracing, shows that DOS does appear to load and enter the debugger executable, however its first far branch to the init section ends up jumping into uninitialised code (all-zeroes seen). | ||
| + | |||
| + | Log of test: | ||
| + | |||
| + | < | ||
| + | DR DOS (R) 9.0 rev 648 | ||
| + | Copyright 2022-2026 Whitehorn Ltd. Co., All Rights Reserved | ||
| + | |||
| + | |||
| + | C: | ||
| + | |||
| + | 0948:0382 | ||
| + | |||
| + | C: | ||
| + | |||
| + | Entire test case source text (mangled by this text input box): | ||
| + | |||
| + | < | ||
| + | |||
| + | cpu 8086 | ||
| + | |||
| + | section CODE | ||
| + | ..start: | ||
| + | mov ax, FIRST | ||
| + | mov es, ax | ||
| + | mov dx, REPEAT | ||
| + | loop: | ||
| + | mov ax, 2626h | ||
| + | mov cx, BLOCKSIZE / 2 | ||
| + | xor di, di | ||
| + | repe scasw | ||
| + | jne bad | ||
| + | dec dx | ||
| + | jz good | ||
| + | mov ax, es | ||
| + | add ax, BLOCKSIZE / 16 | ||
| + | mov es, ax | ||
| + | jmp loop | ||
| + | |||
| + | bad: | ||
| + | int3 | ||
| + | mov ax, es | ||
| + | mov bx, cs | ||
| + | sub ax, bx | ||
| + | call disp_ax_hex | ||
| + | mov dl, ':' | ||
| + | mov ah, 02h | ||
| + | int 21h | ||
| + | mov ax, di | ||
| + | call disp_ax_hex | ||
| + | mov dl, 13 | ||
| + | mov ah, 02h | ||
| + | int 21h | ||
| + | mov dl, 10 | ||
| + | mov ah, 02h | ||
| + | int 21h | ||
| + | mov ax, 4CFFh | ||
| + | int 21h | ||
| + | |||
| + | good: | ||
| + | mov ax, 4C00h | ||
| + | int 21h | ||
| + | |||
| + | disp_ax_hex: | ||
| + | xchg al, ah | ||
| + | call .al | ||
| + | xchg al, ah | ||
| + | .al: | ||
| + | push cx | ||
| + | mov cl, 4 | ||
| + | rol al, cl | ||
| + | call .nybble | ||
| + | rol al, cl | ||
| + | pop cx | ||
| + | .nybble: | ||
| + | push ax | ||
| + | push dx | ||
| + | and al, 15 | ||
| + | add al, ' | ||
| + | cmp al, ' | ||
| + | jbe .got | ||
| + | add al, 7 | ||
| + | .got: | ||
| + | xchg dx, ax | ||
| + | mov ah, 02h | ||
| + | int 21h | ||
| + | pop dx | ||
| + | pop ax | ||
| + | retn | ||
| + | |||
| + | REPEAT equ 64 | ||
| + | BLOCKSIZE equ 1024 | ||
| + | |||
| + | section FIRST align=16 | ||
| + | %assign id 0 | ||
| + | %rep REPEAT | ||
| + | section SECTION%+id align=16 | ||
| + | times BLOCKSIZE db 26h | ||
| + | |||
| + | %assign id id+1 | ||
| + | %endrep | ||
| + | |||
| + | section STACK stack | ||
| + | resb 512</ | ||
| + | |||
| + | |||
| + | ===== lDebug and loader updates ===== | ||
| + | |||
| + | ==== DRDOS9 load protocol ==== | ||
| + | |||
| + | I examined the boot sector loader and parts of the drbios.sys initial loader to figure out their interaction. [[https:// | ||
| + | |||
| + | The boot sector loader stores an LBA flag at 7DFDh (last byte before the 0AA55h boot sector signature), which it uselessly writes to initialise despite being part of the boot sector loaded by the prior stage. | ||
| + | |||
| + | The loader uses 186+ instructions. | ||
| + | |||
| + | The loader also seems to load the FAT to 07E00h, which it doesn' | ||
| + | |||
| + | If the drbios.sys file isn't found, the loader enters a '' | ||
| + | |||
| + | The next stage is entered with DS = ES = CS = 70h, SS:SP = 60h:FFFEh, DL = boot unit, AX = 0060h. However, it appears to be sufficient to pass CS:IP = 70h:0 and DL = boot unit, so that's what lDebug currently does. | ||
| + | |||
| + | The next stage (first kernel file in lDebug terminology) may be as small as 1024 Bytes (1469 Bytes seen), but the boot sector loader will load 8 consecutive sectors. The next stage relocates itself using a 1000h word move, so it seems to expect it may be as large as 8 KiB. lDebug allows to load between 1024 and 8192 Bytes in this revision of the debugger. | ||
| + | |||
| + | |||
| + | ==== Debugging the early kernel load ==== | ||
| + | |||
| + | The drbios.sys stage unconditionally relocates to 8000h:0 (512 KiB) and sets up SS:SP = 8000h:FFFEh (just below 576 KiB). This would corrupt parts of the bootloaded resident debugger leading to funny results such as a loaded quit.eld not reacting to the QUIT command and EXT commands failing to run Extensions for lDebug with some quote related error. | ||
| + | |||
| + | Something that's good (for us) is that the kernel at no point initialises the int 1 and int 3 vectors in the IVT. So the resident debugger is easily accessible by running breakpoints in a small file (eg int3.com) after the kernel has finished booting. | ||
| + | |||
| + | To avoid the debugger corruption, a workaround was to load another instance of the debugger (resident at a lower address) then run the DOS under that. But that's not very satisfactory. So I [[https:// | ||
| + | |||
| + | |||
| + | ==== News update ==== | ||
| + | |||
| + | Last changeset to the debugger [[https:// | ||
| + | |||
| + | |||
| + | ===== How to find the bug ===== | ||
| + | |||
| + | I tried loading another instance of the debugger, in application mode, while running the kernel under the bootloaded mode of the debugger with the memory starting at 512 KiB reserved. To do so, I set up a diskette image like so: | ||
| + | |||
| + | '' | ||
| + | |||
| + | I added the following [[https:// | ||
| + | |||
| + | < | ||
| + | @r ysf or= 4000 | ||
| + | ext extlib.eld alias.eld install #2048 | ||
| + | alias add res rc.execute boot protocol ldos loader.com . move bottom\; ext nreserve.eld install 8000\; move top\; boot protocol ldos cmdline=0 ldebug.com\; | ||
| + | alias add dr9 boot protocol drdos9 hda1 . | ||
| + | alias add seri install serial timer | ||
| + | ext extlib.eld dm.eld install | ||
| + | ext extlib.eld rcexec.eld install | ||
| + | rc.abort | ||
| + | ext extlib.eld quit.eld install | ||
| + | install quickrun | ||
| + | goto :eof | ||
| + | |||
| + | @: | ||
| + | @: | ||
| + | @?version | ||
| + | @install getinput</ | ||
| + | |||
| + | The '' | ||
| + | |||
| + | Running the following allows to trace DOS's EXEC call: | ||
| + | |||
| + | < | ||
| + | dr9 | ||
| + | g | ||
| + | a:int3 | ||
| + | bp at ptr ri21p when ah == 4B | ||
| + | g | ||
| + | a:ldebug /b | ||
| + | seri</ | ||
| + | |||
| + | In my tests I actually tried loading lCDebugX as lcdebugx.com or the shim executable cdebugx.com (without iniload). However, I don't expect the difference to matter. At first I would '' | ||
| + | |||
| + | Eventually I redid the setup, then trace-proceeded with repeated '' | ||
| + | |||
| + | That led me to write the testlong test case program, proving that the DOS doesn' | ||
| + | |||
| + | {{tag> | ||
| + | |||
| + | |||
| + | ~~DISCUSSION~~ | ||