MODULE BootConsole;
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, res: LONGINT; 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: LONGINT; 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);
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;
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);
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);
Machine.GetConfig(alias, s);
k := 0;
IF ~GetString(k, s, gen) THEN Error(alias, s, k); RETURN END;
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);
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()
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.