|
|
1.1 root 1: #include <u.h>
2: #include <libc.h>
3: #include <bio.h>
4: #include <mach.h>
5: #include "../boot/boot.h"
6:
7: typedef struct Net Net;
8: typedef struct Flavor Flavor;
9:
10: int printcol;
11:
12: char cputype[NAMELEN];
13: char terminal[NAMELEN];
14: char sys[2*NAMELEN];
15: char username[NAMELEN];
16: char conffile[2*NAMELEN];
17: char sysname[2*NAMELEN];
18: char buf[8*1024];
19: char bootfile[3*NAMELEN];
20: char conffile[NAMELEN];
21:
22: int mflag;
23: int fflag;
24: int kflag;
25:
26: static int readconf(int);
27: static void readkernel(int);
28: static int readseg(int, int, long, long, int);
29: static Method *rootserver(char*);
30:
31: void
32: bboot(int argc, char *argv[])
33: {
34: int fd;
35: Method *mp;
36: int islocal;
37:
38: sleep(1000);
39:
40: open("#c/cons", OREAD);
41: open("#c/cons", OWRITE);
42: open("#c/cons", OWRITE);
43:
44: /* for(fd = 0; fd < argc; fd++)
45: print("%s ", argv[fd]);
46: print("\n");/**/
47:
48: ARGBEGIN{
49: case 'u':
50: strcpy(username, ARGF());
51: break;
52: case 'k':
53: kflag = 1;
54: break;
55: case 'm':
56: mflag = 1;
57: break;
58: case 'f':
59: fflag = 1;
60: break;
61: }ARGEND
62:
63: readfile("#e/cputype", cputype, sizeof(cputype));
64: readfile("#e/terminal", terminal, sizeof(terminal));
65: getconffile(conffile, terminal);
66: readfile("#c/sysname", sysname, sizeof(sysname));
67: if(argc > 1)
68: strcpy(bootfile, argv[1]);
69: else
70: sprint(bootfile, "/%s/9%s", cputype, conffile);
71:
72: /*
73: * pick a method and initialize it
74: */
75: mp = rootserver(argc ? *argv : 0);
76: (*mp->config)(mp);
77: islocal = strcmp(mp->name, "local") == 0;
78:
79: /*
80: * set user to none
81: */
82: fd = open("#c/user", OWRITE|OTRUNC);
83: if(fd >= 0){
84: if(write(fd, "none", 4) < 0)
85: warning("write user name");
86: close(fd);
87: }else
88: warning("open #c/user");
89:
90: /*
91: * connect to the root file system
92: */
93: fd = (*mp->connect)();
94: if(fd < 0)
95: fatal("can't connect to file server");
96: if(!islocal){
97: if(cfs)
98: fd = (*cfs)(fd);
99: }
100:
101: /*
102: * create the name space, mount the root fs
103: */
104: if(bind("/", "/", MREPL) < 0)
105: fatal("bind");
106: if(mount(fd, "/", MAFTER|MCREATE, "") < 0)
107: fatal("mount");
108: close(fd);
109:
110: /*
111: * open the configuration file and read it
112: * into the kernel
113: */
114: sprint(conffile, "/%s/conf/%s", cputype, sysname);
115: print("%s...", conffile);
116: fd = open(conffile, OREAD);
117: if(fd >= 0){
118: if(readconf(fd) < 0)
119: warning("readconf");
120: close(fd);
121: }
122:
123: /*
124: * read in real kernel
125: */
126: print("%s...", bootfile);
127: while((fd = open(bootfile, OREAD)) < 0)
128: outin(cpuflag, "bootfile", bootfile, sizeof(bootfile));
129: readkernel(fd);
130: fatal("couldn't read kernel");
131: }
132:
133: /*
134: * ask user from whence cometh the root file system
135: */
136: static Method*
137: rootserver(char *arg)
138: {
139: char prompt[256];
140: char reply[64];
141: Method *mp;
142: char *cp;
143: int n;
144:
145: mp = method;
146: n = sprint(prompt, "root is from (%s", mp->name);
147: for(mp++; mp->name; mp++)
148: n += sprint(prompt+n, ", %s", mp->name);
149: sprint(prompt+n, ")");
150:
151: if(arg)
152: strcpy(reply, arg);
153: else
154: strcpy(reply, method->name);
155: for(;;){
156: if(mflag)
157: outin(cpuflag, prompt, reply, sizeof(reply));
158: for(mp = method; mp->name; mp++)
159: if(*reply == *mp->name){
160: cp = strchr(reply, '!');
161: if(cp)
162: strcpy(sys, cp+1);
163: return mp;
164: }
165: if(mp->name == 0)
166: continue;
167: }
168: return 0; /* not reached */
169: }
170:
171:
172: /*
173: * read the configuration
174: */
175: static int
176: readconf(int fd)
177: {
178: int bfd;
179: int n;
180: long x;
181:
182: /*
183: * read the config file
184: */
185: n = read(fd, buf, sizeof(buf)-1);
186: if(n <= 0)
187: return -1;
188: buf[n] = 0;
189:
190: /*
191: * write into 4 meg - 4k
192: */
193: bfd = open("#B/mem", OWRITE);
194: if(bfd < 0)
195: fatal("can't open #B/mem");
196: x = 0x80000000 | 4*1024*1024 - 4*1024;
197: if(seek(bfd, x, 0) != x){
198: close(bfd);
199: return -1;
200: }
201: if(write(bfd, buf, n+1) != n+1){
202: close(bfd);
203: return -1;
204: }
205:
206: close(bfd);
207: return 0;
208: }
209:
210: /*
211: * read the kernel into memory and jump to it
212: */
213: static void
214: readkernel(int fd)
215: {
216: int bfd;
217: Fhdr f;
218:
219: bfd = open("#B/mem", ORDWR);
220: if(bfd < 0)
221: fatal("can't open #B/mem");
222:
223: if(crackhdr(fd, &f) == 0)
224: fatal("not a header I understand");
225:
226: print("\n%d", f.txtsz);
227: if(readseg(fd, bfd, f.txtoff, f.txtaddr, f.txtsz)<0)
228: fatal("can't read boot file");
229: print("+%d", f.datsz);
230: if(readseg(fd, bfd, f.datoff, f.dataddr, f.datsz)<0)
231: fatal("can't read boot file");
232: print("+%d", f.bsssz);
233:
234: close(bfd);
235: bfd = open("#B/boot", OWRITE);
236: if(bfd < 0)
237: fatal("can't open #B/boot");
238:
239: print(" entry: 0x%ux\n", f.entry);
240: sleep(1000);
241: if(write(bfd, &f.entry, sizeof f.entry) != sizeof f.entry)
242: fatal("can't start kernel");
243: }
244:
245: /*
246: * read a segment into memory
247: */
248: static int
249: readseg(int in, int out, long inoff, long outoff, int len)
250: {
251: long n;
252:
253: if(seek(in, inoff, 0) < 0){
254: warning("seeking bootfile");
255: return -1;
256: }
257: if(seek(out, outoff, 0) != outoff){
258: warning("seeking #B/mem");
259: return -1;
260: }
261: for(; len > 0; len -= n){
262: if((n = read(in, buf, sizeof buf)) <= 0){
263: warning("reading bootfile");
264: return -1;
265: }
266: if(write(out, buf, n) != n){
267: warning("writing #B/mem");
268: return -1;
269: }
270: }
271: return 0;
272: }
273:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.