vsta

Check-in [d3f575178f]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Attic obsolete files
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | master | trunk
Files: files | file ages | folders
SHA3-256:d3f575178f56e1ff015d7e5c0d83c10bb45fe52b9d77511224b960ff19a06176
User & Date: vandys 2001-10-22 14:56:54
Context
2001-10-22
14:57
Leave note behind. check-in: 2bcb9fc9f1 user: vandys tags: master, trunk
14:56
Attic obsolete files check-in: d3f575178f user: vandys tags: master, trunk
14:54
Add installation rules for CVS controlled lib/etc files. check-in: 6c91745487 user: vandys tags: master, trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Deleted vsta/src/boot.386/boot.h.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#ifndef _BOOT_H
#define _BOOT_H
/*
 * boot.h
 *	Some defines for the boot loader
 */
#include <stdio.h>

typedef unsigned long ulong;
typedef unsigned int uint;
typedef unsigned short ushort;
typedef unsigned char uchar;
#define K (1024)
#define M ((long)K*(long)K)
#define NBPG (4*K)

/*
 * This is what lives at the front of a djgpp-generated i386 binary
 * which we'll load as the VSTa kernel.
 */
struct aouthdr {
	ushort a_magic;		/* Magic # */
	uchar a_mach;		/* Machine type */
	uchar a_flags;		/* Misc. flags */
	ulong a_text;		/* Length of text, in bytes */
	ulong a_data;		/* Length of data, in bytes */
	ulong a_bss;		/* Length of BSS, in bytes */
	ulong a_syms;		/* Length of symbol info--not used */
	ulong a_entry;		/* Start address */
	ulong a_trsize;		/* Reloc info--not used */
	ulong a_drsize;
};

/*
 * VSTa must boot 413 formats--keeping everything page aligned and
 * data and text distinct is very helpful.
 */
#define VMAGIC 0413

extern void *lptr(ulong), setup_ptes(ulong), setup_gdt(void),
	load_image(FILE *);
extern void move_jump(void);
extern void load_kernel(struct aouthdr *, FILE *);
extern void lread(FILE *, ulong, ulong);
extern void lbzero(ulong, ulong), lbcopy(ulong, ulong, ulong);
extern ulong linptr(void *);
extern void set_args32(void);

#endif /* _BOOT_H */
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


































































































Deleted vsta/src/boot.386/gdt.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
/*
 * gdt.c
 *	Stuff for setting up a boot GDT
 */
#include <memory.h>
#include <dos.h>
#include "boot.h"
#include "gdt.h"
#include "../mach/tss.h"

extern ulong cr3, topbase, pbase, basemem, bootbase;
extern struct aouthdr hdr;

struct tss *tss16,	/* Scratch task for boot 16-bit mode */
	*tss32;		/* 32-bit task to switch to 32-bit world */
ulong *args32;		/* Array of argument words on 32-bit stack */
ulong gdt;		/* Linear address of GDT */
struct gdtdesc {
	ushort g_len;
	ulong g_off;
} gdtdesc;

/*
 * setup_gdt()
 *	Set up GDT, and associated data structures
 */
