|
|
1.1 ! root 1: /* builtin.c -- builtin routines for tboot. ! 2: * ! 3: * Add new ones by adding a check for them in interpret(). ! 4: * ! 5: * La Monte H. Yarroll <[email protected]>, September 1991 ! 6: */ ! 7: ! 8: #include <string.h> ! 9: #include <sys/inode.h> ! 10: #include <sys/ino.h> ! 11: #include <sys/dir.h> ! 12: #include <sys/typed.h> ! 13: #include "tboot.h" ! 14: ! 15: extern int slow_flag; /* Slow down pacifier. */ ! 16: extern int feet_flag; /* Enable pacifier footprints. */ ! 17: ! 18: /* ! 19: * If possible, execute "command". ! 20: * Return "true" if the command exists, "false" otherwise. ! 21: */ ! 22: int ! 23: interpret(command) ! 24: char *command; ! 25: { ! 26: char *argv[MAX_TOKENS+1]; /* Command vector. */ ! 27: char *current_token; ! 28: char *cmd_name; /* The first token of the command line. */ ! 29: int i; ! 30: ! 31: current_token = strtok(command, WS); ! 32: cmd_name = current_token; /* Extract the command. */ ! 33: /* Build the command argv. */ ! 34: for (i = 0; NULL != current_token && i < MAX_TOKENS; ++i) { ! 35: argv[i] = current_token; ! 36: current_token = strtok(NULL, WS); ! 37: } ! 38: ! 39: argv[i] = NULL; /* NULL terminate the list of pointers. */ ! 40: ! 41: /* ! 42: * If we ran out of token slots, print a warning. ! 43: */ ! 44: if (i >= MAX_TOKENS) { ! 45: puts("\r\nWarning: truncating line to:\r\n"); ! 46: for (i = 0 ; i < MAX_TOKENS; ++i) { ! 47: puts(argv[i]); ! 48: puts(" "); ! 49: } ! 50: puts("\r\n"); ! 51: } ! 52: ! 53: /* ! 54: * Interpret the lexed command. ! 55: */ ! 56: if (0 == strcmp(cmd_name, "info")) { ! 57: dpb(); ! 58: return(TRUE); ! 59: } else if ((0 == strcmp(cmd_name, "dir")) || ! 60: (0 == strcmp(cmd_name, "ls") ) || ! 61: (0 == strcmp(cmd_name, "lc") )) { ! 62: dir(); ! 63: return(TRUE); ! 64: } else if ( (0 == strncmp(cmd_name, "sys_base", strlen("sys_base")) ) || ! 65: (0 == strncmp(cmd_name, "scs", strlen("scs")) ) ! 66: ) { ! 67: char lbuf[5]; /* 5 == strlen("0000") + 1 */ ! 68: if (NULL != strchr(cmd_name, '=')){ ! 69: puts("Setting sys_base.\r\n"); ! 70: sys_base_set = (1==1); ! 71: sys_base = (uint16) ! 72: basetoi(1 + strchr(cmd_name, '='), 16); ! 73: } ! 74: if (!sys_base_set) { ! 75: puts("sys_base will default to "); ! 76: print16(DEF_SYS_BASE); ! 77: puts(" for l.out executables,\r\n and to "); ! 78: print16(COFF_SYS_BASE); ! 79: puts(" for COFF executables.\r\n"); ! 80: } else { ! 81: puts("sys_base is "); ! 82: itobase((uint16) sys_base, lbuf, 16); ! 83: puts(lbuf); ! 84: puts("\r\n"); ! 85: } ! 86: return(TRUE); ! 87: } else if (0 == strcmp(cmd_name, "monitor")) { ! 88: monitor(); ! 89: return(TRUE); ! 90: } else if (0 == strcmp(cmd_name, "cpu_type")) { ! 91: switch(get_cpu_type()) { ! 92: case 0: puts("less than 286\r\n"); break; ! 93: case 1: puts("286\r\n"); break; ! 94: case 2: puts("386 or better\r\n"); break; ! 95: } ! 96: return(TRUE); ! 97: } else if ((0 == strcmp(cmd_name, "verbose"))) { ! 98: verbose_flag = TRUE; ! 99: puts("Verbose mode.\r\n"); ! 100: return(TRUE); ! 101: } else if ((0 == strcmp(cmd_name, "terse"))) { ! 102: verbose_flag = FALSE; ! 103: puts("Terse mode.\r\n"); ! 104: return(TRUE); ! 105: } else if ((0 == strcmp(cmd_name, "slow"))) { ! 106: slow_flag = TRUE; ! 107: puts("Slow pacifier mode.\r\n"); ! 108: return(TRUE); ! 109: } else if ((0 == strcmp(cmd_name, "fast"))) { ! 110: slow_flag = FALSE; ! 111: puts("Normal pacifier mode.\r\n"); ! 112: return(TRUE); ! 113: } else if ((0 == strcmp(cmd_name, "feet"))) { ! 114: feet_flag = TRUE; ! 115: puts("Pacifier footprints enabled.\r\n"); ! 116: return(TRUE); ! 117: } else if ((0 == strcmp(cmd_name, "nofeet"))) { ! 118: feet_flag = FALSE; ! 119: puts("No pacifier footprints.\r\n"); ! 120: return(TRUE); ! 121: } else if ((0 == strcmp(cmd_name, "gift"))) { ! 122: dump_gift(); /* Dump boot_gift. */ ! 123: return(TRUE); ! 124: } else if ((0 == strcmp(cmd_name, "test"))) { ! 125: if (arg_exist("arg")) { ! 126: puts("Yep.\r\n"); ! 127: } else { ! 128: puts("Nope.\r\n"); ! 129: } ! 130: return(TRUE); ! 131: } else if ((0 == strcmp(cmd_name, "help")) || ! 132: (0 == strcmp(cmd_name, "?")) ) { ! 133: puts("info Print disk information.\r\n"); ! 134: puts("dir|ls List contents of /.\r\n"); ! 135: puts("?|help Print this list.\r\n"); ! 136: return(TRUE); ! 137: } else if (0 == strcmp(cmd_name, "mon_on")) { ! 138: want_monitor = TRUE; ! 139: puts("Mini-monitor will autoinvoke before running kernel.\r\n"); ! 140: return(TRUE); ! 141: } else if (0 == strcmp(cmd_name, "??")) { ! 142: puts("UNSUPPORTED FEATURES: (don't call :-)\r\n"); ! 143: puts("sys_base|scs Print current load segment.\r\n"); ! 144: puts("sys_base=tttt Set current load segment to 0xtttt.\r\n"); ! 145: puts("test arg Test for the presence of arg.\r\n"); ! 146: puts("monitor Invoke the mini-monitor.\r\n"); ! 147: puts("mon_on Autoinvoke the mini-monitor before kernel.\r\n"); ! 148: puts("cpu_type print the cpu type.\r\n"); ! 149: puts("verbose Be verbose.\r\n"); ! 150: puts("terse Do not be verbose.\r\n"); ! 151: puts("slow Slow down pacifier.\r\n"); ! 152: puts("fast Normal speed pacifier.\r\n"); ! 153: puts("feet Enable pacifier footprints.\r\n"); ! 154: puts("nofeet Disable pacifier footprints.\r\n"); ! 155: return(TRUE); ! 156: } else { ! 157: execute(argv); ! 158: return(FALSE); ! 159: } ! 160: puts("\r\nUNREACHABLE CODE IN interpret() EXECUTED.\r\n"); ! 161: puts("There is probably a missing return() in interpret().\r\n"); ! 162: return(FALSE); /* This should be an unreachable line. */ ! 163: } /* interpret() */ ! 164: ! 165: /* Display the BIOS parameters loaded up by the startup code. */ ! 166: void ! 167: dpb() ! 168: { ! 169: char buffer[BLOCK]; ! 170: int i; ! 171: int num_of_drives; ! 172: struct reg r; ! 173: ! 174: ! 175: num_of_drives = get_num_of_drives(); ! 176: ! 177: puts("\r\nHere are the BIOS parameters for your hard drive"); ! 178: if (num_of_drives > 1) { putchar('s'); } ! 179: puts(".\r\n"); ! 180: puts("Write them down for use during installation.\r\n"); ! 181: ! 182: for (i = 0; i < num_of_drives; ++i) { ! 183: ! 184: r.r_ax = DISK_PARAMS; ! 185: r.r_dx = HARD_DRIVE + i; ! 186: ! 187: intcall(&r, &r, DISKINT); /* Ask the BIOS. */ ! 188: ! 189: puts("Drive "); ! 190: itobase((uint16) i, buffer, 10); ! 191: puts(buffer); ! 192: ! 193: ! 194: /* ch is the lower 8 bits of number of cylinders. ! 195: * The high two bits of cl are the top two bits of ! 196: * 10 bit number of cylinders. ! 197: * ! 198: * The cylinder count is actually 1 short. ! 199: */ ! 200: puts(": Cylinders="); ! 201: itobase((uint16) ( ! 202: ((LOW(r.r_cx) >> 6) * 256) + /* Top two bits... */ ! 203: (HIGH(r.r_cx) + 1) ! 204: ), ! 205: buffer, 10); ! 206: puts(buffer); ! 207: ! 208: /* The head count is actually 1 short. */ ! 209: puts(" Heads="); ! 210: itobase((uint16) HIGH(r.r_dx) + 1, buffer, 10); ! 211: puts(buffer); ! 212: ! 213: /* Only the lower 6 bits of cl are the sectors per track. */ ! 214: puts(" Sectors per track="); ! 215: itobase((uint16) SIXBITS & LOW(r.r_cx), buffer, 10); ! 216: puts(buffer); ! 217: ! 218: puts("\r\n"); ! 219: } /* for i = 0 to num_of_drives - 1 */ ! 220: } /* dpb() */ ! 221: ! 222: ! 223: /* ! 224: * Ask the BIOS how many drives are attached. ! 225: * ! 226: * If the BIOS says more than MAX_DRIVES, ask again. Some BIOS's ! 227: * seem to answer this question differently on alternate calls, or ! 228: * on the first call. ! 229: */ ! 230: #define MAX_DRIVES 8 ! 231: int get_num_of_drives() ! 232: { ! 233: struct reg r; ! 234: ! 235: r.r_ax = DISK_PARAMS; /* ah = 8 -- Return disk drive parameters */ ! 236: r.r_dx = HARD_DRIVE; /* set bit 7 of dl for hard disk info. */ ! 237: ! 238: intcall(&r, &r, DISKINT); ! 239: ! 240: if ( verbose_flag ) { ! 241: /* ! 242: * Print out the flags for debugging purposes. ! 243: */ ! 244: puts("flags: "); ! 245: print16(r.r_flags); ! 246: puts(" "); ! 247: } ! 248: ! 249: if (LOW(r.r_dx) > MAX_DRIVES) { ! 250: puts("I doubt that you have 0x"); ! 251: print8(LOW(r.r_dx)); ! 252: puts(" disk drives. Let's try again.\r\n"); ! 253: ! 254: r.r_ax = DISK_PARAMS; /* ah = 8 -- Return disk drive parameters */ ! 255: r.r_dx = HARD_DRIVE; /* set bit 7 of dl for hard disk info. */ ! 256: ! 257: intcall(&r, &r, DISKINT); ! 258: ! 259: if (LOW(r.r_dx) <= MAX_DRIVES) { ! 260: puts(" That's better!"); ! 261: } ! 262: } ! 263: ! 264: if (LOW(r.r_dx) > MAX_DRIVES) { ! 265: puts("I simply don't believe that you have 0x"); ! 266: print8(LOW(r.r_dx)); ! 267: puts(" disk drives.\r\n"); ! 268: puts("I'm going to guess that you have 0x"); ! 269: print8(MAX_DRIVES); ! 270: puts(" drives.\r\n"); ! 271: ! 272: return(MAX_DRIVES); ! 273: } else { ! 274: return(LOW(r.r_dx)); ! 275: } ! 276: } /* get_num_of_drives() */ ! 277: ! 278: /* Create a listing of file names in /. */ ! 279: void ! 280: dir() ! 281: { ! 282: int i, j; ! 283: char outbuff[LINESIZE]; /* Buffer for outputing numbers. */ ! 284: struct inode rootinode; ! 285: struct direct dirent; ! 286: ! 287: /* Open "/" and print out the direct block file entries. */ ! 288: iopen(&rootinode, (ino_t) 2); ! 289: ! 290: /* Read each directory entry one at a time. */ ! 291: /* We are careful to print an even fraction of 80 for each ! 292: * directory entry, so that everything lines up nicely. ! 293: */ ! 294: for (i = 0; i < rootinode.i_size; i += sizeof(struct direct)) { ! 295: ! 296: iread(&rootinode, (char *) &dirent, (fsize_t) i, ! 297: (uint16) sizeof(struct direct)); ! 298: ! 299: /* If the entry is not active, skip the rest. */ ! 300: if (0 == dirent.d_ino) { ! 301: continue; ! 302: } ! 303: ! 304: /* NUL terminate the name. */ ! 305: strncpy(outbuff, ! 306: dirent.d_name, ! 307: DIRSIZ); ! 308: outbuff[DIRSIZ] = '\0'; ! 309: /* Print the file name. */ ! 310: puts(outbuff); ! 311: for (j = DIRSIZ - strlen(outbuff); j > 0; --j) { ! 312: putchar(' '); ! 313: } ! 314: puts(" :"); /* Bring total to 16 (80/5) characters. */ ! 315: } ! 316: puts("\r\n"); ! 317: ! 318: } /* dir() */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.