Exemplo n.º 1
0
 public static void DumpStats()
 {
     KernelMessage.WriteLine("Threads, Can scheduled:");
     Dump(true);
     KernelMessage.WriteLine("Non-Schedulable Threads:");
     Dump(false);
 }
Exemplo n.º 2
0
        public unsafe Page *AllocatePages(uint pages, AllocatePageOptions options = default)
        {
            if (pages > _FreePages)
            {
                Panic.Error("Out of Memory");
                return(null);
            }

            Page *page;

            if (AddressSpaceKind == AddressSpaceKind.Virtual || options.Continuous)
            {
                page = AllocatePagesContinuous(pages, options);
            }
            else
            {
                page = AllocatePagesNormal(pages, options);
            }

            if (page == null)
            {
                KernelMessage.WriteLine("DebugName: {0}", DebugName);
                KernelMessage.WriteLine("Free pages: {0:X8}, Requested: {1:X8}", FreePages, pages);
                Panic.Error("Out of Memory");
            }

            KernelMessage.Path(DebugName, "SimpleAlloc: Request {0} Pages, Addr {1:X8}", pages, GetAddress(page));

            return(page);
        }
Exemplo n.º 3
0
        private static void MapKernelImage()
        {
            var phys    = Address.KernelElfSectionPhys;
            var diff    = Address.KernelBaseVirt - Address.KernelBasePhys;
            var endPhys = phys + OriginalKernelElf.TotalFileSize;
            var addr    = phys;

            KernelMessage.WriteLine("Mapping Kernel Image from physical {0:X8} to virtual {1:X8}", phys, phys + diff);
            while (addr < endPhys)
            {
                PageTable.KernelTable.MapVirtualAddressToPhysical(addr + diff, addr);
                addr += 0x1000;
            }
            PageTable.KernelTable.Flush();

            var map = new BootInfoMemory
            {
                Start            = phys + diff,
                Size             = OriginalKernelElf.TotalFileSize,
                Type             = BootInfoMemoryType.KernelElfVirt,
                AddressSpaceKind = AddressSpaceKind.Virtual,
            };

            BootInfo_.AddMap(map);
        }
Exemplo n.º 4
0
        public static unsafe void SaveThreadState(uint threadID, IntPtr stackState)
        {
            //Assert.True(threadID < MaxThreads, "SaveThreadState(): invalid thread id > max");

            var thread = Threads[threadID];

            if (thread.Status != ThreadStatus.Running)
            {
                return; // New threads doesn't have a stack in use. Take the initial one.
            }
            //Assert.True(thread != null, "SaveThreadState(): thread id = null");

            if (thread.User)
            {
                Assert.IsSet(thread.StackState, "thread.StackState is null");
                *thread.StackState = *(IDTTaskStack *)stackState;
            }
            else
            {
                thread.StackState = (IDTTaskStack *)stackState;
            }

            if (KConfig.Log.TaskSwitch)
            {
                KernelMessage.Write("Task {0}: Stored ThreadState from {1:X8} stored at {2:X8}, EIP={3:X8}", threadID, (uint)stackState, (uint)thread.StackState, thread.StackState->Stack.EIP);
                if (thread.User)
                {
                    KernelMessage.WriteLine(" ESP={0:X8}", thread.StackState->TASK_ESP);
                }
                else
                {
                    KernelMessage.WriteLine();
                }
            }
        }
Exemplo n.º 5
0
 /// <summary>
 /// Enable the IDTManager
 /// </summary>
 public static void Start()
 {
     KernelMessage.Write("Enabling interrupts...");
     Enabled = true;
     Flush();
     KernelMessage.WriteLine("done");
 }
Exemplo n.º 6
0
 private void PrintAddress()
 {
     KernelMessage.WriteLine("PageDirectoryPTPhys: {0:X8}", this.GetPageTablePhysAddr());
     KernelMessage.WriteLine("PageDirectoryPT: {0:X8}", AddrPageDirectoryPT);
     KernelMessage.WriteLine("PageDirectory: {0:X8}", AddrPageDirectory);
     KernelMessage.WriteLine("PageTable: {0:X8}", (uint)PageTableEntries);
 }
Exemplo n.º 7
0
        public virtual void Setup(MemoryRegion region, AddressSpaceKind addressSpaceKind)
        {
            AddressSpaceKind = addressSpaceKind;
            region.Size      = KMath.FloorToPowerOfTwo(region.Size);
            _Region          = region;
            var totalPages = region.Size >> BuddyAllocatorImplementation.BUDDY_PAGE_SHIFT;

            KernelMessage.WriteLine("Init Allocator: StartAddr: {0}, {1} Pages", region.Start, totalPages);
            // init global memory block
            // all pages area
            var pages_size = totalPages * (uint)sizeof(Page);

            KernelMessage.WriteLine("Page Array Size in bytes: {0}", pages_size);
            Pages = (Page *)AllocRawMemory(pages_size).Start;
            KernelMessage.WriteLine("Page Array Addr: {0:X8}", (uint)Pages);
            var start_addr = region.Start;

            Zone.free_area = (BuddyAllocatorImplementation.free_area *)AllocRawMemory(BuddyAllocatorImplementation.BUDDY_MAX_ORDER * (uint)sizeof(BuddyAllocatorImplementation.free_area)).Start;

            fixed(BuddyAllocatorImplementation.mem_zone *zone = &Zone)
            ZonePtr = zone;

            BuddyAllocatorImplementation.buddy_system_init(
                ZonePtr,
                Pages,
                start_addr,
                totalPages);
        }
Exemplo n.º 8
0
        private static void AssertError(string message, uint arg1 = 0, uint arg2 = 0, uint arg3 = 0)
        {
            KernelMessage.WriteLine("ASSERT ERROR! ");
            var sb = new StringBuffer();

            sb.Append(message, arg1, arg2, arg3);
            KernelMessage.WriteLine(sb);
        }
Exemplo n.º 9
0
 /// <summary>
 /// Dump the statistics of interest
 /// </summary>
 public static unsafe void DumpStats()
 {
     for (var i = 0; i < ProcessList.Count; i++)
     {
         var proc = ProcessList[i];
         KernelMessage.WriteLine("PID {1} Name {0} State {2}", proc.Path, (uint)proc.ProcessID, (uint)proc.RunState);
     }
 }
Exemplo n.º 10
0
        internal static unsafe uint WriteDebugMessage(ref SysCallContext context, ref SystemMessage args)
        {
            var msg = (NullTerminatedString *)args.Arg1;

            KernelMessage.WriteLine(msg);

            return(0);
        }
Exemplo n.º 11
0
        private static uint Cmd_WriteDebugMessage(SysCallContext *context, SystemMessage *args)
        {
            var msg = (NullTerminatedString *)args->Arg1;

            KernelMessage.WriteLine(msg);

            return(0);
        }
Exemplo n.º 12
0
        public void EnablePaging()
        {
            KernelMessage.Write("Enable Paging... ");

            // Set CR0 register on processor - turns on virtual memory
            Native.SetCR0(Native.GetCR0() | 0x80000000);

            KernelMessage.WriteLine("Done");
        }
Exemplo n.º 13
0
 private static void PrintMapArray(string name, KernelMemoryMapArray *mapArray)
 {
     KernelMessage.WriteLine("Items of MemoryMap Array [{0}]", name);
     for (var i = 0; i < mapArray->Count; i++)
     {
         var mm = &mapArray->Items[i];
         KernelMessage.WriteLine("Map {0:X8}-{1:X8}, Size={2:X8}, Type={3}, AddrKind={4}", mm->Start, mm->Start + mm->Size - 1, mm->Size, (uint)mm->Type, (uint)mm->AddressSpaceKind);
     }
 }
Exemplo n.º 14
0
        public static void Setup()
        {
            KernelMessage.WriteLine("Setup ELF Headers");
            //KernelMessage.WriteLine("Image Header:");
            //KernelMemory.DumpToConsoleLine(Address.KernelElfSection, 124);

            Main   = FromAddress(Address.KernelElfSectionVirt);
            Native = FromSectionName("native");
        }
