]> git.lizzy.rs Git - plan9front.git/blob - sys/src/9/port/rebootcmd.c
audioac97: fix inverted recgain control, init to zero recgain
[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 static void
36 setbootcmd(int argc, char *argv[])
37 {
38         char *buf, *p, *ep;
39         int i;
40
41         p = buf = smalloc(1024);
42         ep = buf + 1024;
43         for(i=0; i<argc; i++)
44                 p = seprint(p, ep, "%q ", argv[i]);
45         *p = 0;
46         ksetenv("bootcmd", buf, 1);
47         free(buf);
48 }
49
50 void
51 rebootcmd(int argc, char *argv[])
52 {
53         Chan *c;
54         Exec exec;
55         ulong magic, text, rtext, entry, data, size;
56         uchar *p;
57
58         if(argc == 0)
59                 exit(0);
60
61         c = namec(argv[0], Aopen, OEXEC, 0);
62         if(waserror()){
63                 cclose(c);
64                 nexterror();
65         }
66
67         readn(c, &exec, sizeof(Exec));
68         magic = l2be(exec.magic);
69         entry = l2be(exec.entry);
70         text = l2be(exec.text);
71         data = l2be(exec.data);
72         if(magic != AOUT_MAGIC)
73                 error(Ebadexec);
74
75         /* round text out to page boundary */
76         rtext = PGROUND(entry+text)-entry;
77         size = rtext + data;
78         p = malloc(size);
79         if(p == nil)
80                 error(Enomem);
81
82         if(waserror()){
83                 free(p);
84                 nexterror();
85         }
86
87         memset(p, 0, size);
88         readn(c, p, text);
89         readn(c, p + rtext, data);
90
91         ksetenv("bootfile", argv[0], 1);
92         setbootcmd(argc-1, argv+1);
93
94         reboot((void*)entry, p, size);
95
96         panic("return from reboot!");
97 }