Gem5の勉強のために、チュートリアルを1からやってみることにした。
さらに、システムが正しく動作するためにさらにいくつかのポートを接続する。
I/OコントローラをCPUとメモリバスに接続する必要がある。
メモリバスに対して特殊なポートを接続する必要がある。このポートはシステムが読み書きを行うためのポートとなる。
system.cpu.createInterruptController() system.cpu.interrupts[0].pio = system.membus.mem_side_ports system.cpu.interrupts[0].int_requestor = system.membus.cpu_side_ports system.cpu.interrupts[0].int_responder = system.membus.mem_side_ports system.system_port = system.membus.cpu_side_ports
次にメモリコントローラを作成して、メモリバスに接続する。単純なDDR3コントローラを作成して、システム中のメモリ領域全体を制御するようにする。
system.mem_ctrl = MemCtrl()
system.mem_ctrl.dram = DDR3_1600_8x8()
system.mem_ctrl.dram.range = system.mem_ranges[0]
system.mem_ctrl.port = system.membus.mem_side_ports
これらの接続を行った結果、最終的にシステム構成は以下のようになる。
- Syscallエミュレーションモード(SE Mode)
- Full systemエミュレーションモード(FS Mode)
まず、プロセスを作成し、そのプロセスに実行したいコマンドを設定する。次にCPUに対してそのプロセスのコマンドを使用するように設定し、CPU内に機能実行コンテキストを作成する。
binary = 'tests/test-progs/hello/bin/x86/linux/hello' # for gem5 V21 and beyond system.workload = SEWorkload.init_compatible(binary) process = Process() process.cmd = [binary] system.cpu.workload = process system.cpu.createThreads()
最後に、システムをインスタンス化して実行を開始する。最初に、rootオブジェクトを作成する。
root = Root(full_system = False, system = system)
m5.instantiate()
最後に、シミュレーションを開始する。
print("Beginning simulation!") exit_event = m5.simulate()
シミュレーションを終了すると、システムの状態を調査する。
print('Exiting @ tick {} because {}' .format(m5.curTick(), exit_event.getCause()))
このスクリプトを使って、シミュレーションを行う。
build/X86/gem5.opt configs/tutorial/part1/simple.py
スクリプト全体をまとめると、以下のようになる。
# """ This file creates a barebones system and executes 'hello', a simple Hello # World application. # See Part 1, Chapter 2: Creating a simple configuration script in the # learning_gem5 book for more information about this script. # IMPORTANT: If you modify this file, it's likely that the Learning gem5 book # also needs to be updated. For now, email Jason <power.jg@gmail.com> # This script uses the X86 ISA. `simple-arm.py` and `simple-riscv.py` may be # referenced as examples of scripts which utilize the ARM and RISC-V ISAs # respectively. # このスクリプトでは、ベアボーンシステムを立ち上げてシンプルな`Hello World`アプリケーションんである # 'hello'を実行する。 # Part 1, Chapter 2: Creating simple configuration script in the learning_gem5 bookの内容である。 # このスクリプトでは、X86 ISAを使用している。ARMとRISC-V ISAを使用する場合には、 # `simple-arm.py`および`simple-riscv.py`を使用する。 # """ # gem5をビルドした際に作成したm5ライブラリをインポートする import m5 # すべてのSimObjectsをインポートする from m5.objects import * # シミュレーション用のシステムを作成する system = System() # システム(およびシステム内のすべてのモジュール)のクロック周波数を設定する system.clk_domain = SrcClockDomain() system.clk_domain.clock = "1GHz" system.clk_domain.voltage_domain = VoltageDomain() # システムをセットアップする system.mem_mode = "timing" # タイミングアクセスを使用する system.mem_ranges = [AddrRange("512MB")] # アドレス領域を設定する # Simple CPUを作成する # CPU毎に応じて`RiscvTimingSimpleCPU`, `ArmTimingSimpleCPU`を使用できる system.cpu = X86TimingSimpleCPU() # メモリバスを作成する。今回はシステムクロスバを使用する system.membus = SystemXBar() # CPUポートをメモリバスに接続する system.cpu.icache_port = system.membus.cpu_side_ports system.cpu.dcache_port = system.membus.cpu_side_ports # CPUの割り込みコントローラをメモリバスに接続する system.cpu.createInterruptController() # X86にのみ、割り込みをメモリに接続する # 注記: これらはメモリバスに直接接続され、キャッシュされない # 他のISAでは以下の3行は削除すべきである system.cpu.interrupts[0].pio = system.membus.mem_side_ports system.cpu.interrupts[0].int_requestor = system.membus.cpu_side_ports system.cpu.interrupts[0].int_responder = system.membus.mem_side_ports # DDR3メモリコントローラを作成し、メモリバスに接続する system.mem_ctrl = MemCtrl() system.mem_ctrl.dram = DDR3_1600_8x8() system.mem_ctrl.dram.range = system.mem_ranges[0] system.mem_ctrl.port = system.membus.mem_side_ports # システムポートをメモリバスに接続する system.system_port = system.membus.cpu_side_ports # X86の"hello world"バイナリを設定する。 # 他のISAではそれに応じたバイナリを設定する。 thispath = os.path.dirname(os.path.realpath(__file__)) binary = os.path.join( thispath, "../../../", "tests/test-progs/hello/bin/x86/linux/hello", ) system.workload = SEWorkload.init_compatible(binary) # シンプルな"Hello World"アプリケーションのプロセスを作成する process = Process() # コマンドを設定する # cmdは実行バイナリ(およびその引数)で設定する process.cmd = [binary] # CPUにそのプロセスを使用するように設定し、スレッドコンテキストを作成する system.cpu.workload = process system.cpu.createThreads() # root SimObjectを設定し、シミュレーションを開始する root = Root(full_system=False, system=system) # 上記で作成したオブジェクトをインスタンス化する m5.instantiate() print("Beginning simulation!") exit_event = m5.simulate() print("Exiting @ tick %i because %s" % (m5.curTick(), exit_event.getCause()))