1 #include "u.h"
2 #include "../port/lib.h"
3 #include "mem.h"
4 #include "dat.h"
5 #include "fns.h"
6 #include "../port/error.h"
7
8 #include <a.out.h>
9
10 void
readn(Chan * c,void * vp,long n)11 readn(Chan *c, void *vp, long n)
12 {
13 char *p;
14 long nn;
15
16 p = vp;
17 while(n > 0) {
18 nn = devtab[c->type]->read(c, p, n, c->offset);
19 if(nn == 0)
20 error(Eshort);
21 c->offset += nn;
22 p += nn;
23 n -= nn;
24 }
25 }
26
27 static void
setbootcmd(int argc,char * argv[])28 setbootcmd(int argc, char *argv[])
29 {
30 char *buf, *p, *ep;
31 int i;
32
33 buf = malloc(1024);
34 if(buf == nil)
35 error(Enomem);
36 p = buf;
37 ep = buf + 1024;
38 for(i=0; i<argc; i++)
39 p = seprint(p, ep, "%q ", argv[i]);
40 *p = 0;
41 ksetenv("bootcmd", buf, 1);
42 free(buf);
43 }
44
45 void
rebootcmd(int argc,char * argv[])46 rebootcmd(int argc, char *argv[])
47 {
48 Chan *c;
49 Exec exec;
50 ulong magic, text, rtext, entry, data, size;
51 uchar *p;
52
53 if(argc == 0)
54 exit(0);
55
56 c = namec(argv[0], Aopen, OEXEC, 0);
57 if(waserror()){
58 cclose(c);
59 nexterror();
60 }
61
62 readn(c, &exec, sizeof(Exec));
63 magic = l2be(exec.magic);
64 entry = l2be(exec.entry);
65 text = l2be(exec.text);
66 data = l2be(exec.data);
67 if(magic != AOUT_MAGIC)
68 error(Ebadexec);
69
70 /* round text out to page (and segment) boundary */
71 /* 1024*1024 should be Mach->pgsize from libmach */
72 rtext = ROUNDUP(entry + text, 1024*1024) - entry;
73 size = rtext + data;
74 p = malloc(size);
75 if(p == nil)
76 error(Enomem);
77
78 if(waserror()){
79 free(p);
80 nexterror();
81 }
82
83 memset(p, 0, size);
84 readn(c, p, text);
85 readn(c, p + rtext, data);
86
87 ksetenv("bootfile", argv[0], 1);
88 setbootcmd(argc-1, argv+1);
89
90 reboot((void*)entry, p, size);
91
92 panic("return from reboot!");
93 }
94