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