The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/boot/boot.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 #include <u.h>
    2 #include <libc.h>
    3 #include <auth.h>
    4 #include <fcall.h>
    5 #include "../boot/boot.h"
    6 
    7 char    cputype[64];
    8 char    sys[2*64];
    9 char    reply[256];
   10 int     printcol;
   11 int     mflag;
   12 int     fflag;
   13 int     kflag;
   14 
   15 char    *bargv[Nbarg];
   16 int     bargc;
   17 
   18 static void     swapproc(void);
   19 static Method   *rootserver(char*);
   20 static void     usbinit(void);
   21 static void     kbmap(void);
   22 
   23 void
   24 boot(int argc, char *argv[])
   25 {
   26         int fd, afd;
   27         Method *mp;
   28         char *cmd, cmdbuf[64], *iargv[16];
   29         char rootbuf[64];
   30         int islocal, ishybrid;
   31         char *rp, *rsp;
   32         int iargc, n;
   33         char buf[32];
   34         AuthInfo *ai;
   35 
   36         fmtinstall('r', errfmt);
   37 
   38         bind("#c", "/dev", MBEFORE);
   39         open("/dev/cons", OREAD);
   40         open("/dev/cons", OWRITE);
   41         open("/dev/cons", OWRITE);
   42         /*
   43          * init will reinitialize its namespace.
   44          * #ec gets us plan9.ini settings (*var variables).
   45          */
   46         bind("#ec", "/env", MREPL);
   47         bind("#e", "/env", MBEFORE|MCREATE);
   48         bind("#s", "/srv", MREPL|MCREATE);
   49 #ifdef DEBUG
   50         print("argc=%d\n", argc);
   51         for(fd = 0; fd < argc; fd++)
   52                 print("%lux %s ", argv[fd], argv[fd]);
   53         print("\n");
   54 #endif DEBUG
   55 
   56         ARGBEGIN{
   57         case 'k':
   58                 kflag = 1;
   59                 break;
   60         case 'm':
   61                 mflag = 1;
   62                 break;
   63         case 'f':
   64                 fflag = 1;
   65                 break;
   66         }ARGEND
   67 
   68         readfile("#e/cputype", cputype, sizeof(cputype));
   69 
   70         /*
   71          *  set up usb keyboard, mouse and disk, if any.
   72          */
   73         usbinit();
   74 
   75         /*
   76          *  pick a method and initialize it
   77          */
   78         if(method[0].name == nil)
   79                 fatal("no boot methods");
   80         mp = rootserver(argc ? *argv : 0);
   81         (*mp->config)(mp);
   82         islocal = strcmp(mp->name, "local") == 0;
   83         ishybrid = strcmp(mp->name, "hybrid") == 0;
   84 
   85         /*
   86          *  load keymap if it's there.
   87          */
   88         kbmap();
   89 
   90         /*
   91          *  authentication agent
   92          */
   93         authentication(cpuflag);
   94 
   95         /*
   96          *  connect to the root file system
   97          */
   98         fd = (*mp->connect)();
   99         if(fd < 0)
  100                 fatal("can't connect to file server");
  101         if(getenv("srvold9p"))
  102                 fd = old9p(fd);
  103         if(!islocal && !ishybrid){
  104                 if(cfs)
  105                         fd = (*cfs)(fd);
  106         }
  107         print("version...");
  108         buf[0] = '\0';
  109         n = fversion(fd, 0, buf, sizeof buf);
  110         if(n < 0)
  111                 fatal("can't init 9P");
  112         srvcreate("boot", fd);
  113 
  114         /*
  115          *  create the name space, mount the root fs
  116          */
  117         if(bind("/", "/", MREPL) < 0)
  118                 fatal("bind /");
  119         rp = getenv("rootspec");
  120         if(rp == nil)
  121                 rp = "";
  122         
  123         afd = fauth(fd, rp);
  124         if(afd >= 0){
  125                 ai = auth_proxy(afd, auth_getkey, "proto=p9any role=client");
  126                 if(ai == nil)
  127                         print("authentication failed (%r), trying mount anyways\n");
  128         }
  129         if(mount(fd, afd, "/root", MREPL|MCREATE, rp) < 0)
  130                 fatal("mount /");
  131         rsp = rp;
  132         rp = getenv("rootdir");
  133         if(rp == nil)
  134                 rp = rootdir;
  135         if(bind(rp, "/", MAFTER|MCREATE) < 0){
  136                 if(strncmp(rp, "/root", 5) == 0){
  137                         fprint(2, "boot: couldn't bind $rootdir=%s to root: %r\n", rp);
  138                         fatal("second bind /");
  139                 }
  140                 snprint(rootbuf, sizeof rootbuf, "/root/%s", rp);
  141                 rp = rootbuf;
  142                 if(bind(rp, "/", MAFTER|MCREATE) < 0){
  143                         fprint(2, "boot: couldn't bind $rootdir=%s to root: %r\n", rp);
  144                         if(strcmp(rootbuf, "/root//plan9") == 0){
  145                                 fprint(2, "**** warning: remove rootdir=/plan9 entry from plan9.ini\n");
  146                                 rp = "/root";
  147                                 if(bind(rp, "/", MAFTER|MCREATE) < 0)
  148                                         fatal("second bind /");
  149                         }else
  150                                 fatal("second bind /");
  151                 }
  152         }
  153         close(fd);
  154         setenv("rootdir", rp);
  155 
  156         settime(islocal, afd, rsp);
  157         if(afd > 0)
  158                 close(afd);
  159         swapproc();
  160 
  161         cmd = getenv("init");
  162         if(cmd == nil){
  163                 sprint(cmdbuf, "/%s/init -%s%s", cputype,
  164                         cpuflag ? "c" : "t", mflag ? "m" : "");
  165                 cmd = cmdbuf;
  166         }
  167         iargc = tokenize(cmd, iargv, nelem(iargv)-1);
  168         cmd = iargv[0];
  169 
  170         /* make iargv[0] basename(iargv[0]) */
  171         if(iargv[0] = strrchr(iargv[0], '/'))
  172                 iargv[0]++;
  173         else
  174                 iargv[0] = cmd;
  175 
  176         iargv[iargc] = nil;
  177 
  178         exec(cmd, iargv);
  179         fatal(cmd);
  180 }
  181 
  182 static Method*
  183 findmethod(char *a)
  184 {
  185         Method *mp;
  186         int i, j;
  187         char *cp;
  188 
  189         if((i = strlen(a)) == 0)
  190                 return nil;
  191         cp = strchr(a, '!');
  192         if(cp)
  193                 i = cp - a;
  194         for(mp = method; mp->name; mp++){
  195                 j = strlen(mp->name);
  196                 if(j > i)
  197                         j = i;
  198                 if(strncmp(a, mp->name, j) == 0)
  199                         break;
  200         }
  201         if(mp->name)
  202                 return mp;
  203         return nil;
  204 }
  205 
  206 /*
  207  *  ask user from whence cometh the root file system
  208  */
  209 static Method*
  210 rootserver(char *arg)
  211 {
  212         char prompt[256];
  213         Method *mp;
  214         char *cp;
  215         int n;
  216 
  217         /* look for required reply */
  218         readfile("#e/nobootprompt", reply, sizeof(reply));
  219         if(reply[0]){
  220                 mp = findmethod(reply);
  221                 if(mp)
  222                         goto HaveMethod;
  223                 print("boot method %s not found\n", reply);
  224                 reply[0] = 0;
  225         }
  226 
  227         /* make list of methods */
  228         mp = method;
  229         n = sprint(prompt, "root is from (%s", mp->name);
  230         for(mp++; mp->name; mp++)
  231                 n += sprint(prompt+n, ", %s", mp->name);
  232         sprint(prompt+n, ")");
  233 
  234         /* create default reply */
  235         readfile("#e/bootargs", reply, sizeof(reply));
  236         if(reply[0] == 0 && arg != 0)
  237                 strcpy(reply, arg);
  238         if(reply[0]){
  239                 mp = findmethod(reply);
  240                 if(mp == 0)
  241                         reply[0] = 0;
  242         }
  243         if(reply[0] == 0)
  244                 strcpy(reply, method->name);
  245 
  246         /* parse replies */
  247         do{
  248                 outin(prompt, reply, sizeof(reply));
  249                 mp = findmethod(reply);
  250         }while(mp == nil);
  251 
  252 HaveMethod:
  253         bargc = tokenize(reply, bargv, Nbarg-2);
  254         bargv[bargc] = nil;
  255         cp = strchr(reply, '!');
  256         if(cp)
  257                 strcpy(sys, cp+1);
  258         return mp;
  259 }
  260 
  261 static void
  262 swapproc(void)
  263 {
  264         int fd;
  265 
  266         fd = open("#c/swap", OWRITE);
  267         if(fd < 0){
  268                 warning("opening #c/swap");
  269                 return;
  270         }
  271         if(write(fd, "start", 5) <= 0)
  272                 warning("starting swap kproc");
  273         close(fd);
  274 }
  275 
  276 int
  277 old9p(int fd)
  278 {
  279         int p[2];
  280 
  281         if(pipe(p) < 0)
  282                 fatal("pipe");
  283 
  284         print("srvold9p...");
  285         switch(fork()) {
  286         case -1:
  287                 fatal("rfork srvold9p");
  288         case 0:
  289                 dup(fd, 1);
  290                 close(fd);
  291                 dup(p[0], 0);
  292                 close(p[0]);
  293                 close(p[1]);
  294                 execl("/srvold9p", "srvold9p", "-s", 0);
  295                 fatal("exec srvold9p");
  296         default:
  297                 close(fd);
  298                 close(p[0]);
  299         }
  300         return p[1];    
  301 }
  302 
  303 static void
  304 run(char *prog, char **args)
  305 {
  306         int i, pid;
  307 
  308         if (access(args[0], AEXIST) < 0)
  309                 return;                 /* avoid error messages */
  310         print("%s...", prog);
  311         switch(pid = fork()){
  312         case -1:
  313                 fatal("fork");
  314         case 0:
  315                 exec(args[0], args);
  316                 fatal(smprint("can't exec %s: %r", args[0]));
  317         }
  318         while ((i = waitpid()) != pid && i != -1)
  319                 ;
  320         if(i == -1)
  321                 fatal(smprint("waitpid for %s failed", args[0]));
  322 }
  323 
  324 static void
  325 usbinit(void)
  326 {
  327         static char *darg[] = { "/boot/usbd", nil };
  328 
  329         if(bind("#u", "/dev", MAFTER) >= 0 && access("/dev/usb", 0) >= 0)
  330                 run("usbd", darg);
  331 }
  332 
  333 static void
  334 kbmap(void)
  335 {
  336         char *f;
  337         int n, in, out;
  338         char buf[1024];
  339 
  340         f = getenv("kbmap");
  341         if(f == nil)
  342                 return;
  343         if(bind("#κ", "/dev", MAFTER) < 0){
  344                 warning("can't bind #κ");
  345                 return;
  346         }
  347 
  348         in = open(f, OREAD);
  349         if(in < 0){
  350                 warning("can't open kbd map: %r");
  351                 return;
  352         }
  353         out = open("/dev/kbmap", OWRITE);
  354         if(out < 0) {
  355                 warning("can't open /dev/kbmap: %r");
  356                 close(in);
  357                 return;
  358         }
  359         while((n = read(in, buf, sizeof(buf))) > 0)
  360                 if(write(out, buf, n) != n){
  361                         warning("write to /dev/kbmap failed");
  362                         break;
  363                 }
  364         close(in);
  365         close(out);
  366 }

Cache object: 9725c36fa9c3bc6d00fe5c84ae3180e9


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.