|
|
1.1 root 1: /*
2: * execute.c -- Attempt to run a loadable file.
3: * Returns only if it fails.
4: * Takes the inode for the file to be loaded, and a command line vector
5: * to pass in.
6: */
7: #include <coff.h>
8: #include <canon.h>
9: #include <sys/typed.h>
10: #include <sys/inode.h>
11: #include <sys/dir.h>
12:
13: #ifdef TEST
14: #define MAIN
15: #endif
16: #include "tboot.h"
17: #undef MAIN
18:
19: void
20: execute( argv )
21: char *argv[];
22: {
23: extern uint16 myds; /* My data segment, from Setup.s. */
24: char *cmd_name; /* File to boot. */
25: char response[BLOCK]; /* Command typed at prompt. */
26:
27: struct inode imageinode; /* Inode structure for the boot image. */
28: ino_t imageinum; /* inode number of the boot image. */
29:
30: uint16 filemagic; /* Magic number from file. */
31: struct load_segment imagetable[MAX_SEGS]; /* How to load a file. */
32: struct load_segment *cur_segment; /* Pointer for walking imagetable. */
33:
34: uint16 data_seg; /* Data segment register for image. */
35:
36: uint16 boot_value; /* Offset of boot_gift into
37: * load image data segment.
38: */
39:
40: uint16 cpu_type; /* What kind of CPU are we running on? */
41:
42: cpu_type = get_cpu_type();
43:
44: /*
45: * Extract the command name from the command line.
46: */
47: cmd_name = argv[0];
48:
49: /*
50: * Try to find the requested file.
51: */
52: if (0 == (imageinum = namei(cmd_name)) ) {
53: puts("No such file: ");
54: puts(cmd_name);
55: puts("\r\n");
56: return;
57: }
58:
59: /*
60: * Try to open that inode.
61: */
62: if (0 == iopen(&imageinode, imageinum)) {
63: puts("Can't open ");
64: puts(cmd_name);
65: puts(". Type \"dir\" for a list of files.\r\n");
66: return;
67: }
68:
69: /*
70: * Read the magic number.
71: */
72: iread(&imageinode, &filemagic, (fsize_t) 0, (uint16) sizeof (uint16));
73: canint(filemagic); /* Harmless on 80386. */
74:
75: /*
76: * COFF executables probably should not be run on anything less
77: * than a 386.
78: */
79: if (ISCOFF(filemagic)) {
80: if (!IS_I386(cpu_type)) {
81: puts("This is not a 386 or 486--");
82: puts("you probably can not run this file.\r\n");
83: puts("Continue anyway? ");
84: gets(response, BLOCK);
85: if ( 0 != strcmp(response, "y") &&
86: 0 != strcmp(response, "Y") &&
87: 0 != strcmp(response, "yes") &&
88: 0 != strcmp(response, "YES") &&
89: 0 != strcmp(response, "sure") ) {
90: return;
91: }
92: }
93: } /* Is it COFF? */
94:
95: /*
96: * If we haven't explicitly set sys_base, default it based
97: * on the type of file we are loading.
98: */
99: if (!sys_base_set) {
100: VERBOSE( {puts("Assuming default sys_base.\r\n");} );
101: sys_base = object_sys_base(filemagic);
102: }
103:
104: /*
105: * Try to read the information we need to actually load this file.
106: */
107: if (! object2load(filemagic, &imageinode, imagetable, &data_seg)) {
108: puts("File ");
109: puts(cmd_name);
110: puts(" is not an executable.\r\n");
111: puts(".\r\n");
112: return;
113: }
114:
115: /* ASSERTION: imageinode and imagetable describe a valid executable. */
116:
117: VERBOSE( {
118: puts("OK! Loading ");
119: puts(cmd_name);
120: puts("...\r\n");
121: } );
122:
123: /* Now actually load everything into memory. */
124: for (cur_segment = &imagetable[0]; cur_segment->valid; ++cur_segment) {
125: puts(cur_segment->message);
126:
127: /*
128: * Make sure that this segment will not overwrite tboot.
129: */
130: if (seg_too_high(cur_segment)) {
131: puts("This segment would overwrite tboot.\r\n");
132: puts("Aborting...\r\n");
133: return;
134: }
135: ifread(&imageinode,
136: cur_segment->load_toseg,
137: cur_segment->load_tooffset,
138: cur_segment->load_offset,
139: cur_segment->load_length);
140: }
141:
142: /* Does the program we just loaded want more info? */
143:
144: /* Look up the variable "boot_gift" in the image. */
145: puts("\r\nPlease wait...\r\n");
146: boot_value = object_nlist(filemagic, cmd_name, "boot_gift");
147:
148:
149: if (0 != boot_value) {
150: VERBOSE( { puts("Preparing arguments.\r\n"); } );
151: /* Yes, this program can accept more information. */
152: prepare_gift(data_seg, boot_value, argv);
153: }
154:
155: VERBOSE( {
156: puts("\r\nRunning ");
157: puts(cmd_name);
158: puts("...\r\n");
159: } );
160:
161: if (want_monitor) {
162: puts("The kernel is ready to run.\r\n");
163: puts("SYS_START: ");
164: print16(SYS_START);
165: puts(" sys_base: ");
166: print16(sys_base);
167: puts(" data_seg: ");
168: print16(data_seg);
169: puts("\r\n");
170: monitor();
171: }
172:
173: /* Run the image (the kernel). */
174: gotoker(SYS_START, sys_base, data_seg);
175: } /* execute() */
176:
177:
178: /*
179: * int
180: * seg_too_high( struct load_segment *lseg )
181: * Check to see if a segment will overlap tboot.
182: * Returns TRUE if it would, FALSE otherwise.
183: */
184: int
185: seg_too_high( lseg )
186: struct load_segment *lseg;
187: {
188: uint32 load_top;
189:
190: load_top = (lseg->load_toseg << 4) +
191: lseg->load_tooffset +
192: lseg->load_length;
193:
194: #if 0
195: printf("%x:%x + %lx = %lx\n",
196: lseg->load_toseg,
197: lseg->load_tooffset,
198: lseg->load_length,
199: load_top);
200: #endif /* 0 */
201:
202: return ( load_top >= ( ((uint32) RBOOTS) << 4 ) );
203: } /* seg_too_high() */
204:
205: #ifdef TEST
206: int boot_gift; /* Lie. */
207: main()
208: {
209: struct load_segment lseg;
210:
211: lseg.load_toseg = 0x200;
212: lseg.load_tooffset = 0;
213: lseg.load_length = 128L*1024L;
214:
215: if (seg_too_high(&lseg)) {
216: printf("BAD: %x:%x + %lx > %lx.\n",
217: lseg.load_toseg,
218: lseg.load_tooffset,
219: lseg.load_length,
220: (((unsigned long)RBOOTS) << 4) );
221:
222: } else {
223: printf("OK: %x:%x + %lx < %lx.\n",
224: lseg.load_toseg,
225: lseg.load_tooffset,
226: lseg.load_length,
227: (((unsigned long)RBOOTS) << 4) );
228:
229: }
230: } /* main() */
231: #endif /* TEST */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.