調べているのはここにあるソース。
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とかgdbでAT&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の実装ではよく使われる関数なので重要ではある。