読者です 読者をやめる 読者になる 読者になる

trampolineを見る前に、気分を変えて普段よくでてくる関数でも見るよ。

minix

調べているのはここにあるソース。
http://gsd.unex.es/projects/minixsmp/

こいつは直接使うというか、ラップ関数の中から使われる。

void phys_copy_dword (unsigned long source, unsigned long destination);

例えばこんな感じで・・

void LOCAL_APIC_WRITE(u32_t reg, u32_t val) {
   phys_copy_dword( vir2phys(&val), local_apic_base+reg );
}

u32_t LOCAL_APIC_READ(u32_t reg) {
   u32_t val;
   phys_copy_dword( local_apic_base+reg, vir2phys(&val) );
   return val;
}

この中にでてくるvir2phys()はkernel/const.hにいるマクロで、
virで指定したアドレスの物理アドレスを取得するためのもの。

/* To translate an address in kernel space to a physical address.  This is
 * the same as umap(proc_ptr, D, vir, sizeof(*vir)), but a lot less costly.
 */
#define vir2phys(vir)   (data_base + (vir_bytes) (vir))


そして、phys_copy_dword()の実装はアセンブラxmp.sにいる。

!*===========================================================================*
!*                              phys_copy_dword                              *
!*===========================================================================*
! PUBLIC void phys_copy_dword(phys_bytes source, phys_bytes destination);
! Copy a block of physical memory.
PC_ARGS =       4 + 4 + 4 + 4   ! 4 + 4 
!               es edi esi eip   src dst

        .align  16
_phys_copy_dword:
        cld
        push    esi
        push    edi
        push    ds

        mov     eax, FLAT_DS_SELECTOR
        mov     ds, ax

        mov     eax, PC_ARGS(esp)       ! src
        mov     ebx, PC_ARGS+4(esp)     ! dst

        mov     edx, (eax)
        mov     (ebx), edx

        pop     ds
        pop     edi
        pop     esi
        ret

minixアセンブラAT&Tシンタックスではないので、構文は以下の形。
operand destination, source
gccとかgdbAT&T形式に慣れると、違うシンタックスは混乱するorz


FLAT_DS_SELECTORはprotect.hで定義されてて値は0x21。
PC_ARGSはスタックに積まれてるこの関数に対する引数を取得するための計算処理。

この関数でメインの処理は以下の2行

        mov     edx, (eax)
        mov     (ebx), edx

上の行で、eaxで示されるアドレス(引数のsource)の内容をedxレジスタにコピー。
下の行で、edxレジスタの内容をebxで示されるアドレス(引数のdestination)にコピー。

処理内容は上の2行だけだし、MP環境の設定には直接関係しないけどsmpの実装ではよく使われる関数なので重要ではある。