|
@@ -4,6 +4,13 @@
|
|
|
#include <fcall.h>
|
|
|
#include "../boot/boot.h"
|
|
|
|
|
|
+#define PARTSRV "partfs.sdXX"
|
|
|
+
|
|
|
+enum {
|
|
|
+ Dontpost,
|
|
|
+ Post,
|
|
|
+};
|
|
|
+
|
|
|
char cputype[64];
|
|
|
char sys[2*64];
|
|
|
char reply[256];
|
|
@@ -11,15 +18,148 @@ int printcol;
|
|
|
int mflag;
|
|
|
int fflag;
|
|
|
int kflag;
|
|
|
+int debugboot;
|
|
|
|
|
|
char *bargv[Nbarg];
|
|
|
int bargc;
|
|
|
|
|
|
+static char usbdisk0[] = "/dev/sdU0.0";
|
|
|
+static char sdxxctl[] = "/dev/sdXX/ctl";
|
|
|
+
|
|
|
static void swapproc(void);
|
|
|
static Method *rootserver(char*);
|
|
|
-static void usbinit(void);
|
|
|
static void kbmap(void);
|
|
|
|
|
|
+/*
|
|
|
+ * run argv[0] (short name is name) and wait awhile for file to appear.
|
|
|
+ * file must be generated by running argv[0]; if it already exists, we're done.
|
|
|
+ */
|
|
|
+static int
|
|
|
+start(char *name, char **argv, char *file)
|
|
|
+{
|
|
|
+ int cnt;
|
|
|
+
|
|
|
+ if(access(file, AEXIST) >= 0)
|
|
|
+ return 0;
|
|
|
+ if(access(argv[0], AEXIST) < 0) {
|
|
|
+ fprint(2, "no %s...", argv[0]);
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+
|
|
|
+ if(debugboot)
|
|
|
+ fprint(2, "%s...", name);
|
|
|
+ runv(argv);
|
|
|
+ for(cnt = 10; cnt > 0 && access(file, AEXIST) < 0; cnt--)
|
|
|
+ sleep(100);
|
|
|
+ if (cnt <= 0) {
|
|
|
+ fprint(2, "no %s...", name);
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+static int
|
|
|
+chmod(char *file, int mode)
|
|
|
+{
|
|
|
+ Dir *dir;
|
|
|
+
|
|
|
+ dir = dirstat(file);
|
|
|
+ if (dir == nil) {
|
|
|
+ if(debugboot)
|
|
|
+ fprint(2, "can't stat %s: %r\n", file);
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+ dir->mode &= ~0777;
|
|
|
+ dir->mode |= mode & 0777;
|
|
|
+ dirwstat("/srv/" PARTSRV, dir);
|
|
|
+ free(dir);
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+/* start partfs on first usb disk, if any */
|
|
|
+static int
|
|
|
+startpartfs(int post)
|
|
|
+{
|
|
|
+ int r, i;
|
|
|
+ char *parts;
|
|
|
+ char *partfsv[32];
|
|
|
+
|
|
|
+ if(access(usbdisk0, AEXIST) < 0)
|
|
|
+ return -1; /* can't run partfs until usbd is mounted */
|
|
|
+
|
|
|
+ if (post)
|
|
|
+ remove("/srv/" PARTSRV);
|
|
|
+
|
|
|
+ i = 0;
|
|
|
+ partfsv[i++] = "/boot/partfs";
|
|
|
+ /*
|
|
|
+ * hack for booting from usb: if /env/sdB0part (from 9load) exists,
|
|
|
+ * pass it to partfs for sdXX.
|
|
|
+ */
|
|
|
+ parts = getenv("sdB0part");
|
|
|
+ if (parts != nil) {
|
|
|
+ partfsv[i++] = "-p";
|
|
|
+ partfsv[i++] = parts;
|
|
|
+ }
|
|
|
+ if (post) {
|
|
|
+ partfsv[i++] = "-s";
|
|
|
+ partfsv[i++] = PARTSRV;
|
|
|
+ }
|
|
|
+ partfsv[i++] = usbdisk0;
|
|
|
+ partfsv[i] = nil;
|
|
|
+ r = start("partfs", partfsv, sdxxctl);
|
|
|
+
|
|
|
+ if (post)
|
|
|
+ chmod("/srv/" PARTSRV, 0666);
|
|
|
+ return r;
|
|
|
+}
|
|
|
+
|
|
|
+static int
|
|
|
+mountusb(void)
|
|
|
+{
|
|
|
+ int fd;
|
|
|
+
|
|
|
+ if(debugboot)
|
|
|
+ fprint(2, "mount usbd...");
|
|
|
+ fd = open("/srv/usb", ORDWR);
|
|
|
+ if(fd < 0)
|
|
|
+ warning("can't open /srv/usb");
|
|
|
+ else if(mount(fd, -1, "/dev", MBEFORE, "") < 0) {
|
|
|
+ warning("mount -a /srv/usb /dev");
|
|
|
+ close(fd);
|
|
|
+ } else
|
|
|
+ return 0; /* mount closed fd */
|
|
|
+ return -1;
|
|
|
+}
|
|
|
+
|
|
|
+int
|
|
|
+mountusbparts(void)
|
|
|
+{
|
|
|
+ mountusb();
|
|
|
+ return startpartfs(Post);
|
|
|
+}
|
|
|
+
|
|
|
+static void
|
|
|
+usbinit(int post)
|
|
|
+{
|
|
|
+ int cnt;
|
|
|
+ static char *usbdv[] = { "/boot/usbd", nil };
|
|
|
+
|
|
|
+ if(access("#u/usb/ctl", 0) < 0 || bind("#u", "/dev", MAFTER) < 0)
|
|
|
+ return;
|
|
|
+ if(debugboot)
|
|
|
+ fprint(2, "usbinit...");
|
|
|
+ start("usbd", usbdv, "/srv/usb");
|
|
|
+
|
|
|
+ /* allow a little time for usbd's device discovery */
|
|
|
+ for(cnt = 20; cnt > 0 && access(usbdisk0, AEXIST) < 0; cnt--)
|
|
|
+ sleep(100);
|
|
|
+ if(cnt > 0)
|
|
|
+ startpartfs(post);
|
|
|
+ else if(debugboot)
|
|
|
+ fprint(2, "no usb disk...");
|
|
|
+}
|
|
|
+
|
|
|
void
|
|
|
boot(int argc, char *argv[])
|
|
|
{
|
|
@@ -52,13 +192,15 @@ boot(int argc, char *argv[])
|
|
|
*/
|
|
|
bind("#ec", "/env", MREPL);
|
|
|
bind("#e", "/env", MBEFORE|MCREATE);
|
|
|
- bind("#s", "/srv", MREPL|MCREATE);
|
|
|
+ bind("#s", "/srv/", MREPL|MCREATE);
|
|
|
+ if(getenv("debugboot"))
|
|
|
+ debugboot = 1;
|
|
|
#ifdef DEBUG
|
|
|
print("argc=%d\n", argc);
|
|
|
for(fd = 0; fd < argc; fd++)
|
|
|
print("%#p %s ", argv[fd], argv[fd]);
|
|
|
print("\n");
|
|
|
-#endif DEBUG
|
|
|
+#endif /* DEBUG */
|
|
|
|
|
|
ARGBEGIN{
|
|
|
case 'k':
|
|
@@ -75,9 +217,11 @@ boot(int argc, char *argv[])
|
|
|
readfile("#e/cputype", cputype, sizeof(cputype));
|
|
|
|
|
|
/*
|
|
|
- * set up usb keyboard, mouse and disk, if any.
|
|
|
+ * set up usb keyboard & mouse, if any.
|
|
|
+ * starts usbd, which mounts itself on /dev.
|
|
|
+ * starts partfs on first disk, if any, to permit nvram on usb.
|
|
|
*/
|
|
|
- usbinit();
|
|
|
+ usbinit(Dontpost);
|
|
|
|
|
|
/*
|
|
|
* pick a method and initialize it
|
|
@@ -96,9 +240,20 @@ boot(int argc, char *argv[])
|
|
|
|
|
|
/*
|
|
|
* authentication agent
|
|
|
+ * sets hostowner, creating an auth discontinuity
|
|
|
*/
|
|
|
+ if(debugboot)
|
|
|
+ fprint(2, "auth...");
|
|
|
authentication(cpuflag);
|
|
|
|
|
|
+ /* leave existing subprocesses in their own namespace */
|
|
|
+ rfork(RFNAMEG);
|
|
|
+
|
|
|
+ /*
|
|
|
+ * restart partfs under the new hostowner id
|
|
|
+ */
|
|
|
+ usbinit(Post);
|
|
|
+
|
|
|
/*
|
|
|
* connect to the root file system
|
|
|
*/
|
|
@@ -182,6 +337,7 @@ boot(int argc, char *argv[])
|
|
|
|
|
|
iargv[iargc] = nil;
|
|
|
|
|
|
+ chmod("/srv/" PARTSRV, 0600);
|
|
|
exec(cmd, iargv);
|
|
|
fatal(cmd);
|
|
|
}
|
|
@@ -307,16 +463,6 @@ old9p(int fd)
|
|
|
return p[1];
|
|
|
}
|
|
|
|
|
|
-static void
|
|
|
-usbinit(void)
|
|
|
-{
|
|
|
- static char usbd[] = "/boot/usbd";
|
|
|
-
|
|
|
- if(access("#u/usb/ctl", 0) >= 0 && bind("#u", "/dev", MAFTER) >= 0 &&
|
|
|
- access(usbd, AEXIST) >= 0)
|
|
|
- run(usbd, nil);
|
|
|
-}
|
|
|
-
|
|
|
static void
|
|
|
kbmap(void)
|
|
|
{
|
|
@@ -334,12 +480,12 @@ kbmap(void)
|
|
|
|
|
|
in = open(f, OREAD);
|
|
|
if(in < 0){
|
|
|
- warning("can't open kbd map: %r");
|
|
|
+ warning("can't open kbd map");
|
|
|
return;
|
|
|
}
|
|
|
out = open("/dev/kbmap", OWRITE);
|
|
|
if(out < 0) {
|
|
|
- warning("can't open /dev/kbmap: %r");
|
|
|
+ warning("can't open /dev/kbmap");
|
|
|
close(in);
|
|
|
return;
|
|
|
}
|