123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163 |
- (* Aos, Copyright 2001, Pieter Muller, ETH Zurich *)
- MODULE BootConsole; (** AUTHOR "pjm"; PURPOSE "Boot console"; *)
- (*
- Config strings:
- BootVol# = prefix [hash] [cache] alias [volpar] ["|" fspar]. (* # is "1".."9" *)
- alias = gen gen . (* defines a volume and file system generator *)
- gen = mod "." cmd .
- Examples:
- BootVol1="AOS AosFS IDE0#2"
- BootVol2="RAM RamFS 2000 4096"
- AosFS="DiskVolumes.New DiskFS.NewFS"
- RamFS="RAMVolumes.New DiskFS.NewFS"
- RFS="RfsClientProxy.New RfsFS.NewFS"
- *)
- IMPORT
- Machine, Trace, KernelLog, Modules, Streams, Objects, Files, Commands;
- CONST
- ModuleName = "Console";
- TraceBoot = FALSE;
- PROCEDURE BootCommand(CONST config: ARRAY OF CHAR; flags: SET);
- VAR i, j: LONGINT; res: WORD; par: ARRAY 32 OF CHAR; s: ARRAY 256 OF CHAR;
- BEGIN
- COPY(config, par);
- i := 0; j := 0; WHILE par[j] # 0X DO INC(j) END;
- LOOP
- Machine.GetConfig(par, s);
- IF s # "" THEN
- IF TraceBoot THEN Trace.String("Bootconsole:Commands.Call: "); Trace.String(s); Trace.Ln END;
- Commands.Call(s, flags, res, s);
- IF (res # Commands.Ok) THEN KernelLog.Enter; KernelLog.String(s); KernelLog.Exit END
- END;
- INC(i);
- IF i = 10 THEN EXIT END;
- par[j] := CHR(ORD("0") + i); par[j+1] := 0X
- END
- END BootCommand;
- PROCEDURE GetString(VAR i: LONGINT; CONST r : ARRAY OF CHAR; VAR s: ARRAY OF CHAR): BOOLEAN;
- VAR j: LONGINT;
- BEGIN
- WHILE r[i] = " " DO INC(i) END;
- j := 0; WHILE r[i] > " " DO s[j] := r[i]; INC(j); INC(i) END;
- s[j] := 0X;
- IF TraceBoot THEN Trace.String("GetString: "); Trace.String(s); Trace.Ln END;
- RETURN j # 0
- END GetString;
- PROCEDURE Error(CONST config, val: ARRAY OF CHAR; i: LONGINT);
- VAR j: LONGINT; s: ARRAY 32 OF CHAR;
- BEGIN
- s := "BootConsole: Bad ";
- KernelLog.String(s);
- j := 0; WHILE s[j] # 0X DO INC(j) END; INC(i, j);
- KernelLog.String(config);
- j := 0; WHILE config[j] # 0X DO INC(j) END; INC(i, j);
- KernelLog.Char("="); KernelLog.Char(22X); INC(i, 2);
- KernelLog.String(val); KernelLog.Char(22X); KernelLog.Ln;
- WHILE i > 0 DO KernelLog.Char(" "); DEC(i) END;
- KernelLog.Char("^"); KernelLog.Ln
- END Error;
- PROCEDURE Generate(CONST name: ARRAY OF CHAR; par: Files.Parameters): BOOLEAN;
- VAR
- factory : Files.FileSystemFactory; res: WORD; msg: ARRAY 256 OF CHAR;
- moduleName, procedureName : Modules.Name;
- BEGIN
- Commands.Split(name, moduleName, procedureName, res, msg);
- IF (res = Commands.Ok) THEN
- GETPROCEDURE(moduleName, procedureName, factory);
- IF (factory # NIL) THEN
- factory(par);
- RETURN TRUE;
- ELSE
- KernelLog.String(ModuleName); KernelLog.String(": File system alias unknown"); KernelLog.Ln;
- END;
- ELSE
- KernelLog.String(ModuleName); KernelLog.String(": "); KernelLog.String(msg); KernelLog.Ln;
- END;
- RETURN FALSE;
- END Generate;
- PROCEDURE OpenVolume(CONST config: ARRAY OF CHAR);
- VAR
- i, j, k: LONGINT; parvol, parfs: Files.Parameters;
- volReady : BOOLEAN;
- prefix, alias: Files.Prefix; gen: ARRAY 64 OF CHAR; s: ARRAY 256 OF CHAR;
- argVol, argFs : Streams.StringReader;
- BEGIN
- Machine.GetConfig(config, s); (* s = prefix alias [volpar] ["|" fspar] . *)
- IF s = "" THEN RETURN END;
- i := 0;
- IF ~GetString(i, s, prefix) THEN Error(config, s, i); RETURN END;
- IF ~GetString(i, s, alias) THEN Error(config, s, i); RETURN END;
- (* generate volume generator parameter *)
- IF s[i] = " " THEN INC(i) END;
- j := 0; WHILE (s[i] # 0X) & (s[i] # "|") DO s[j] := s[i]; INC(i); INC(j) END;
- IF s[i] = "|" THEN INC(i) END;
- s[j] := 0X;
- NEW(argVol, j+1); argVol.SetRaw(s, 0, j+1);
- NEW(parvol, NIL, argVol, NIL, NIL, NIL);
- (* generate file system generator parameter *)
- j := 0; WHILE s[i] # 0X DO s[j] := s[i]; INC(i); INC(j) END;
- s[j] := 0X;
- NEW(argFs, j+1); argFs.SetRaw(s, 0, j+1);
- NEW(parfs, NIL, argFs, NIL, NIL, NIL);
- (* call volume generator *)
- Machine.GetConfig(alias, s); (* s = gen gen . ; gen = mod "." cmd . *)
- k := 0;
- IF ~GetString(k, s, gen) THEN Error(alias, s, k); RETURN END;
- (* call volume generator *)
- volReady := FALSE;
- IF gen = "NIL" THEN volReady := TRUE
- ELSE
- IF Generate(gen, parvol) & (parvol.vol # NIL) THEN
- INCL(parvol.vol.flags, Files.Boot); parfs.vol := parvol.vol;
- volReady := TRUE
- END
- END;
- IF volReady THEN
- COPY(prefix, parfs.prefix);
- (* call file system generator *)
- IF GetString(k, s, gen) THEN
- IF Generate(gen, parfs) THEN parvol.vol := NIL END
- ELSE
- Error(alias, s, k)
- END
- END;
- IF Files.This(prefix) = NIL THEN
- KernelLog.String("BootConsole: Mount failed on "); KernelLog.String(config); KernelLog.Ln;
- IF parvol.vol # NIL THEN
- parvol.vol.Finalize() (* unmount volume *)
- END
- END;
- parfs.out.Update; parfs.error.Update;
- parvol.out.Update; parvol.error.Update;
- END OpenVolume;
- PROCEDURE OpenVolumes;
- VAR config: ARRAY 16 OF CHAR; i: LONGINT;
- BEGIN
- config := "BootVol#";
- FOR i := 1 TO 9 DO
- config[7] := CHR(ORD("0") + i); config[8] := 0X;
- OpenVolume(config)
- END
- END OpenVolumes;
- BEGIN
- OpenVolumes;
- BootCommand("Boot", {Commands.Wait});
- BootCommand("BootSystem", {});
- Objects.Terminate();
- END BootConsole.
|