Exemplo n.º 15
0
        /// <summary>
        /// Releases a page to the free list
        /// </summary>
        public void Free(Page *page)
        {
            var    oldFree   = _FreePages;
            string debugName = null;

            if (page->DebugTag != null)
            {
                debugName = (string)Intrinsic.GetObjectFromAddress((Pointer)(uint)page->DebugTag);
            }

            UninterruptableMonitor.Enter(this);
            try
            {
                var debugCount = list_head.list_count((list_head *)page); // DEBUG

                SelfCheck("SCF1", debugCount);
                Page *temp   = page;
                uint  result = 0;

                do
                {
                    result++;
                    if (temp->Status == PageStatus.Free)
                    {
                        //Panic.Error("Double Free");
                        SelfCheck("SCF3", debugCount);
                        KernelMessage.WriteLine("Double Free. Pages {0} Iteration {1}", debugCount, result);
                        Debug.Break();
                    }

                    temp->Status = PageStatus.Free;

                    var oldTemp = temp;
                    temp = (Page *)temp->Lru.next;
                    Native.Nop();
                    _FreePages++;

                    list_head.list_move_tail((list_head *)oldTemp, FreeList);
                }while (temp != page && result != debugCount);

                //list_head.list_headless_splice_tail((list_head*)page, FreeList);
                SelfCheck("SCF2", debugCount);
            }
            finally
            {
                UninterruptableMonitor.Exit(this);
            }
            var freedPages = _FreePages - oldFree;

            if (KConfig.Log.PageAllocation && TraceOptions.Enabled && freedPages >= TraceOptions.MinPages)
            {
                KernelMessage.Path(DebugName, "Freed Pages: {1}. Addr: {2:X8}. Now available: {3} --> {4}. Allocations={5} DebugName={0}.", debugName, freedPages, GetAddress(page), oldFree, _FreePages, (uint)Requests);
            }

            _Releases++;
        }
Exemplo n.º 16
0
        internal static void Undefined(ref IDTStack stack)
        {
            var handler = IDTManager.Handlers[stack.Interrupt];

            if (handler.NotifyUnhandled)
            {
                handler.NotifyUnhandled = false;
                KernelMessage.WriteLine("Unhandled Interrupt {0}", stack.Interrupt);
            }
        }
Exemplo n.º 17
0
        public void Setup(MemoryRegion region, AddressSpaceKind addrKind)
        {
            TraceOptions      = new PageFrameAllocatorTraceOptions();
            _AddressSpaceKind = addrKind;
            _Region           = region;
            FistPageNum       = region.Start / PageSize;
            _TotalPages       = region.Size / PageSize;
            kmap      = AllocRawMemory(_TotalPages * (uint)sizeof(Page));
            PageArray = (Page *)kmap.Start;

            var firstSelfPageNum = KMath.DivFloor(kmap.Start, 4096);
            var selfPages        = KMath.DivFloor(kmap.Size, 4096);

            KernelMessage.WriteLine("Page Frame Array allocated {0} pages, beginning with page {1} at {2:X8}", selfPages, firstSelfPageNum, (uint)PageArray);

            PageTable.KernelTable.SetWritable(kmap.Start, kmap.Size);
            kmap.Clear();

            var addr = FistPageNum * 4096;

            for (uint i = 0; i < _TotalPages; i++)
            {
                //KernelMessage.WriteLine(i);
                PageArray[i].Address = addr;
                //if (i != 0)
                //    PageArray[i - 1].Next = &PageArray[i];
                addr += 4096;
            }

            KernelMessage.WriteLine("Setup free memory");
            SetupFreeMemory();
            KernelMessage.WriteLine("Build linked lists");
            BuildLinkedLists();
            KernelMessage.WriteLine("Build linked lists done");

            _FreePages = 0;
            for (uint i = 0; i < _TotalPages; i++)
            {
                if (PageArray[i].Status == PageStatus.Free)
                {
                    _FreePages++;
                }
            }

            //Assert.True(list_head.list_count(FreeList) == _FreePages, "list_head.list_count(FreeList) == _FreePages");
            var debugCheckCount = list_head.list_count(FreeList);

            if (debugCheckCount != _FreePages)
            {
                KernelMessage.WriteLine("debugCheckCount {0} != {1}", debugCheckCount, _FreePages);
                Debug.Break();
            }

            KernelMessage.Path(DebugName, "Pages Free: {0}", FreePages);
        }
Exemplo n.º 18
0
        public static void TerminateCurrentThread()
        {
            KernelMessage.WriteLine("Terminating Thread");

            var threadID = GetCurrentThreadID();

            if (threadID != 0)
            {
                TerminateThread(threadID);
            }
        }
