pts / owtarget16

targeting ELKS and other 8086 operating systems with the OpenWatcom C compiler
5 stars 0 forks source link

Nice project for ELKS! #1

Open ghaerr opened 1 month ago

ghaerr commented 1 month ago

Hello @pts,

Nice work! Its pretty cool what you've done here, converting OS/2 v1.1 NE binaries to ELKS a.out format and then executing the system calls directly using OpenWatcom ASM. As someone who appreciates tiny binaries, I must say these are even smaller than the smallest executables we've produced at ELKS (in our case due to the inclusion of some libc syscall infrastructure).

At ELKS, we're using the ia16-elf-gcc compiler almost exclusively now for compiling the kernel, libc and all applications. Some enhancements were done allowing for compiling, linking and loading a far text (.fartext) section that is limited to 128k, but other than that effectively runs like medium model.

Some ELKS developers are interested in the large data model, mostly for far data pointers but possibly for larger text segments. I was wondering whether you are familiar with what OpenWatcom might produce within the OS/2 v1.1 NE header when 1) large code and data are used - does this produce relocation entries that must be converted? and 2) whether multiple data segments are produced in the case of the data segment exceeding 64k. I'm thinking your prog16cv could be possibly enhanced to be able to use OpenWatcom's large model for ELKS, along with a possible kernel loader enhancement.

Depending on the nature of the OS/2 NE header for large model, I suppose it is possible that the Watcom compiler suite could in fact be compiled for ELKS itself, with some C library work and prog16cv or kernel enhancements. That would be very neat! (It did take over 45 minutes to compile OW on macOS though for my testing so this could be arduous).

I am also potentially interested in either converting Watcom C library to produce the appropriate ELKS system calls (very close to Linux 2.0), or instead just compiling the ELKS C library with OpenWatcom. Of course, this is a bit complicated due to the multiple models and calling sequences required.

On another note, the ELKS v1 a.out header now uses the chmem (previously a_total) field slightly differently than v0 and your prog16cv do: the stack size is specified in the high order word, and the heap size in the low order word. If 0, a default of 4K is used for each. The field does not include the data segment size, only the extra heap value desired above data+bss; thus higher or lower values than the default of 4K can be specified. If the heap value is set to 0xFFFF, all available heap is used, otherwise the executable loading can be rejected if a specified heap is not available. I'm happy to produce a PR for this if you'd like.

Thank you!

pts commented 1 month ago

Feel free to create a PR for filling the chmem header for ELKS v1 correctly. You may want to add a command-line flag to prog16cv.c, and you may want to specify the command-line flag (optionally) in compile.sh.

Unfortunately I don't have much wisdom to share with you about the medium or large models. I'm not an OS/2 1.x user or programmer, and I don't know much more about the NE file format than what was required for writing prog16cv.c. What I know is that the Watcom C compiler and the linker support the usual 8086 memory models, and the compiler also supports both near and far pointers.

If you want to create smaller executables, ignore the usual libc (typically it's bloated), and use (write?) a libc with smaller bloat and controllable overhead. I've done this when targeting the DOS 8086 small model in https://github.com/pts/dosmc.

The OpenWatcom C compiler is an optimizing compiler (it can optimize for speed or size), but it's a much simpler and smaller C compiler than GCC. The primary reason why the OpenWatcom C compiler can generate small machine code output is that its default register-based calling convention (__watcall) uses fewer bytes for stack manipulation in function calls.