📄 boot.c
字号:
device= tmpdev.device; if (!dev_geometry()) return B_NODEV; active->lowsec= 0; /* Select a partition table entry. */ while (tmpdev.primary >= 0) { masterpos= active->lowsec; if ((r= get_master(master, table, masterpos)) != 0) return r; active= table[tmpdev.primary]; /* How does one check a partition table entry? */ if (active->sysind == NO_PART) return B_NOSIG; tmpdev.primary= tmpdev.secondary; tmpdev.secondary= -1; } if (activate && !active->bootind) { for (n= 0; n < NR_PARTITIONS; n++) table[n]->bootind= 0; active->bootind= ACTIVE_FLAG; dirty= 1; } /* Read the boot sector. */ if ((r= readsectors(0, BOOTSEG, active->lowsec, 1)) != 0) return r; /* Check signature word. */ if (get_word(SIGNATPOS, BOOTSEG) != SIGNATURE) return B_NOSIG; /* Write the partition table if a member must be made active. */ if (dirty && (r= writesectors((u16_t) master, dseg, masterpos, 1)) != 0) return r; bootstrap(device, (u16_t) active, dseg);}void boot_device(devname) char *devname;{ dev_t dev= name2dev(devname); int r; if (tmpdev.device < 0) { if (dev != -1) printf("Can't boot from %s\n", devname); return; } switch (r= exec_bootstrap()) { case B_NODEV: printf("%s: device not present\n", devname); break; case B_NOSIG: printf("%s is not bootable\n", devname); break; default: printf("Can't boot %s: %s\n", devname, bios_err(r)); } device= bootdev.device; (void) dev_geometry(); /* Restore boot device setting. */}void ls(dir) char *dir;{ ino_t ino; struct stat st; char name[NAME_MAX+1]; if (!fsok) return; if ((ino= r_lookup(ROOT_INO, dir)) == 0 || (r_stat(ino, &st), r_readdir(name)) == -1 ) { printf("ls: %s: %s\n", dir, unix_err(errno)); return; } (void) r_readdir(name); /* Skip ".." too. */ while ((ino= r_readdir(name)) != 0) printf("%s/%s\n", dir, name);}char *Thandler;u32_t Tbase, Tcount;void unschedule()/* Invalidate a waiting command. */{ if (Thandler != nil) { free((void *) Thandler); Thandler= nil; }}void schedule(msec, cmd) long msec; char *cmd;/* Schedule command at a certain time from now. */{ unschedule(); Thandler= cmd; Tbase= get_tick(); Tcount= (msec + MSEC_PER_TICK - 1) / MSEC_PER_TICK;}int expired()/* Check if the timer expired. If so prepend the scheduled command to * the command chain and return 1. */{ int fundef= 0; if (Thandler == nil || (get_tick() - Tbase) < Tcount) return 0; (void) tokenize(tokenize(&cmds, Thandler, &fundef), ";", &fundef); unschedule(); return 1;}int delay(msec) char *msec;/* Delay for a given time. Returns true iff delay was not interrupted. * Make sure get_tick is not called for nonpositive msec, because get_tick * may do funny things on the original IBM PC (not the XT!). * If msec happens to be the string "swap" then wait till the user hits * return after changing diskettes. */{ int swap= 0; u32_t base, count; if (strcmp(msec, "swap") == 0) { swap= 1; count= 0; printf("\nInsert the root diskette then hit RETURN\n"); } else if ((count= a2l(msec)) > 0) { count/= MSEC_PER_TICK; base= get_tick(); } do { switch (peekchar()) { case 0: break; case ESC: interrupt(); return 0; case '\n': swap= 0; default: (void) getchar(); } } while (!expired() && (swap || (count > 0 && (get_tick() - base) < count)) ); return 1;}enum whatfun { NOFUN, SELECT, DEFFUN, USERFUN } menufun(e) environment *e;{ if (!(e->flags & E_FUNCTION) || e->arg[0] == 0) return NOFUN; if (e->arg[1] != ',') return SELECT; return e->flags & E_RESERVED ? DEFFUN : USERFUN;}void menu()/* By default: Show a simple menu. * Multiple kernels/images: Show extra selection options. * User defined function: Kill the defaults and show these. * Wait for a keypress and execute the given function. */{ int fundef= 0, c, def= 1; char *choice= nil; environment *e; /* Just a default menu? */ for (e= env; e != nil; e= e->next) if (menufun(e) == USERFUN) def= 0; printf("\nHit a key as follows:\n\n"); /* Show the choices. */ for (e= env; e != nil; e= e->next) { switch (menufun(e)) { case DEFFUN: if (!def) break; case USERFUN: printf(" %c %s\n", e->arg[0], e->arg+2); break; case SELECT: printf(" %c Select %s kernel\n", e->arg[0],e->name); } } /* Wait for a keypress. */ do { while (peekchar() == 0) if (expired()) return; if ((c= getchar()) == ESC) { interrupt(); return; } for (e= env; e != nil; e= e->next) { switch (menufun(e)) { case DEFFUN: if (!def) break; case USERFUN: case SELECT: if (c == e->arg[0]) choice= e->value; } } } while (choice == nil); /* Execute the chosen function. */ printf("%c\n", c); (void) tokenize(&cmds, choice, &fundef);}void execute()/* Get one command from the command chain and execute it. Legal commands are * listed at the end. */{ token *second, *third, *fourth, *fifth, *sep; char *name= cmds->token; size_t n= 0; /* There must be a separator lurking somewhere. */ for (sep= cmds; sep != nil && sep->token[0] != ';'; sep= sep->next) n++; if ((second= cmds->next) != nil && (third= second->next) != nil && (fourth= third->next) != nil) fifth= fourth->next; /* Null command? */ if (n == 0) { voidtoken(); return; } else /* name = [device] value? */ if ((n == 3 || n == 4) && !sugar(name) && second->token[0] == '=' && !sugar(third->token) && (n == 3 || (n == 4 && third->token[0] == 'd' && !sugar(fourth->token) ))) { char *value= third->token; int flags= E_VAR; if (n == 4) { value= fourth->token; flags|= E_DEV; } if ((flags= b_setvar(flags, name, value)) != 0) { printf("%s is a %s\n", name, flags & E_RESERVED ? "reserved word" : "special function"); void_cmds(); } else while (cmds != sep) voidtoken(); return; } else /* name '(' arg ')' '{' ... '}'? */ if (n >= 5 && !sugar(name) && second->token[0] == '(' && fourth->token[0] == ')' && fifth->token[0] == '{' ) { token *fun= fifth->next; int ok= 1, flags; char *body; size_t len= 1; sep= fun; while (sep != nil && sep->token[0] != '}') { len+= strlen(sep->token) + 1; sep= sep->next; } if (sep == nil || (sep= sep->next) == nil || sep->token[0] != ';' ) ok= 0; if (ok) { body= (char *) malloc(len * sizeof(char)); *body= 0; while (fun->token[0] != '}') { strcat(body, fun->token); if (!sugar(fun->token) && !sugar(fun->next->token) ) strcat(body, " "); fun= fun->next; } if ((flags= b_setenv(E_FUNCTION, name, third->token, body)) != 0) { printf("%s is a %s\n", name, flags & E_RESERVED ? "reserved word" : "special variable"); void_cmds(); } else while (cmds != sep) voidtoken(); free((void *) body); return; } } else /* Command coming up, check if ESC typed. */ if (peekchar() == ESC) { interrupt(); return; } else /* unset name ..., echo word ...? */ if (n >= 1 && ( strcmp(name, "unset") == 0 || strcmp(name, "echo") == 0 )) { int cmd= name[0]; char *arg= poptoken(); for (;;) { free((void *) arg); if (cmds == sep) break; arg= poptoken(); if (cmd == 'u') b_unset(arg); else { printf("%s", arg); if (cmds != sep) putchar(' '); } } if (cmd == 'e') putchar('\n'); return; } else /* boot device, ls dir, delay msec? */ if (n == 2 && ( strcmp(name, "boot") == 0 || strcmp(name, "delay") == 0 || strcmp(name, "ls") == 0 )) { int cmd= name[0]; char *arg; voidtoken(); arg= poptoken(); switch (cmd) { case 'b': boot_device(arg); break; case 'd': (void) delay(arg); break; case 'l': ls(arg); } free((void *) arg); return; } else /* trap msec command? */ if (n == 3 && strcmp(name, "trap") == 0 && numeric(second->token)) { long msec= a2l(second->token); voidtoken(); voidtoken(); schedule(msec, poptoken()); return; } else /* Simple command. */ if (n == 1) { char *cmd= poptoken(); char *body; int fundef= 0; int ok= 0; if (strcmp(cmd, "boot") == 0) { minix(); ok= 1; } if (strcmp(cmd, "delay") == 0) { (void) delay("500"); ok= 1; } if (strcmp(cmd, "ls") == 0) { ls(null); ok= 1; } if (strcmp(cmd, "menu") == 0) { menu(); ok= 1; } if (strcmp(cmd, "save") == 0) { save_parameters(); ok= 1; } if (strcmp(cmd, "set") == 0) { show_env(); ok= 1; } /* Command to check bootparams: */ if (strcmp(cmd, ":") == 0) ok= 1; /* User defined function. */ if (!ok && (body= b_body(cmd)) != nil) { (void) tokenize(&cmds, body, &fundef); ok= 1; } if (!ok) printf("%s: unknown function", cmd); free((void *) cmd); if (ok) return; } else { /* Syntax error. */ printf("Can't parse:"); while (cmds != sep) { printf(" %s", cmds->token); voidtoken(); } } /* Getting here means that the command is not understood. */ printf("\nLegal commands:\n"); printf(" name = [device] value - Set environment variable\n"); printf(" name(arg) { ... } - Define function\n"); printf(" name - Call function\n"); printf(" boot [device] - Boot Minix or another O.S.\n"); printf(" delay [msec] - Delay (500 msec default)\n"); printf(" echo word ... - Print these words\n"); printf(" ls [directory] - List contents of directory\n"); printf(" menu - Simple menu driven startup\n"); printf(" save - Save environment\n"); printf(" set - Show environment\n"); printf(" trap msec command - Schedule command\n"); printf(" unset name ... - Unset environment variables\n"); void_cmds();}void monitor()/* Read one or more lines and tokenize them. */{ char *line; int fundef= 0; token **acmds= &cmds; unschedule(); /* Kill a trap. */ do { putchar(fundef == 0 ? '>' : '+'); line= readline(); acmds= tokenize(acmds, line, &fundef); free((void *) line); } while (fundef != 0);}void boot()/* Load Minix and start it, among other things. */{ /* Print greeting message. The copyright message is not yet displayed, * because this boot program need not necessarily start Minix. */ reset_video(get_video() & 1); printf("\nMinix boot monitor %s\n", version); printf("\nPress ESC to enter the monitor\n"); /* Relocate program to end of memory. */ migrate(); /* Initialize tables. */ initialize(); /* Block cache. */ init_cache(); /* Get environment variables from the parameter sector. */ get_parameters(); /* Read and check the superblock. */ fsok= r_super() != 0; while (1) { /* While there are commands, execute them! */ while (cmds != nil) { execute(); (void) expired(); } /* The "monitor" is just a "read one command" thing. */ monitor(); }}/* Kees J. Bot 27-12-91. */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -