目录

請見底下文件,

opteron48.iis.sinica.edu.tw

建置 COREMU

COREMU 著墨在 system mode,不支援 process mode。COREMU 需要 root 權限設定執行緒的優先權。如果要以一般使用者執行 COREMU,請自己把會噴 assert 的地方關掉。:-D 請閱讀 coremu/README。

  1. 安裝 libtopology。請見 Portable Hardware Locality
    $ wget http://sourceforge.net/projects/coremu/files/coremu-img/libtopology-0.9.tar.gz/download
    $ tar xvf libtopology-0.9.tar.gz
    $ mkdir build; cd build
    $ ../libtopology-0.9/configure --prefix=$INSTALL
    $ make; make install
  2. 安裝 COREMU。
    $ wget http://sourceforge.net/projects/coremu/files/coremu-0.1.2.tar.gz/download
    # coremu-0.1.2 目錄底下分別有兩個目錄:
    # coremu: COREMU 核心函式庫
    # qemu: QEMU 0.13 補丁版
    $ tar xvf coremu-0.1.2.tar.gz
    $ cd coremu
    # 修改 configure。
    # --extra-cflags="-I${coremuroot}/incl -g -I/tmp/chenwj/install" \
    # --extra-ldflags="-L/tmp/chenwj/install/lib" \
    # 將 PKG_CONFIG_PATH 指向編譯 libtopology 所在的目錄 
    $ export PKG_CONFIG_PATH=$BUILD/topology.pc
    $ ./configure --target=arm --prefix=$INSTALL ../qemu
    $ make; make install
  3. 下載映像檔。
    $ wget http://sourceforge.net/projects/coremu/files/coremu-img/debian-x86_64.img.gz/download
    $ cd coremu/scripts
    $ export LD_LIBRARY_PATH=/PATH/TO/libtopology.so
    $ ./x86_64-linux.sh <path2qemu> <path2img> <core number>
    $ ./arm-linux.sh ~/install/atomic/bin/qemu-system-arm arm-zImage-2.6.28 arm-initrd.gz 1

Internal

  1. 進入主要執行迴圈之前,COREMU 會做額外初始化。
    static void main_loop(void)
    {
        int r;
    #ifdef CONFIG_COREMU
        /* 1. Not finish: need some initialization */
     
        /* 2. register hook functions */
        /* register the interrupt handler */
        coremu_register_event_handler((void (*)(void*))cm_common_intr_handler);
        /* register the event notifier */
        coremu_register_event_notifier(cm_notify_event);
     
        /* 3. register core alarm handler. */
        struct sigaction act;
        sigfillset(&act.sa_mask);
        act.sa_flags = 0;
        act.sa_handler = cm_local_host_alarm_handler;
        sigaction(COREMU_CORE_ALARM, &act, NULL);
     
        /* 4. Create cpu thread body*/
        coremu_run_all_cores(cm_cpu_loop);  // coremu_run_all_cores coremu/main/core.c cm_cpu_loop (qemu/cm-loop.c)
    #else
        qemu_main_loop_start();

針對客戶的 atomic 指令,COREMU 會另行處理。以 x86 為例,

  1. xchg 為 atomic 指令。
        case 0x87: /* xchg Ev, Gv */
            if ((b & 1) == 0)
                ot = OT_BYTE;
            else
                ot = dflag + OT_WORD;
            modrm = ldub_code(s->pc++);
            reg = ((modrm >> 3) & 7) | rex_r;
            mod = (modrm >> 6) & 3;
            if (mod == 3) {
                rm = (modrm & 7) | REX_B(s);
            do_xchg_reg:
                gen_op_mov_TN_reg(ot, 0, reg);
                gen_op_mov_TN_reg(ot, 1, rm);
                gen_op_mov_reg_T0(ot, rm);
                gen_op_mov_reg_T1(ot, reg);
            } else {
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
     
    #ifdef CONFIG_COREMU
                /* for xchg, lock is implicit.
                   XXX: none flag is affected! */
                switch (ot & 3) {
                case 0:
                    gen_helper_xchgb(cpu_A0, tcg_const_i32(reg),
                            tcg_const_i32(X86_64_HREGS));
                    break;
                case 1:
                    gen_helper_xchgw(cpu_A0, tcg_const_i32(reg),
                            tcg_const_i32(X86_64_HREGS));
                    break;
                case 2:
                    gen_helper_xchgl(cpu_A0, tcg_const_i32(reg),
                            tcg_const_i32(X86_64_HREGS));
                    break;
    #ifdef TARGET_X86_64
                    case 3:
                    gen_helper_xchgq(cpu_A0, tcg_const_i32(reg),
                            tcg_const_i32(x86_64_hregs));
    #endif
                }
    #else
  2. 呼叫 COREMU 自行定義的 helper function (target-i386/cm-atomic.c)。
    #define GEN_ATOMIC_XCHG(type) \
    void helper_xchg##type(target_ulong a0, int reg, int hreg)    \
    {                                                             \
        DATA_##type val, out;                                     \
        unsigned long q_addr;                                     \
                                                                  \
        CM_GET_QEMU_ADDR(q_addr, a0);                             \
        val = (DATA_##type)cm_get_reg_val(OT_##type, hreg, reg);  \
        out = atomic_exchange##type((DATA_##type *)q_addr, val);  \
        mb();                                                     \
                                                                  \
        cm_set_reg_val(OT_##type, hreg, reg, out);                \
    }

外部連結