extern C int kernel_main() { // Initialize heap at 3MB offset // TODO: fix this Kernel::heap( MegaByte(3), MegaByte(1) ); // Start kernel debug serial console // TODO: can I re-use the user-land driver here somehow???? IntelSerial *serial = new IntelSerial(0x3f8); serial->setMinimumLogLevel(Log::Notice); // TODO: put this in the boot.S, or maybe hide it in the support library? maybe a _run_main() or something. constructors(); // Kernel memory range (first 4MB, includes 1MB heap) Memory::Range kernelRange; kernelRange.phys = 0; kernelRange.size = MegaByte(4); // RAM physical range for this core (SplitAllocator lower memory). Memory::Range ramRange; ramRange.phys = 0; ramRange.size = (multibootInfo.memUpper * 1024) + MegaByte(1); // Create and run the kernel IntelKernel *kernel = new IntelKernel(kernelRange, ramRange); return kernel->run(); }
void multibootToCoreInfo(MultibootInfo *info) { // Fill coreId and memory info MemoryBlock::set(&coreInfo, 0, sizeof(CoreInfo)); coreInfo.coreId = 0; coreInfo.kernel.phys = 0; coreInfo.kernel.size = MegaByte(4); coreInfo.memory.phys = 0; coreInfo.memory.size = (info->memUpper * 1024) + MegaByte(1); // Fill the kernel command line MemoryBlock::copy(coreInfo.kernelCommand, (void *)info->cmdline, KERNEL_PATHLEN); // Fill the bootimage address for (Size n = 0; n < info->modsCount; n++) { MultibootModule *mod = (MultibootModule *) info->modsAddress; mod += n; String str((char *)(mod->string), false); // Is this the BootImage? if (str.match("*.img.gz")) { coreInfo.bootImageAddress = mod->modStart; coreInfo.bootImageSize = mod->modEnd - mod->modStart; break; } } }
std::ostream& operator<<(std::ostream& os, const MemoryInfo& mem) { char buf[1024]; sprintf(buf, "\n%20s %20s %20s\n%20g %20g %20g\n", "used [MB]", "footprint [MB]", "max_footprint [MB]", MegaByte(mem.m_malloc_used), MegaByte(mem.m_malloc_footprint), MegaByte(mem.m_malloc_max_footprint) ); os << buf; return os; }
ARMMap::ARMMap() { MemoryBlock::set(m_regions, 0, sizeof(m_regions)); m_regions[KernelData].virt = 0; m_regions[KernelData].phys = 0; m_regions[KernelData].size = GigaByte(1) - MegaByte(128); m_regions[KernelData].access = Memory::Readable | Memory::Writable | Memory::Executable; m_regions[KernelPrivate].virt = GigaByte(1) - MegaByte(128); m_regions[KernelPrivate].phys = GigaByte(1) - MegaByte(128); m_regions[KernelPrivate].size = MegaByte(128); m_regions[KernelPrivate].access = Memory::Readable | Memory::Writable; m_regions[UserData].virt = 0x80000000; m_regions[UserData].size = MegaByte(256); m_regions[UserHeap].virt = 0xb0000000; m_regions[UserHeap].size = MegaByte(256); m_regions[UserStack].virt = 0xc0000000; m_regions[UserStack].size = KiloByte(4); m_regions[UserPrivate].virt = 0xa0000000; m_regions[UserPrivate].size = MegaByte(256); }
IntelMap::IntelMap() { MemoryBlock::set(m_regions, 0, sizeof(m_regions)); m_regions[KernelData].virt = 0; m_regions[KernelData].size = GigaByte(1) - MegaByte(128); m_regions[KernelPrivate].virt = GigaByte(1) - MegaByte(128); m_regions[KernelPrivate].size = MegaByte(128); m_regions[UserData].virt = 0x80000000; m_regions[UserData].size = MegaByte(256); m_regions[UserHeap].virt = 0xb0000000; m_regions[UserHeap].size = MegaByte(256); m_regions[UserStack].virt = 0xc0000000; m_regions[UserStack].size = KiloByte(4); m_regions[UserPrivate].virt = 0xa0000000; m_regions[UserPrivate].size = MegaByte(256); m_regions[UserShare].virt = 0xd0000000; m_regions[UserShare].size = MegaByte(256); }
extern C int kernel_main(u32 r0, u32 r1, u32 r2) { // Invalidate all caches now Arch::Cache cache; cache.invalidate(Cache::Unified); #ifdef ARMV7 // Raise the SMP bit for ARMv7 ARMControl ctrl; ctrl.set(ARMControl::SMPBit); #endif // Retrieve boot image from ATAGS Arch::MemoryMap mem; BroadcomInterrupt irq; ARMTags tags(r2); Memory::Range initrd = tags.getInitRd2(); // Fill coreInfo MemoryBlock::set(&coreInfo, 0, sizeof(CoreInfo)); coreInfo.bootImageAddress = initrd.phys; coreInfo.bootImageSize = initrd.size; coreInfo.kernel.phys = 0; coreInfo.kernel.size = MegaByte(4); coreInfo.memory.phys = 0; coreInfo.memory.size = MegaByte(512); // Initialize heap Kernel::heap( MegaByte(3), MegaByte(1) ); // TODO: put this in the boot.S, or maybe hide it in the support library? maybe a _run_main() or something. constructors(); // Open the serial console as default Log RaspiSerial console; console.setMinimumLogLevel(Log::Notice); // Create the kernel ARMKernel kernel(&irq, &coreInfo); // Run the kernel return kernel.run(); }
MemoryContext::Result IntelPageDirectory::copy(IntelPageDirectory *directory, Address from, Address to) { while (from < to) { m_tables[ DIRENTRY(from) ] = directory->m_tables[ DIRENTRY(from) ]; from += MegaByte(4); } return MemoryContext::Success; }
extern C int kernel_main(u32 r0, u32 r1, u32 r2) { Arch::MemoryMap mem; BroadcomInterrupt irq; ARMTags tags(r2); Memory::Range initrd = tags.getInitRd2(); // Fill coreInfo MemoryBlock::set(&coreInfo, 0, sizeof(CoreInfo)); coreInfo.bootImageAddress = initrd.phys; coreInfo.bootImageSize = initrd.size; coreInfo.kernel.phys = 0; coreInfo.kernel.size = MegaByte(4); coreInfo.memory.phys = 0; coreInfo.memory.size = MegaByte(512); // Initialize heap Kernel::heap( MegaByte(3), MegaByte(1) ); // TODO: put this in the boot.S, or maybe hide it in the support library? maybe a _run_main() or something. constructors(); // Open the serial console as default Log RaspiSerial console; console.setMinimumLogLevel(Log::Notice); // Create the kernel ARMKernel kernel(&irq, &coreInfo); // Print some info DEBUG("ATAGS = " << r2); ARMControl ctrl; DEBUG("MainID = " << ctrl.read(ARMControl::MainID)); ctrl.write(ARMControl::UserProcID, 11223344); DEBUG("UserProcID = " << ctrl.read(ARMControl::UserProcID)); // Run the kernel return kernel.run(); }
extern C int kernel_main(CoreInfo *info) { // Initialize heap at 3MB offset // TODO: fix this Kernel::heap( MegaByte(3), MegaByte(1) ); // Start kernel debug serial console // TODO: can I re-use the user-land driver here somehow???? if (info->coreId == 0) { IntelSerial *serial = new IntelSerial(0x3f8); serial->setMinimumLogLevel(Log::Notice); } // TODO: put this in the boot.S, or maybe hide it in the support library? maybe a _run_main() or something. constructors(); // Create and run the kernel IntelKernel *kernel = new IntelKernel(info); return kernel->run(); }
extern C int kernel_main(u32 r0, u32 r1, u32 r2) { Arch::MemoryMap mem; BCM2835Interrupt irq; // Initialize heap Kernel::heap( MegaByte(3), MegaByte(1) ); // TODO: put this in the boot.S, or maybe hide it in the support library? maybe a _run_main() or something. constructors(); // Open the serial console as default Log RaspiSerial console; console.setMinimumLogLevel(Log::Notice); // Kernel memory range Memory::Range kernelRange; kernelRange.phys = 0; kernelRange.size = MegaByte(4); // RAM physical range Memory::Range ramRange; ramRange.phys = 0; ramRange.size = MegaByte(512); // Create the kernel ARMKernel kernel(kernelRange, ramRange, &irq, r2); // Print some info DEBUG("ATAGS = " << r2); ARMControl ctrl; DEBUG("MainID = " << ctrl.read(ARMControl::MainID)); ctrl.write(ARMControl::UserProcID, 11223344); DEBUG("UserProcID = " << ctrl.read(ARMControl::UserProcID)); // Run the kernel return kernel.run(); }
MemoryContext::Result IntelPageDirectory::translate(Address virt, Address *phys, SplitAllocator *alloc) { IntelPageTable *table = getPageTable(virt, alloc); if (!table) { if (m_tables[DIRENTRY(virt)] & PAGE_SECTION) { *phys = (m_tables[DIRENTRY(virt)] & PAGEMASK) + ((virt % MegaByte(4)) & PAGEMASK); return MemoryContext::Success; } return MemoryContext::InvalidAddress; } else return table->translate(virt, phys); }
MemoryContext::Result ARMFirstTable::mapLarge(Memory::Range range, SplitAllocator *alloc) { if (range.size & 0xfffff) return MemoryContext::InvalidSize; if ((range.phys & ~PAGEMASK) || (range.virt & ~PAGEMASK)) return MemoryContext::InvalidAddress; for (Size i = 0; i < range.size; i += MegaByte(1)) { if (m_tables[ DIRENTRY(range.virt + i) ] & (PAGE1_TABLE | PAGE1_SECTION)) return MemoryContext::AlreadyExists; m_tables[ DIRENTRY(range.virt + i) ] = (range.phys + i) | PAGE1_SECTION | flags(range.access); cache1_clean(&m_tables[DIRENTRY(range.virt + i)]); } return MemoryContext::Success; }
CoreServer::Result CoreServer::discover() { #ifdef INTEL SystemInformation sysInfo; Size memPerCore = 0; if (m_acpi.initialize() == IntelACPI::Success && m_acpi.discover() == IntelACPI::Success) { NOTICE("using ACPI as CoreManager"); // TODO: hack. Must always call IntelMP::discover() for IntelMP::boot() m_mp.discover(); m_cores = &m_acpi; } else if (m_mp.discover() == IntelMP::Success) { NOTICE("using MPTable as CoreManager"); m_cores = &m_mp; } else { ERROR("no CoreManager found (ACPI or MPTable)"); return NotFound; } List<uint> & cores = m_cores->getCores(); if (cores.count() == 0) { ERROR("no cores found"); return NotFound; } memPerCore = sysInfo.memorySize / cores.count(); memPerCore /= MegaByte(4); memPerCore *= MegaByte(4); NOTICE("found " << cores.count() << " cores -- " << (memPerCore / 1024 / 1024) << "MB per core"); // Allocate CoreInfo for each core m_coreInfo = new Index<CoreInfo>(cores.count()); // Boot each core for (ListIterator<uint> i(cores); i.hasCurrent(); i++) { uint coreId = i.current(); if (coreId != 0) { CoreInfo *info = new CoreInfo; m_coreInfo->insert(coreId, *info); MemoryBlock::set(info, 0, sizeof(CoreInfo)); info->coreId = coreId; info->memory.phys = memPerCore * coreId; info->memory.size = memPerCore - PAGESIZE; info->kernel.phys = info->memory.phys; info->kernel.size = MegaByte(4); info->bootImageAddress = info->kernel.phys + info->kernel.size; info->bootImageSize = sysInfo.bootImageSize; info->coreChannelAddress = info->bootImageAddress + info->bootImageSize; info->coreChannelAddress += PAGESIZE - (info->bootImageSize % PAGESIZE); info->coreChannelSize = PAGESIZE * 4; clearPages(info->coreChannelAddress, info->coreChannelSize); m_kernel->entry(&info->kernelEntry); info->timerCounter = sysInfo.timerCounter; strlcpy(info->kernelCommand, kernelPath, KERNEL_PATHLEN); } } #endif return Success; }