1
0
Files
irix-657m-src/irix/cmd/lboot/main.c
2022-09-29 17:59:04 +03:00

360 lines
8.5 KiB
C

/* Copyright (c) 1984 AT&T */
/* All Rights Reserved */
#ident "$Revision: 2.44 $"
#include <sys/types.h>
#include <a.out.h>
#include <sys/param.h>
#include "lboot.h"
#include <sys/syssgi.h>
#include <sys/conf.h>
#include <sys/fstyp.h>
#include <sys/mload.h>
#include <getopt.h>
/*
* lboot facts ... good things to know
*
* 1. How does lboot come up with the order of the object files sent to ld ?
*
* lboot parses the system files, parses all of the vector, include and
* use lines, and creates a driver list. It then goes thru that list and
* adds all of the dependencies from the master files, so that they get
* added in the order that the other modules were put in the list. When
* the ld line is created, lboot puts all of the .o's from the list first,
* then the .a's, then the stubs. The order in the ld line is the reverse
* order as things appear in the system files. The following comment exists
* in system.gen:
*
* VECTOR lines must occur in the opposite order that the devices
* should be probed. Do not change the order of the VECTOR
* lines in this file, unless you understand the implications.
*
* 2. Why is autoconfig building a new kernel and how does it decide ?
*
* Use autoconfig -v and lboot will tell you why it has decided that a new
* kernel should be built.
*
* lboot via autoconfig decides to generate a new kernel if any of the
* following are true:
*
* - /unix does not exist
* - one or more files in /var/sysgen/master.d are newer than /unix
* - one or more files in /var/sysgen/boot are newer than /unix
* - if /var/sysgen/boot is newer than /unix
* - if /var/sysgen/stune is newer than /unix
* - one or more files in /var/sysgen/system are newer than /unix
* - if new/different hardware is detected, in which case the edt file
* generated is different from the previous one
*
*/
char *root; /* root path prefix */
char *toolpath; /* path to tools */
char *cc;
char *ccopts;
char *ld;
char *ldopts;
char *slash_boot = "/var/sysgen/boot";
int bspec = 0; /* user overrode boot directory */
char *slash_runtime;
int wspec = 0;
char *slash_mtune = "/var/sysgen/mtune";
int mtspec = 0; /* user overrode mtune directory */
char *stune_file = "/var/sysgen/stune";
int stspec = 0; /* user overrode stune file */
char *master_dot_d = "/var/sysgen/master.d";
int mspec = 0; /* user overrode master directory */
char *unix_name = 0;
char *etcsystem = "/var/sysgen/system";
int esspec = 0; /* user overrode system file */
char *kernel_master = 0; /* master.d/kernel */
char *mtune_kernel = 0; /* mtune/kernel file */
static char *cwd;
char *cwd_slash; /* current working directory */
#define MAXMOD 1024
int modloadc;
char *modloadv[MAXMOD];
int modregc;
char *modregv[MAXMOD];
int modunldc;
int modunldv[MAXMOD];
int modunregc;
int modunregv[MAXMOD];
int do_mreg_diags;
int Debug = 0;
int Verbose = 0;
int Smart = 0;
int Autoconfig = 1;
int Autoreg = 0; /* perform an autoregister only */
int Noautoreg = 0; /* do normal autoconfig, but don't autoreg */
int Dolink = 0;
int Nogo = 0;
int
main(int argc, char *argv[])
{
struct stat statbuffer;
int c;
cwd = getcwd(0, MAXPATHLEN);
if (cwd == 0)
error(ER2, "getcwd");
cwd_slash = concat(cwd, "/");
while ((c = getopt(argc, argv, "NeladfvtTu:m:r:b:w:s:n:c:L:R:VU:W:O:")) != EOF)
switch (c) {
case 'N':
Noautoreg = TRUE;
break;
case 'a':
Autoreg = TRUE;
break;
case 'd':
Debug = TRUE;
break;
case 'v':
Verbose = TRUE;
break;
case 'e':
Nogo = TRUE;
Noautoreg = TRUE;
break;
case 't':
Smart = TRUE;
Autoconfig = FALSE;
if (!unix_name)
unix_name = "unix";
break;
case 'T':
Smart = TRUE;
Autoconfig = TRUE;
if (!unix_name)
unix_name = "unix";
break;
case 'O':
do_tunetag(1, &optarg, NULL);
break;
case 'u':
unix_name = optarg;
break;
case 'l':
Dolink = TRUE;
break;
case 'r':
root = optarg;
break;
case 'm':
master_dot_d = optarg;
if (master_dot_d[0] != '/')
master_dot_d = concat(cwd_slash,
master_dot_d);
if (stat(master_dot_d, &statbuffer) < 0)
error(ER2, master_dot_d);
if (!(statbuffer.st_mode & S_IFDIR))
error(ER100, master_dot_d);
mspec++;
break;
case 'w':
slash_runtime = optarg;
if (slash_runtime[0] != '/')
slash_runtime = concat(cwd_slash, slash_runtime);
if (stat(slash_runtime, &statbuffer) < 0)
error(ER2, slash_runtime);
if (!(statbuffer.st_mode & S_IFDIR))
error(ER100, slash_runtime);
wspec++;
break;
case 's':
etcsystem = optarg;
if (etcsystem[0] != '/')
etcsystem = concat(cwd_slash, etcsystem);
esspec++;
break;
case 'b':
slash_boot = optarg;
if (slash_boot[0] != '/')
slash_boot = concat(cwd_slash, slash_boot);
if (stat(slash_boot, &statbuffer) < 0)
error(ER2, slash_boot);
if (!(statbuffer.st_mode & S_IFDIR))
error(ER100, slash_boot);
bspec++;
break;
case 'c':
stune_file = optarg;
if (stune_file[0] != '/')
stune_file = concat(cwd_slash, stune_file);
stspec++;
break;
case 'n':
slash_mtune = optarg;
if (slash_mtune[0] != '/')
slash_mtune = concat(cwd_slash, slash_mtune);
if (stat(slash_mtune, &statbuffer) < 0)
error(ER2, slash_mtune);
if (!(statbuffer.st_mode & S_IFDIR))
error(ER100, slash_mtune);
mtspec++;
break;
case 'L': /* dynamic load */
for (;;) {
char *modname;
for (modname = strtok(optarg,", ");
modname && modloadc < MAXMOD;
modname = strtok(0,", "))
modloadv[modloadc++] = modname;
if ( optind >= argc || *argv[optind] == '-' )
break;
optarg = argv[optind++];
}
break;
case 'R': /* dynamic register */
for (;;) {
char *modname;
for (modname = strtok(optarg,", ");
modname && modregc < MAXMOD;
modname = strtok(0,", "))
modregv[modregc++] = modname;
if ( optind >= argc || *argv[optind] == '-' )
break;
optarg = argv[optind++];
}
break;
case 'U': /* dynamic unload */
for (;;) {
modunldv[modunldc++] = (int)atol(optarg);
if ( optind >= argc || *argv[optind] == '-' )
break;
optarg = argv[optind++];
}
break;
case 'W': /* dynamic unregister */
for (;;) {
modunregv[modunregc++] = (int)atol(optarg);
if ( optind >= argc || *argv[optind] == '-' )
break;
optarg = argv[optind++];
}
break;
case 'V': /* list loaded/registered modules */
do_mlist();
break;
case '?':
fprintf(stderr,"[-dv] [-t|T] [-a] [-N] [-l] [-u /unix] [-m master.d] [-b boot] [-w workarea]\n\t[-s system] [-p /toolroot] [-r /root] [-c stune]\n\t[-n mtune] [-L master] [-R master] [-U id] [-W id] [-V] [-O tag]\n");
exit(2);
}
if (!unix_name)
unix_name = "unix.new";
if (unix_name[0] != '/')
unix_name = concat(cwd_slash, unix_name);
/*
* If "ROOT" was specified in some way, re-wire the paths
* (if the user didn't explicitly set them) to be at the
* proper place.
*/
if (!root) {
root = getenv("ROOT");
if (root && strcmp(root, "/"))
printf ("Lboot using ROOT=%s\n", root);
}
if (!root) {
root = "";
} else {
if (!bspec) {
slash_boot = concat(root, slash_boot);
}
if (!mspec) {
master_dot_d = concat(root, master_dot_d);
}
if (!esspec) {
etcsystem = concat(root, etcsystem);
}
if (!stspec) {
stune_file = concat(root, stune_file);
}
if (!mtspec) {
slash_mtune = concat(root, slash_mtune);
}
}
if (!wspec) {
slash_runtime = slash_boot;
}
/*
* If "TOOLROOT" was specified in some way, re-wire the paths
* to be at the proper place.
*/
toolpath = getenv("TOOLROOT");
if (toolpath != 0) {
if(strcmp(toolpath, "/var/sysgen/root"))
printf ("Lboot using TOOLROOT=%s\n", toolpath);
toolpath = concat(toolpath, "/usr/bin/");
}
init_dev_admin();
{ char *c_default;
/* this is just a warning; we don't use it directly, unlike
* ROOT and TOOLROOT. This is new in mipspro 7.1 */
if(c_default=getenv("COMPILER_DEFAULTS_PATH"))
printf ("Lboot using compiler defaults in COMPILER_DEFAULTS_PATH=%s\n",
c_default);
}
if (chdir(slash_boot) == -1)
error(ER2, slash_boot);
if (modloadc || modregc || modunldc || modunregc) {
if (modloadc)
do_mloadreg(modloadc,modloadv,CF_LOAD);
if (modregc)
do_mloadreg(modregc,modregv,CF_REGISTER);
if (modunldc)
do_munloadreg(modunldc,modunldv,CF_UNLOAD);
if (modunregc)
do_munloadreg(modunregc,modunregv,CF_UNREGISTER);
} else
loadunix(); /* do the work */
return 0;
}