public void AddClock(byte interrupt, HalClock clock) { Tracing.Log(Tracing.Audit, "AddClock({0}) on {1}\n", Kernel.TypeName(clock), interrupt); this.clock = clock; this.clockInterrupt = interrupt; }
internal static int Main() { bootReturnCode = Platform.EXIT_AND_RESTART; InitPreMonitoring(); try { InitServices(); // Consider boot successful at this stage. bootReturnCode = Platform.EXIT_AND_SHUTDOWN; ARM_SPIN_FOREVER("kernel.arm Spinning forever"); bootReturnCode = SpawnAndWaitForShell(); // The shell has exited when we get here FinalizeServices(); } catch (Exception e) { System.Console.WriteLine("EXCEPTION:: " + e.Message); Tracing.Log(Tracing.Fatal, "Caught exception {0}", e.Message); DebugStub.WriteLine("Caught {0}", __arglist(e.Message)); bootReturnCode = -1; DebugStub.Break(); } DebugStub.WriteLine("Kernel exiting with 0x{0:x4}", __arglist(bootReturnCode)); FinalizePreMonitoring(); if (bootReturnCode != Platform.EXIT_AND_WARMBOOT) { Kill(bootReturnCode); } return(bootReturnCode); }
private static void FinalizeServices() { ARM_PROGRESS("Kernel!075"); Tracing.Log(Tracing.Audit, "Shutting down AP processors"); Processor.StopApProcessors(); Tracing.Log(Tracing.Audit, "Shutting down I/O system"); Console.WriteLine("Shutting down I/O system"); IoSystem.Finalize(); Tracing.Log(Tracing.Audit, "Interrupts OFF."); Processor.DisableInterrupts(); Tracing.Log(Tracing.Audit, "Shutting down scheduler"); Console.WriteLine("Shutting down scheduler"); for (int i = 0; i < Processor.processorTable.Length; i++) { Processor p = Processor.processorTable[i]; if (p != null) { Console.WriteLine(" cpu {0}: {1} context switches, {2} interrupts", i, p.NumContextSwitches, p.NumInterrupts); } } // Finalize the scheduler scheduler.Finalize(); // We should turn off interrupts here! Platform.ReleaseResources(); PEImage.Finalize(); DebugStub.WriteLine("Kernel Exiting [{0}]", __arglist(bootReturnCode)); }
public void AddTimer(byte interrupt, HalTimer timer) { Tracing.Log(Tracing.Audit, "AddTimer({0}) on {1}\n", Kernel.TypeName(timer), interrupt); this.timer = timer; this.timerInterrupt = interrupt; }
private static void InitPreMonitoring() { Tracing.Log(0); Tracing.Log(1); Tracing.Log(2); Tracing.Log(3); DebugStub.WriteLine("-------------------------------------------------------------------------------"); ARM_PROGRESS("Kernel!001"); // Indicate that we are not booted yet hasBooted = false; // Rather than mark all bootstrap code with [NoBarriers], perform a mini- // initialization that gives us a working WriteBarrier. System.GCs.Barrier.PreInitialize(); ARM_PROGRESS("Kernel!002"); // Initialize the memory subsystem. If enabled this turns on paging MemoryManager.Initialize(); // Note for Monitoring early boot process: // if you ever want to monitor stuff before this point, you should // allocate a static memory area in BootInit.cs, init the // monitoring system earlier, hold the system at this point here, // copy over all the collected data up to now to the new // dynamically created buffer and continue Monitoring.Initialize(); // uses page memory ARM_PROGRESS("Kernel!003"); HandleTable.Initialize(); }
public static void StartApProcessors(int cpuCount) { // At this point only the BSP is running. Tracing.Log(Tracing.Debug, "Processor.StartApProcessors()"); Platform.StartApProcessors(cpuCount); // At this point the BSP and APs are running. }
internal static void Shutdown(int exitCode) { unchecked { Tracing.Log(Tracing.Audit, "Kernel.Shutdown({0})", (UIntPtr)(uint)exitCode); } DebugStub.WriteLine("Kernel.Shutdown(0x{0:x4})", __arglist(exitCode)); DebugStub.Break(); VTable.Shutdown(exitCode); }
private static int SpawnAndWaitForShell() { #if ISA_ARM // spin here for now while (true) { Thread.Yield(); } #else Tracing.Log(Tracing.Audit, "Creating Shell Process"); ARM_PROGRESS("Kernel!071"); int exit = -10000; Manifest manifest; #if KERNEL_USE_LOGIN IoMemory memory; if (args[0] == "bvt") { memory = Binder.LoadImage(Thread.CurrentProcess, "tty", out manifest); } else { // TODO: The login app needs to be fixed to setup stdin and stdout pipes for // the shell and pump the data back and forth. memory = Binder.LoadImage(Thread.CurrentProcess, "login", out manifest); } #else IoMemory memory = Binder.LoadImage(Thread.CurrentProcess, "tty", out manifest); #endif ARM_PROGRESS("Kernel!073"); if (memory == null || memory.Length > 0) { String[] shellArgs = new String[args.Length + 2]; shellArgs[0] = "tty"; shellArgs[1] = "shell"; for (int i = 0; i < args.Length; i++) { shellArgs[i + 2] = args[i]; } Process process = new Process(Thread.CurrentProcess, memory, null, shellArgs, manifest); if (process != null) { PrintBootTime(); process.Start(); process.Join(); exit = process.ExitCode; } ARM_PROGRESS("Kernel!074"); } return(DetermineShutdown(exit)); #endif }
internal static void Stop(int exitCode) { // // Halt the process immediately. // Tracing.Log(Tracing.Audit, "Runtime.Stop({0})", (UIntPtr) unchecked ((uint)exitCode)); DebugStub.WriteLine("Runtime.Stop({0})", __arglist(exitCode)); ProcessService.Stop(exitCode); }
internal unsafe void Display() { int stackVariable; UIntPtr currentStack = new UIntPtr(&stackVariable); unchecked { Tracing.Log(Tracing.Debug, "Interrupt stack: {0:x} {1:x}..{2:x} uses", currentStack, context->cpuRecord.interruptStackBegin, context->cpuRecord.interruptStackLimit); } }
private unsafe void Initialize(int processorId) { uint DefaultStackSize = 0xA000; processorTable[processorId] = this; context = (ProcessorContext *)Isa.GetCurrentCpu(); DebugStub.WriteLine("Processor context: {0} {1:x8}", __arglist(processorId, Kernel.AddressOf(context))); context->UpdateAfterGC(this); if (0 != processorId) { Thread.BindKernelThread(kernelThread, kernelStackBegin, kernelStackLimit); } AllocateStack(DefaultStackSize, out context->cpuRecord.interruptStackBegin, out context->cpuRecord.interruptStackLimit); Tracing.Log(Tracing.Debug, "Initialized Processor {0}", (UIntPtr)processorId); Tracing.Log(Tracing.Debug, "asmInterruptStack={0:x}..{1:x}", context->cpuRecord.interruptStackBegin, context->cpuRecord.interruptStackLimit); #if false DebugStub.WriteLine("proc{0}: InterruptStack={1:x}..{2:x}", __arglist( processorId, context->cpuRecord.interruptStackBegin, context->cpuRecord.interruptStackLimit )); #endif Interlocked.Increment(ref runningCpus); MpExecution.AddProcessorContext(context); // Need to allocate this callback object outside of NoThreadAllocation region if (processorId == 0) { resumeThreadCallback = new ResumeThreadCallback(); } Isa.EnableCycleCounter(); }
internal static int MpMain(int cpu) { Tracing.Log(Tracing.Audit, "processor"); Processor processor = Processor.EnableProcessor(cpu); // Initialize dispatcher Processor.InitializeDispatcher(cpu); // Initialize the HAL processor services // Note that this must occur after EnableProcessor, as the kernel // thread does not get bound until then. (It gets bound much // earlier in the boot processor case -- need to decide if this difference is // really appropriate.) Platform.Cpu(cpu).InitializeServices(); Platform.InitializeHal(processor); Thread.CurrentThread.Affinity = cpu; Processor.ActivateTimer(cpu); #if DEBUG_SYSTEM_LOCKUP // Spin one CPU on debugger. For instance with a quad-proc // box, spin CPU 3. while (cpu == 3) { if (DebugStub.PollForBreak() == true) { DebugStub.Break(); } } #endif // DEBUG_SYSTEM_LOCKUP Processor.RestoreInterrupts(true); Tracing.Log(Tracing.Audit, "Looping in processor's kernel thread."); //while (cpu > 0) { // Thread.Yield(); //} // This probably won't be the // ultimate way of dissociating kernel entry threads // from the kernel. DebugStub.Print("AP Processor started, about to wait\n"); mpEndEvent.WaitOne(); return(0); }
internal static void Shutdown(int exitCode) { // // Gracefully close down the process. // Tracing.Log(Tracing.Audit, "Runtime.Shutdown({0})", (UIntPtr) unchecked ((uint)exitCode)); DebugStub.WriteLine("Runtime.Shutdown({0})", __arglist(exitCode)); VTable.Shutdown(exitCode); Tracing.Log(Tracing.Audit, "Runtime.Shutdown({0}) terminating", (UIntPtr) unchecked ((uint)exitCode)); ProcessService.Stop(exitCode); }
// Main loop of the shared heap walker. Walk each node in // the shared heap whenever Signal is called. // // Currently, we signal the walker whenever any process exits, // so that one very small process exit can trigger a traversal // of a large shared heap. This raises issues: // - Is this a wise use of resources in the common case? // - Can a malicious small process leverage the large shared heap // to deny service to others? // We could avoid these issues by keeping segregated shared // heap allocation lists (one list per process), but we feared // the common case overhead of maintaining these lists (e.g. locking // during Send/Receive). Furthermore: // - The shared heap is typically not large, and process // exit is infrequent compared to other operations, so the common // case resource usage is not likely to be significant. // - Only one thread walks the heap, so the denial-of-service // potential is small. At worst, such an attack could: // - Cause the thread below to use some fraction of the CPU time // (a waste of cycles, but not a denial of service) // - Try to increase the size of the shared heap in order to // increase the latency of a shared heap walk (but it's not // clear that well-behaved apps are affected by this latency) private void Loop() { while (true) { try { doWalkEvent.WaitOne(); Tracing.Log(Tracing.Audit, "Shared heap walk begin"); allocationOwnerId.IterateMatchingForModify( match, allocationVisitor); endpointOwnerId.IterateMatchingForModify( match, endpointVisitor); // (Don't visit the endpointPeer list; this gets erased // as part of walking the endpoint list.) Tracing.Log(Tracing.Audit, "Shared heap walk end"); } catch (System.Exception) { Tracing.Log(Tracing.Warning, "Exception thrown in shared heap walker"); } } }
private static int DetermineShutdown(int exit) { switch (exit) { case -10000: Tracing.Log(Tracing.Audit, "Failed to start shell process."); return(Platform.EXIT_AND_RESTART); case Platform.EXIT_AND_WARMBOOT: case Platform.EXIT_AND_RESTART: case Platform.EXIT_AND_SHUTDOWN: return(exit); default: DebugStub.WriteLine("Shell process terminated improperly (0x{0:x4})", __arglist(exit)); Tracing.Log(Tracing.Audit, "Shell process terminated improperly"); DebugStub.Break(); return(Platform.EXIT_AND_SHUTDOWN); } }
private static void InitIO(Processor p, XmlNode initConfig, XmlNode driverConfig) { // obtain the configuration for the namespace service // and initialize the namespace service ARM_PROGRESS("Kernel!041"); DirectoryService.Initialize(initConfig); Tracing.Log(Tracing.Audit, "IoSystem"); ARM_PROGRESS("Kernel!042"); IoSystem.Initialize(driverConfig); Tracing.Log(Tracing.Audit, "Registering HAL Drivers."); ARM_PROGRESS("Kernel!043"); Devices.RegisterPnpResources(); // add the root devices ARM_PROGRESS("Kernel!044"); Platform.InitializeHal(p); }
public static void StopApProcessors() { // // Note: This should go into a HAL interface and this // code confined to Platform.cs // // At this point the BSP and APs are running. Tracing.Log(Tracing.Debug, "Processor.StopApProcessors()"); if (Processor.GetRunningProcessorCount() > 1) { // // This stops them in MpExecution in a halt state with // interrupts off. // Platform.BroadcastFixedIPI((byte)Isal.IX.EVectors.HaltApProcessors, true); } while (GetRunningProcessorCount() != 1) { // Thread.Sleep(100); Thread.Sleep needs NoHeapAllocation annotation Thread.Yield(); } // // We must reset the AP Processors since a debug entry // will generated a NMI which will wake them up from HALT, // and they may start executing code again while the kernel // is still shutting down. // Platform.ResetApProcessors(); DebugStub.RevertToUniprocessor(); // At this point only the BSP is running. }
public void Uninitialize(int processorId) { Tracing.Log(Tracing.Debug, "UnInitializing Processor {0}", (UIntPtr)processorId); Interlocked.Decrement(ref runningCpus); // #if DEBUG // Interrupts should be off now if (!InterruptsDisabled()) { DebugStub.WriteLine("Processor::Uninitialize AP Processor does not have interrupts disabled\n"); DebugStub.Break(); } // #endif // DBG // Processor is out of commission HaltUntilInterrupt(); // #if DEBUG DebugStub.WriteLine("Processor::Uninitialize: AP processor woke up on shutdown!\n"); DebugStub.Break(); // #endif // DBG }
public static unsafe int AppStart(Type userClass) { System.GCs.Transitions.ThreadStart(); int result = 0; string arg0 = "(unknown)"; try { Tracing.Log(Tracing.Audit, "Runtime.Main()"); // Initialize the primitive runtime, which calls the // class constructor for Runtime(). VTable.Initialize((RuntimeType)typeof(AppRuntime)); //VTable.ParseArgs(args); Tracing.Log(Tracing.Audit, "Enabling GC Heap"); GC.EnableHeap(); Controller.InitializeSystem(); GCProfilerLogger.StartProfiling(); InitializeConsole(); SetDebuggerPresence(DebugService.IsDebuggerPresent()); int argCount = 0; int argMaxLen = 0; for (;; argCount++) { int len = ProcessService.GetStartupArg(argCount, null, 0); if (len == 0) { break; } if (argMaxLen < len) { argMaxLen = len; } } char[] argArray = new char [argMaxLen]; string[] args = new string[argCount]; for (int arg = 0; arg < argCount; arg++) { fixed(char *argptr = &argArray[0]) { int len = ProcessService.GetStartupArg(arg, argptr, argArray.Length); args[arg] = String.StringCTOR(argptr, 0, len); if (arg == 0) { arg0 = args[arg]; } } } #if DEBUG || true // Record the first argument passed to this program, under the assumption that // this is the application name. We use this string in DebugStub.WriteLine. // Also, if the name has an extension, such as ".x86", chop it off. // Also chop off any path prefix, such as "/init/". appName = arg0; int index = appName.LastIndexOf('.'); if (index != -1) { appName = appName.Substring(0, index); } index = appName.LastIndexOf('/'); if (index != -1) { appName = appName.Substring(index + 1); } // The default DebugName value for the main thread is "main"; // apps can override this by setting Thread.CurrentThread.DebugName. Thread mainThread = Thread.CurrentThread; if (mainThread != null) { mainThread.DebugName = "main"; } #endif if (userClass != null) { VTable.initType((RuntimeType)userClass); } result = CallMain(args); if (!MainReturnsInt()) { result = 0; } Tracing.Log(Tracing.Audit, "Main thread exited [{0}]", (UIntPtr) unchecked ((uint)result)); } catch (Exception e) { Tracing.Log(Tracing.Fatal, "Failed with exception {0}.{1}", e.GetType().Namespace, e.GetType().Name); Tracing.Log(Tracing.Trace, "Exception message was {0}", e.ToString()); TopLevelException(e); result = -1; } Thread.RemoveThread(Thread.CurrentThread.threadIndex); Thread.JoinAll(); try { FinalizeConsole(); } catch (Exception e) { Tracing.Log(Tracing.Fatal, "An exception occurred while shutting down the console: {0}", e.ToString()); } Controller.Finalize(); Tracing.Log(Tracing.Audit, "Runtime shutdown started."); VTable.Shutdown(result); Tracing.Log(Tracing.Audit, "Runtime exiting [{0}]", (UIntPtr) unchecked ((uint)result)); return(result); }
public void AddPic(HalPic pic) { Tracing.Log(Tracing.Audit, "AddPic({0})\n", Kernel.TypeName(pic)); this.pic = pic; }
public static void AddMemory(HalMemory aHalMemory) { Tracing.Log(Tracing.Audit, "AddHalMemory({0})\n", Kernel.TypeName(aHalMemory)); halMemory = aHalMemory; }
private static void InitServices() { InitGCSupport(); args = GetCommandLine(); VTable.ParseArgs(args); ARM_PROGRESS("Kernel!011"); InitSchedulerTypes(); ARM_PROGRESS("Kernel!018"); Controller.InitializeSystem(); Tracing.InitializeSystem(); ARM_PROGRESS("Kernel!019"); // Read the profiler settings. The values are assumed in kbytes // convert them to bytes for direct consumption ProfilerBufferSize = (uint)GetIntegerArgument("profiler", 0); ProfilerBufferSize *= 1024; ARM_PROGRESS("Kernel!020"); SpinLock.StaticInitialize(); int cpusLength; int cpuCount = GetCpuCount(out cpusLength); Processor.InitializeProcessorTable(cpusLength); ARM_PROGRESS("Kernel!021"); Tracing.Log(Tracing.Audit, "processor"); Processor processor = Processor.EnableProcessor(0); PEImage.Initialize(); ARM_PROGRESS("Kernel!034"); // Initialize the sample profiling for the processor // after the initial breakpoint in kd in the call // PEImage.Initialize(). This will allow enabling profiling // from kd, by overwriting the ProfilerBufferSize value processor.EnableProfiling(); ARM_PROGRESS("Kernel!035"); FlatPages.InitializeMemoryMonitoring(); // initialize endpoints InitType(typeof(Microsoft.Singularity.Channels.EndpointCore)); // TODO Bug 59: Currently broken, need to review paging build. //#if PAGING // Microsoft.Singularity.Channels.EndpointTrusted.StaticInitialize(); //#endif ARM_PROGRESS("Kernel!036"); // get the system manifest IoMemory systemManifest = GetSystemManifest(); ARM_PROGRESS("Kernel!037"); XmlReader xmlReader = new XmlReader(systemManifest); XmlNode xmlData = xmlReader.Parse(); XmlNode manifestRoot = xmlData.GetChild("system"); XmlNode initConfig = manifestRoot.GetChild("initConfig"); ARM_PROGRESS("Kernel!038"); PerfCounters.Initialize(); // need to have processed the manifest before we can call Process initialize ARM_PROGRESS("Kernel!039"); PrincipalImpl.Initialize(initConfig); ARM_PROGRESS("Kernel!040"); Process.Initialize(manifestRoot.GetChild("processConfig")); InitIO(processor, initConfig, manifestRoot.GetChild("drivers")); InitBootTime(); ARM_PROGRESS("Kernel!045"); // From here on, we want lazy type initialization to worry about // competing threads. VTable.InitializeForMultipleThread(); ARM_PROGRESS("Kernel!046"); Console.WriteLine("Running C# Kernel of {0}", GetLinkDate()); Console.WriteLine(); // TODO: remove this Console.WriteLine("Current time: {0}", SystemClock.GetUtcTime().ToString("r")); ARM_PROGRESS("Kernel!047"); InitScheduling(); DirectoryService.StartNotificationThread(); Console.WriteLine("Initializing Shared Heap Walker"); ProtectionDomain.InitializeSharedHeapWalker(); ARM_PROGRESS("Kernel!050"); Console.WriteLine("Initializing Service Thread"); ServiceThread.Initialize(); ARM_PROGRESS("Kernel!051"); GC.EnableHeap(); GCProfilerLogger.StartProfiling(); ARM_PROGRESS("Kernel!052"); Tracing.Log(Tracing.Audit, "Waypoints init"); Waypoints = new long[2048]; WaypointSeq = new int[2048]; WaypointThd = new int[2048]; Tracing.Log(Tracing.Audit, "Interrupts ON."); Processor.RestoreInterrupts(true); ARM_PROGRESS("Kernel!053"); #if ISA_ARM && TEST_GC for (int i = 0; i < 1000; i++) { DebugStub.WriteLine("Iteration {0}", __arglist(i)); ArrayList a = new ArrayList(); for (int j = 0; j < 128; j++) { int size = 1024 * 1024; a.Add(new byte [size]); } } #endif // ISA_ARM ARM_PROGRESS("Kernel!054"); Tracing.Log(Tracing.Audit, "Binder"); Binder.Initialize(manifestRoot.GetChild("namingConventions")); #if ISA_ARM DebugStub.WriteLine("Exporting local namespace to BSP\n"); DirectoryService.ExportArmNamespace(); DebugStub.WriteLine("Export complete...redirecting binder\n"); Binder.RedirectRootRef(); DebugStub.WriteLine("Binder redirect complete\n"); #endif #if false Tracing.Log(Tracing.Audit, "Starting Security Service channels"); PrincipalImpl.Export(); ARM_PROGRESS("Kernel!055"); #endif Tracing.Log(Tracing.Audit, "Creating Root Directory."); //This can be moved below IoSystem.InitializeDirectoryService(); ARM_PROGRESS("Kernel!055"); #if false // Start User space namespace manager Console.WriteLine("Starting Directory Service SIP"); DirectoryService.StartUserSpaceDirectoryService(); #endif ARM_PROGRESS("Kernel!055.5"); #if !ISA_ARM Tracing.Log(Tracing.Audit, "Starting Security Service channels"); PrincipalImpl.Export(); #endif ARM_PROGRESS("Kernel!056"); Console.WriteLine("Initializing system channels"); // starting channels services DebugStub.Print("Initializing Channel Services\n"); ChannelDeliveryImplService.Initialize(); ARM_PROGRESS("Kernel!057"); ConsoleOutput.Initialize(); ARM_PROGRESS("Kernel!058"); // Initialize MP after Binder and ConsoleOutput // are initialized so there are no // initialization races if the additional // threads try to use them. Tracing.Log(Tracing.Audit, "Starting additional processors"); // For ABI to ARM support MpExecution.Initialize(); ARM_PROGRESS("Kernel!059"); mpEndEvent = new ManualResetEvent(false); Tracing.Log(Tracing.Audit, "Initializing Volume Manager."); #if !ISA_ARM IoSystem.InitializeVolumeManager(); #endif // ISA_ARM ARM_PROGRESS("Kernel!060"); InitDrivers(); if (cpuCount > 1) { unsafe { Console.WriteLine("Enabling {0} cpus out of {1} real cpus\n", cpuCount, Platform.ThePlatform.CpuRealCount); } Processor.EnableMoreProcessors(cpuCount); ARM_PROGRESS("Kernel!064"); } Tracing.Log(Tracing.Audit, "Initializing Service Manager."); IoSystem.InitializeServiceManager(manifestRoot.GetChild("serviceConfig")); ARM_PROGRESS("Kernel!065"); InitDiagnostics(); #if !ISA_ARM // At this point consider kernel finshed booting hasBooted = true; #endif // ISA_ARM Processor.StartSampling(); ARM_PROGRESS("Kernel!069"); Microsoft.Singularity.KernelDebugger.KdFilesNamespace.StartNamespaceThread(); ARM_PROGRESS("Kernel!070"); }