|
|
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.