]> git.lizzy.rs Git - plan9front.git/blob - sys/src/9/port/rebootcmd.c
kernel: avoid selecting the boot process in killbig()
[plan9front.git] / sys / src / 9 / 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 void
36 rebootcmd(int argc, char *argv[])
37 {
38         Chan *c;
39         Exec exec;
40         ulong magic, text, rtext, entry, data, size, align;
41         uchar *p;
42
43         if(argc == 0)
44                 exit(0);
45
46         c = namec(argv[0], Aopen, OEXEC, 0);
47         if(waserror()){
48                 cclose(c);
49                 nexterror();
50         }
51
52         readn(c, &exec, sizeof(Exec));
53         magic = l2be(exec.magic);
54         entry = l2be(exec.entry);
55         text = l2be(exec.text);
56         data = l2be(exec.data);
57
58         if(!(magic == AOUT_MAGIC)){
59                 switch(magic){
60                 case I_MAGIC:
61                 case S_MAGIC:
62                         if((I_MAGIC == AOUT_MAGIC) || (S_MAGIC == AOUT_MAGIC))
63                                 break;
64                 default:
65                         error(Ebadexec);
66                 }
67         }
68         if(magic & HDR_MAGIC)
69                 readn(c, &exec, 8);
70
71         switch(magic){
72         case R_MAGIC:
73                 align = 0x10000;        /* 64k segment alignment for arm64 */
74                 break;
75         default:
76                 align = BY2PG;
77                 break;
78         }
79
80         /* round text out to page boundary */
81         rtext = ROUND(entry+text, align)-entry;
82         size = rtext + data;
83         p = malloc(size);
84         if(p == nil)
85                 error(Enomem);
86
87         if(waserror()){
88                 free(p);
89                 nexterror();
90         }
91
92         memset(p, 0, size);
93         readn(c, p, text);
94         readn(c, p + rtext, data);
95
96         ksetenv("bootfile", argv[0], 1);
97
98         reboot((void*)entry, p, size);
99         error(Egreg);
100 }