X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=Kernel%2Farch%2Fx86%2Fmain.c;h=a65c2308d2e2dce230f02e25fd6a157a0368e86a;hb=eb98f1f2915446ef05120482a2fc353c76330b50;hp=304c3dd8175d229ae8e94beb6cff67842d18a123;hpb=f119d0e5b18b7286d04fc536a94e0f96e3c51714;p=tpg%2Facess2.git diff --git a/Kernel/arch/x86/main.c b/Kernel/arch/x86/main.c index 304c3dd8..a65c2308 100644 --- a/Kernel/arch/x86/main.c +++ b/Kernel/arch/x86/main.c @@ -3,74 +3,157 @@ * x86 Kernel Main * arch/x86/main.c */ -#include +#include #include +#include #include #include #include #define VGA_ERRORS 0 +#define MAX_ARGSTR_POS (0x400000-0x2000) + // === IMPORTS === -extern void Heap_Install(); -extern void Desctab_Install(); -extern void MM_PreinitVirtual(); +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(); -extern void Threads_Init(); -extern Uint Proc_Clone(Uint *Err, Uint Flags); -extern void Threads_Sleep(); -extern void Threads_Exit(); +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, tMBoot_Info *MbInfo) +int kmain(Uint MbMagic, void *MbInfoPtr) { int i; tMBoot_Module *mods; + tMBoot_Info *mbInfo; - // Adjust Multiboot structure address - MbInfo = (void*)( (Uint)MbInfo + KERNEL_BASE ); + Log("MbMagic = %08x", MbMagic); + Log("MbInfoPtr = %p", MbInfoPtr); + // Set up non-boot info dependent stuff Desctab_Install(); // Set up GDT and IDT - MM_PreinitVirtual(); // Initialise vital mappings - MM_Install( MbInfo ); // Set up physical memory manager + 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 - Log("Starting Multitasking..."); + //Log_Log("Arch", "Starting Multitasking..."); // Start Multitasking Threads_Init(); - Log("Starting VFS..."); + // Start Timers + Time_Setup(); + + Log_Log("Arch", "Starting VFS..."); // Load Virtual Filesystem VFS_Init(); - Log("Loading Modules..."); - // Load initial modules - mods = (void*)( MbInfo->Modules + KERNEL_BASE ); - for(i=0;iModuleCount;i++) + 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 ++ ) { - // Adjust into higher half - mods[i].Start += KERNEL_BASE; - mods[i].End += KERNEL_BASE; - mods[i].String += KERNEL_BASE; - - Log("Loading '%s'", mods[i].String); + 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 ); - if( !Module_LoadMem( (void *)mods[i].Start, mods[i].End-mods[i].Start, (char *)mods[i].String ) ) + // Only map the string if needed + if( (tVAddr)mods[i].String > MAX_ARGSTR_POS ) { - Warning("Unable to load module\n"); + // 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("Loading Configuration..."); - System_Init( (char*)(MbInfo->CommandLine + KERNEL_BASE) ); + Log_Log("Arch", "Starting system"); + System_Init(gsBootCmdLine); // Sleep forever (sleeping beauty) - for(;;) Threads_Sleep(); + 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 ); +}