alexfru / SmallerC

Simple C compiler
BSD 2-Clause "Simplified" License
1.4k stars 156 forks source link

DOS: 32-bit code segments with 16-bit entry point #23

Closed lighth7015 closed 5 years ago

lighth7015 commented 5 years ago

is it possible to create an MZ EXE with both 16-bit and 32-bit code segments? (for example, you have a stub that enters Protected Mode, calls into your main application to do some work, then returns to DOS) without DPMI?

lighth7015 commented 5 years ago

I think -seg32 will work with a 16-bit .obj file that contains a hybrid 16 and 32-bit _start.

alexfru commented 5 years ago

Linking mixed 16-bit and 32-bit code is problematic in general and I advise against it.

If all you need is a non-DPMI protected mode program, you can create your own stub similar to mine (but w/o DPMI) and tell the compiler/linker to use it (there's an option for that).

What are you trying to achieve with this anyway?

lighth7015 commented 5 years ago

I am writing a software package (similar to Windows 3) on DOS that is going to read and execute ELF as its native executable format.

alexfru commented 5 years ago

Then just roll your own stub for your "win.exe".

Use himem.sys, BIOS, CMOS memory to find/allocate memory above 1MB (and don't forget about A20).

Load the rest of "win.exe" in chunks of several KB and use himem.sys, BIOS (int 15h, fxn 87h, AFAIR) or unreal mode to copy them above 1MB.

You may also set up graphics mode using VESA/VBE BIOS before switching to protected mode.

Interrupt handling and v86 setup may be done outside of the stub. However, you may want to have some v86-supporting 16-bit code in the stub (as well as I/O buffers (below 1MB) for I/O through DOS and/or BIOS).

alexfru commented 5 years ago

@lighth7015 Was your question answered or is there anything else here?

lighth7015 commented 5 years ago

Since it's ELF, yeah; my team and I will work on writing display (based on your VESA code), as well as storage device drivers.

Anyway, just to confirm- we supply our own stub, which combined with (essentially copy /b startup.exe stub.exe+pmode.bin) our 16-bit MZ stub, an MZ relocation record, and 32-bit executable code (essentially a flat 32-bit a.out binary); if I am understanding what is happening correctly?

alexfru commented 5 years ago

Not sure what any of this has to do with ELF other than you eventually writing code to handle it.

Also, I don't know what you mean by MZ relocation record. Smaller C's DPMI .EXEs have this structure, 3 things glued together: dpstub.exe (without any relocation records) + 64-bytes of extra info (e.g. stack and heap sizes) + a.out (with relocation records).

The 64-bytes are referred to in dpstub.asm (look up stub_info) and smlrl.c (look up stubInfo[16]).

You can keep or change this three-piece structure. DOS won't care about anything in the .EXE beyond what's described in its MZ header and it loads only the first part, dpstub.exe, leaving to it the rest of the work.

lighth7015 commented 5 years ago

Ah, okay. So it's the a.out that has the relocation records, not the EXE. This has all been tremendously helpful! And I was just saying "Since ELF is our format", referring back to my earlier comment that we aren't going to use PE.

alexfru commented 5 years ago

PE is actually simpler than ELF in terms of basic relocation (at least when not considering dynamic linking), even simpler than a.out.

You could follow the comments in dpstub.asm to see what's happening.