[comp.os.minix] MS-DOS->MINIX cross-compilation

ddl@husc6.UUCP (02/02/87)

	There has been some interest in using split i & d (and using
cross-compilers in general) with MINIX.  Here are the tools I use to
cross-compile from MS-DOS to OS.  I haven't seen MINIX, but OS uses
a standard a.out header and if MINIX uses something similar this
program should be applicable.  The general idea is that you compile
your C program with MSC 4.0 (or maybe even 3.0) and link it with crt0.obj.
Note that crt0.obj should have DOSSEG.EXE run on it else you will have
to specify the /DOSSEG switch to link.
	Once you've compiled and linked and eliminated references
to MSC library routines that you shouldn't really be using, run
exetoos with standard input your .EXE file and standard output your
a.out-like file.  If you specify the -t flag, exetoos will tell you about
your .EXE file.  (The -f and -o flags set other bits in the header and
would have no meaning for MINIX.)
	For those of you who don't know, MSC is Microsoft's C compiler.
It seems to produce good code and has only a few optimization bugs...
In any case, if you can't run PC/IX it just might do.  On a completely
different subject, I wrote a simple-minded MS-DOS emulator for my OS.
It doesn't support FCB calls; would anyone care to give me an idea of how
many useful programs out there use them?  Please send mail.

				Dan Lanciani
				ddl@harvard.*
-----------------------------------------------------------------------
#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create the files:
#	exetoos.c
#	exec.h
#	crt0.asm
# This archive created: Mon Feb  2 02:29:18 1987
export PATH; PATH=/bin:$PATH
if test -f 'exetoos.c'
then
	echo shar: will not over-write existing file "'exetoos.c'"
else
cat << \SHAR_EOF > 'exetoos.c'
/* (c) Copyright 1987 Daniel D. Lanciani */
/* Permission is granted to copy for any noncommercial, nonmilitary */
/* purpose provided this notice remains. */

/* exetoos - convert an MS-DOS format .EXE file to a.out-like format */
/* Depends on special crt0.obj which provides relocation information */
/* necessary to split text and data space. */

#include <stdio.h>
#include "exec.h"

/* OS a.out header */
struct osexec {
	long a_magic;
	unsigned long a_text;
	unsigned long a_data;
	unsigned long a_bss;
	unsigned long a_syms;
	unsigned long a_entry;
	unsigned long a_trsize;
	unsigned long a_srsize;
} osexec;

#define MFSIZE 0x10000	/* Process is well-behaved. */
#define MOLD 0x20000	/* Process needs old signal system. */
#define SMAGIC 0411	/* Split i & d */

char buf[1024];
struct exec exec;

main(argc, argv)
char **argv;
{
	register int i;
	unsigned x, y;

	setmode(0, 0x8000);
	read(0, &exec, sizeof(exec));
	if(argc > 1 && !strcmp(argv[1], "-t")) {
		printf("magic = %x\n", exec.exec_magic);
		printf("isr = %x\n", exec.exec_isr);
		printf("size = %x\n", exec.exec_size);
		printf("nrel = %x\n", exec.exec_nrel);
		printf("hsize = %x\n", exec.exec_hsize);
		printf("min = %x\n", exec.exec_min);
		printf("max = %x\n", exec.exec_max);
		printf("ss = %x\n", exec.exec_ss);
		printf("sp = %x\n", exec.exec_sp);
		printf("cksum = %x\n", exec.exec_cksum);
		printf("pc = %x\n", exec.exec_pc);
		printf("cs = %x\n", exec.exec_cs);
		printf("orel = %x\n", exec.exec_orel);
		printf("ovno = %x\n", exec.exec_ovno);
		for(i = 0; i < exec.exec_nrel; i++) {
			lseek(0, (long)exec.exec_orel + 4 * i, 0);
			read(0, &x, 2);
			read(0, &y, 2);
			printf("Relocation at: %x:%x, ", y, x);
			lseek(0, 16L * (exec.exec_hsize + y) + x, 0);
			read(0, &x, 2);
			printf("%x\n", x);
		}
		exit(0);
	}

/* Begin consistency checks.  If you see one of these messages, you probably */
/* didn't link with the right crt0.obj or used MSC's memory allocator. */

	if(exec.exec_magic != 0x5a4d) {
		fprintf(stderr, "Bad magic number %x\n", exec.exec_magic);
		exit(1);
	}
	if(exec.exec_cs) {
		fprintf(stderr, "Non-zero cs %x\n", exec.exec_cs);
		exit(1);
	}
	if(exec.exec_nrel != 1) {
		fprintf(stderr, "Relocations = %d\n", exec.exec_nrel);
		exit(1);
	}

/* Now locate the reference to DGROUP in crt0.obj to split text and data. */

	lseek(0, (long)exec.exec_orel, 0);
	read(0, &x, 2);
	read(0, &y, 2);
	if(y) {
		fprintf(stderr, "Relocation not in cs %x\n", y);
		exit(1);
	}
	lseek(0, 16L * (exec.exec_hsize + y) + x, 0);
	read(0, &x, 2);
	setmode(1, 0x8000);
	osexec.a_magic = SMAGIC;
loop:
	if(argc > 2 && !strcmp(argv[1], "-f")) {
		osexec.a_magic |= MFSIZE;
		osexec.a_magic |= ((long)((255 + atoi(argv[2])) / 256)) << 24;
		argc -= 2;
		argv += 2;
		goto loop;
	}
	if(argc > 1 && !strcmp(argv[1], "-o")) {
		osexec.a_magic |= MOLD;
		argc--;
		argv++;
		goto loop;
	}
	osexec.a_text = 16L * x;
	osexec.a_data = 512L * exec.exec_size - 16L * (exec.exec_hsize + x);

/* Next line is, unfortunately, correct. */

	if(exec.exec_isr)
		osexec.a_data -= (512 - exec.exec_isr);
	osexec.a_bss = 16L * exec.exec_min;
	osexec.a_entry = exec.exec_pc;
	lseek(0, 16L * exec.exec_hsize, 0);
	write(1, &osexec, sizeof(osexec));
	while((x = read(0, buf, sizeof(buf))) > 0)
		write(1, buf, x);
}
SHAR_EOF
fi # end of overwriting check
if test -f 'exec.h'
then
	echo shar: will not over-write existing file "'exec.h'"
