What is this FreeDOS kernel loader found on the âW3x4NTFSâ disk image?
I've found an io.sys file which looks like an uncompressed FreeDOS kernel (kernel.sys), prefixed with a 4048-byte loader starting with MZ, containing the following ASCII strings:
What is this loader? Is it part of some famous software? Is the source available? Why is it better to use this loader than booting kernel.sys directly?
I've found it on http://www.multiboot.ru/download/ . Click the link W3x4NTFS, it downloads w3l.zip, uncompress it, then uncompress w3l.gz, then copy it out mcopy -i w3l ::io.sys ./.
It is (my) lDOS iniload. At offset 1020 (1024 - 4) you should find an "lDXX" signature, the "XX" likely containing "FD" for an fdkernpl + FreeDOS kernel payload. I was not aware of any use of this in the wild so thanks for the pointer!
As to why it is better, it can be loaded as a number of different kernels including MS-DOS v6 io.sys and MS-DOS v7 io.sys:
The lDOS iniload stage can be loaded as the (first) load file for any of the sector load protocols described in this manual:
(The io.sys file in that disk image is dated as 2023-04-02 so it seems like it won't be any later revision of iniload and fdkernpl than 2023-02-28's. This does not yet support loading as an EDR-DOS drbio.sys file.)
lDOS's iniload can load as an MZ application or as a DOS device driver as well, either with a single (dual-mode or triple-mode) image or using a second payload that's used as the MZ image while the first image is only used for booting as a kernel. It is likely that the use you found is kernel-only however, in which case the MZ header should encode an impossible size so the DOS loader will abort if you try to load it. (Eg rename the io.sys to test.com and try running it.)
The reason for still including an MZ header for a kernel-only file is that, as pointed out by user3840170 in a comment, the MS-DOS v7 load protocol requires it:
Further, at offset 2046 we include an "MS" signature although this doesn't seem to be needed by anyone:
You can find these error strings you listed, mostly after call error instructions, in the sources:
The iniload stage contains the "initial loader" stage of the kernel which can run with as little as 1536 bytes loaded from the start of the file. This is called ibmload or msload for MS-DOS, but does not exist for the original FreeDOS load protocol (as in this case the entire kernel file is loaded). Quoting a comment from me:
No, msload is the "Non-Contiguous IBMBIO Loader (MSLOAD)", I wrote about it some on my blog. The msload stage is the initial loader stored in the first 1536 bytes of io.sys. (The MS-DOS v7 boot load protocol changed the msload length to 2048 bytes.) The boot sector has to load msload to 00700h for both v6 + v7. In v4 its start cluster must be cluster 2.
The kernel/first payload to iniload is stored at a 16-byte (paragraph) boundary after the code of the iniload stage (unlike MS-DOS v4 msload which didn't align its msbio as the payload of msload):
I went and recreated the exact revisions of ldosboot, lmacros, and scanptab in https://pushbx.org/ecm/test/20250104.txt
So it is the same code in fdkernpl.asm and iniload.asm as revision a4823a5555d4 of 2023-01-10. I also found the oldest revision that matches the code:
That's revision 9c885120139d of 2022-12-29.
prefixed with a 4048-byte loader starting with MZ, containing the following ASCII strings:
Actually part of fdkernpl is located after its payload (contents of kernel.sys) which is why I specified the count=$((0x13378)) to the dd command that I listed to extract kernel.sys. It was easy to find the exact length because fdkernpl's payload is aligned to a paragraph boundary at the end using align 16, db 38 so in this case we get a number of repeated '&' text literals after the exact payload end.