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