else
cat << \SHAR_EOF > 'exec.h'
/* MS-DOS .EXE header */

struct exec {
	unsigned exec_magic;	/* 0x4d, 0x5a signature */
	unsigned exec_isr;	/* image size remainder (mod 512) */
	unsigned exec_size;	/* file size in pages (512) */
	unsigned exec_nrel;	/* number of relocation items */
	unsigned exec_hsize;	/* header size in paragraphs */
	unsigned exec_min;	/* minimum extra paragraphs */
	unsigned exec_max;	/* maximum extra paragraphs */
	unsigned exec_ss;	/* stack segment */
	unsigned exec_sp;	/* stack offset */
	unsigned exec_cksum;	/* word checksum of entire file */
	unsigned exec_pc;	/* initial pc */
	unsigned exec_cs;	/* code segment */
	unsigned exec_orel;	/* offset of relocation table */
	unsigned exec_ovno;	/* overlay number */
} exec;
SHAR_EOF
fi # end of overwriting check
if test -f 'crt0.asm'
then
	echo shar: will not over-write existing file "'crt0.asm'"
else
cat << \SHAR_EOF > 'crt0.asm'
;
; crt0.asm - masm crt0/ml; & dosseg crt0.obj
;
; NOTE:  The data segments really do need to be paragraph aligned if
; we are to have any hope of splitting i & d space later.
;
_TEXT	segment byte public 'CODE'
	extrn	_main:near
_TEXT	ends
_DATA	segment para public 'DATA'
	public	__acrtused
	__acrtused = 1
_DATA	ends
CONST	segment para public 'CONST'
CONST	ends
_BSS	segment para public 'BSS'
_BSS	ends
DGROUP	group CONST, _BSS, _DATA
	assume cs:_TEXT, ds:DGROUP, ss:DGROUP, es:DGROUP
_TEXT	segment
start:	mov	ax, DGROUP
	cld
	call	_main
	jmp	start
_TEXT	ends
	end	start
SHAR_EOF
fi # end of overwriting check
#	End of shell archive
exit 0

thomps@gitpyr.UUCP (02/03/87)

In article <1150@husc6.UUCP>, ddl@husc6.UUCP (Dan Lanciani) writes:
> 
> 	There has been some interest in using split i & d (and using
> cross-compilers in general) with MINIX.  Here are the tools I use to
> cross-compile from MS-DOS to OS.  I haven't seen MINIX, but OS uses
> a standard a.out header and if MINIX uses something similar this
> program should be applicable.  

Dr. Tanenbaum  discusses cross-compiling in one of the appendices to his book

He discusses problems with libraries and indicates that the software that

comes with MINIX provides a utility to help with conversion. It does not appear

that MINIX uses "standard" a.out file formats but I am not sure.


-- 
Ken Thompson  Phone : (404) 894-7089
Georgia Tech Research Institute
Georgia Insitute of Technology, Atlanta Georgia, 30332
...!{akgua,allegra,amd,hplabs,ihnp4,seismo,ut-ngp}!gatech!gitpyr!thomps

ast@botter.cs.vu.nl (Andy Tanenbaum) (02/04/87)

The standard MINIX distribution contains a program dos2out that does
the same thing as Dan Lanciani's conversion program.  Mine has only
been tested with the Computer Innovations C86 compiler, so if you
are interested in MS-DOS->MINIX, hang onto his as well in case mine
doesn't work with your MS-DOS compiler.

Andy Tanenbaum