|
|
1.1 ! root 1: /* tboot.c -- tertiary boot ! 2: * This is invoked by the secondary boot to do all the things we can't ! 3: * do in just 512 bytes. ! 4: * ! 5: * Includes an interpreter for builtin commands. Just type "info" or "dir" ! 6: * to get disk information, or a directory listing of "/". ! 7: * ! 8: * Can load an image up to 1 gigabyte in length. Segments can be as ! 9: * big as the whole file. ! 10: * ! 11: * La Monte H. Yarroll <[email protected]>, September 1991 ! 12: */ ! 13: ! 14: #include <canon.h> ! 15: #include <sys/types.h> ! 16: #include <sys/dir.h> ! 17: #include <sys/ino.h> ! 18: #include <sys/inode.h> ! 19: #include <l.out.h> ! 20: #include <filehdr.h> ! 21: #include <string.h> ! 22: #include <sys/typed.h> ! 23: ! 24: #define MAIN ! 25: #include "tboot.h" ! 26: #undef MAIN ! 27: ! 28: ! 29: /* Potentially communicated information from an earlier tboot. */ ! 30: TYPED_SPACE(boot_gift, 8192, T_FIFO_SIC); /* Static In-Core FIFO. */ ! 31: ! 32: main() ! 33: { ! 34: extern uint16 myds; /* My data segment, from Setup.s. */ ! 35: char cmd_line[BLOCK]; /* Command typed at prompt. */ ! 36: char cmd_name[BLOCK] = "autoboot"; /* File to boot. */ ! 37: ! 38: ino_t imageinum; /* inode number of the boot image. */ ! 39: struct inode imageinode; /* Inode structure for the boot image. */ ! 40: int imageok; /* Flag to identify usable executables. */ ! 41: ! 42: uint16 filemagic; /* Magic number from file. */ ! 43: struct load_segment imagetable[MAX_SEGS]; /* How to load a file. */ ! 44: struct load_segment *cur_segment; /* Pointer for walking imagetable. */ ! 45: ! 46: uint16 data_seg; /* Data segment register for image. */ ! 47: ! 48: uint16 boot_value; /* Offset of boot_gift into ! 49: * load image data segment. ! 50: */ ! 51: ! 52: ! 53: /* Load the kernel here. */ ! 54: sys_base = DEF_SYS_BASE; ! 55: sys_base_set = FALSE; ! 56: ! 57: want_monitor = FALSE; /* Don't invoke mini-monitor before execution. */ ! 58: ! 59: puts("\r\nCOHERENT Tertiary boot Version 1.0.7\r\n"); ! 60: /* Look for a valid executable. */ ! 61: do { ! 62: /* Find the file in the file system. */ ! 63: while ((ino_t) 0 == (imageinum = namei(cmd_name))){ ! 64: ! 65: /* Ask for another name. ! 66: * Don't generate a message for name "". ! 67: */ ! 68: if (cmd_name[0] != '\0' && ! 69: (0 == strcmp(cmd_name, "autoboot"))) { ! 70: puts("\r\nCan't find \""); ! 71: puts(cmd_name); ! 72: puts("\". Type \"dir\" for a list of files.\r\n"); ! 73: puts("If installing COHERENT, please type \"begin\".\r\n"); ! 74: } ! 75: ! 76: /* Fetch new file names, executing them ! 77: * if they are builtins. Terminate loop ! 78: * when we want to try another file name. ! 79: */ ! 80: do { ! 81: puts("? "); ! 82: gets(cmd_line, DIRSIZ); ! 83: puts("\r\n"); ! 84: sanity_check("Main command loop"); ! 85: ! 86: } while (interpret(cmd_line)); ! 87: ! 88: /* Extract the cmd_name from the command line. ! 89: * Do this because strtok is destructive and we ! 90: * want cmd_line for later use. ! 91: */ ! 92: strcpy(cmd_name, cmd_line); ! 93: strtok(cmd_name, WS); ! 94: } ! 95: ! 96: /* We've found the image we want to boot--let's open it. */ ! 97: if (0 == iopen(&imageinode, imageinum)) { ! 98: puts("Can't open "); ! 99: puts(cmd_name); ! 100: puts(". Type \"dir\" for a list of files.\r\n"); ! 101: continue; ! 102: } ! 103: ! 104: /* Read the magic number. */ ! 105: iread(&imageinode, &filemagic, ! 106: (fsize_t) 0, (uint16) sizeof (int)); ! 107: canint(filemagic); /* Harmless on 80386. */ ! 108: ! 109: /* If we haven't explicitly set sys_base, default it based ! 110: * on the type of file we are loading. ! 111: */ ! 112: if (!sys_base_set) { ! 113: #ifdef VERBOSE ! 114: puts("Assuming default sys_base.\r\n"); ! 115: #endif /* VERBOSE */ ! 116: sys_base = object_sys_base(filemagic); ! 117: } ! 118: ! 119: imageok = object2load(filemagic, &imageinode, imagetable, &data_seg); ! 120: ! 121: if (!imageok) { ! 122: puts("File "); ! 123: puts(cmd_name); ! 124: puts(" is not an executable.\r\n"); ! 125: puts(".\r\n"); ! 126: cmd_name[0] = '\0'; ! 127: } ! 128: ! 129: if (imageok && (0 == strcmp(cmd_name, "autoboot"))) { ! 130: puts("Press <SPACE> to abort boot.\r\n"); ! 131: imageok = !wait_for_keystroke(WAIT_DELAY, (int) ' '); ! 132: if (!imageok) { ! 133: cmd_name[0] = '\0'; ! 134: } ! 135: } ! 136: } while (!imageok); ! 137: ! 138: /* ASSERTION: imageinode and imagetable describe a valid executable. */ ! 139: ! 140: #ifdef VERBOSE ! 141: puts("OK! Loading "); ! 142: puts(cmd_name); ! 143: puts("...\r\n"); ! 144: #endif /* VERBOSE */ ! 145: ! 146: /* Now actually load everything into memory. */ ! 147: for (cur_segment = &imagetable[0]; cur_segment->valid; ++cur_segment) { ! 148: puts(cur_segment->message); ! 149: ! 150: ifread(&imageinode, ! 151: cur_segment->load_toseg, ! 152: cur_segment->load_tooffset, ! 153: cur_segment->load_offset, ! 154: cur_segment->load_length); ! 155: } ! 156: ! 157: /* Does the program we just loaded want more info? */ ! 158: ! 159: /* Look up the variable "boot_gift" in the image. */ ! 160: puts("\r\nPlease wait...\r\n"); ! 161: boot_value = object_nlist(filemagic, cmd_name, "boot_gift"); ! 162: ! 163: ! 164: if (0 != boot_value) { ! 165: #ifdef VERBOSE ! 166: puts("Preparing arguments.\r\n"); ! 167: #endif /* VERBOSE */ ! 168: /* Yes, this program can accept more information. */ ! 169: prepare_gift(data_seg, boot_value, cmd_line); ! 170: } ! 171: ! 172: #ifdef VERBOSE ! 173: puts("\r\nRunning "); ! 174: puts(cmd_name); ! 175: puts("...\r\n"); ! 176: #endif /* VERBOSE */ ! 177: ! 178: if (want_monitor) { ! 179: puts("The kernel is ready to run.\r\n"); ! 180: puts("SYS_START: "); ! 181: print16(SYS_START); ! 182: puts(" sys_base: "); ! 183: print16(sys_base); ! 184: puts(" data_seg: "); ! 185: print16(data_seg); ! 186: puts("\r\n"); ! 187: monitor(); ! 188: } ! 189: ! 190: /* Run the image (the kernel). */ ! 191: gotoker(SYS_START, sys_base, data_seg); ! 192: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.