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