粗略的把gem5 documentation扫了一遍。仍不知道如何建立一个以PCM位介质的内存模型。于是又google了一段时间,在gem5 users 的mailing list中找到了点有用的东西how and where to start gem5。于是按照他的建议,看了下源码src/mem/Abstrac_memory.* src/mem/simple_mem.*。似乎有了点理解。
先来看看 AbstractMemory.py
class AbstractMemory(MemObject):
type = 'AbstractMemory'
abstract = True
cxx_header = "mem/abstract_mem.hh"
# A default memory size of 128 MB (starting at 0) is used to
# simplify the regressions
range = Param.AddrRange('128MB', "Address range (potentially interleaved)")
null = Param.Bool(False, "Do not store data, always return zero")
# All memories are passed to the global physical memory, and
# certain memories may be excluded from the global address map,
# e.g. by the testers that use shadow memories as a reference
in_addr_map = Param.Bool(True, "Memory part of the global address map")
# Should the bootloader include this memory when passing
# configuration information about the physical memory layout to
# the kernel, e.g. using ATAG or ACPI
conf_table_reported = Param.Bool(True, "Report to configuration table")
首先既然是内存类,既然要继承MemObject。而MemObject最重要的地方在于定义了两个方法用来获取master port 和 slave port 。而关于master port和slave port 在gem5中的第一篇tutorial中有介绍。这里截出个人认为比较重要的两句话:1.A master module has at least one master port, a slave module at least one slave port, and an interconnect module at least one of each 2.A master module, e.g. a CPU, changes the state of a slave module,e.g. a memory through a Request transported between master ports and slave ports using Packets。也就是说master port往往是在master module上的,而master module往往是用来改变slave module的状态的。比如由CPU发出的request packet t改变了memory的状态。对了,GEM5中CPU和memory的交互往往是建立在packet上的。
然后再看该AbstractMemory定义了几个跟memory相关的属性。其中null变量是指该块内存存不了数据,你非要从上面取数据的话,只能得到0。而conf_table_reported变量是用来告诉bootloader是否要把该块内存的存在告诉内核。不告诉的话,那内核就不知道该块内核的存在。我觉得是应该配合in_addr_map变量的使用。如果in_addr_map=false的话,那么该块内存应该就不能用于全局地址映射。
好了,再来看看Abstract_mem.h: