diff options
author | Andreas Sandberg <andreas.sandberg@arm.com> | 2015-12-03 23:53:37 +0000 |
---|---|---|
committer | Andreas Sandberg <andreas.sandberg@arm.com> | 2015-12-03 23:53:37 +0000 |
commit | a1aeff27ce2978bb5fd0a3da66878d914cfb4da2 (patch) | |
tree | 6ec8b023033566edef0276710153fabc2917e33e /src/arch/arm/system.cc | |
parent | 146dfd0356c4a086e397679eba1ffb57b19ce07a (diff) | |
download | gem5-a1aeff27ce2978bb5fd0a3da66878d914cfb4da2.tar.xz |
arm: Add support for automatic boot loader selection
Add support for automatically selecting a boot loader that matches the
guest system's kernel. Instead of accepting a single boot loader, the
ArmSystem class now accepts a vector of boot loaders. When
initializing a system, the we now look for the first boot loader with
an architecture that matches the kernel.
This changeset makes it possible to use the same system for both
64-bit and 32-bit kernels.
Diffstat (limited to 'src/arch/arm/system.cc')
-rw-r--r-- | src/arch/arm/system.cc | 44 |
1 files changed, 35 insertions, 9 deletions
diff --git a/src/arch/arm/system.cc b/src/arch/arm/system.cc index 8e4e82571..f4241aa3c 100644 --- a/src/arch/arm/system.cc +++ b/src/arch/arm/system.cc @@ -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 std; 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 @@ ArmSystem::ArmSystem(Params *p) 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<ObjectFile> 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 @@ ArmSystem::ArmSystem(Params *p) "is for AArch32. Assuming you wanted these to match.\n"); _highestELIs64 = false; } - - bootldr->loadGlobalSymbols(debugSymbolTable); - } + debugPrintkEvent = addKernelFuncEvent<DebugPrintkEvent>("dprintk"); } @@ -168,6 +183,17 @@ ArmSystem::~ArmSystem() 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) { |