2
0

Unix.BootConsole.Mod 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. MODULE BootConsole; (** AUTHOR "G.F."; PURPOSE "Boot console"; *)
  2. IMPORT S := SYSTEM, Trace, Glue, Unix, Modules, Objects, Commands, Heaps;
  3. TYPE
  4. Module = Modules.Module;
  5. CommandProc = PROCEDURE;
  6. CommandThread = OBJECT
  7. VAR
  8. mod, cmd: Modules.Name;
  9. PROCEDURE &Init( CONST modName, cmdName: Modules.Name );
  10. BEGIN
  11. mod := modName; cmd := cmdName
  12. END Init;
  13. BEGIN {ACTIVE}
  14. Execute( mod, cmd );
  15. Modules.Shutdown( Modules.Reboot )
  16. END CommandThread;
  17. VAR
  18. appl: CommandThread;
  19. PROCEDURE LoadModule( CONST name: Modules.Name );
  20. VAR
  21. m: Module; res: LONGINT; msg: ARRAY 256 OF CHAR;
  22. BEGIN
  23. m := Modules.ThisModule( name, res, msg );
  24. IF m = NIL THEN
  25. Trace.String( "could not load module " ); Trace.String( name ); Trace.Ln
  26. END
  27. END LoadModule;
  28. PROCEDURE Command( CONST cmd: Modules.Name );
  29. VAR
  30. res: LONGINT;
  31. s: ARRAY 256 OF CHAR;
  32. BEGIN
  33. Commands.Call( cmd, {}, res, s );
  34. IF res # 0 THEN Trace.String( s ); Trace.Ln END
  35. END Command;
  36. (** Return the named command. *)
  37. PROCEDURE ThisCommand( m: Module; CONST name: Modules.Name ): CommandProc;
  38. VAR cmd: Modules.Command; i: LONGINT; found: BOOLEAN;
  39. BEGIN
  40. i := 0; found := FALSE;
  41. WHILE ~found & (i # LEN( m.command^ )) DO
  42. IF m.command[i].name = name THEN found := TRUE; cmd := m.command[i] ELSE INC( i ) END
  43. END;
  44. IF (cmd.entryAdr # 0) & (cmd.argTdAdr = 0) & (cmd.retTdAdr = 0) THEN
  45. RETURN S.VAL( CommandProc, cmd.entryAdr )
  46. ELSE
  47. RETURN NIL
  48. END
  49. END ThisCommand;
  50. PROCEDURE Execute( CONST modName, procName: Modules.Name );
  51. VAR m: Module; cmd: PROCEDURE; res: LONGINT;
  52. msg: ARRAY 256 OF CHAR;
  53. BEGIN
  54. m := Modules.ThisModule( modName, res, msg );
  55. IF m # NIL THEN
  56. cmd := ThisCommand( m, procName );
  57. IF cmd # NIL THEN cmd
  58. ELSE
  59. Trace.String( "BootConsole.Execute: module '" ); Trace.String( modName );
  60. Trace.String( "' has no command '" ); Trace.String( procName ); Trace.Char( "'" );
  61. Trace.Ln;
  62. END
  63. ELSE
  64. Trace.String( "BootConsole.Execute: could not load module " ); Trace.String( modName );
  65. Trace.Ln;
  66. Trace.String( msg ); Trace.Ln
  67. END
  68. END Execute;
  69. PROCEDURE CommandError( CONST cmd, msg: ARRAY OF CHAR );
  70. BEGIN
  71. Trace.String( "bad command line parameter: -x " ); Trace.String( cmd );
  72. Trace.String( ": " ); Trace.String( msg ); Trace.Ln;
  73. END CommandError;
  74. PROCEDURE TryCommand( ): BOOLEAN;
  75. VAR
  76. cmd: ARRAY 128 OF CHAR; ci: INTEGER;
  77. modName, cmdName: Modules.Name;
  78. PROCEDURE IsCharacter( c: CHAR ): BOOLEAN;
  79. BEGIN RETURN (('a' <= c) & (c <= 'z')) OR (( 'A' <= c) & (c <= 'Z'))
  80. END IsCharacter;
  81. PROCEDURE IsCharOrDigit( c: CHAR ): BOOLEAN;
  82. BEGIN RETURN IsCharacter( c ) OR (("0" <= c) & (c <= "9"))
  83. END IsCharOrDigit;
  84. PROCEDURE GetName( VAR name: ARRAY OF CHAR ): BOOLEAN;
  85. VAR j: LONGINT; c: CHAR;
  86. BEGIN
  87. j := -1;
  88. IF IsCharacter( cmd[ci] ) THEN
  89. REPEAT c := cmd[ci]; INC( ci ); INC( j ); name[j] := c UNTIL ~IsCharOrDigit( c ) OR (j = 31);
  90. IF c = '.' THEN name[j] := 0X
  91. ELSIF c # 0X THEN
  92. IF IsCharOrDigit( c ) THEN CommandError( cmd, "name too long" )
  93. ELSE CommandError( cmd, "invalid name" )
  94. END;
  95. RETURN FALSE
  96. END;
  97. RETURN TRUE
  98. ELSE
  99. CommandError( cmd, "name must start with a character" );
  100. RETURN FALSE
  101. END
  102. END GetName;
  103. BEGIN
  104. Unix.GetArgval( "-x", cmd );
  105. IF cmd # "" THEN
  106. ci := 0;
  107. IF GetName( modName ) & GetName( cmdName ) THEN
  108. IF Glue.debug # {} THEN
  109. Trace.String( "Starting " );
  110. Trace.String( modName ); Trace.Char( "." ); Trace.String( cmdName );
  111. Trace.Ln
  112. END;
  113. NEW( appl, modName, cmdName );
  114. RETURN TRUE
  115. ELSE
  116. (* invalid command string*)
  117. Unix.exit( 1 )
  118. END
  119. END;
  120. RETURN FALSE
  121. END TryCommand;
  122. PROCEDURE InitializeCoreModules;
  123. TYPE Body = PROCEDURE;
  124. VAR m: Modules.Module; body: Body; trace: BOOLEAN;
  125. BEGIN
  126. m := Modules.root; trace := Glue.debug # {};
  127. LOOP
  128. IF m.name = "BootConsole" THEN EXIT END; (* initialize modules belonging to bootfile only *)
  129. IF trace THEN
  130. Trace.String( "#### Initializing " ); Trace.String( m.name );
  131. Trace.String( " code: [" ); Trace.Hex( ADDRESSOF( m.code[0] ), -8 );
  132. Trace.String( ".." ); Trace.Hex( ADDRESSOF( m.code[0] ) + LEN( m.code^ ), -8 );
  133. Trace.Char( ']' ); Trace.Ln
  134. END;
  135. body := S.VAL( Body, ADDRESSOF( m.code[0] ) );
  136. body;
  137. m := m.next
  138. END
  139. END InitializeCoreModules;
  140. PROCEDURE StartSystem;
  141. BEGIN
  142. IF ~TryCommand() THEN
  143. (* normal system start *)
  144. LoadModule( "Clock" );
  145. Execute( "XDisplay", "Install" );
  146. Execute( "KbdMouse", "Init" );
  147. Command( "WindowManager.Install" );
  148. Command( "DisplayRefresher.Install" );
  149. Command( "Autostart.Run" );
  150. END
  151. END StartSystem;
  152. BEGIN
  153. Glue.Initialize;
  154. InitializeCoreModules;
  155. StartSystem;
  156. Objects.GCLoop
  157. END BootConsole.