1 /* $NetBSD: bootstrap.h,v 1.9 2014/03/25 18:35:32 christos Exp $ */ 2 3 /*- 4 * Copyright (c) 1998 Michael Smith <msmith@freebsd.org> 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 * 28 * $FreeBSD: src/sys/boot/common/bootstrap.h,v 1.38.6.1 2004/09/03 19:25:40 iedowse Exp $ 29 */ 30 31 #ifndef _BOOTSTRAP_H_ 32 #define _BOOTSTRAP_H_ 33 34 #include <sys/types.h> 35 #include <sys/queue.h> 36 37 /* 38 * Generic device specifier; architecture-dependent 39 * versions may be larger, but should be allowed to 40 * overlap. 41 */ 42 43 struct devdesc 44 { 45 struct devsw *d_dev; 46 int d_type; 47 #define DEVT_NONE 0 48 #define DEVT_DISK 1 49 #define DEVT_NET 2 50 #define DEVT_CD 3 51 }; 52 53 typedef int (bootblk_cmd_t)(int argc, char *argv[]); 54 int command_seterr(const char *fmt, ...) __printflike(1, 2); 55 const char *command_geterr(void); 56 57 #define CMD_OK 0 58 #define CMD_ERROR 1 59 60 61 /* interp.c */ 62 void interact(void); 63 int include(const char *filename); 64 65 /* interp_backslash.c */ 66 char *backslash(char *str); 67 68 /* interp_parse.c */ 69 int parse(int *argc, char ***argv, char *str); 70 71 /* interp_forth.c */ 72 void bf_init(void); 73 int bf_run(char *line); 74 75 /* boot.c */ 76 int autoboot(int timeout, char *prompt); 77 void autoboot_maybe(void); 78 int getrootmount(char *rootdev); 79 80 /* misc.c */ 81 char *unargv(int argc, char *argv[]); 82 void hexdump(void *region, size_t len); 83 size_t strlenout(vaddr_t str); 84 char *strdupout(vaddr_t str); 85 void kern_bzero(vaddr_t dest, size_t len); 86 int kern_pread(int fd, vaddr_t dest, size_t len, off_t off); 87 void *alloc_pread(int fd, off_t off, size_t len); 88 89 /* bcache.c */ 90 int bcache_init(u_int nblks, size_t bsize); 91 void bcache_flush(void); 92 int bcache_strategy(void *devdata, int unit, int rw, daddr_t blk, 93 size_t size, char *buf, size_t *rsize); 94 95 96 /* strdup.c */ 97 char *strdup(const char*); 98 99 /* 100 * Disk block cache 101 */ 102 struct bcache_devdata 103 { 104 int (*dv_strategy)(void *devdata, int rw, daddr_t blk, size_t size, char *buf, size_t *rsize); 105 void *dv_devdata; 106 }; 107 108 /* 109 * Modular console support. 110 */ 111 struct console 112 { 113 const char *c_name; 114 const char *c_desc; 115 int c_flags; 116 #define C_PRESENTIN (1<<0) 117 #define C_PRESENTOUT (1<<1) 118 #define C_ACTIVEIN (1<<2) 119 #define C_ACTIVEOUT (1<<3) 120 void (* c_probe)(struct console *cp); /* set c_flags to match hardware */ 121 int (* c_init)(int arg); /* reinit XXX may need more args */ 122 void (* c_out)(int c); /* emit c */ 123 int (* c_in)(void); /* wait for and return input */ 124 int (* c_ready)(void); /* return nonzer if input waiting */ 125 }; 126 extern struct console *consoles[]; 127 void cons_probe(void); 128 int ischar(void); 129 130 /* 131 * Plug-and-play enumerator/configurator interface. 132 */ 133 struct pnphandler 134 { 135 const char *pp_name; /* handler/bus name */ 136 void (* pp_enumerate)(void); /* enumerate PnP devices, add to chain */ 137 }; 138 139 struct pnpident 140 { 141 char *id_ident; /* ASCII identifier, actual format varies with bus/handler */ 142 STAILQ_ENTRY(pnpident) id_link; 143 }; 144 145 struct pnpinfo 146 { 147 char *pi_desc; /* ASCII description, optional */ 148 int pi_revision; /* optional revision (or -1) if not supported */ 149 char *pi_module; /* module/args nominated to handle device */ 150 int pi_argc; /* module arguments */ 151 char **pi_argv; 152 struct pnphandler *pi_handler; /* handler which detected this device */ 153 STAILQ_HEAD(,pnpident) pi_ident; /* list of identifiers */ 154 STAILQ_ENTRY(pnpinfo) pi_link; 155 }; 156 157 STAILQ_HEAD(pnpinfo_stql, pnpinfo); 158 159 extern struct pnpinfo_stql pnp_devices; 160 161 extern struct pnphandler *pnphandlers[]; /* provided by MD code */ 162 163 void pnp_addident(struct pnpinfo *pi, char *ident); 164 struct pnpinfo *pnp_allocinfo(void); 165 void pnp_freeinfo(struct pnpinfo *pi); 166 void pnp_addinfo(struct pnpinfo *pi); 167 char *pnp_eisaformat(u_int8_t *data); 168 169 /* 170 * < 0 - No ISA in system 171 * == 0 - Maybe ISA, search for read data port 172 * > 0 - ISA in system, value is read data port address 173 */ 174 extern int isapnp_readport; 175 176 struct preloaded_file; 177 178 /* 179 * Preloaded file information. Depending on type, file can contain 180 * additional units called 'modules'. 181 * 182 * At least one file (the kernel) must be loaded in order to boot. 183 * The kernel is always loaded first. 184 * 185 * String fields (m_name, m_type) should be dynamically allocated. 186 */ 187 struct preloaded_file 188 { 189 char *f_name; /* file name */ 190 char *f_type; /* verbose file type, eg 'ELF kernel', 'pnptable', etc. */ 191 char *f_args; /* arguments for the file */ 192 int f_loader; /* index of the loader that read the file */ 193 vaddr_t f_addr; /* load address */ 194 size_t f_size; /* file size */ 195 struct preloaded_file *f_next; /* next file */ 196 u_long marks[MARK_MAX];/* filled by loadfile() */ 197 }; 198 199 struct file_format 200 { 201 /* Load function must return EFTYPE if it can't handle the module supplied */ 202 int (* l_load)(char *filename, u_int64_t dest, struct preloaded_file **result); 203 /* Only a loader that will load a kernel (first module) should have an exec handler */ 204 int (* l_exec)(struct preloaded_file *mp); 205 }; 206 207 extern struct file_format *file_formats[]; /* supplied by consumer */ 208 extern struct preloaded_file *preloaded_files; 209 210 int mod_load(char *name, int argc, char *argv[]); 211 int mod_loadkld(const char *name, int argc, char *argv[]); 212 213 struct preloaded_file *file_alloc(void); 214 struct preloaded_file *file_findfile(char *name, char *type); 215 216 int file_loadkernel(char *filename, int argc, char *argv[]); 217 void file_discard(struct preloaded_file *fp); 218 219 int elf64_loadfile(char *filename, u_int64_t dest, struct preloaded_file **result); 220 221 /* 222 * Support for commands 223 */ 224 struct bootblk_command 225 { 226 const char *c_name; 227 const char *c_desc; 228 bootblk_cmd_t *c_fn; 229 }; 230 231 /* Prototypes for the command handlers within stand/common/ */ 232 233 /* command.c */ 234 235 int command_help(int argc, char *argv[]) ; 236 int command_commandlist(int argc, char *argv[]); 237 int command_show(int argc, char *argv[]); 238 int command_set(int argc, char *argv[]); 239 int command_unset(int argc, char *argv[]); 240 int command_echo(int argc, char *argv[]); 241 int command_read(int argc, char *argv[]); 242 int command_more(int argc, char *argv[]); 243 int command_lsdev(int argc, char *argv[]); 244 245 /* bcache.c XXX: Fixme: Do we need the bcache ?*/ 246 /* int command_bcache(int argc, char *argv[]); */ 247 /* boot.c */ 248 int command_boot(int argc, char *argv[]); 249 int command_autoboot(int argc, char *argv[]); 250 /* fileload.c */ 251 int command_load(int argc, char *argv[]); 252 int command_unload(int argc, char *argv[]); 253 int command_lskern(int argc, char *argv[]); 254 /* interp.c */ 255 int command_include(int argc, char *argv[]); 256 /* ls.c */ 257 int command_ls(int argc, char *argv[]); 258 259 #define COMMAND_SET(a, b, c, d) /* nothing */ 260 261 #define COMMON_COMMANDS \ 262 /* common.c */ \ 263 { "help", "detailed help", command_help }, \ 264 { "?", "list commands", command_commandlist }, \ 265 { "show", "show variable(s)", command_show }, \ 266 { "set", "set a variable", command_set }, \ 267 { "unset", "unset a variable", command_unset }, \ 268 { "echo", "echo arguments", command_echo }, \ 269 { "read", "read input from the terminal", command_read }, \ 270 { "more", "show contents of a file", command_more }, \ 271 { "lsdev", "list all devices", command_lsdev }, \ 272 \ 273 /* bcache.c XXX: Fixme: Do we need the bcache ? */ \ 274 \ 275 /* { "bcachestat", "get disk block cache stats", command_bcache }, */\ 276 \ 277 /* boot.c */ \ 278 \ 279 { "boot", "boot a file or loaded kernel", command_boot }, \ 280 { "autoboot", "boot automatically after a delay", command_autoboot }, \ 281 \ 282 /* fileload.c */ \ 283 \ 284 { "load", "load a kernel", command_load }, \ 285 { "unload", "unload all modules", command_unload }, \ 286 { "lskern", "list loaded kernel", command_lskern }, \ 287 \ 288 /* interp.c */ \ 289 \ 290 { "include", "read commands from a file", command_include }, \ 291 \ 292 /* ls.c */ \ 293 \ 294 { "ls", "list files", command_ls } 295 296 extern struct bootblk_command commands[]; 297 298 299 /* 300 * The intention of the architecture switch is to provide a convenient 301 * encapsulation of the interface between the bootstrap MI and MD code. 302 * MD code may selectively populate the switch at runtime based on the 303 * actual configuration of the target system. 304 */ 305 struct arch_switch 306 { 307 /* Automatically load modules as required by detected hardware */ 308 int (*arch_autoload)(void); 309 /* Locate the device for (name), return pointer to tail in (*path) */ 310 int (*arch_getdev)(void **dev, const char *name, const char **path); 311 /* Copy from local address space to module address space, similar to bcopy() */ 312 ssize_t (*arch_copyin)(const void *src, vaddr_t dest, 313 const size_t len); 314 /* Copy to local address space from module address space, similar to bcopy() */ 315 ssize_t (*arch_copyout)(const vaddr_t src, void *dest, 316 const size_t len); 317 /* Read from file to module address space, same semantics as read() */ 318 ssize_t (*arch_readin)(const int fd, vaddr_t dest, 319 const size_t len); 320 /* Perform ISA byte port I/O (only for systems with ISA) */ 321 int (*arch_isainb)(int port); 322 void (*arch_isaoutb)(int port, int value); 323 }; 324 extern struct arch_switch archsw; 325 326 /* This must be provided by the MD code, but should it be in the archsw? */ 327 void delay(int delay); 328 329 void dev_cleanup(void); 330 331 time_t time(time_t *tloc); 332 333 /* calloc.c */ 334 void *calloc(unsigned int, unsigned int); 335 336 /* various string functions */ 337 size_t strspn(const char *s1, const char *s2); 338 size_t strlen(const char *s); 339 char *strcpy(char * restrict dst, const char * restrict src); 340 char *strcat(char * restrict s, const char * restrict append); 341 342 /* pager.c */ 343 extern void pager_open(void); 344 extern void pager_close(void); 345 extern int pager_output(const char *lines); 346 extern int pager_file(const char *fname); 347 348 /* environment.c */ 349 #define EV_DYNAMIC (1<<0) /* value was dynamically allocated, free if changed/unset */ 350 #define EV_VOLATILE (1<<1) /* value is volatile, make a copy of it */ 351 #define EV_NOHOOK (1<<2) /* don't call hook when setting */ 352 353 struct env_var; 354 typedef char *(ev_format_t)(struct env_var *ev); 355 typedef int (ev_sethook_t)(struct env_var *ev, int flags, 356 const void *value); 357 typedef int (ev_unsethook_t)(struct env_var *ev); 358 359 struct env_var 360 { 361 char *ev_name; 362 int ev_flags; 363 void *ev_value; 364 ev_sethook_t *ev_sethook; 365 ev_unsethook_t *ev_unsethook; 366 struct env_var *ev_next, *ev_prev; 367 }; 368 extern struct env_var *environ; 369 370 extern struct env_var *env_getenv(const char *name); 371 extern int env_setenv(const char *name, int flags, 372 const void *value, ev_sethook_t sethook, 373 ev_unsethook_t unsethook); 374 extern char *getenv(const char *name); 375 extern int setenv(const char *name, const char *value, 376 int overwrite); 377 extern int putenv(const char *string); 378 extern int unsetenv(const char *name); 379 380 extern ev_sethook_t env_noset; /* refuse set operation */ 381 extern ev_unsethook_t env_nounset; /* refuse unset operation */ 382 383 384 385 /* FreeBSD wrappers */ 386 387 388 struct dirent *readdirfd(int); /* XXX move to stand.h */ 389 390 #define free(ptr) dealloc(ptr, 0) /* XXX UGLY HACK!!! This should work for just now though. See: libsa/alloc.c:free() */ 391 392 /* XXX Hack Hack Hack!!! Need to update stand.h with fs_ops->fo_readdir */ 393 #ifdef SKIFS /* defined via stand/ia64/ski/Makefile */ 394 #define FS_READDIR(f, dirptr) skifs_readdir(f, dirptr) 395 #else 396 #define FS_READDIR(f, dirptr) efifs_readdir(f, dirptr) 397 #endif 398 399 /* gets.c XXX move to libsa/ */ 400 401 extern int fgetstr(char *buf, int size, int fd); 402 extern void ngets(char *, int); 403 404 /* imports from stdlib, modified for sa */ 405 406 extern long strtol(const char *, char **, int); 407 extern char *optarg; /* getopt(3) external variables */ 408 extern int optind, opterr, optopt, optreset; 409 extern int getopt(int, char * const [], const char *); 410 411 extern long strtol(const char *, char **, int); 412 413 /* XXX: From <fcntl.h>. Its not very _STANDALONE friendly */ 414 /* open-only flags */ 415 #define O_RDONLY 0x00000000 /* open for reading only */ 416 #define O_WRONLY 0x00000001 /* open for writing only */ 417 #define O_RDWR 0x00000002 /* open for reading and writing */ 418 #define O_ACCMODE 0x00000003 /* mask for above modes */ 419 420 #define ELF64_KERNELTYPE "elf kernel" 421 422 #endif /* _BOOTSTRAP_H_ */ 423