123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207 |
- MODULE BootConsole; (** AUTHOR "G.F."; PURPOSE "Boot console"; *)
- IMPORT S := SYSTEM, Trace, Glue, Unix, Machine, Modules, Objects, Commands, KernelLog;
- TYPE
- Module = Modules.Module;
- CommandProc = PROCEDURE;
- CommandThread = OBJECT
- VAR
- mod, cmd: Modules.Name;
-
- PROCEDURE &Init( CONST modName, cmdName: Modules.Name );
- BEGIN
- mod := modName; cmd := cmdName
- END Init;
-
- BEGIN {ACTIVE}
- Execute( mod, cmd );
- Modules.Shutdown( Modules.Reboot )
- END CommandThread;
- VAR
- appl: CommandThread;
- PROCEDURE LoadModule( CONST name: Modules.Name );
- VAR
- m: Module; res: LONGINT; msg: ARRAY 256 OF CHAR;
- BEGIN
- m := Modules.ThisModule( name, res, msg );
- IF m = NIL THEN
- Trace.String( "could not load module " ); Trace.String( name ); Trace.Ln
- END
- END LoadModule;
- PROCEDURE Command( CONST cmd: Modules.Name );
- VAR
- res: LONGINT;
- s: ARRAY 256 OF CHAR;
- BEGIN
- Commands.Call( cmd, {}, res, s );
- IF res # 0 THEN Trace.String( s ); Trace.Ln END
- END Command;
- (** Return the named command. *)
- PROCEDURE ThisCommand( m: Module; CONST name: Modules.Name ): CommandProc;
- VAR cmd: Modules.Command; i: LONGINT; found: BOOLEAN;
- BEGIN
- i := 0; found := FALSE;
- WHILE ~found & (i # LEN( m.command^ )) DO
- IF m.command[i].name = name THEN found := TRUE; cmd := m.command[i] ELSE INC( i ) END
- END;
- IF (cmd.entryAdr # 0) & (cmd.argTdAdr = 0) & (cmd.retTdAdr = 0) THEN
- RETURN S.VAL( CommandProc, cmd.entryAdr )
- ELSE
- RETURN NIL
- END
- END ThisCommand;
- PROCEDURE Execute( CONST modName, procName: Modules.Name );
- VAR m: Module; cmd: PROCEDURE; res: LONGINT;
- msg: ARRAY 256 OF CHAR;
- BEGIN
- m := Modules.ThisModule( modName, res, msg );
- IF m # NIL THEN
- cmd := ThisCommand( m, procName );
- IF cmd # NIL THEN cmd
- ELSE
- Trace.String( "BootConsole.Execute: module '" ); Trace.String( modName );
- Trace.String( "' has no command '" ); Trace.String( procName ); Trace.Char( "'" );
- Trace.Ln;
- END
- ELSE
- Trace.String( "BootConsole.Execute: could not load module " ); Trace.String( modName );
- Trace.Ln;
- Trace.String( msg ); Trace.Ln
- END
- END Execute;
- PROCEDURE CommandError( CONST cmd, msg: ARRAY OF CHAR );
- BEGIN
- Trace.String( "bad command line parameter: -x " ); Trace.String( cmd );
- Trace.String( ": " ); Trace.String( msg ); Trace.Ln;
- END CommandError;
-
-
- PROCEDURE TryCommand( ): BOOLEAN;
- VAR
- cmd: ARRAY 128 OF CHAR; ci: INTEGER;
- modName, cmdName: Modules.Name;
-
- PROCEDURE IsCharacter( c: CHAR ): BOOLEAN;
- BEGIN RETURN (('a' <= c) & (c <= 'z')) OR (( 'A' <= c) & (c <= 'Z'))
- END IsCharacter;
-
- PROCEDURE IsCharOrDigit( c: CHAR ): BOOLEAN;
- BEGIN RETURN IsCharacter( c ) OR (("0" <= c) & (c <= "9"))
- END IsCharOrDigit;
-
- PROCEDURE GetName( VAR name: ARRAY OF CHAR ): BOOLEAN;
- VAR j: LONGINT; c: CHAR;
- BEGIN
- j := -1;
- IF IsCharacter( cmd[ci] ) THEN
- REPEAT c := cmd[ci]; INC( ci ); INC( j ); name[j] := c UNTIL ~IsCharOrDigit( c ) OR (j = 31);
- IF c = '.' THEN name[j] := 0X
- ELSIF c # 0X THEN
- IF IsCharOrDigit( c ) THEN CommandError( cmd, "name too long" )
- ELSE CommandError( cmd, "invalid name" )
- END;
- RETURN FALSE
- END;
- RETURN TRUE
- ELSE
- CommandError( cmd, "name must start with a character" );
- RETURN FALSE
- END
- END GetName;
-
- BEGIN
- Unix.GetArgval( "-x", cmd );
- IF cmd # "" THEN
- ci := 0;
- IF GetName( modName ) & GetName( cmdName ) THEN
- IF Glue.debug # {} THEN
- Trace.String( "Starting " );
- Trace.String( modName ); Trace.Char( "." ); Trace.String( cmdName );
- Trace.Ln
- END;
- NEW( appl, modName, cmdName );
- RETURN TRUE
- ELSE
- (* invalid command string*)
- Unix.exit( 1 )
- END
- END;
- RETURN FALSE
- END TryCommand;
-
-
-
- PROCEDURE InitializeCoreModules;
- TYPE Body = PROCEDURE;
- VAR m: Modules.Module; body: Body; trace: BOOLEAN;
- BEGIN
- m := Modules.root; trace := Glue.debug # {};
- LOOP
- IF m.name = "BootConsole" THEN EXIT END; (* initialize modules belonging to bootfile only *)
- IF trace THEN
- Trace.String( "#### Initializing " ); Trace.String( m.name );
- Trace.String( " code: [" ); Trace.Hex( ADDRESSOF( m.code[0] ), -8 );
- Trace.String( ".." ); Trace.Hex( ADDRESSOF( m.code[0] ) + LEN( m.code^ ), -8 );
- Trace.Char( ']' ); Trace.Ln
- END;
- body := S.VAL( Body, ADDRESSOF( m.code[0] ) );
- body;
- m := m.next
- END
- END InitializeCoreModules;
- PROCEDURE StartSystem;
- BEGIN
- IF ~TryCommand() THEN
- Machine.VerboseLog( );
- KernelLog.String( Machine.version ); KernelLog.Ln;
- (* normal system start *)
- LoadModule( "Clock" );
- Execute( "XDisplay", "Install" );
- Execute( "KbdMouse", "Init" );
- Command( "WindowManager.Install" );
- Command( "DisplayRefresher.Install" );
- Command( "Autostart.Run" );
- END
- END StartSystem;
- PROCEDURE InitSignalHandling;
- BEGIN
- Unix.HandleSignal( Unix.SIGHUP );
- Unix.HandleSignal( Unix.SIGINT );
- Unix.HandleSignal( Unix.SIGQUIT );
- Unix.HandleSignal( Unix.SIGILL );
- Unix.HandleSignal( Unix.SIGTRAP );
-
- Unix.HandleSignal( Unix.SIGABRT );
- Unix.HandleSignal( Unix.SIGBUS );
- Unix.HandleSignal( Unix.SIGFPE );
- Unix.HandleSignal( Unix.SIGBUS );
- Unix.HandleSignal( Unix.SIGPIPE );
- Unix.HandleSignal( Unix.SIGALRM );
- Unix.HandleSignal( Unix.SIGTERM );
- END InitSignalHandling;
-
- BEGIN
- Glue.Initialize;
- InitializeCoreModules;
- InitSignalHandling;
- StartSystem;
- Objects.GCLoop
- END BootConsole.
|