From 97d5b830761c0a62490a16c2f4942930afcbba94 Mon Sep 17 00:00:00 2001 From: msmith Date: Mon, 14 Sep 1998 18:27:06 +0000 Subject: Resynch with working sources before BTX integration. - Use format-independant module allocator. - Conditionalise ISA PnP support. - Simplify PnP enumerator interface. - Improve module/object searching. - Add missing depend/install targets in BTX makefiles. - Pass the kernel environment and module data in extended bootinfo fields. - Add a pointer to the end of the kernel + modules in bootinfo. - Fix parsing of old-style kernel arguments. --- sys/boot/common/Makefile.inc | 12 +++- sys/boot/common/bootstrap.h | 53 ++++++++++---- sys/boot/common/interp.c | 4 +- sys/boot/common/load_aout.c | 10 +-- sys/boot/common/module.c | 114 ++++++++++++++++++++++-------- sys/boot/common/pnp.c | 161 +++++++++++++++++++++++++++++-------------- 6 files changed, 248 insertions(+), 106 deletions(-) (limited to 'sys/boot/common') diff --git a/sys/boot/common/Makefile.inc b/sys/boot/common/Makefile.inc index 8826353..0eacbe7 100644 --- a/sys/boot/common/Makefile.inc +++ b/sys/boot/common/Makefile.inc @@ -1,4 +1,12 @@ -# $Id: Makefile.inc,v 1.3 1998/09/01 00:41:24 msmith Exp $ +# $Id: Makefile.inc,v 1.4 1998/09/04 02:43:26 msmith Exp $ SRCS+= boot.c commands.c console.c devopen.c interp.c interp_backslash.c -SRCS+= interp_parse.c load_aout.c ls.c misc.c module.c panic.c # pnp.c +SRCS+= interp_parse.c load_aout.c ls.c misc.c module.c panic.c + +# Machine-independant ISA PnP +.if HAVE_ISABUS +SRCS+= isapnp.c +.endif +.if HAVE_PNP +SRCS+= pnp.c +.endif diff --git a/sys/boot/common/bootstrap.h b/sys/boot/common/bootstrap.h index 0d7950c..f624c29 100644 --- a/sys/boot/common/bootstrap.h +++ b/sys/boot/common/bootstrap.h @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: bootstrap.h,v 1.3 1998/09/03 02:10:07 msmith Exp $ + * $Id: bootstrap.h,v 1.4 1998/09/04 02:43:26 msmith Exp $ */ #include @@ -57,6 +57,9 @@ extern char command_errbuf[]; /* XXX blah, length */ extern void interact(void); extern void source(char *filename); +/* interp_parse.c */ +extern int parse(int *argc, char ***argv, char *str); + /* boot.c */ extern int autoboot(int delay, char *prompt); @@ -89,25 +92,33 @@ extern void cons_probe(void); /* * Plug-and-play enumerator/configurator interface. */ +struct pnpident +{ + char *id_ident; /* ASCII identifier, actual format varies with bus/handler */ + struct pnpident *id_next; /* the next identifier */ +}; + +struct pnphandler; struct pnpinfo { - char *pi_ident; /* ASCII identifier, actual format varies with bus/handler */ + struct pnpident *pi_ident; /* list of identifiers */ int pi_revision; /* optional revision (or -1) if not supported */ char *pi_module; /* module/args nominated to handle device */ int pi_argc; /* module arguments */ char **pi_argv; - int pi_handler; /* handler which detected this device */ + struct pnphandler *pi_handler; /* handler which detected this device */ struct pnpinfo *pi_next; -} +}; struct pnphandler { - char *pp_name; /* handler/bus name */ - struct pnpinfo *(pp_enumerate *)(int index); /* return a string identifying device (index) */ + char *pp_name; /* handler/bus name */ + void (* pp_enumerate)(struct pnpinfo **); /* add detected devices to chain */ }; -extern struct pnphandler *pnphandlers[]; /* provided by MD code */ - +extern struct pnphandler *pnphandlers[]; /* provided by MD code */ + +extern void pnp_addident(struct pnpinfo *pi, char *ident); /* * Module metadata header. @@ -158,11 +169,21 @@ extern struct loaded_module *mod_findmodule(char *name, char *type); extern void mod_addmetadata(struct loaded_module *mp, int type, size_t size, void *p); extern struct module_metadata *mod_findmetadata(struct loaded_module *mp, int type); extern void mod_discard(struct loaded_module *mp); +extern struct loaded_module *mod_allocmodule(void); + + +/* MI module loaders */ +extern int aout_loadmodule(char *filename, vm_offset_t dest, struct loaded_module **result); +extern vm_offset_t aout_findsym(char *name, struct loaded_module *mp); + +/* extern int elf_loadmodule(char *filename, vm_offset_t dest, struct loaded_module **result); */ /* * Module information subtypes + * + * XXX these are copies of the defines in , and should be nuked + * XXX before being committed. */ -/* XXX these belong in */ #define MODINFO_NAME 0x0000 #define MODINFO_TYPE 0x0001 #define MODINFO_ADDR 0x0002 @@ -173,16 +194,12 @@ extern void mod_discard(struct loaded_module *mp); #define MODINFOMD_ELFHDR 0x0002 /* ELF header */ #define MODINFOMD_NOCOPY 0x8000 /* don't copy this metadata to the kernel */ -/* MI module loaders */ -extern int aout_loadmodule(char *filename, vm_offset_t dest, struct loaded_module **result); -extern vm_offset_t aout_findsym(char *name, struct loaded_module *mp); - -/* extern int elf_loadmodule(char *filename, vm_offset_t dest, struct loaded_module **result); */ - #define KLD_IDENT_SYMNAME "kld_identifier_" #define MODINFOMD_KLDIDENT (MODINFOMD_NOCOPY | 0x4000) #define MODINFOMD_KLDDEP (MODINFOMD_NOCOPY | 0x4001) + + #if defined(__ELF__) /* @@ -268,9 +285,15 @@ struct arch_switch int (*arch_copyout)(vm_offset_t src, void *dest, size_t len); /* Read from file to module address space, same semantics as read() */ int (*arch_readin)(int fd, vm_offset_t dest, size_t len); + /* Perform ISA byte port I/O (only for systems with ISA) */ + int (*arch_isainb)(int port); + void (*arch_isaoutb)(int port, int value); }; extern struct arch_switch archsw; +/* This must be provided by the MD code, but should it be in the archsw? */ +extern void delay(int delay); + /* * XXX these belong in a system header */ diff --git a/sys/boot/common/interp.c b/sys/boot/common/interp.c index c58b1c4..69a2fc3 100644 --- a/sys/boot/common/interp.c +++ b/sys/boot/common/interp.c @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: interp.c,v 1.2 1998/09/01 00:41:24 msmith Exp $ + * $Id: interp.c,v 1.3 1998/09/03 02:10:07 msmith Exp $ */ /* * Simple commandline interpreter, toplevel and misc. @@ -37,8 +37,6 @@ #define MAXARGS 20 /* maximum number of arguments allowed */ -extern int parse(int *argc, char ***argv, char *str); /* interp_parse.c */ - static void prompt(void); /* diff --git a/sys/boot/common/load_aout.c b/sys/boot/common/load_aout.c index 5c59372..3ecba66 100644 --- a/sys/boot/common/load_aout.c +++ b/sys/boot/common/load_aout.c @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: load_aout.c,v 1.1 1998/08/31 21:10:42 msmith Exp $ + * $Id: load_aout.c,v 1.2 1998/09/03 02:10:07 msmith Exp $ */ #include @@ -126,11 +126,11 @@ aout_loadmodule(char *filename, vm_offset_t dest, struct loaded_module **result) /* * Ok, we think we should handle this. */ - mp = malloc(sizeof(struct loaded_module)); - mp->m_name = kernel ? strdup(filename) : NULL; /* XXX should we prune the name? */ + mp = mod_allocmodule(); + if (kernel) + mp->m_name = strdup(filename); /* XXX should we prune the name? */ mp->m_type = strdup(kernel ? aout_kerneltype : aout_moduletype); - mp->m_args = NULL; /* filled in by parent */ - mp->m_metadata = NULL; + /* Page-align the load address */ addr = dest; pad = (u_int)addr & PAGE_MASK; diff --git a/sys/boot/common/module.c b/sys/boot/common/module.c index f10fe3b..d7f4019 100644 --- a/sys/boot/common/module.c +++ b/sys/boot/common/module.c @@ -23,14 +23,11 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: module.c,v 1.2 1998/08/31 21:10:42 msmith Exp $ + * $Id: module.c,v 1.3 1998/09/03 02:10:08 msmith Exp $ */ /* * module function dispatcher, support, etc. - * - * XXX need a 'searchmodule' function that takes a name and - * traverses a search path. */ #include @@ -40,12 +37,15 @@ static struct loaded_module *mod_loadmodule(char *name, int argc, char *argv[]); static char *mod_searchdep(struct loaded_module *mp); +static char *mod_searchfile(char *name); static char *mod_searchmodule(char *name); static void mod_append(struct loaded_module *mp); -/* XXX load address should be tweaked by first module loaded (kernel) */ +/* load address should be tweaked by first module loaded (kernel) */ static vm_offset_t loadaddr = 0; +static char *default_searchpath ="/;/boot"; + struct loaded_module *loaded_modules = NULL; /* @@ -231,9 +231,13 @@ mod_loadobj(char *type, char *name) return(CMD_ERROR); } - /* Try to come up with a fully-qualified name if we don't have one */ - if ((cp = mod_searchmodule(name)) != NULL) - name = cp; + /* locate the file on the load path */ + cp = mod_searchfile(name); + if (cp == NULL) { + sprintf(command_errbuf, "can't find '%s'", name); + return(CMD_ERROR); + } + name = cp; if ((fd = open(name, O_RDONLY)) < 0) { sprintf(command_errbuf, "can't open '%s': %s", name, strerror(errno)); @@ -282,9 +286,14 @@ mod_loadmodule(char *name, int argc, char *argv[]) int i, err; char *cp; - /* Try to come up with a fully-qualified name if we don't have one */ - if ((cp = mod_searchmodule(name)) != NULL) - name = cp; + /* locate the module on the search path */ + cp = mod_searchmodule(name); + if (cp == NULL) { + sprintf(command_errbuf, "can't find '%s'", name); + return(NULL); + } + name = cp; + err = 0; for (i = 0, mp = NULL; (module_formats[i] != NULL) && (mp == NULL); i++) { if ((err = (module_formats[i]->l_load)(name, loadaddr, &mp)) != 0) { @@ -422,7 +431,7 @@ mod_findmetadata(struct loaded_module *mp, int type) } /* - * Attempt to locate a kernel module file for the module (name). + * Attempt to find the file (name) on the module searchpath. * If (name) is qualified in any way, we simply check it and * return it or NULL. If it is not qualified, then we attempt * to construct a path using entries in the environment variable @@ -432,10 +441,10 @@ mod_findmetadata(struct loaded_module *mp, int type) * it internally. */ static char * -mod_searchmodule(char *name) +mod_searchfile(char *name) { static char *result = NULL; - static char *defpath = "/boot", *path; + char *path; char *cp, *sp; struct stat sb; @@ -458,7 +467,7 @@ mod_searchmodule(char *name) * Get the module path */ if ((cp = getenv("module_path")) == NULL) - cp = defpath; + cp = default_searchpath; sp = path = strdup(cp); /* @@ -467,9 +476,14 @@ mod_searchmodule(char *name) if (result != NULL) free(result); while((cp = strsep(&path, ";")) != NULL) { - result = malloc(strlen(cp) + strlen(name) + 2); - sprintf(result, "%s/%s", cp, name); - if (stat(result, &sb) == 0) + result = malloc(strlen(cp) + strlen(name) + 5); + strcpy(result, cp); + if (cp[strlen(cp) - 1] != '/') + strcat(result, "/"); + strcat(result, name); +/* printf("search '%s'\n", result); */ + if ((stat(result, &sb) == 0) && + S_ISREG(sb.st_mode)) break; free(result); result = NULL; @@ -479,6 +493,28 @@ mod_searchmodule(char *name) } /* + * Attempt to locate the file containing the module (name) + */ +static char * +mod_searchmodule(char *name) +{ + char *tn, *result; + + /* Look for (name).ko */ + tn = malloc(strlen(name) + 3); + strcpy(tn, name); + strcat(tn, ".ko"); + result = mod_searchfile(tn); + free(tn); + /* Look for just (name) (useful for finding kernels) */ + if (result == NULL) + result = mod_searchfile(name); + + return(result); +} + + +/* * Throw a module away */ void @@ -486,21 +522,39 @@ mod_discard(struct loaded_module *mp) { struct module_metadata *md; - while (mp->m_metadata != NULL) { - md = mp->m_metadata; - mp->m_metadata = mp->m_metadata->md_next; - free(md); - } - if (mp->m_name != NULL) - free(mp->m_name); - if (mp->m_type != NULL) - free(mp->m_type); - if (mp->m_args != NULL) - free(mp->m_args); - free(mp); + if (mp != NULL) { + while (mp->m_metadata != NULL) { + md = mp->m_metadata; + mp->m_metadata = mp->m_metadata->md_next; + free(md); + } + if (mp->m_name != NULL) + free(mp->m_name); + if (mp->m_type != NULL) + free(mp->m_type); + if (mp->m_args != NULL) + free(mp->m_args); + free(mp); + } } /* + * Allocate a new module; must be used instead of malloc() + * to ensure safe initialisation. + */ +struct loaded_module * +mod_allocmodule(void) +{ + struct loaded_module *mp; + + if ((mp = malloc(sizeof(struct loaded_module))) != NULL) { + bzero(mp, sizeof(struct loaded_module)); + } + return(mp); +} + + +/* * Add a module to the chain */ static void diff --git a/sys/boot/common/pnp.c b/sys/boot/common/pnp.c index d0b6061..84f3825 100644 --- a/sys/boot/common/pnp.c +++ b/sys/boot/common/pnp.c @@ -10,81 +10,97 @@ */ #include +#include #include static struct pnpinfo *pnp_devices = NULL; -static void pnp_discard(void); +static void pnp_discard(struct pnpinfo **list); +static int pnp_readconf(char *path); +static int pnp_scankernel(void); /* * Perform complete enumeration sweep, and load required module(s) if possible. */ +COMMAND_SET(pnpscan, "pnpscan", "scan for PnP devices", pnp_scan); + int -pnp_autoload(void) +pnp_scan(int argc, char *argv[]) { - int hdlr, idx; + int hdlr; /* forget anything we think we knew */ - pnp_discard(); + pnp_discard(&pnp_devices); /* iterate over all of the handlers */ - for (hdlr = 0; pnphandlers[hdlr]->pp_name != NULL; i++) { + for (hdlr = 0; pnphandlers[hdlr] != NULL; hdlr++) { printf("Probing bus '%s'...\n", pnphandlers[hdlr]->pp_name); - idx = 0; - while ((pi = pnphandlers[hdlr]->pp_enumerate(idx++)) != NULL) { - printf(" %s\n", pi->pi_ident); - pi->pi_handler = hdlr; - pi->pi_next = pnp_devices; - pnp_devices = pi; - } - } - /* find anything? */ - if (pnp_devices != NULL) { - /* XXX hardcoded paths! should use loaddev? */ - pnp_readconf("/boot/pnpdata.local"); - pnp_readconf("/boot/pnpdata"); - - pnp_reload(); + pnphandlers[hdlr]->pp_enumerate(&pnp_devices); } + return(CMD_OK); } /* * Try to load outstanding modules (eg. after disk change) */ int -pnp_reload(void) +pnp_reload(char *fname) { struct pnpinfo *pi; char *modfname; - /* try to load any modules that have been nominated */ - for (pi = pnp_devices; pi != NULL; pi = pi->pi_next) { - /* Already loaded? */ - if ((pi->pi_module != NULL) && (mod_findmodule(pi->pi_module, NULL) == NULL)) { - modfname = malloc(strlen(pi->pi_module + 3)); - sprintf(modfname, "%s.ko", pi->pi_module); /* XXX implicit knowledge of KLD module filenames */ - if (mod_load(pi->pi_module, pi->pi_argc, pi->pi_argv)) - printf("Could not load module '%s' for device '%s'\n", modfname, pi->pi_ident); - free(modfname); + /* find anything? */ + if (pnp_devices != NULL) { + + /* check for kernel, assign modules handled by static drivers there */ + if (pnp_scankernel()) { + command_errmsg = "cannot load drivers until kernel loaded"; + return(CMD_ERROR); + } + if (fname == NULL) { + /* default paths */ + pnp_readconf("/boot/pnpdata.local"); + pnp_readconf("/boot/pnpdata"); + } else { + if (pnp_readconf("fname")) { + sprintf(command_errbuf, "can't read PnP information from '%s'", fname); + return(CMD_ERROR); + } + } + + /* try to load any modules that have been nominated */ + for (pi = pnp_devices; pi != NULL; pi = pi->pi_next) { + /* Already loaded? */ + if ((pi->pi_module != NULL) && (mod_findmodule(pi->pi_module, NULL) == NULL)) { + modfname = malloc(strlen(pi->pi_module + 3)); + sprintf(modfname, "%s.ko", pi->pi_module); /* XXX implicit knowledge of KLD module filenames */ + if (mod_load(pi->pi_module, pi->pi_argc, pi->pi_argv)) + printf("Could not load module '%s' for device '%s'\n", modfname, pi->pi_ident->id_ident); + free(modfname); + } } } + return(CMD_OK); } - /* - * Throw away anything we think we know about PnP devices + * Throw away anything we think we know about PnP devices on (list) */ static void -pnp_discard(void) +pnp_discard(struct pnpinfo **list) { struct pnpinfo *pi; + struct pnpident *id; - while (pnp_devices != NULL) { - pi = pnp_devices; - pnp_devices = pnp_devices->pi_next; - if (pi->pi_ident) - free(pi->pi_ident); + while (*list != NULL) { + pi = *list; + *list = (*list)->pi_next; + while (pi->pi_ident) { + id = pi->pi_ident; + pi->pi_ident = pi->pi_ident->id_next; + free(id); + } if (pi->pi_module) free(pi->pi_module); if (pi->pi_argv) @@ -114,10 +130,11 @@ pnp_discard(void) * ignored (but should be used), and the 'args' field must come * last. */ -static void +static int pnp_readconf(char *path) { struct pnpinfo *pi; + struct pnpident *id; int fd, line; char lbuf[128], *currbus, *ident, *revision, *module, *args; char *cp, *ep, *tp, c; @@ -155,7 +172,7 @@ pnp_readconf(char *path) continue; /* mapping */ - for (ident = module = args = NULL; *cp != 0;) { + for (ident = module = args = revision = NULL; *cp != 0;) { /* discard leading whitespace */ if (isspace(*cp)) { @@ -164,12 +181,12 @@ pnp_readconf(char *path) } /* scan for terminator, separator */ - for (ep = cp; (*ep != 0) && (*ep != '=') && !isspace(ep); ep++) + for (ep = cp; (*ep != 0) && (*ep != '=') && !isspace(*ep); ep++) ; if (*ep == '=') { *ep = 0; - for (tp = ep + 1; (*tp != 0) && !isspace(tp); tp++) + for (tp = ep + 1; (*tp != 0) && !isspace(*tp); tp++) ; c = *tp; *tp = 0; @@ -200,22 +217,64 @@ pnp_readconf(char *path) } /* - * Loop looking for module/bus that might match this + * Loop looking for module/bus that might match this, but aren't already + * assigned. * XXX no revision parse/test here yet. */ - for (pi = pnp_modules; pi != NULL; pi = pi->pi_next) { - if (!strcmp(pnphandlers[pi->pi_handler]->pp_name, currbus) && - !strcmp(pi->pi_indent, ident)) { - if (args != NULL) - if (parse(&pi->pi_argc, &pi->pi_argv, args)) { - printf("%s line %d: bad arguments\n", path, line); + for (pi = pnp_devices; pi != NULL; pi = pi->pi_next) { + + /* no driver assigned, bus matches OK */ + if ((pi->pi_module == NULL) && + !strcmp(pi->pi_handler->pp_name, currbus)) { + + /* scan idents, take first match */ + for (id = pi->pi_ident; id != NULL; id = id->id_next) + if (!strcmp(id->id_ident, ident)) break; - } - pi->pi_module = strdup(module); + + /* find a match? */ + if (id != NULL) { + if (args != NULL) + if (parse(&pi->pi_argc, &pi->pi_argv, args)) { + printf("%s line %d: bad arguments\n", path, line); + continue; + } + pi->pi_module = strdup(module); + printf("use module '%s' for %s:%s\n", module, pi->pi_handler->pp_name, id->id_ident); + } } } } close(fd); } + return(CMD_OK); +} + +static int +pnp_scankernel(void) +{ + return(CMD_OK); +} + +/* + * Add a unique identifier to (pi) + */ +void +pnp_addident(struct pnpinfo *pi, char *ident) +{ + struct pnpident *id, **idp; + + if (pi->pi_ident == NULL) { + idp = &(pi->pi_ident); + } else { + for (id = pi->pi_ident; id->id_next != NULL; id = id->id_next) + if (!strcmp(id->id_ident, ident)) + return; /* already have this one */ + ; + idp = &(id->id_next); + } + *idp = malloc(sizeof(struct pnpident)); + (*idp)->id_next = NULL; + (*idp)->id_ident = strdup(ident); } -- cgit v1.1