$ svn co http://llvm-qemu.googlecode.com/svn/trunk/ llvm-qemu # qemu 0.9 需要 GCC 3.x # wget http://qemu.sourcearchive.com/downloads/0.9.1/qemu_0.9.1.orig.tar.gz # wget ftp://gd.tuwien.ac.at/gnu/gcc/releases/gcc-3.4.6/gcc-3.4.6.tar.gz $ wget http://llvm.org/releases/2.1/llvm-2.1.tar.gz; tar xvf llvm-2.1.tar.gz $ wget http://llvm.org/releases/2.1/llvm-gcc4.0-2.1.source.tar.gz; tar xvf llvm-gcc4.0-2.1.source.tar.gz $ mkdir build; cd build $ wget http://llvm.org/releases/2.1/llvm-gcc4.0-2.1-x86-linux-RHEL4.tar.gz;
QEMU 0.9 版以前使用 dyngen,對於 dyngen 的描述可以參考以下文件。QEMU 0.10 以後改採 TCG。
QEMU 0.9 版的作法:
- micro op 用 C 函式實現。再用 GCC 編譯 micro op,最後從目的檔中把 host binary 切出來備用。micro op 函式的 prprologue/epilogue 會被忽略。
- guest binary → micro ops: 手寫 parser 將 guest binary 翻譯成若干 micro op。
- 將 micro op 對應的 host binary 拼湊起來。
dyngen 是在建置 QEMU 的時候,負責由包含 micro op 的目的檔生成 dynamic code generator。dynamic code generator 在 QEMU 執行的時候負責動態翻譯。
target-*/op.* 實現 micro op 對應的 C 函式。
block chaining。
- 在此稱目前 TB 為 tb1。
- 如果下一個 TB 位址已知,則跳至該 TB; 若否,則往下執行。
- 將 guest pc 設成離開 tb1 之後下一個欲執行的指令的位址。
- 將 tb1 的位址 (後兩位設成 00 或 01,代表分支的方向) 存起來。
- 回到 QEMU。QEMU 會利用前兩步所得資訊做 block chaining。一但完成 block chaining,下一次再執行到這個分支時,就會跳至下一個 TB 在 code cache 的位址執行。