void
setup_gdt(void)
{
	struct tss *t;
	struct seg *s;
	ulong l;
	struct seg *g;

	/*
	 * Carve data structures out of high memory
	 */
	tss32 = lptr(topbase -= sizeof(struct tss));
	memset(tss32, '\0', sizeof(struct tss));
	tss16 = lptr(topbase -= sizeof(struct tss));
	memset(tss16, '\0', sizeof(struct tss));
	gdt = (topbase -= (sizeof(struct seg) * NGDT));
	g = lptr(gdt);
	memset(g, '\0', sizeof(struct seg) * NGDT);
	gdtdesc.g_len = sizeof(struct seg) * NGDT;
	gdtdesc.g_off = gdt;
	topbase &= ~(NBPG-1);	/* Leave page aligned */

	/*
	 * Create 32-bit TSS
	 */
	t = tss32;
	t->cr3 = cr3;
	t->eip = hdr.a_entry;
	t->cs = GDT_KTEXT;
	t->ss0 = t->ds = t->es = t->ss = GDT_KDATA;

	/*
	 * Leave arguments on stack of 32-bit task
	 */
	l = topbase;
	topbase -= NBPG;
	l -= (4 * sizeof(ulong));
	t->esp0 = t->esp = l;
	args32 = lptr(l);

	/*
	 * Null entry--actually, zero whole thing to be safe
	 */
	memset(g, '\0', NGDT * sizeof(struct seg));

	/*
	 * Kernel data--all 32 bits allowed, read-write
	 */
	s = &g[GDTIDX(GDT_KDATA)];
	s->seg_limit0 = 0xFFFF;
	s->seg_base0 = 0;
	s->seg_base1 = 0;
	s->seg_type = T_MEMRW;
	s->seg_dpl = 0;
	s->seg_p = 1;
	s->seg_limit1 = 0xF;
	s->seg_32 = 1;
	s->seg_gran = 1;
	s->seg_base2 = 0;

	/*
	 * Kernel text--low 2 gig, execute and read
	 */
	s = &g[GDTIDX(GDT_KTEXT)];
	*s = g[GDTIDX(GDT_KDATA)];
	s->seg_type = T_MEMXR;
	s->seg_limit1 = 0x7;

	/*
	 * 32-bit boot TSS descriptor
	 */
	l = linptr(tss32);
	s = &g[GDTIDX(GDT_BOOT32)];
	s->seg_limit0 = sizeof(struct tss)-1;
	s->seg_base0 = l & 0xFFFF;
	s->seg_base1 = (l >> 16) & 0xFF;
	s->seg_type = T_TSS;
	s->seg_dpl = 0;
	s->seg_p = 1;
	s->seg_limit1 = 0;
	s->seg_32 = 0;
	s->seg_gran = 0;
	s->seg_base2 = (l >> 24) & 0xFF;

	/*
	 * 16-bit scratch TSS
	 */
	l = linptr(tss16);
	s = &g[GDTIDX(GDT_TMPTSS)];
	*s = g[GDTIDX(GDT_BOOT32)];
	s->seg_base0 = l & 0xFFFF;
	s->seg_base1 = (l >> 16) & 0xFF;
	s->seg_base2 = (l >> 24) & 0xFF;
}


/*
 * Ports in NVRAM from PC
 */
#define BASELO 0x15	/* Base memory registers */
#define BASEHI 0x16
#define EXTLO 0x17	/*  ...extended */
#define EXTHI 0x18

/*
 * nvread()
 *	Read a value from NVRAM
 */
static
nvread(int port)
{
	outportb(0x70, port & 0xFF);
	return(inportb(0x71) & 0xFF);
}

/*
 * set_args32()
 *	Set args to boot task now that all memory use is known
 */
