Virt to Phy addr in Gem5?
Binary loading (process creation) in Gem5?
Reference 1
Use ARM as example.
To access a memory for the packet in DRAM:
src/mem/dram_ctrl.c: DRAMCtrl::accessAndRespond() ->
src/mem/abstract_mem.cc: AbstractMemory::access():
To convert the Gem5 address into host machine address:
uint8_t *host_addr = toHostAddr(pkt->getAddr());
The address transformation is simply to add an addent (pmemAddr
) to the gem5 address, with tweaked offset according to the memory range starting point.
The defined as:
// src/mem/abstract_mem.hh
inline uint8_t *
toHostAddr(Addr addr) const
{
return pmemAddr + addr - range.start();
}
The addent pmemAddr
is the starting address for the backing store of this DRAM memory on the host machine.
It is set by PhysicalMemory::createBackingStore -> AbstractMemory::setBackingStore
.
This is done when create the PhysicalMemory physmem;
object when creating the System
object.
// src/sim/system.cc
System::System(Params *p)
: SimObject(p), _systemPort("system_port", this),
multiThread(p->multi_thread),
pagePtr(0),
init_param(p->init_param),
physProxy(_systemPort, p->cache_line_size),
workload(p->workload),
#if USE_KVM
kvmVM(p->kvm_vm),
#else
kvmVM(nullptr),
#endif
physmem(name() + ".physmem", p->memories, p->mmap_using_noreserve),
memoryMode(p->mem_mode),
_cacheLineSize(p->cache_line_size),
workItemsBegin(0),
workItemsEnd(0),
numWorkIds(p->num_work_ids),
thermalModel(p->thermal_model),
_params(p),
_m5opRange(p->m5ops_base ?
RangeSize(p->m5ops_base, 0x10000) :
AddrRange(1, 0)), // Create an empty range if disabled
totalNumInsts(0),
redirectPaths(p->redirect_paths)
{
To copy the data from host_addr to the packet:
pkt->setData(host_addr);
Gem5 phy address space (AddrRange, AbstractMemory) –> mmap –> host machine address space (Backing stores, host memory blocks, one for each Range/AbstractMemory object)
See definition in PhysicalMemory::createBackingStore
// src/mem/physical.cc
void
PhysicalMemory::createBackingStore(AddrRange range,
const vector<AbstractMemory*>& _memories,
bool conf_table_reported,
bool in_addr_map, bool kvm_map)
{
panic_if(range.interleaved(),
"Cannot create backing store for interleaved range %s\n",
range.to_string());
// perform the actual mmap
DPRINTF(AddrRanges, "Creating backing store for range %s with size %d\n",
range.to_string(), range.size());
int map_flags = MAP_ANON | MAP_PRIVATE;
// to be able to simulate very large memories, the user can opt to
// pass noreserve to mmap
if (mmapUsingNoReserve) {
map_flags |= MAP_NORESERVE;
}
uint8_t* pmem = (uint8_t*) mmap(NULL, range.size(),
PROT_READ | PROT_WRITE,
map_flags, -1, 0);
if (pmem == (uint8_t*) MAP_FAILED) {
perror("mmap");
fatal("Could not mmap %d bytes for range %s!\n", range.size(),
range.to_string());
}
// remember this backing store so we can checkpoint it and unmap
// it appropriately
backingStore.emplace_back(range, pmem,
conf_table_reported, in_addr_map, kvm_map);
// point the memories to their backing store
for (const auto& m : _memories) {
DPRINTF(AddrRanges, "Mapping memory %s to backing store\n",
m->name());
m->setBackingStore(pmem);
}
}
If you could revise
the fundmental principles of
computer system design
to improve security...
... what would you change?