Exemplo n.º 19
0
        /// <summary>
        /// Switch to a specific thread.
        /// This method will not return!
        /// </summary>
        public static unsafe void SwitchToThread(int threadID)
        {
            var thread = Threads[threadID];
            var proc   = thread.Process;

            if (KConfig.Log.TaskSwitch)
            {
                KernelMessage.WriteLine("Switching to Thread {0}. StackState: {1:X8}", threadID, (uint)thread.StackState);
            }

            //Assert.True(thread != null, "invalid thread id");

            thread.Ticks++;

            SetThreadID(threadID);

            PIC.SendEndOfInterrupt((int)KnownInterrupt.ClockTimer);

            thread.Status = ThreadStatus.Running;

            if (thread.StackState == null)
            {
                DumpStats();
                KernelMessage.WriteLine("threadID: {0}", threadID);
                Debug.Break();
            }

            thread.StackState->Stack.EFLAGS |= X86_EFlags.InterruptEnableFlag;

            if (proc.PageTable != PageTable.KernelTable)
            {
                Debug.Nop();
            }

            uint pageDirAddr = proc.PageTable.GetPageTablePhysAddr();
            //KernelMessage.WriteLine("PageDirAddr: {0:X8}", pageDirAddr);
            uint stackStateAddr = (uint)thread.StackState;
            uint dataSelector   = thread.DataSelector;

            if (!thread.User)
            {
                thread.StackState = null; // just to be sure
            }
            GDT.Tss->ESP0 = thread.KernelStackBottom;

            if (thread.Debug)
            {
                Native.Nop();
            }

            GDT.SetThreadStorageSegmentBase(thread.ThreadLocalStorageBaseAddr);

            InterruptReturn(stackStateAddr, pageDirAddr, dataSelector, KnownSegments.UserThreadStorage);
        }
Exemplo n.º 20
0
        public static void StartProcessByID(int processID)
        {
            KernelMessage.WriteLine("Starting process ID {0}", processID);
            var proc = GetProcessByID(processID);

            if (proc == null)
            {
                return;
            }

            proc.Start();
        }
Exemplo n.º 21
0
        /// <summary>
        /// Prints the error and halts the system
        /// </summary>
        public static void Error(string message)
        {
            Native.Cli();

            KernelMessage.WriteLine("Kernel Panic: {0}", message);

            //Screen.Goto(0, 0);
            //Screen.Color = 11;
            //Screen.Write(message);
            //while(true){ Native.Nop(); };
            //return;
            Screen.BackgroundColor = ScreenColor.Green;

            Screen.Clear();
            Screen.Goto(1, 0);
            Screen.Color = ScreenColor.White;
            Screen.Write("*** Kernel Panic ***");

            if (firstError)
            {
                firstError = false;
            }
            else
            {
                Screen.Write(" (multiple)");
            }

            Screen.NextLine();
            Screen.NextLine();
            Screen.Write(message);
            Screen.NextLine();
            Screen.NextLine();
            Screen.Write("REGISTERS:");
            Screen.NextLine();
            Screen.NextLine();
            DumpRegisters();
            Screen.NextLine();
            Screen.Write("STACK TRACE:");
            Screen.NextLine();
            Screen.NextLine();
            DumpStackTrace();

            while (true)
            {
                // keep debugger running
                unsafe
                {
                    //Debugger.Process(null);
                }

                Native.Hlt();
            }
        }
Exemplo n.º 22
0
        private static uint Cmd_GetProcessIDForCommand(SysCallContext *context, SystemMessage *args)
        {
            var cmdNum = GetCommandNum((SysCallTarget)args->Arg1);
            var proc   = Commands[cmdNum].Process;

            if (proc == null)
            {
                proc = ProcessManager.System;
            }
            KernelMessage.WriteLine("Return ProcessID {0} for Command {1}", proc.ProcessID, cmdNum);
            return((uint)proc.ProcessID);
        }
Exemplo n.º 23
0
        private static uint Cmd_GetPhysicalMemory(SysCallContext *context, SystemMessage *args)
        {
            var physAddr = args->Arg1;
            var pages    = KMath.DivCeil(args->Arg2, 4096);

            KernelMessage.WriteLine("Got Request for {0:X8} pages at Physical Addr {1:X8}", pages, physAddr);
            var proc     = Scheduler.GetCurrentThread().Process;
            var virtAddr = proc.UserPageAllocator.AllocatePagesAddr(pages);

            proc.PageTable.Map(virtAddr, physAddr, pages * 4096);
            return(virtAddr);
        }
Exemplo n.º 24
0
        public static unsafe Process CreateProcessFromBuffer(MemoryRegion region, uint argumentBufferSize = 0)
        {
            KernelMessage.WriteLine("StartProcessFromBuffer at {0:X8} size {1:X8}", region.Start, region.Size);
            var cs = region.Checksum();

            KernelMessage.WriteLine("CheckSum: {0:X8}", cs);

            // TODO: Copy Buffer!!
            var elf = KernelElf.FromAddress(region.Start);

            return(CreateProcessFromElf(elf, "memory", argumentBufferSize));
        }
