예제 #1
0
파일: Process.cs 프로젝트: jncronin/tysos
        internal static Thread Create(string name, ulong e_point, ulong stack_size, ulong tls_size, Virtual_Regions vreg, SymbolTable stab, object[] parameters)
        {
            Thread t = new Thread();

            if (e_point == 0)
            {
                throw new Exception("Thread entry point is null (" + name + ")");
            }
            t.mt = new System.Threading.Thread(System.Runtime.InteropServices.Marshal.GetDelegateForFunctionPointer <System.Threading.ThreadStart>((IntPtr)e_point));
            SetTysosThread(t.mt, t);

            t.thread_id = next_thread_id++;

            t.saved_state = Program.arch.CreateTaskSwitchInfo();
            t.stack       = vreg.AllocRegion(stack_size, 0x1000, name + "_Stack", 0x1000, Virtual_Regions.Region.RegionType.Stack, true);
            t.tls         = vreg.AllocRegion(tls_size, 0x1000, name + "_TLS", 0, Virtual_Regions.Region.RegionType.ModuleSection, true);
            t.saved_state.Init(new UIntPtr(e_point), t.stack, t.tls, new UIntPtr(stab.GetAddress("__exit")), parameters);

            t.name = name;

            t.exit_address = stab.GetAddress("__exit");

            return(t);
        }
