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 } 101