Sorting source tree a bit
[tpg/acess2.git] / KernelLand / Kernel / arch / x86 / main.c
diff --git a/KernelLand/Kernel/arch/x86/main.c b/KernelLand/Kernel/arch/x86/main.c
new file mode 100644 (file)
index 0000000..2106b6a
--- /dev/null
@@ -0,0 +1,160 @@
+/*
+ * Acess 2
+ * x86 Kernel Main
+ * arch/x86/main.c
+ */
+#include <acess.h>
+#include <mboot.h>
+#include <multiboot2.h>
+#include <init.h>
+#include <mm_virt.h>
+#include <mp.h>
+
+#define        VGA_ERRORS      0
+
+#define MAX_ARGSTR_POS (0x400000-0x2000)
+
+// === IMPORTS ===
+extern void    Heap_Install(void);
+extern void    Desctab_Install(void);
+extern void    MM_PreinitVirtual(void);
+extern void    MM_Install(tMBoot_Info *MBoot);
+extern void    MM_InstallVirtual(void);
+extern void    Threads_Init(void);
+extern int     Time_Setup(void);
+// --- Core ---
+extern void    System_Init(char *Commandline);
+
+// === PROTOTYPES ===
+ int   kmain(Uint MbMagic, void *MbInfoPtr);
+
+// === GLOBALS ===
+char   *gsBootCmdLine = NULL;
+struct {
+       Uint32  PBase;
+       void    *Base;
+       Uint    Size;
+       char    *ArgString;
+}      *gaArch_BootModules;
+ int   giArch_NumBootModules = 0;
+
+// === CODE ===
+int kmain(Uint MbMagic, void *MbInfoPtr)
+{
+        int    i;
+       tMBoot_Module   *mods;
+       tMBoot_Info     *mbInfo;
+
+       LogF("Acess2 x86-"PLATFORM" v"EXPAND_STR(KERNEL_VERSION)"\n");
+       LogF(" Build %i, Git Hash %s\n", BUILD_NUM, gsGitHash);
+       
+       Log("MbMagic = %08x, MbInfoPtr = %p", MbMagic, MbInfoPtr);
+       
+       // Set up non-boot info dependent stuff
+       Desctab_Install();      // Set up GDT and IDT
+       MM_PreinitVirtual();    // Initialise virtual mappings
+       
+       switch(MbMagic)
+       {
+       // Multiboot 1
+       case MULTIBOOT_MAGIC:
+               // Adjust Multiboot structure address
+               mbInfo = (void*)( (Uint)MbInfoPtr + KERNEL_BASE );
+               gsBootCmdLine = (char*)(mbInfo->CommandLine + KERNEL_BASE);
+               
+               MM_Install( mbInfo );   // Set up physical memory manager
+               break;
+       
+       // Multiboot 2
+       case MULTIBOOT2_MAGIC:
+               Panic("Multiboot 2 not yet supported");
+               //MM_InstallMBoot2( MbInfo );   // Set up physical memory manager
+               return 0;
+               break;
+       
+       default:
+               Panic("Multiboot magic invalid %08x, expected %08x or %08x\n",
+                       MbMagic, MULTIBOOT_MAGIC, MULTIBOOT2_MAGIC);
+               return 0;
+       }
+       
+       MM_InstallVirtual();    // Clean up virtual address space
+       Heap_Install();         // Create initial heap
+       
+       // Start Multitasking
+       Threads_Init();
+       
+       // Start Timers
+       Time_Setup();
+       
+       Log_Log("Arch", "Starting VFS...");
+       // Load Virtual Filesystem
+       VFS_Init();
+       
+       // Load initial modules
+       mods = (void*)( mbInfo->Modules + KERNEL_BASE );
+       giArch_NumBootModules = mbInfo->ModuleCount;
+       gaArch_BootModules = malloc( giArch_NumBootModules * sizeof(*gaArch_BootModules) );
+       for( i = 0; i < mbInfo->ModuleCount; i ++ )
+       {
+                int    ofs;
+       
+               Log_Log("Arch", "Multiboot Module at 0x%08x, 0x%08x bytes (String at 0x%08x)",
+                       mods[i].Start, mods[i].End-mods[i].Start, mods[i].String);
+       
+               gaArch_BootModules[i].PBase = mods[i].Start;
+               gaArch_BootModules[i].Size = mods[i].End - mods[i].Start;
+       
+               // Always HW map the module data        
+               ofs = mods[i].Start&0xFFF;
+               gaArch_BootModules[i].Base = (void*)( MM_MapHWPages(mods[i].Start,
+                       (gaArch_BootModules[i].Size+ofs+0xFFF) / 0x1000
+                       ) + ofs );
+               
+               // Only map the string if needed
+               if( (tVAddr)mods[i].String > MAX_ARGSTR_POS )
+               {
+                       // Assumes the string is < 4096 bytes long)
+                       gaArch_BootModules[i].ArgString = (void*)(
+                               MM_MapHWPages(mods[i].String, 2) + (mods[i].String&0xFFF)
+                               );
+               }
+               else
+                       gaArch_BootModules[i].ArgString = (char *)mods[i].String + KERNEL_BASE;
+       }
+       
+       // Pass on to Independent Loader
+       Log_Log("Arch", "Starting system");
+       System_Init(gsBootCmdLine);
+       
+       // Sleep forever (sleeping beauty)
+       for(;;)
+               Threads_Sleep();
+       return 0;
+}
+
+void Arch_LoadBootModules(void)
+{
+        int    i, j, numPages;
+       for( i = 0; i < giArch_NumBootModules; i ++ )
+       {
+               Log_Log("Arch", "Loading '%s'", gaArch_BootModules[i].ArgString);
+               
+               if( !Module_LoadMem( gaArch_BootModules[i].Base, gaArch_BootModules[i].Size, gaArch_BootModules[i].ArgString ) )
+               {
+                       Log_Warning("Arch", "Unable to load module");
+               }
+               
+               // Unmap and free
+               numPages = (gaArch_BootModules[i].Size + ((Uint)gaArch_BootModules[i].Base&0xFFF) + 0xFFF) >> 12;
+               MM_UnmapHWPages( (tVAddr)gaArch_BootModules[i].Base, numPages );
+               
+               for( j = 0; j < numPages; j++ )
+                       MM_DerefPhys( gaArch_BootModules[i].PBase + (j << 12) );
+               
+               if( (tVAddr) gaArch_BootModules[i].ArgString > MAX_ARGSTR_POS )
+                       MM_UnmapHWPages( (tVAddr)gaArch_BootModules[i].ArgString, 2 );
+       }
+       Log_Log("Arch", "Boot modules loaded");
+       free( gaArch_BootModules );
+}

UCC git Repository :: git.ucc.asn.au