void
set_args32(void)
{
	int base, ext;

	/*
	 * Get base and extended memory in K.  We'll scale to longword
	 * byte units as we assign to the array.
	 */
	base = nvread(BASELO) | (nvread(BASEHI) << 8);
	ext = nvread(EXTLO) | (nvread(EXTHI) << 8);

	args32[0] = (pbase - basemem) / NBPG;
	args32[1] = 1024L * ext;
	args32[2] = 1024L * base;
	args32[3] = (bootbase - basemem) / NBPG;
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




































































































































































































































































































































Deleted vsta/src/boot.386/gdt.h.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
#ifndef _GDT_H
#define _GDT_H
/*
 * gdt.h
 *	Definitions for Global Descriptor Table and friends
 */

/*
 * Memory and System segment descriptors
 */
struct seg {
	uint seg_limit0 : 16;	/* Size 0 */
	uint seg_base0 : 16;	/* Base 0 */
	uint seg_base1 : 8;	/* Base 1 */
	uint seg_type : 5;	/* Type */
	uint seg_dpl : 2;	/* Priv level */
	uint seg_p : 1;		/* Present */
	uint seg_limit1 : 4;	/* Size 1 */
	uint seg_pad0 : 2;	/* Pad */
	uint seg_32 : 1;	/* 32-bit size? */
	uint seg_gran : 1;	/* Granularity (pages if set) */
	uint seg_base2 : 8;	/* Base 2 */
};

/*
 * Gate descriptors.
 */
struct gate {
	uint gd_off0 : 16;	/* Offset 0 */
	uint gd_sel : 16;	/* Selector */
	uint gd_stkwds : 5;	/* Stack words to copy (always 0) */
	uint gd_pad0 : 3;	/* Pad */
	uint gd_type : 5;	/* Type */
	uint gd_dpl : 2;	/* Priv level */
	uint gd_p : 1;		/* Present */
	uint gd_off1 : 16;	/* Offset 1 */
};

/* Segment types used in VSTa */
#define	T_INVAL		 0	/* Invalid */
#define	T_LDT		 2	/* LDT */
#define	T_TASK		 5	/* Task gate (struct gate) */
#define	T_TSS		 9	/* TSS */
#define	T_CALL		12	/* Call gate (struct gate) */
#define	T_INTR		14	/* Interrupt gate (struct gate) */
#define	T_TRAP		15	/* Trap gate (struct gate) */
#define	T_MEMRO		16	/* Read only */
#define	T_MEMRW		18	/* Read+write */
#define	T_MEMX		24	/* Execute only */
#define	T_MEMXR		26	/* Execute+read */

/*
 * Linear memory description for lgdt and lidt instructions
 */
struct linmem {
	ushort l_len;	/* Length */
	ulong l_addr;	/* Address  */
};

/*
 * Layout of Global Descriptor Table
 */
#define GDT_NULL (0 << 3)
#define GDT_KDATA (1 << 3)
#define GDT_KTEXT (2 << 3)
#define GDT_BOOT32 (3 << 3)
#define GDT_TMPTSS (4 << 3)
#define NGDT 5			/* # entries in GDT */

/*
 * Convert descriptor value into GDT index
 */
#define GDTIDX(sel) ((unsigned)(sel) >> 3)

#endif /* _GDT_H */
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






















































































































































Deleted vsta/src/boot.386/load.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
/*
 * load.c
 *	Routines for loading memory from files
 */
#include <stdlib.h>
#include "boot.h"

extern ulong pbase;

/*
 * load_kernel()
 *	Load kernel from its a.out image
 */
void
load_kernel(struct aouthdr *h, FILE *fp)
{
	/*
	 * The first page is invalid to catch null pointers
	 */
	pbase += NBPG;

	/*
	 * Read in the a.out header and text section
	 */
	(void) rewind(fp);
	lread(fp, pbase, sizeof(struct aouthdr));
	pbase += sizeof(struct aouthdr);
	lread(fp, pbase, h->a_text);
	pbase += h->a_text;
	printf(" %ld", h->a_text); fflush(stdout);

	/*
	 * Read in data
	 */
	lread(fp, pbase, h->a_data);
	pbase += h->a_data;
	printf("+%ld", h->a_data); fflush(stdout);

	/*
	 * Zero out BSS
	 */
	lbzero(pbase, h->a_bss);
	pbase += h->a_bss;
	printf("+%ld\n", h->a_bss);
}

/*
 * load_image()
 *	Load a boot task image into the data area
 *
 * This is different than the kernel task load; these images are
 * not in runnable format.  They're simply copied end-to-end after
 * the _end location of the kernel task.
 */
void
load_image(FILE *fp)
{
	struct aouthdr *h;

	/*
	 * Get header
	 */
	h = lptr(pbase);
	lread(fp, pbase, sizeof(struct aouthdr));
	pbase += sizeof(struct aouthdr);
	lread(fp, pbase, h->a_text);
	pbase += h->a_text;
	lread(fp, pbase, h->a_data);
	pbase += h->a_data;
	lbzero(pbase, h->a_bss);
	pbase += h->a_bss;
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
















































































































































Deleted vsta/src/boot.386/main.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
/*
 * main.c
 *	Main routine to pull everything together
 */
#include <stdlib.h>
#include <alloc.h>
#include <string.h>
#include <memory.h>
#include "boot.h"

extern ushort move_jump_len;	/* Assembly support */
extern void move_jump(void), run_move_jump(void);

typedef void (*voidfun)();
voidfun move_jump_hi;		/* Copy of move_jump in high mem */

FILE *aout, *bootf, *fp;	/* Files we load via */
ulong basemem;			/* Start of kernel image */
ulong pbase;			/* Actual physical address (linear, 32-bit) */
ulong topbase;			/* Address of top (640K downward) memory */
struct aouthdr hdr;		/* Header of kernel image */
ulong stackmem;			/* A temp stack for purposes of booting */
ushort stackseg;		/* And a segment pointer for it */
ulong bootbase;			/* Where boot tasks loaded */

/*
 * basename()
 *	Return pointer to just base part of path
 */
static char *
basename(char *path)
{
	char *p;

	p = strrchr(path, '/');
	if (p) {
		return(p+1);
	}
	p = strrchr(path, '\\');
	if (p) {
		return(p+1);
	}
	return(path);
}

/*
 * round_pbase()
 *	Round up base to next page boundary
 */
static void
round_pbase(void)
{
	/*
	 * Point to next chunk of memory, rounded up to a page
	 */
	pbase = (pbase + (NBPG-1)) & ~(NBPG-1);
}

/*
 * try_setarg()
 *	Try to insert the given argument into the area reserved for it
 *
 * This is a very basic argument line being passed; we don't honor
 * quotes or any such nonsense.
 *
 * The layout of the memory area is:
 *	32 bytes a.out header
 *	8 bytes of a jump around the argument patch area to L1
 *	argc
 *	0xDEADBEEF (argv[0])
 *	MAXARG << 16 | ARGSIZE (argv[1])
 *	argv[2]
 *	...
 *	arg string area (ARGSIZE bytes)
 * L1:	<rest of text segment>
 */
static void
try_setarg(ulong base, char *p)
{
	char *buf = p;
	int maxnarg, maxarg, argoff, len = strlen(p)+1;
	ulong *lp;
	const ulong headsz = 32L+8L;

	/*
	 * Skip a.out header and initial jmp instruction.  Keep a pointer
	 * to the memory.
	 */
	base = base + headsz;
	lp = lptr(base);

	/*
	 * Verify that the dummy area exists; otherwise we're trying
	 * to pass boot arguments to a process not linked for it.
	 */
	if (lp[1] != 0xDEADBEEFL) {
		printf("\nError: not linked for boot arguments.\n");
		exit(1);
	}

	/*
	 * Extract maxnarg and maxarg.  Calculate offset to base
	 * of string area.
	 */
	maxnarg = lp[2] & 0xFFFF;
	maxarg = (lp[2] >> 16) & 0xFFFF;
	argoff = sizeof(long) + maxnarg*sizeof(long);

	/*
	 * Make sure it'll fit
	 */
	if (len > maxarg) {
		printf("\nError: arguments too long.\n");
		exit(1);
	}

	/*
	 * Fill in argv while advancing argc.  In the process,
	 * convert our argument strings to null-termination.
	 */
	while (p) {
		if (lp[0] >= maxnarg) {
			printf("\nError: too many arguments.\n");
			exit(1);
		}
		lp[lp[0]+1] =		/* argv */
			(p-buf)+argoff+NBPG+headsz;
		p = strchr(p, ' ');
		if (p) {
			*p++ = '\0';
		}
		lp[0] += 1;		/* argc */
	}

	/*
	 * Blast the buffer down into place, just beyond argc+argv
	 */
	memcpy(&lp[maxnarg+1], buf, len);
}

main(int argc, char **argv)
{
	char *bootname;
	char buf[128];
	extern int cputype(void);

	if (argc < 2) {
		printf("Usage is: boot <image> [ <boot-list-file> ]\n");
		exit(1);
	}
	if (cputype()) {
		printf("Must be in REAL mode (not V86) to boot VSTa\n");
		exit(1);
	}

	/*
	 * Get actual executable file
	 */
	if ((aout = fopen(argv[1], "rb")) == NULL) {
		perror(argv[1]);
		exit(1);
	}
	if (fread(&hdr, sizeof(hdr), 1, aout) != 1) {
		printf("Read of a.out header in %s failed.\n", argv[1]);
		exit(1);
	}

	/*
	 * Get list of process images we will append
	 */
	if (argc > 2) {
		bootname = argv[2];
	} else {
		bootname = "boot.lst";
	}
	if ((bootf = fopen(bootname, "r")) == NULL) {
		perror(bootname);
		exit(1);
	}
	(void)getc(bootf); rewind(bootf);

	/*
	 * For now, open to any old file; this is just to get its buffering
	 * into memory.  We start carving out chunks of memory beyond
	 * sbrk(0) pretty soon, and it would be inconvenient for another
	 * malloc() to conflict with this.
	 */
	fp = fopen(bootname, "rb");
	(void)getc(fp);

	/*
	 * Start at next page up
	 */
	pbase = linptr(sbrk(0));
	round_pbase();
	basemem = pbase;

	/*
	 * Start top pointer at top of memory
	 */
	topbase = 640L * K;

	/*
	 * Carve out a stack
	 */
	stackmem = (topbase -= NBPG);
	stackseg = stackmem >> 4;

	/*
	 * Set up page tables and GDT
	 */
	setup_ptes(hdr.a_text);
	setup_gdt();

	/*
	 * Get kernel image
	 */
	printf("Boot %s:", basename(argv[1])); fflush(stdout);
	round_pbase();
	load_kernel(&hdr, aout);
	fclose(aout);

	/*
	 * Add on each boot task image
	 */
	printf("Tasks:");
	round_pbase();
	bootbase = pbase;
	while (fgets(buf, sizeof(buf)-1, bootf)) {
		char *p, *q;
		ulong opbase;

		/*
		 * Convert to null-termination
		 */
		buf[strlen(buf)-1] = '\0';

		/*
		 * Skip blank lines and comments
		 */
		if (!buf[0] || (buf[0] == '#')) {
			continue;
		}

		/*
		 * Record arg string, if any
		 */
		p = strchr(buf, ' ');
		if (p) {
			*p = '\0';
		}

		/*
		 * Load file
		 */
		if (freopen(buf, "rb", fp) == NULL) {
			perror(buf);
			exit(1);
		}
		printf(" %s", basename(buf)); fflush(stdout);

		/*
		 * Round to next page, load file
		 */
		round_pbase();
		opbase = pbase;
		load_image(fp);

		/*
		 * Skip any leading path on the command name.
		 * Saves precious bytes in the a.out argument
		 * area.
		 */
		q = strrchr(buf, '/');
		if (q) {
			++q;
		} else {
			q = buf;
		}

		/*
		 * If there are args, restore space
		 */
		if (p) {
			*p = ' ';
		}

		/*
		 * Insert command name and args into boot file image
		 */
		try_setarg(opbase, q);
	}
	fclose(fp);
	fclose(bootf);

	/*
	 * Copy the boot code up to high memory
	 */
	topbase -= move_jump_len;
	lbcopy(linptr(move_jump), topbase, (ulong)move_jump_len);
	move_jump_hi = lptr(topbase);

	/*
	 * Fill in arguments to 32-bit task.  We couldn't do this until
	 * the last bit of memory use was known.
	 */
	set_args32();

	/*
	 * Finally, atomically (so far as *we* can tell) move the
	 * image down to 0 and jump to its entry point.
	 */
	printf("\nLaunch at 0x%lx\n", hdr.a_entry);
	run_move_jump();
	return(0);
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
























































































































































































































































































































































































































































































































































































































































Deleted vsta/src/boot.386/makefile.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
OBJS= main.obj ptes.obj seg.obj load.obj gdt.obj move.obj util.obj
CC= bcc
AS= tasm
CFLAGS= -v -g1 -ml
ASFLAGS= -mx

.c.obj:
	$(CC) $(CFLAGS) -c $*.c
.asm.obj:
	$(AS) $(ASFLAGS) $*.asm

boot: $(OBJS)
	$(CC) $(CFLAGS) -eboot.exe $(OBJS)

clean:
	rm -f *.obj

clobber: clean
	rm -f boot

install:

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<












































Deleted vsta/src/boot.386/move.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
;
; move.asm
;	Move a block of memory and jump to it
;
; Tricky, since this code will get tromped unless it is moved
; up out of the way.  This then requires some care since the code
; isn't actually running at the address for which it was assembled.
;
; Once running, this code pulls what it needs from the rest of the
; DOS boot loader, then disables interrupt and bulk-copies the
; stuff down to a base address of 0 (actually 4K, since 32-bit tasks
; are generated with an invalid addr 0).  Finally, it launches the
; 32-bit code through the boot 32-bit task gate.
;
; This isn't easy, but that's why we get the big bucks, right? :-)
;

;
; Prologue
;
	DOSSEG
	.MODEL  large
	.386p

;
; Constants
;
SEGMUL=8		; Shift for segment index (multiply)
GDT_KDATA=(1 * SEGMUL)	;  ...kernel data segment
GDT_BOOT32=(3 * SEGMUL)	;  ...32-bit task segment
GDT_TMPTSS=(4 * SEGMUL)	;  ...temptask segment
CR_PROT=1		; CR0 bit to turn on protected mode
CR_PG=80000000h		;  ...to turn on paging

;
; Data
;
	.DATA
	EXTRN	_gdtdesc : FWORD
	EXTRN	_cr3 : DWORD
	EXTRN	_stackseg : WORD
	EXTRN	_basemem : DWORD
	EXTRN	_pbase : DWORD

;
; Our routine.  NB, it's not running where it was assembled.
;
	.CODE
	PUBLIC  _move_jump
_move_jump	PROC

	;
	; Can point GDT to our buffer now, since it isn't used until
	; we go into protected mode.
	;
	mov	ax,SEG _gdtdesc
	mov	ds,ax
	lgdt	_gdtdesc

	;
	; Also take care of CR3 now
	;
	mov	ax,SEG _cr3
	mov	ds,ax
	mov	eax,_cr3
	mov	cr3,eax

	;
	; We're not ready for interrupts yet, so mask them.
	;
	cli

	;
	; Move to our high stack
	;
	mov	ax,SEG _stackseg
	mov	ds,ax
	mov	ax,_stackseg
	mov	ss,ax
	mov	sp,1000h

	;
	; Load what we'll need into registers
	;	edx - address loaded at
	;	ecx - length in bytes
	;
	mov	ax,SEG _basemem
	mov	ds,ax
	mov	edx,_basemem
	mov	ax,SEG _pbase
	mov	ds,ax
	mov	ecx,_pbase
	sub	ecx,edx

	;
	; Skip first page, which is intended for the null-dereference
	; catching page.
	;
	sub	ecx,1000h
	add	edx,1000h

	;
	; Copy memory image down to 0 base.  Screwball because we're
	; copying more than 64K, so we do paragraphs at a time and
	; advance the segment value.  Sigh.
	;
	shr	edx,4		; Convert pointer to segment
	mov	es,dx
	mov	ax,100h		; Page 0 + one page (null deref)
	mov	ds,ax
	xor	bx,bx		; Constant 0 pointer
l5:	mov	eax,es:0(bx)	; Move a paragraph
	mov	ds:0(bx),eax
	mov	eax,es:4(bx)
	mov	ds:4(bx),eax
	mov	eax,es:8(bx)
	mov	ds:8(bx),eax
	mov	eax,es:12(bx)
	mov	ds:12(bx),eax
	sub	ecx,16		; Decrement count by paragraph
	jle	short l6
	mov	ax,ds		; Advance DS and ES
	inc	ax
	mov	ds,ax
	mov	ax,es
	inc	ax
	mov	es,ax
	jmp	short l5
l6:

	;
	; Switch to paging, protected mode.
	;
	mov	eax,cr0
	or	eax,(CR_PROT or CR_PG)
	mov	cr0,eax
	jmp	short l1
l1:	nop			; Now in protected mode

	;
	; Set "current task"
	;
	mov	ax,GDT_TMPTSS
	nop
	ltr	ax
	jmp	short l4
l4:	nop

	;
	; Jump into our 32-bit task
	;
	db	0EAh		; 16-bit long jump, off 0, seg BOOT32
	dw	0
	dw	GDT_BOOT32

	;
	; No return
	;
l2:	jmp	l2

	;
	; Record size of this routine
	PUBLIC	_move_jump_len
_move_jump_len=$-_move_jump

_move_jump	ENDP

;
; This is needed because Borland C is too hoity-toity to let
; me cast a pointer to a function pointer without bitching.
;
	.DATA
	EXTRN	_move_jump_hi : DWORD
	.CODE
	PUBLIC  _run_move_jump
_run_move_jump	PROC
	jmp	[_move_jump_hi]
_run_move_jump	ENDP

	END
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<








































































































































































































































































































































































Deleted vsta/src/boot.386/ptes.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
/*
 * ptes.c
 *	Code for setting up PTE structures
 */
#include <memory.h>
#include "boot.h"
#include "../mach/pte.h"

extern ulong topbase;
ulong cr3;
ulong *l1, *txt, *dat;

/*
 * setup_ptes()
 *	Set up a boot mapping of PTEs
 *
 * Build the structures in topmem coming downwards.  This keeps them
 * intact during the mass relocation of the kernel image down to 0.
 */
void
setup_ptes(ulong text_size)
{
	ulong x, datpage;

	/*
	 * Get root page table.  Set all slots to 0 (invalid)
	 */
	cr3 = (topbase -= NBPG);
	l1 = lptr(cr3);
	memset(l1, '\0', NBPG);

	/*
	 * First slot is for text--0..4MB.  Map it P==V.
	 */
	l1[0] = (topbase -= NBPG) | PT_V|PT_W;
	txt = lptr(topbase);
	for (x = 0L; x < NPTPG; x += 1L) {
		txt[x] = (x << PT_PFNSHIFT) | PT_V|PT_W;
	}

	/*
	 * Second slot is data.  It starts at next free page above
	 * text and goes up for full page's worth.  Text size doesn't
	 * include size of a.out header, though it's there in memory.
	 * It also doesn't include the NULL page at vaddr 0.
	 */
	l1[1] = (topbase -= NBPG) | PT_V|PT_W;
	dat = lptr(topbase);
	text_size += sizeof(struct aouthdr);
	datpage = (text_size + (NBPG-1)) & ~(NBPG-1);
	datpage /= NBPG;
	datpage += 1;
	for (x = 0L; x < NPTPG; x += 1L) {
		dat[x] = ((x+datpage) << PT_PFNSHIFT) | PT_V|PT_W;
	}
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
















































































































Deleted vsta/src/boot.386/readme.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
The code in this directory is historical.  VSTa now boots using
GRUB, complying with the Multiboot standard.  The code here was
used to bootload VSTa from a loader running as a DOS real mode
application.  It no longer works, since VSTa is now organized
to be loaded above the 1 meg boundary.

In some future release, this directory will go away.

Andy Valencia 5/15/2000

For now, you can use RCS to take a look at the old source files.
One step closer to deleting this....

Andy Valencia 1/17/2001
<
<
<
<
<
<
<
<
<
<
<
<
<
<




























Deleted vsta/src/boot.386/seg.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
/*
 * seg.c
 *	Utilities for straddling the 16- and 32-bit worlds
 */
#include <stdlib.h>
#include <memory.h>
#include "boot.h"

/*
 * lptr()
 *	Convert long linear pointer to a usable long segmented pointer
 */
void *
lptr(ulong l)
{
	ulong l2;

	l2 = l >> 4;
	if (l2 & ~0xFFFF) {
		printf("Error: memory overflow");
		exit(1);
	}
	return (void *)((l2 << 16) | (l & 0xF));
}

/*
 * linptr()
 *	Convert segment pointer to linear
 */
ulong
linptr(void *p)
{
	ulong l;

	l = (ulong)p;
	return (
		(l & 0xFFFF) +		/* Offset */
		((l >> 16) << 4));	/* Seg, converted to bytes */
}

/*
 * lread()
 *	Do reads into a long pointer space
 *
 * Breaks I/O into chunks which DOS will accept.  Aborts program on
 * I/O error.
 */
void
lread(FILE *fp, ulong paddr, ulong nbyte)
{
	char *p;
	int x, count;

	while (nbyte > 0L) {
		p = lptr(paddr);
		if (nbyte > 16*K) {
			count = 16*K;
		} else {
			count = nbyte;
		}
		x = fread(p, sizeof(char), count, fp);
		if (x != count) {
			printf("I/O error during read: want %d got %d\n",
				count, x);
			exit(1);
		}
		nbyte -= count;
		paddr += count;
	}
}

/*
 * lbzero()
 *	Zero memory using linear pointer
 */
void
lbzero(ulong paddr, ulong nbyte)
{
	uint count;
	char *p;

	while (nbyte > 0L) {
		if (nbyte > 16*K) {
			count = 16*K;
		} else {
			count = nbyte;
		}
		p = lptr(paddr);
		memset(p, '\0', count);
		nbyte -= count;
		paddr += count;
	}
}

/*
 * lbcopy()
 *	Copy memory using linear pointers
 */
void
lbcopy(ulong src, ulong dest, ulong nbyte)
{
	uint count;
	char *srcp, *destp;

	while (nbyte > 0L) {
		if (nbyte > 16*K) {
			count = 16*K;
		} else {
			count = nbyte;
		}
		srcp = lptr(src);
		destp = lptr(dest);
		memcpy(destp, srcp, count);
		src += count;
		dest += count;
		nbyte -= count;
	}
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<












































































































































































































































Deleted vsta/src/boot.386/util.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
;
; cputype.asm
;	Routine for determining CPU type
;
; I got this via djgpp, apparently it's originally in the i486
; manual.  I don't have one of those, so I have to trust djgpp
; for the lineage.
;

;
; Prologue
;
	DOSSEG
	.MODEL  large
	.386p

	.CODE
	
	PUBLIC	_cputype	; from Intel 80486 reference manual
_cputype PROC
	pushf
	pop	bx
	and	bx,0fffh
	push	bx
	popf
	pushf
	pop	ax
	and	ax,0f000h
	cmp	ax,0f000h
	jz	bad_cpu
	or	bx,0f000h
	push	bx
	popf
	pushf
	pop	ax
	and	ax,0f000h
	jz	bad_cpu

	smsw	ax
	test	ax,1
	jnz	bad_mode
	mov	ax,0
	ret

bad_mode:
	mov	ax,2
	ret

bad_cpu:
	mov	ax,1
	ret

_cputype ENDP

	END
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<