diff -r 2a4dae30a4f3 -r 9dc14c8c0bd0 src/arch/arm/ArmSystem.py --- a/src/arch/arm/ArmSystem.py Wed Nov 18 11:10:56 2015 +0000 +++ b/src/arch/arm/ArmSystem.py Wed Nov 18 11:19:48 2015 +0000 @@ -1,4 +1,4 @@ -# Copyright (c) 2009, 2012-2013 ARM Limited +# Copyright (c) 2009, 2012-2013, 2015 ARM Limited # All rights reserved. # # The license below extends only to copyright in the software and shall @@ -50,7 +50,10 @@ cxx_header = "arch/arm/system.hh" load_addr_mask = 0xffffffff multi_proc = Param.Bool(True, "Multiprocessor system?") - boot_loader = Param.String("", "File that contains the boot loader code if any") + boot_loader = VectorParam.String( + "File that contains the boot loader code. Zero or more files may be " + "specified. The first boot loader that matches the kernel's " + "architecture will be used.") gic_cpu_addr = Param.Addr(0, "Addres of the GIC CPU interface") flags_addr = Param.Addr(0, "Address of the flags register for MP booting") have_security = Param.Bool(False, diff -r 2a4dae30a4f3 -r 9dc14c8c0bd0 src/arch/arm/system.hh --- a/src/arch/arm/system.hh Wed Nov 18 11:10:56 2015 +0000 +++ b/src/arch/arm/system.hh Wed Nov 18 11:19:48 2015 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2012-2013 ARM Limited + * Copyright (c) 2010, 2012-2013, 2015 ARM Limited * All rights reserved * * The license below extends only to copyright in the software and shall @@ -43,6 +43,7 @@ #ifndef __ARCH_ARM_SYSTEM_HH__ #define __ARCH_ARM_SYSTEM_HH__ +#include #include #include @@ -64,6 +65,9 @@ */ Linux::DebugPrintkEvent *debugPrintkEvent; + /** Bootloaders */ + std::vector> bootLoaders; + /** * Pointer to the bootloader object */ @@ -112,6 +116,16 @@ */ const bool _haveLargeAsid64; + protected: + /** + * Get a boot loader that matches the kernel. + * + * @param obj Kernel binary + * @return Pointer to boot loader ObjectFile or nullptr if there + * is no matching boot loader. + */ + ObjectFile *getBootLoader(ObjectFile *const obj); + public: typedef ArmSystemParams Params; const Params * diff -r 2a4dae30a4f3 -r 9dc14c8c0bd0 src/arch/arm/system.cc --- a/src/arch/arm/system.cc Wed Nov 18 11:10:56 2015 +0000 +++ b/src/arch/arm/system.cc Wed Nov 18 11:19:48 2015 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2012-2013 ARM Limited + * Copyright (c) 2010, 2012-2013, 2015 ARM Limited * All rights reserved * * The license below extends only to copyright in the software and shall @@ -54,7 +54,9 @@ using namespace Linux; ArmSystem::ArmSystem(Params *p) - : System(p), bootldr(NULL), _haveSecurity(p->have_security), + : System(p), + bootLoaders(), bootldr(nullptr), + _haveSecurity(p->have_security), _haveLPAE(p->have_lpae), _haveVirtualization(p->have_virtualization), _genericTimer(nullptr), @@ -72,12 +74,27 @@ fatal("Invalid physical address range (%d)\n", _physAddrRange64); } - if (p->boot_loader != "") { - bootldr = createObjectFile(p->boot_loader); + bootLoaders.reserve(p->boot_loader.size()); + for (const auto &bl : p->boot_loader) { + std::unique_ptr obj; + obj.reset(createObjectFile(bl)); - if (!bootldr) - fatal("Could not read bootloader: %s\n", p->boot_loader); + fatal_if(!obj, "Could not read bootloader: %s\n", bl); + bootLoaders.emplace_back(std::move(obj)); + } + if (kernel) { + bootldr = getBootLoader(kernel); + } else if (!bootLoaders.empty()) { + // No kernel specified, default to the first boot loader + bootldr = bootLoaders[0].get(); + } + + if (!bootLoaders.empty() && !bootldr) + fatal("Can't find a matching boot loader / kernel combination!"); + + if (bootldr) { + bootldr->loadGlobalSymbols(debugSymbolTable); if ((bootldr->getArch() == ObjectFile::Arm64) && !_highestELIs64) { warn("Highest ARM exception-level set to AArch32 but bootloader " "is for AArch64. Assuming you wanted these to match.\n"); @@ -87,10 +104,8 @@ "is for AArch32. Assuming you wanted these to match.\n"); _highestELIs64 = false; } + } - bootldr->loadGlobalSymbols(debugSymbolTable); - - } debugPrintkEvent = addKernelFuncEvent("dprintk"); } @@ -168,6 +183,17 @@ delete debugPrintkEvent; } +ObjectFile * +ArmSystem::getBootLoader(ObjectFile *const obj) +{ + for (auto &bl : bootLoaders) { + if (bl->getArch() == obj->getArch()) + return bl.get(); + } + + return nullptr; +} + bool ArmSystem::haveLPAE(ThreadContext *tc) {