BootConsole.Mod 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. (* Aos, Copyright 2001, Pieter Muller, ETH Zurich *)
  2. MODULE BootConsole; (** AUTHOR "pjm"; PURPOSE "Boot console"; *)
  3. (*
  4. Config strings:
  5. BootVol# = prefix [hash] [cache] alias [volpar] ["|" fspar]. (* # is "1".."9" *)
  6. alias = gen gen . (* defines a volume and file system generator *)
  7. gen = mod "." cmd .
  8. Examples:
  9. BootVol1="AOS AosFS IDE0#2"
  10. BootVol2="RAM RamFS 2000 4096"
  11. AosFS="DiskVolumes.New DiskFS.NewFS"
  12. RamFS="RAMVolumes.New DiskFS.NewFS"
  13. RFS="RfsClientProxy.New RfsFS.NewFS"
  14. *)
  15. IMPORT
  16. Machine, Trace, KernelLog, Modules, Streams, Objects, Files, Commands;
  17. CONST
  18. ModuleName = "Console";
  19. TraceBoot = FALSE;
  20. PROCEDURE BootCommand(CONST config: ARRAY OF CHAR; flags: SET);
  21. VAR i, j, res: LONGINT; par: ARRAY 32 OF CHAR; s: ARRAY 256 OF CHAR;
  22. BEGIN
  23. COPY(config, par);
  24. i := 0; j := 0; WHILE par[j] # 0X DO INC(j) END;
  25. LOOP
  26. Machine.GetConfig(par, s);
  27. IF s # "" THEN
  28. IF TraceBoot THEN Trace.String("Bootconsole:Commands.Call: "); Trace.String(s); Trace.Ln END;
  29. Commands.Call(s, flags, res, s);
  30. IF (res # Commands.Ok) THEN KernelLog.Enter; KernelLog.String(s); KernelLog.Exit END
  31. END;
  32. INC(i);
  33. IF i = 10 THEN EXIT END;
  34. par[j] := CHR(ORD("0") + i); par[j+1] := 0X
  35. END
  36. END BootCommand;
  37. PROCEDURE GetString(VAR i: LONGINT; CONST r : ARRAY OF CHAR; VAR s: ARRAY OF CHAR): BOOLEAN;
  38. VAR j: LONGINT;
  39. BEGIN
  40. WHILE r[i] = " " DO INC(i) END;
  41. j := 0; WHILE r[i] > " " DO s[j] := r[i]; INC(j); INC(i) END;
  42. s[j] := 0X;
  43. IF TraceBoot THEN Trace.String("GetString: "); Trace.String(s); Trace.Ln END;
  44. RETURN j # 0
  45. END GetString;
  46. PROCEDURE Error(CONST config, val: ARRAY OF CHAR; i: LONGINT);
  47. VAR j: LONGINT; s: ARRAY 32 OF CHAR;
  48. BEGIN
  49. s := "BootConsole: Bad ";
  50. KernelLog.String(s);
  51. j := 0; WHILE s[j] # 0X DO INC(j) END; INC(i, j);
  52. KernelLog.String(config);
  53. j := 0; WHILE config[j] # 0X DO INC(j) END; INC(i, j);
  54. KernelLog.Char("="); KernelLog.Char(22X); INC(i, 2);
  55. KernelLog.String(val); KernelLog.Char(22X); KernelLog.Ln;
  56. WHILE i > 0 DO KernelLog.Char(" "); DEC(i) END;
  57. KernelLog.Char("^"); KernelLog.Ln
  58. END Error;
  59. PROCEDURE Generate(CONST name: ARRAY OF CHAR; par: Files.Parameters): BOOLEAN;
  60. VAR
  61. factory : Files.FileSystemFactory; res: WORD; msg: ARRAY 256 OF CHAR;
  62. moduleName, procedureName : Modules.Name;
  63. BEGIN
  64. Commands.Split(name, moduleName, procedureName, res, msg);
  65. IF (res = Commands.Ok) THEN
  66. GETPROCEDURE(moduleName, procedureName, factory);
  67. IF (factory # NIL) THEN
  68. factory(par);
  69. RETURN TRUE;
  70. ELSE
  71. KernelLog.String(ModuleName); KernelLog.String(": File system alias unknown"); KernelLog.Ln;
  72. END;
  73. ELSE
  74. KernelLog.String(ModuleName); KernelLog.String(": "); KernelLog.String(msg); KernelLog.Ln;
  75. END;
  76. RETURN FALSE;
  77. END Generate;
  78. PROCEDURE OpenVolume(CONST config: ARRAY OF CHAR);
  79. VAR
  80. i, j, k: LONGINT; parvol, parfs: Files.Parameters;
  81. volReady : BOOLEAN;
  82. prefix, alias: Files.Prefix; gen: ARRAY 64 OF CHAR; s: ARRAY 256 OF CHAR;
  83. argVol, argFs : Streams.StringReader;
  84. BEGIN
  85. Machine.GetConfig(config, s); (* s = prefix alias [volpar] ["|" fspar] . *)
  86. IF s = "" THEN RETURN END;
  87. i := 0;
  88. IF ~GetString(i, s, prefix) THEN Error(config, s, i); RETURN END;
  89. IF ~GetString(i, s, alias) THEN Error(config, s, i); RETURN END;
  90. (* generate volume generator parameter *)
  91. IF s[i] = " " THEN INC(i) END;
  92. j := 0; WHILE (s[i] # 0X) & (s[i] # "|") DO s[j] := s[i]; INC(i); INC(j) END;
  93. IF s[i] = "|" THEN INC(i) END;
  94. s[j] := 0X;
  95. NEW(argVol, j+1); argVol.SetRaw(s, 0, j+1);
  96. NEW(parvol, NIL, argVol, NIL, NIL, NIL);
  97. (* generate file system generator parameter *)
  98. j := 0; WHILE s[i] # 0X DO s[j] := s[i]; INC(i); INC(j) END;
  99. s[j] := 0X;
  100. NEW(argFs, j+1); argFs.SetRaw(s, 0, j+1);
  101. NEW(parfs, NIL, argFs, NIL, NIL, NIL);
  102. (* call volume generator *)
  103. Machine.GetConfig(alias, s); (* s = gen gen . ; gen = mod "." cmd . *)
  104. k := 0;
  105. IF ~GetString(k, s, gen) THEN Error(alias, s, k); RETURN END;
  106. (* call volume generator *)
  107. volReady := FALSE;
  108. IF gen = "NIL" THEN volReady := TRUE
  109. ELSE
  110. IF Generate(gen, parvol) & (parvol.vol # NIL) THEN
  111. INCL(parvol.vol.flags, Files.Boot); parfs.vol := parvol.vol;
  112. volReady := TRUE
  113. END
  114. END;
  115. IF volReady THEN
  116. COPY(prefix, parfs.prefix);
  117. (* call file system generator *)
  118. IF GetString(k, s, gen) THEN
  119. IF Generate(gen, parfs) THEN parvol.vol := NIL END
  120. ELSE
  121. Error(alias, s, k)
  122. END
  123. END;
  124. IF Files.This(prefix) = NIL THEN
  125. KernelLog.String("BootConsole: Mount failed on "); KernelLog.String(config); KernelLog.Ln;
  126. IF parvol.vol # NIL THEN
  127. parvol.vol.Finalize() (* unmount volume *)
  128. END
  129. END;
  130. parfs.out.Update; parfs.error.Update;
  131. parvol.out.Update; parvol.error.Update;
  132. END OpenVolume;
  133. PROCEDURE OpenVolumes;
  134. VAR config: ARRAY 16 OF CHAR; i: LONGINT;
  135. BEGIN
  136. config := "BootVol#";
  137. FOR i := 1 TO 9 DO
  138. config[7] := CHR(ORD("0") + i); config[8] := 0X;
  139. OpenVolume(config)
  140. END
  141. END OpenVolumes;
  142. BEGIN
  143. OpenVolumes;
  144. BootCommand("Boot", {Commands.Wait});
  145. BootCommand("BootSystem", {});
  146. Objects.Terminate();
  147. END BootConsole.