1 using System;
  2 using System.Collections;
  3 using cmsx.machine;
  4 
  5 namespace cmsx.kernel
  6 {
  7     public void* mainFiber = null;
  8 
  9     public const char* KernelVersion()
 10     {
 11         return "4.0.0";
 12     }
 13 
 14     public nothrow void InitializeInterruptVector(Machine& machine)
 15     {
 16         Memory& mem = machine.GetMemory();
 17         for (byte i = 0u; i < irqMax; ++i;)
 18         {
 19             mem.WriteULong(MakeInterruptHandlerPtrAddress(i)0uProtection.write);
 20         }
 21         InterruptHandler softwareInterruptHandler = SoftwareInterruptHandler;
 22         ulong softwareInterruptHandlerAddress = cast<ulong>(cast<void*>(softwareInterruptHandler));
 23         mem.WriteULong(MakeInterruptHandlerPtrAddress(irqSoftware)softwareInterruptHandlerAddressProtection.write);
 24         InterruptHandler clockInterruptHandler = ClockInterruptHandler;
 25         ulong clockInterruptHandlerAddress = cast<ulong>(cast<void*>(clockInterruptHandler));
 26         mem.WriteULong(MakeInterruptHandlerPtrAddress(irqClock)clockInterruptHandlerAddressProtection.write);
 27         InterruptHandler diskInterruptHandler = DiskInterruptHandler;
 28         ulong diskInterruptHandlerAddress = cast<ulong>(cast<void*>(diskInterruptHandler));
 29         mem.WriteULong(MakeInterruptHandlerPtrAddress(irqDisk)diskInterruptHandlerAddressProtection.write);
 30         InterruptHandler keyboardInterruptHandler = KeyboardInterruptHandler;
 31         ulong keyboardInterruptHandlerAddress = cast<ulong>(cast<void*>(keyboardInterruptHandler));
 32         mem.WriteULong(MakeInterruptHandlerPtrAddress(irqKeyboard)keyboardInterruptHandlerAddressProtection.write);
 33         InterruptHandler pageFaultHandler = PageFaultHandler;
 34         ulong pageFaultHandlerAddress = cast<ulong>(cast<void*>(pageFaultHandler));
 35         mem.WriteULong(MakeInterruptHandlerPtrAddress(irqR)pageFaultHandlerAddressProtection.write);
 36         mem.WriteULong(MakeInterruptHandlerPtrAddress(irqW)pageFaultHandlerAddressProtection.write);
 37         mem.WriteULong(MakeInterruptHandlerPtrAddress(irqX)pageFaultHandlerAddressProtection.write);
 38         mem.WriteULong(MakeInterruptHandlerPtrAddress(irqCOW)pageFaultHandlerAddressProtection.write);
 39         InterruptHandler securityViolationHandler = SecurityViolationHandler;
 40         ulong securityViolationHandlerAddress = cast<ulong>(cast<void*>(securityViolationHandler));
 41         mem.WriteULong(MakeInterruptHandlerPtrAddress(irqS)securityViolationHandlerAddressProtection.write);
 42         machine.GetRegisters().SetSpecial(Registers.rTTinterruptVectorBaseAddress);
 43         machine.GetRegisters().SetSpecial(Registers.rTtrapTableBaseAddress);
 44     }
 45 
 46     public nothrow void InitializeSystemCalls(Machine& machine)
 47     {
 48         Memory& mem = machine.GetMemory();
 49         for (int i = 0; i < maxTraps; ++i;)
 50         {
 51             mem.WriteULong(MakeSystemCallPtrAddress(i)0uProtection.write);
 52         }
 53         SystemCallHandler exitSystemCallHandler = Exit;
 54         ulong exitSystemCallAddress = cast<ulong>(cast<void*>(exitSystemCallHandler));
 55         mem.WriteULong(MakeSystemCallPtrAddress(sys_exit)exitSystemCallAddressProtection.write);
 56         SystemCallHandler waitSystemCallHandler = Wait;
 57         ulong waitSystemCallAddress = cast<ulong>(cast<void*>(waitSystemCallHandler));
 58         mem.WriteULong(MakeSystemCallPtrAddress(sys_wait)waitSystemCallAddressProtection.write);
 59         SystemCallHandler forkSystemCallHandler = Fork;
 60         ulong forkSystemCallAddress = cast<ulong>(cast<void*>(forkSystemCallHandler));
 61         mem.WriteULong(MakeSystemCallPtrAddress(sys_fork)forkSystemCallAddressProtection.write);
 62         SystemCallHandler execSystemCallHandler = Exec;
 63         ulong execSystemCallAddress = cast<ulong>(cast<void*>(execSystemCallHandler));
 64         mem.WriteULong(MakeSystemCallPtrAddress(sys_exec)execSystemCallAddressProtection.write);
 65         SystemCallHandler killSystemCallHandler = Kill;
 66         ulong killSystemCallAddress = cast<ulong>(cast<void*>(killSystemCallHandler));
 67         mem.WriteULong(MakeSystemCallPtrAddress(sys_kill)killSystemCallAddressProtection.write);
 68         SystemCallHandler createSystemCallHandler = Create;
 69         ulong createSystemCallAddress = cast<ulong>(cast<void*>(createSystemCallHandler));
 70         mem.WriteULong(MakeSystemCallPtrAddress(sys_create)createSystemCallAddressProtection.write);
 71         SystemCallHandler openSystemCallHandler = Open;
 72         ulong openSystemCallAddress = cast<ulong>(cast<void*>(openSystemCallHandler));
 73         mem.WriteULong(MakeSystemCallPtrAddress(sys_open)openSystemCallAddressProtection.write);
 74         SystemCallHandler closeSystemCallHandler = Close;
 75         ulong closeSystemCallAddress = cast<ulong>(cast<void*>(closeSystemCallHandler));
 76         mem.WriteULong(MakeSystemCallPtrAddress(sys_close)closeSystemCallAddressProtection.write);
 77         SystemCallHandler readSystemCallHandler = Read;
 78         ulong readSystemCallAddress = cast<ulong>(cast<void*>(readSystemCallHandler));
 79         mem.WriteULong(MakeSystemCallPtrAddress(sys_read)readSystemCallAddressProtection.write);
 80         SystemCallHandler writeSystemCallHandler = Write;
 81         ulong writeSystemCallAddress = cast<ulong>(cast<void*>(writeSystemCallHandler));
 82         mem.WriteULong(MakeSystemCallPtrAddress(sys_write)writeSystemCallAddressProtection.write);
 83         SystemCallHandler seekSystemCallHandler = Seek;
 84         ulong seekSystemCallAddress = cast<ulong>(cast<void*>(seekSystemCallHandler));
 85         mem.WriteULong(MakeSystemCallPtrAddress(sys_seek)seekSystemCallAddressProtection.write);
 86         SystemCallHandler tellSystemCallHandler = Tell;
 87         ulong tellSystemCallAddress = cast<ulong>(cast<void*>(tellSystemCallHandler));
 88         mem.WriteULong(MakeSystemCallPtrAddress(sys_tell)tellSystemCallAddressProtection.write);
 89         SystemCallHandler poolEndSystemCallHandler = PoolEnd;
 90         ulong poolEndSystemCallAddress = cast<ulong>(cast<void*>(poolEndSystemCallHandler));
 91         mem.WriteULong(MakeSystemCallPtrAddress(sys_pool_end)poolEndSystemCallAddressProtection.write);
 92         SystemCallHandler setPoolEndSystemCallHandler = SetPoolEnd;
 93         ulong setPoolEndSystemCallAddress = cast<ulong>(cast<void*>(setPoolEndSystemCallHandler));
 94         mem.WriteULong(MakeSystemCallPtrAddress(sys_set_pool_end)setPoolEndSystemCallAddressProtection.write);
 95         SystemCallHandler debugBreakSystemCallHandler = DebugBreak;
 96         ulong debugBreakSystemCallAddress = cast<ulong>(cast<void*>(debugBreakSystemCallHandler));
 97         mem.WriteULong(MakeSystemCallPtrAddress(sys_debug_break)debugBreakSystemCallAddressProtection.write);
 98         SystemCallHandler stackTraceSystemCallHandler = StackTrace;
 99         ulong stackTraceSystemCallAddress = cast<ulong>(cast<void*>(stackTraceSystemCallHandler));
100         mem.WriteULong(MakeSystemCallPtrAddress(sys_stack_trace)stackTraceSystemCallAddressProtection.write);
101         SystemCallHandler throwSystemCallHandler = Throw;
102         ulong throwSystemCallAddress = cast<ulong>(cast<void*>(throwSystemCallHandler));
103         mem.WriteULong(MakeSystemCallPtrAddress(sys_throw)throwSystemCallAddressProtection.write);
104         SystemCallHandler catchSystemCallHandler = Catch;
105         ulong catchSystemCallAddress = cast<ulong>(cast<void*>(catchSystemCallHandler));
106         mem.WriteULong(MakeSystemCallPtrAddress(sys_catch)catchSystemCallAddressProtection.write);
107         SystemCallHandler resumeSystemCallHandler = Resume;
108         ulong resumeSystemCallAddress = cast<ulong>(cast<void*>(resumeSystemCallHandler));
109         mem.WriteULong(MakeSystemCallPtrAddress(sys_resume)resumeSystemCallAddressProtection.write);
110         SystemCallHandler getSystemErrorSystemCallHandler = GetSystemError;
111         ulong getSystemErrorSystemCallAddress = cast<ulong>(cast<void*>(getSystemErrorSystemCallHandler));
112         mem.WriteULong(MakeSystemCallPtrAddress(sys_get_system_error)getSystemErrorSystemCallAddressProtection.write);
113         SystemCallHandler getCurrentTimePointSystemCallHandler = GetCurrentTimePoint;
114         ulong getCurrentTimePointSystemCallAddress = cast<ulong>(cast<void*>(getCurrentTimePointSystemCallHandler));
115         mem.WriteULong(MakeSystemCallPtrAddress(sys_get_current_time_point)getCurrentTimePointSystemCallAddressProtection.write);
116         SystemCallHandler sleepSystemCallHandler = Sleep;
117         ulong sleepSystemCallAddress = cast<ulong>(cast<void*>(sleepSystemCallHandler));
118         mem.WriteULong(MakeSystemCallPtrAddress(sys_sleep)sleepSystemCallAddressProtection.write);
119         SystemCallHandler getCurrentDateSystemCallHandler = GetCurrentDate;
120         ulong getCurrentDateSystemCallAddress = cast<ulong>(cast<void*>(getCurrentDateSystemCallHandler));
121         mem.WriteULong(MakeSystemCallPtrAddress(sys_get_current_date)getCurrentDateSystemCallAddressProtection.write);
122         SystemCallHandler getCurrentDateTimeSystemCallHandler = GetCurrentDateTime;
123         ulong getCurrentDateTimeSystemCallAddress = cast<ulong>(cast<void*>(getCurrentDateTimeSystemCallHandler));
124         mem.WriteULong(MakeSystemCallPtrAddress(sys_get_current_date_time)getCurrentDateTimeSystemCallAddressProtection.write);
125         SystemCallHandler powSystemCallHandler = Pow;
126         ulong powSystemCallAddress = cast<ulong>(cast<void*>(powSystemCallHandler));
127         mem.WriteULong(MakeSystemCallPtrAddress(sys_pow)powSystemCallAddressProtection.write);
128         SystemCallHandler getRandomSeedSystemCallHandler = GetRandomSeed;
129         ulong getRandomSeedSystemCallAddress = cast<ulong>(cast<void*>(getRandomSeedSystemCallHandler));
130         mem.WriteULong(MakeSystemCallPtrAddress(sys_get_random_seed)getRandomSeedSystemCallAddressProtection.write);
131         SystemCallHandler linkSystemCallHandler = Link;
132         ulong linkSystemCallAddress = cast<ulong>(cast<void*>(linkSystemCallHandler));
133         mem.WriteULong(MakeSystemCallPtrAddress(sys_link)linkSystemCallAddressProtection.write);
134         SystemCallHandler unlinkSystemCallHandler = Unlink;
135         ulong unlinkSystemCallAddress = cast<ulong>(cast<void*>(unlinkSystemCallHandler));
136         mem.WriteULong(MakeSystemCallPtrAddress(sys_unlink)unlinkSystemCallAddressProtection.write);
137         SystemCallHandler renameSystemCallHandler = Rename;
138         ulong renameSystemCallAddress = cast<ulong>(cast<void*>(renameSystemCallHandler));
139         mem.WriteULong(MakeSystemCallPtrAddress(sys_rename)renameSystemCallAddressProtection.write);
140         SystemCallHandler mkdirSystemCallHandler = Mkdir;
141         ulong mkdirSystemCallAddress = cast<ulong>(cast<void*>(mkdirSystemCallHandler));
142         mem.WriteULong(MakeSystemCallPtrAddress(sys_mkdir)mkdirSystemCallAddressProtection.write);
143         SystemCallHandler opendirSystemCallHandler = OpenDir;
144         ulong opendirSystemCallAddress = cast<ulong>(cast<void*>(opendirSystemCallHandler));
145         mem.WriteULong(MakeSystemCallPtrAddress(sys_opendir)opendirSystemCallAddressProtection.write);
146         SystemCallHandler readdirSystemCallHandler = ReadDir;
147         ulong readdirSystemCallAddress = cast<ulong>(cast<void*>(readdirSystemCallHandler));
148         mem.WriteULong(MakeSystemCallPtrAddress(sys_readdir)readdirSystemCallAddressProtection.write);
149         SystemCallHandler closedirSystemCallHandler = CloseDir;
150         ulong closedirSystemCallAddress = cast<ulong>(cast<void*>(closedirSystemCallHandler));
151         mem.WriteULong(MakeSystemCallPtrAddress(sys_closedir)closedirSystemCallAddressProtection.write);
152         SystemCallHandler getcwdSystemCallHandler = GetCWD;
153         ulong getcwdSystemCallAddress = cast<ulong>(cast<void*>(getcwdSystemCallHandler));
154         mem.WriteULong(MakeSystemCallPtrAddress(sys_getcwd)getcwdSystemCallAddressProtection.write);
155         SystemCallHandler chdirSystemCallHandler = ChDir;
156         ulong chdirSystemCallAddress = cast<ulong>(cast<void*>(chdirSystemCallHandler));
157         mem.WriteULong(MakeSystemCallPtrAddress(sys_chdir)chdirSystemCallAddressProtection.write);
158         SystemCallHandler statSystemCallHandler = Stat;
159         ulong statSystemCallAddress = cast<ulong>(cast<void*>(statSystemCallHandler));
160         mem.WriteULong(MakeSystemCallPtrAddress(sys_stat)statSystemCallAddressProtection.write);
161         SystemCallHandler umaskSystemCallHandler = UMask;
162         ulong umaskSystemCallAddress = cast<ulong>(cast<void*>(umaskSystemCallHandler));
163         mem.WriteULong(MakeSystemCallPtrAddress(sys_umask)umaskSystemCallAddressProtection.write);
164         SystemCallHandler ioctlSystemCallHandler = IOCtl;
165         ulong ioctlSystemCallAddress = cast<ulong>(cast<void*>(ioctlSystemCallHandler));
166         mem.WriteULong(MakeSystemCallPtrAddress(sys_ioctl)ioctlSystemCallAddressProtection.write);
167         SystemCallHandler chmodSystemCallHandler = Chmod;
168         ulong chmodSystemCallAddress = cast<ulong>(cast<void*>(chmodSystemCallHandler));
169         mem.WriteULong(MakeSystemCallPtrAddress(sys_chmod)chmodSystemCallAddressProtection.write);
170         SystemCallHandler chownSystemCallHandler = Chown;
171         ulong chownSystemCallAddress = cast<ulong>(cast<void*>(chownSystemCallHandler));
172         mem.WriteULong(MakeSystemCallPtrAddress(sys_chown)chownSystemCallAddressProtection.write);
173         SystemCallHandler utimeSystemCallHandler = UTime;
174         ulong utimeSystemCallAddress = cast<ulong>(cast<void*>(utimeSystemCallHandler));
175         mem.WriteULong(MakeSystemCallPtrAddress(sys_utime)utimeSystemCallAddressProtection.write);
176         SystemCallHandler getuidSystemCallHandler = GetUID;
177         ulong getuidSystemCallAddress = cast<ulong>(cast<void*>(getuidSystemCallHandler));
178         mem.WriteULong(MakeSystemCallPtrAddress(sys_getuid)getuidSystemCallAddressProtection.write);
179         SystemCallHandler setuidSystemCallHandler = SetUID;
180         ulong setuidSystemCallAddress = cast<ulong>(cast<void*>(setuidSystemCallHandler));
181         mem.WriteULong(MakeSystemCallPtrAddress(sys_setuid)setuidSystemCallAddressProtection.write);
182         SystemCallHandler getgidSystemCallHandler = GetGID;
183         ulong getgidSystemCallAddress = cast<ulong>(cast<void*>(getgidSystemCallHandler));
184         mem.WriteULong(MakeSystemCallPtrAddress(sys_getgid)getgidSystemCallAddressProtection.write);
185         SystemCallHandler setgidSystemCallHandler = SetGID;
186         ulong setgidSystemCallAddress = cast<ulong>(cast<void*>(setgidSystemCallHandler));
187         mem.WriteULong(MakeSystemCallPtrAddress(sys_setgid)setgidSystemCallAddressProtection.write);
188         SystemCallHandler getpidSystemCallHandler = GetPID;
189         ulong getpidSystemCallAddress = cast<ulong>(cast<void*>(getpidSystemCallHandler));
190         mem.WriteULong(MakeSystemCallPtrAddress(sys_getpid)getpidSystemCallAddressProtection.write);
191         SystemCallHandler getpgidSystemCallHandler = GetPGID;
192         ulong getpgidSystemCallAddress = cast<ulong>(cast<void*>(getpgidSystemCallHandler));
193         mem.WriteULong(MakeSystemCallPtrAddress(sys_getpgid)getpgidSystemCallAddressProtection.write);
194         SystemCallHandler setpgidSystemCallHandler = SetPGID;
195         ulong setpgidSystemCallAddress = cast<ulong>(cast<void*>(setpgidSystemCallHandler));
196         mem.WriteULong(MakeSystemCallPtrAddress(sys_setpgid)setpgidSystemCallAddressProtection.write);
197         SystemCallHandler getfgpidSystemCallHandler = GetFGPID;
198         ulong getfgpidSystemCallAddress = cast<ulong>(cast<void*>(getfgpidSystemCallHandler));
199         mem.WriteULong(MakeSystemCallPtrAddress(sys_getfgpid)getfgpidSystemCallAddressProtection.write);
200         SystemCallHandler setfgpidSystemCallHandler = SetFGPID;
201         ulong setfgpidSystemCallAddress = cast<ulong>(cast<void*>(setfgpidSystemCallHandler));
202         mem.WriteULong(MakeSystemCallPtrAddress(sys_setfgpid)setfgpidSystemCallAddressProtection.write);
203         SystemCallHandler syncSystemCallHandler = Sync;
204         ulong syncSystemCallAddress = cast<ulong>(cast<void*>(syncSystemCallHandler));
205         mem.WriteULong(MakeSystemCallPtrAddress(sys_sync)syncSystemCallAddressProtection.write);
206         SystemCallHandler timesSystemCallHandler = Times;
207         ulong timesSystemCallAddress = cast<ulong>(cast<void*>(timesSystemCallHandler));
208         mem.WriteULong(MakeSystemCallPtrAddress(sys_times)timesSystemCallAddressProtection.write);
209         SystemCallHandler getHostNameSystemCallHandler = GetHostName;
210         ulong getHostNameSystemCallAddress = cast<ulong>(cast<void*>(getHostNameSystemCallHandler));
211         mem.WriteULong(MakeSystemCallPtrAddress(sys_get_host_name)getHostNameSystemCallAddressProtection.write);
212         SystemCallHandler dupSystemCallHandler = Dup;
213         ulong dupSystemCallAddress = cast<ulong>(cast<void*>(dupSystemCallHandler));
214         mem.WriteULong(MakeSystemCallPtrAddress(sys_dup)dupSystemCallAddressProtection.write);
215         SystemCallHandler pipeSystemCallHandler = Pipe;
216         ulong pipeSystemCallAddress = cast<ulong>(cast<void*>(pipeSystemCallHandler));
217         mem.WriteULong(MakeSystemCallPtrAddress(sys_pipe)pipeSystemCallAddressProtection.write);
218         SystemCallHandler logSystemCallHandler = cmsx.kernel.Log;
219         ulong logSystemCallAddress = cast<ulong>(cast<void*>(logSystemCallHandler));
220         mem.WriteULong(MakeSystemCallPtrAddress(sys_log)logSystemCallAddressProtection.write);
221         SystemCallHandler logmessageSystemCallHandler = cmsx.kernel.LogMessage;
222         ulong logmessageSystemCallAddress = cast<ulong>(cast<void*>(logmessageSystemCallHandler));
223         mem.WriteULong(MakeSystemCallPtrAddress(sys_log_message)logmessageSystemCallAddressProtection.write);
224     }
225 
226     public void Boot(Machine& machine)
227     {
228         mainFiber = OsConvertThreadToFiber(null);
229         if (Log())
230         {
231             StartLog();
232             LogMessage("boot""begin");
233         }
234         if (Machine.GetFlag(Machine.Flags.verbose))
235         {
236             Console.Out() << "Cmajor System X kernel version " << KernelVersion() << " booting...";
237         }
238         Kernel& kernel = Kernel.Instance();
239         kernel.SetBooting();
240         machine.GetProcessor().SetInterruptReturn(KernelInterruptReturn);
241         SetKernelMaxStackSizeFunction(KernelGetMaxStackSize);
242         SetKernelGrowStackFunction(KernelGrowStack);
243         SetStartUserTimeFunction(StartUserTime);
244         SetStopUserTimeFunction(StopUserTime);
245         Registers& regs = machine.GetRegisters();
246         DisableAllInterrupts(regs);
247         InitializeInterruptVector(machine);
248         InitializeSystemCalls(machine);
249         GetDiskDriver().Start();
250         GetMountTable().Init();
251         SessionTable& sessionTable = kernel.GetSessionTable();
252         Session* currentSession = sessionTable.CreateSession();
253         kernel.SetCurrentSession(currentSession);
254         if (!kernel.HasUserDebugger())
255         {
256             kernel.SetConsoleDriver(&cmsx.kernel.GetConsoleDriver());
257         }
258         ProcessTable& processTable = kernel.GetProcessTable();
259         int pid = -1;
260         if (Machine.GetFlag(Machine.Flags.runProgram))
261         {
262             pid = Load(kernel.GetProgramFileName()kernel.GetProgramArguments()currentSession->sid);
263             kernel.SetProgramPID(pid);
264         }
265         else
266         {
267             string cmajorRootDir = RtGetEnvironmentVariable("CMAJOR_ROOT");
268             if (cmajorRootDir.IsEmpty())
269             {
270                 throw Exception("CMAJOR_ROOT environment variable not set. Please set it to contain /path/to/cmajor directory");
271             }
272             string initProgramFileName = System.IO.GetFullPath(System.IO.Path.Combine(System.IO.Path.Combine(System.IO.Path.Combine(System.IO.Path.Combine(System.IO.Path.Combine(
273                 System.IO.Path.Combine(System.IO.Path.Combine(System.IO.Path.Combine(cmajorRootDir"projects")"cmsx")"build")"proc")"init")"bin")"release")"init"));
274             List<string> initProgramArguments;
275             initProgramArguments.Add("--user=" + kernel.User());
276             if (Machine.GetFlag(Machine.Flags.install))
277             {
278                 initProgramArguments.Add("--install");
279             }
280             if (Machine.GetFlag(Machine.Flags.verbose))
281             {
282                 initProgramArguments.Add("--verbose");
283             }
284             pid = Load(initProgramFileNameinitProgramArgumentscurrentSession->sid);
285             kernel.SetProgramPID(pid);
286             processTable.SetInit(processTable.GetProcess(pid));
287         }
288         if (pid != -1)
289         {
290             cmsx.kernel.Process* process = processTable.GetProcess(pid);
291             Debugger* debugger = kernel.GetDebugger();
292             debugger->Init(process);
293         }
294         Schedule(machineprocessTable);
295         SetProcessorToUserMode(regs);
296         EnableAllInterrupts(regs);
297         if (Machine.GetFlag(Machine.Flags.verbose))
298         {
299             Console.Out() << "\b\b\b, done." << endl();
300         }
301         if (Machine.GetFlag(Machine.Flags.runProgram))
302         {
303             if (Machine.GetFlag(Machine.Flags.verbose))
304             {
305                 Console.Out() << "running program '" << kernel.GetProgramFileName() << "' as process " << pid << endl();
306             }
307         }
308         ConsoleDriver* consoleDriver = kernel.GetConsoleDriver();
309         if (consoleDriver != null)
310         {
311             consoleDriver->GetDimensions();
312         }
313         kernel.ResetBooting();
314         if (Log())
315         {
316             LogMessage("boot""done");
317         }
318     }
319 }