Exemplo n.º 25
0
        public static void Setup()
        {
            KernelMessage.WriteLine("Setup Native Calls");

            // TODO: VirtAddr!
            // TODO: SetExecutable!
            //PageTable.SetExecutableForRegion(...);

            prog1Addr      = KernelElf.Native.GetPhysAddrOfSymbol("test_proc1");
            prog2Addr      = KernelElf.Native.GetPhysAddrOfSymbol("test_proc2");
            bochsDebugAddr = KernelElf.Native.GetPhysAddrOfSymbol("bochs_debug");
        }
Exemplo n.º 26
0
        /// <summary>
        /// Sets up the PageTable
        /// </summary>
        public override void Setup(Addr entriesAddr)
        {
            SetupBasicStructure(entriesAddr);

            // Set CR3 register on processor - sets page directory
            KernelMessage.WriteLine("Set CR3 to {0:X8}", (uint)PageDirectoryEntries);
            Flush();

            if (KConfig.UseKernelMemoryProtection)
            {
                EnableKernelWriteProtection();
            }
        }
Exemplo n.º 27
0
 public static void DumpStats(this IPageFrameAllocator allocator)
 {
     KernelMessage.WriteLine("Stats for {0}", allocator.DebugName);
     KernelMessage.WriteLine("TotalPages {0}, FreePages {1}, Requests {2}, Releases {3}, Allocations {4}", allocator.TotalPages, allocator.FreePages, (uint)allocator.Requests, (uint)allocator.Releases, (uint)(allocator.Requests - allocator.Releases));
     if (allocator is MultiAllocator)
     {
         var multi = (MultiAllocator)allocator;
         for (var i = 0; i < multi.Allocators.Length; i++)
         {
             multi.Allocators[i].DumpStats();
         }
     }
 }
Exemplo n.º 28
0
        public static void Setup()
        {
            KernelMessage.WriteLine("Initialize SysCall Manager");

            IDTManager.SetInterruptHandler(FunctionIRQ, FunctionInterruptHandler);
            IDTManager.SetPrivilegeLevel(FunctionIRQ, 0x03);
            IDTManager.SetInterruptHandler(ActionIRQ, ActionInterruptHandler);
            IDTManager.SetPrivilegeLevel(ActionIRQ, 0x03);
            IDTManager.Flush();

            Commands = new SysCallHandlerInfo[256];
            SetCommands();
        }
Exemplo n.º 29
0
        public static unsafe void Start()
        {
            SetThreadID(0);
            Enabled = true;

            KernelMessage.WriteLine("Enable Scheduler");
            IDTManager.SetPrivilegeLevel((uint)KnownInterrupt.TerminateCurrentThread, 0x03);
            GDT.Tss->ESP0 = Threads[0].KernelStackBottom;
            GDT.LoadTaskRegister();
            TriggerScheduler();

            // Normally, you should never get here
            Panic.Error("Main-Thread still alive");
        }
Exemplo n.º 30
0
        /// <summary>
        /// Syscall interrupt handler. Dispatcher for every SysCall.
        /// </summary>
        private static void InterruptHandler(ref IDTStack stack, SysCallCallingType callingMethod)
        {
            var args = new SystemMessage
            {
                Target = (SysCallTarget)stack.EAX,
                Arg1   = stack.EBX,
                Arg2   = stack.ECX,
                Arg3   = stack.EDX,
                Arg4   = stack.ESI,
                Arg5   = stack.EDI,
                Arg6   = stack.EBP,
            };

            var commandNum = GetCommandNum(args.Target);

            if (KConfig.Log.SysCall)
            {
                KernelMessage.WriteLine("Got SysCall cmd={0} arg1={1:X8} arg2={2:X8} arg3={3:X8} arg4={4:X8} arg5={5:X8} arg6={6:X8}", (uint)args.Target, args.Arg1, args.Arg2, args.Arg3, args.Arg4, args.Arg5, args.Arg6);
            }

            Scheduler.SaveThreadState(Scheduler.GetCurrentThread().ThreadID, ref stack);

            var info = Commands[commandNum];

            if (info == null)
            {
                Panic.Error("Undefined SysCall");
            }

            var ctx = new SysCallContext
            {
                CallingType = callingMethod,
                Debug       = info.Debug,
            };

            if (info.Debug)
            {
                KDebug.DumpStats();
                Debug.Nop();
            }

            var result = info.Handler(ref ctx, ref args);

            if (KConfig.Log.SysCall)
            {
                KernelMessage.WriteLine("Result of Syscall cmd={0}: {1:X8}", (uint)args.Target, result);
            }

            stack.EAX = result;
        }