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(); }
private static void InitDrivers() { // Register drivers who depend on scheduling and resource management. DebugStub.WriteLine("--- Registering Drivers ---------------------------"); Console.WriteLine("Registering Non-HAL Drivers."); // register the metadata-based drivers IoSystem.RegisterDrivers(); ARM_PROGRESS("Kernel!061"); // register the internal kernel drivers Devices.RegisterInternalDrivers(); ARM_PROGRESS("Kernel!062"); #if DEBUG // and output the results IoSystem.Dump(false); #endif DebugStub.WriteLine("--- Activating Devices ----------------------------"); // now do device initialization IoSystem.ActivateDrivers(); ARM_PROGRESS("Kernel!063"); #if DEBUG // and output the results // IoSystem.Dump(true); #endif }
public void SetNextTimerInterrupt(TimeSpan delta) { // Make sure that interrupts are disabled bool iflag = Processor.DisableInterrupts(); TimeSpan start = delta; if (delta < timer.MinInterruptInterval) { delta = timer.MinInterruptInterval; } if (delta > timer.MaxInterruptInterval) { delta = timer.MaxInterruptInterval; } #if false DebugStub.WriteLine("-- SetNextTimerInterrupt(delta={0}, start={1} [min={2},max={3})", __arglist(delta.Ticks, start.Ticks, timer.MinInterruptInterval.Ticks, timer.MaxInterruptInterval.Ticks)); #endif timer.SetNextInterrupt(delta); // Restore interrupts if necessary Processor.RestoreInterrupts(iflag); }
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)); }
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 ApServiceLoop() { DebugStub.WriteLine("ApServiceThread is initialized and sleeping ..."); MpExecution.MpCall mpCall; bool iflag; while (true) { abiEvent.WaitOne(); DebugStub.WriteLine ("HSG: ** cpu.{0} receives AbiCall interrupt", __arglist(Processor.GetCurrentProcessorId())); // Current design: the boot processor will get all // unserved abi call. So we don't need to worry // missing any calls while (true) { iflag = Processor.DisableInterrupts(); mpCall = MpExecution.GetMpCall(Processor.GetCurrentProcessorId()); Processor.RestoreInterrupts(iflag); // There is no unserved abi call, just break if (mpCall == null) { break; } BspAbiStub.ProcessMpCall(Processor.GetCurrentProcessorId(), mpCall); } } }
/// <summary> /// This method runs when the "main" thread terminates by throwing an exception. /// It is a separate method, rather than simply code within the AppStart method, /// in order to make life easier during debugging. /// </summary> /// <param name="ex"></param> private static void TopLevelException(Exception /*!*/ ex) { DebugStub.WriteLine("AppRuntime: Main app thread terminated with exception:"); for (Exception focus = ex; focus != null; focus = focus.InnerException) { DebugStub.WriteLine("{0}: {1}", __arglist(focus.GetType().FullName, focus.Message)); } }
internal static void PrintBootTime() { // Console.WriteLine("Current time: {0}", SystemClock.GetUtcTime().ToString("r")); // Console.WriteLine("Boot time: {0}", BootTime.ToString("r")); TimeSpan delta = SystemClock.GetUtcTime() - BootTime; DebugStub.WriteLine("Elapsed boot time = {0} msec.", __arglist(delta.TotalMilliseconds)); }
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); }
public void EnableProfiling() { if (SamplingEnabled()) { Profiler = SamplingProfiler.Create("SampleProfiler:" + Id.ToString(), 32, // maximum stack depth Kernel.ProfilerBufferSize); // sampling buffer size DebugStub.WriteLine("Sampling profiler enabled"); } }
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 static void InitializeProcessorTable(int cpus) { // use the full value initially ExpectedProcessors = cpus; processorTable = new Processor[cpus]; for (int i = 0; i < processorTable.Length; i++) { processorTable[i] = new Processor(i); } DebugStub.WriteLine("Processors: {0} of {1}", __arglist(processorTable.Length, cpus)); }
private ProtectionDomain(AddressSpace space, string name, bool isKernelDomain) { this.space = space; this.name = name; this.kernelMode = isKernelDomain; this.initSpin = new SmartSpinlock(SpinLock.Types.ProtectionDomainInit); this.userMappingLock = new SmartSpinlock(SpinLock.Types.ProtectionDomainMapping); this.refCount = 1; // represents the table entry #if VERBOSE DebugStub.WriteLine("Created protection domain \"{0}\"", __arglist(name)); #endif }
private static IoMemory GetSystemManifest() { IoMemory res = Binder.GetSystemManifest(); if (res == null) { DebugStub.WriteLine("Failed to load system manifest."); DebugStub.Break(); throw new Exception("The system manifest could not be loaded."); } return(res); }
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(); }
private Processor(int index) { processorIndex = index; if (interruptCounts == null) { interruptCounts = new int [256]; } ProcessorLog = ProcessorLogger.Create("ProcessorLogger:" + index.ToString()); processorCounter = ProcessorCounter.Create("ProcessorCounters:" + index.ToString(), 256); DebugStub.WriteLine("Processor: {0}", __arglist(index)); }
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); }
private static void ARM_SPIN_FOREVER(string msg) { DebugStub.Assert(!Processor.InterruptsDisabled()); Processor p = Processor.CurrentProcessor; DebugStub.WriteLine(msg); DateTime last = DateTime.Now; uint n = 0; while (true) { Thread.Sleep(1000); } }
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); } }
public static void WaypointDump() { bool iflag = Processor.DisableInterrupts(); DebugStub.WriteLine("Interrupts: {0}", __arglist(Processor.CurrentProcessor.NumInterrupts - WaypointInterrupt)); DebugStub.WriteLine("WPT Waypoint Sequence THD Diff"); for (int i = 1; i < WaypointNumber; i++) { DebugStub.WriteLine("{0,3:d} {1,10:d} {2,10:d} {3,3:d} {4,10:d}", __arglist( i, Waypoints[i], WaypointSeq[i], WaypointThd[i].GetHashCode(), Waypoints[i] - Kernel.Waypoints[i - 1])); } Processor.RestoreInterrupts(iflag); }
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 }
// The public API for a typical client app. static public void StartProfiling() { // Query the diagnosis service whether the GC profiling is enabled // This allows setting from the kernel debugger the buffer sizes // for both kernel and SIP profiling. // Note, these are controlled independently, the implementation // of GCProfileSettings is different between kernel and SIP if (CurrentProfiler != null) { // // The profiler has been set already. No second attempt is allowed // return; } unsafe { int result; ulong defaultMemorySize = 0; ulong Options = 0; result = DiagnosisService.GCProfileSettingsImpl( out defaultMemorySize, out Options ); if ((result == 0) && (defaultMemorySize > 0)) { CurrentProfiler = new GCProfilerLogger(); CurrentProfiler.Initialize(defaultMemorySize, Options); GC.SetProfiler(CurrentProfiler); DebugStub.WriteLine("GC Profiling started"); } } }
// [System.Diagnostics.Conditional("ISA_ARM")] private static void ARM_PROGRESS(string msg) { DebugStub.WriteLine(msg); }
// // Someone must arrange to call this from *within* the // Protection Domain for us to have an opportunity to finish // initializing. // internal unsafe void InitHook() { // If paging is disabled then just return immediately if (!MemoryManager.UseAddressTranslation) { return; } DebugStub.Assert(AddressSpace.CurrentAddressSpace == this.AddressSpace); if (this.initialized) { // Someone else has already set up the space return; } bool iflag = initSpin.Lock(); try { if (this.initialized) { // Someone else snuck in and initialized return; } // // We're first into this space, so set it up. // #if VERBOSE DebugStub.WriteLine("Setting up protection domain \"{0}\"", __arglist(this.name)); #endif userRange = new VirtualMemoryRange(VMManager.UserHeapBase, VMManager.UserHeapLimit, this); #if PAGING if (kernelMode) { // This will be a ring-0, trusted domain, so just // point the userSharedHeap at the kernel's comm heap. userSharedHeap = SharedHeap.KernelSharedHeap; this.initialized = true; } else { // Create a new shared heap that lives in // user-land. userSharedHeap = new SharedHeap(this, userRange); #if VERBOSE DebugStub.WriteLine(" ...Created a shared heap"); #endif // // N.B.: this is kind of tricky. Loading an // executable image involves allocating memory, // which goes through this object. So, before // attempting the load, mark ourselves as initialized. // // ---- DON'T PUT GENUINE INITIALIZATION // CODE BELOW HERE! --------- this.initialized = true; // Load our own, protection-domain-private copy of the // ABI stubs. These will get shared by all apps in // this domain. IoMemory syscallsMemory = Binder.LoadRawImage("/init", "syscalls.dll"); IoMemory loadedMemory; // Load the stubs library into the user range, but make // the kernel process the logical owner. This seems like // the only sensible approach since the stubs do not // belong to any particular process but must be in the // user range of memory. // N.B.: RE-ENTERS this object! ring3AbiImage = PEImage.Load(Process.kernelProcess, syscallsMemory, out loadedMemory, false, // isForMp false // inKernelSpace ); ring3AbiExports = ring3AbiImage.GetExportTable(loadedMemory); #if VERBOSE DebugStub.WriteLine(" ...Loaded ring-3 ABI stubs"); #endif } #else // PAGING this.initialized = true; #endif // PAGING } finally { DebugStub.Assert(this.initialized); initSpin.Unlock(iflag); } }
internal static void Panic(string why) { DebugStub.WriteLine("KERNEL PANIC: {0}", __arglist(why)); Shutdown(Platform.EXIT_AND_HALT); }
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"); }