예제 #2
0
        public static void KMain(Multiboot.Header mboot)
        {
            // Disable profiling until we have enabled the arch.DebugOutput port
            do_profile = false;

            // Get the multiboot header
            mboot_header = mboot;

            /* Create a temporary heap, then initialize the architecture
             * which will set up the permanent heap.  Then initialize the garbage collector */
            ulong arch_data_length = 0;

            switch (mboot.machine_major_type)
            {
            case (uint)Multiboot.MachineMajorType.x86_64:
                arch_data_length = tysos.x86_64.Arch.GetRecommendedChunkLength();
                break;

            default:
                return;
            }

            ulong heap_start = mboot.heap_start + arch_data_length;

            //ulong heap_len = mboot.heap_end - heap_start;
            gc.gc.Heap = gc.gc.HeapType.Startup;
            gc.simple_heap.Init(heap_start, mboot.heap_end);

            log_lock = new object();

            /* Set up the default startup thread */
            StartupThread = new System.Threading.Thread(null_func);

            /* Initialize the architecture */
            UIntPtr chunk_vaddr  = new UIntPtr(mboot.heap_start);
            UIntPtr chunk_length = new UIntPtr(arch_data_length);

            switch (mboot.machine_major_type)
            {
            case (uint)Multiboot.MachineMajorType.x86_64:
                //libsupcs.OtherOperations.AsmBreakpoint();
                arch = new tysos.x86_64.Arch();
                break;
            }
            arch.Init(chunk_vaddr, chunk_length, mboot);

            do_profile = true;

            /* Parse the kernel command line */
            kernel_cmd_line = mboot.cmdline.Split(' ');

            //while (true) ;

            // test dynamic types
            //if (test_dynamic() == null)
            //    throw new Exception("test_dynamic failed");
            //if (test_dynamic2() == null)
            //    throw new Exception("test_dynamic2 failed");

            // Say hi
            Formatter.WriteLine("Tysos v0.2.0", arch.BootInfoOutput);
            Formatter.WriteLine("Tysos v0.2.0", arch.DebugOutput);
            Formatter.Write("mboot @ ", arch.DebugOutput);
            Formatter.Write(libsupcs.CastOperations.ReinterpretAsUlong(mboot), "X", arch.DebugOutput);
            Formatter.WriteLine(arch.DebugOutput);
            Formatter.Write("Loaded by ", arch.DebugOutput);
            Formatter.WriteLine(mboot.loader_name, arch.DebugOutput);
            Formatter.Write("Command line: ", arch.DebugOutput);
            Formatter.WriteLine(mboot.cmdline, arch.DebugOutput);
            bool do_debug = false;

            if (GetCmdLine("debug"))
            {
                Formatter.Write("Kernel debug: ", arch.BootInfoOutput);
                Formatter.WriteLine("Kernel debug requested", arch.DebugOutput);

                if (arch.InitGDBStub())
                {
                    Formatter.WriteLine("enabled", arch.BootInfoOutput);
                    Formatter.WriteLine("Kernel debug started", arch.DebugOutput);
                    do_debug = true;
                }
                else
                {
                    Formatter.WriteLine("not supported by current architecture", arch.BootInfoOutput);
                    Formatter.WriteLine("Kernel debug not supported by current architecture", arch.DebugOutput);
                }
            }


            /* Map in the ELF image of the kernel, so we can load its symbols */
            ulong tysos_vaddr = map_in(mboot.tysos_paddr, mboot.tysos_size, "tysos binary");

            /* Trigger a breakpoint to synchronize with gdb */
            if (do_debug)
            {
                Formatter.WriteLine("Synchronizing with debugger...", arch.BootInfoOutput);
                Formatter.WriteLine("Synchronizing with debugger...", arch.DebugOutput);
                System.Diagnostics.Debugger.Break();
            }

            /* Set up a default environment */
            env = new Environment();
            env.env_vars.Add("OS", "tysos");
            env.env_vars.Add("OSVER", "v0.2.0");
            env.env_vars.Add("NUMBER_OF_PROCESSORS", "1");

#if NO_BOEHM
            gc.heap_arena.debug = true;
#endif  // NO_BOEHM

            /* Load up the symbol table for tysos */
            if (GetCmdLine("skip_kernel_syms") == false)
            {
                ulong sym_vaddr = Program.map_in(mboot.tysos_sym_tab_paddr, mboot.tysos_sym_tab_size,
                                                 "tysos_sym_tab");
                ulong str_vaddr = Program.map_in(mboot.tysos_str_tab_paddr, mboot.tysos_str_tab_size,
                                                 "tysos_str_tab");

                stab = new SymbolTable();
                Formatter.Write("Loading kernel symbols... ", arch.BootInfoOutput);
                Formatter.Write("Loading kernel symbols.  Tysos base: ", arch.DebugOutput);
                Formatter.Write(tysos_vaddr, "X", arch.DebugOutput);
                Formatter.WriteLine(arch.DebugOutput);

                var hr = new ElfReader.ElfHashTable((ulong)tysos_hash, sym_vaddr, mboot.tysos_sym_tab_entsize, str_vaddr,
                                                    null, 0, mboot.tysos_sym_tab_size);
                stab.symbol_providers.Add(hr);

                Formatter.WriteLine("done", arch.BootInfoOutput);
            }

            /* Test the garbage collector */
            if (GetCmdLine("skip_test_gc") == false)
            {
                Formatter.Write("Testing garbage collector... ", arch.BootInfoOutput);
                gc.gc.DoCollection();
                Formatter.WriteLine("done", arch.BootInfoOutput);
            }

            /* Start the scheduler */
            Formatter.Write("Starting scheduler... ", arch.DebugOutput);
            arch.CurrentCpu.CurrentScheduler = new Scheduler();
            if (GetCmdLine("ignore_timer") == false)
            {
                arch.SchedulerTimer.Callback = new Timer.TimerCallback(Scheduler.TimerProc);
            }
            Formatter.WriteLine("done", arch.DebugOutput);

            /* Store the process info */
            running_processes = new Dictionary <string, Process>(new MyGenericEqualityComparer <string>());

            /* Add in threads for GC collections */
            Formatter.Write("Starting GC collection threads... ", arch.DebugOutput);
            Thread t_max = Thread.Create("gc_max_alloc", new System.Threading.ThreadStart(gc.gengc.MaxAllocCollectThreadProc),
                                         new object[] { });
            t_max.priority = 10;
            arch.CurrentCpu.CurrentScheduler.Reschedule(t_max);

            Thread t_min = Thread.Create("gc_min_alloc", new System.Threading.ThreadStart(gc.gengc.MinAllocCollectThreadProc),
                                         new object[] { });
            t_min.priority = 0;
            arch.CurrentCpu.CurrentScheduler.Reschedule(t_min);

            Thread t_request = Thread.Create("gc_request", new System.Threading.ThreadStart(gc.gengc.OnRequestCollectThreadProc),
                                             new object[] { });
            t_min.priority = 10;
            arch.CurrentCpu.CurrentScheduler.Reschedule(t_request);
            Formatter.WriteLine("done", arch.DebugOutput);


            /* Init vfs signatures */
            lib.File.InitSigs();



            /* Load the logger */
            Formatter.Write("Starting logger... ", arch.DebugOutput);
            Process logger = LoadELFModule("logger", mboot, stab, running_processes, 0x8000,
                                           new object[] { });

            Process debugprint = LoadELFModule("debugprint", mboot, stab, running_processes,
                                               0x8000, new object[] { });

            logger.Start();
            //debugprint.Start();
            Formatter.WriteLine("done", arch.DebugOutput);

            /* Load the vfs */
            Formatter.Write("Starting vfs... ", arch.DebugOutput);
            Process vfs = LoadELFModule("vfs", mboot, stab, running_processes, 0x8000, new object[] { });
            vfs.Start();
            Formatter.WriteLine("done", arch.DebugOutput);

            /* Load the gui */
            Formatter.Write("Starting gui... ", arch.DebugOutput);
            Process gui = LoadELFModule("gui", mboot, stab, running_processes, 0x8000, new object[] { });
            gui.Start();
            Formatter.WriteLine("done", arch.DebugOutput);

            /* Load the network subsystem */
            Formatter.Write("Starting net... ", arch.DebugOutput);
            Process net = LoadELFModule("net", mboot, stab, running_processes, 0x8000, new object[] { });
            net.Start();
            Formatter.WriteLine("done", arch.DebugOutput);

            /* Startup thread does the rest as we need to wait for the Vfs to come up */
            Process kernel_startup = Process.Create("kernel_startup", stab.GetAddress("_ZN11tysos#2Edll5tysos7Program_11SetupThread_Rv_P0"), 0x1000, arch.VirtualRegions, stab, new object[] { }, Program.arch.tysos_tls_length);
            arch.CurrentCpu.CurrentScheduler.Reschedule(kernel_startup.startup_thread);
            kernel_startup.started = true;



            if (do_debug)
            {
                System.Diagnostics.Debugger.Break();
            }

            //libsupcs.OtherOperations.AsmBreakpoint();

            //arch.EnableMultitasking();
            Syscalls.SchedulerFunctions.Yield();

            while (true)
            {
                ;
            }



            // Halt here
            libsupcs.OtherOperations.Halt();


            /* Create kernel threads */
            CreateKernelThreads();

            /* Dump the current virtual region table */
            arch.VirtualRegions.Dump(arch.DebugOutput);



            /* Start the processes */
            Formatter.WriteLine("Going multitasking...", arch.BootInfoOutput);
            arch.EnableMultitasking();
            while (true)
            {
                ;
            }
        }