syscall.c int fetchint(uint addr, int *ip)
トップページ
jupiteroak.hatenablog.com
syscall.c
https://github.com/mit-pdos/xv6-public/blob/master/syscall.c#L17
int fetchint(uint addr, int *ip) { struct proc *curproc = myproc(); if(addr >= curproc->sz || addr+4 > curproc->sz) return -1; *ip = *(int*)(addr); return 0; }
fetchint関数は、プロセスのユーザ空間内にあるアドレスaddrが指定するメモリ領域から、アドレスipが指定するメモリ領域へ、4バイトのデータをコピーします。
引数 uint addr
コピー元となるメモリ領域を指定するアドレスです。
引数 int *ip
コピー先となるメモリ領域を指定するアドレスです。
戻り値 0 または -1
データのコピーに成功した場合は、0が戻り値とまります。
データのコピーに失敗した場合は、-1が戻り値となります。
処理の内容
- 現在実行中のプロセスに対応しているプロセスディスクリプタを取得する
- アドレスaddrが不正な値ではないことを確認する
- アドレスaddが指定するメモリ領域からアドレスipが指定するメモリ領域へ4バイトのデータをコピーする
- 0を戻り値としてリターンする
現在実行中のプロセスに対応しているプロセスディスクリプタを取得する
struct proc *curproc = myproc();
myproc関数を呼び出して、現在この関数を実行中のプロセスに対応しているプロセスディスクリプタを取得します。
アドレスaddrが不正な値ではないことを確認する
if(addr >= curproc->sz || addr+4 > curproc->sz) return -1;
addr >= curproc->szが真となる場合→アドレスaddrがプロセスのカーネル空間に入ってしまっている場合、または、addr+4 > curproc->szが真となる場合→プロセスのユーザー空間の終端アドレス付近でアドレスaddrが4バイト境界(4バイトの倍数値)ではない場合は、-1を戻り値として処理を終了します。
プロセスのユーザー空間のサイズがszの時、プロセスのユーザー空間の終端アドレスはsz-1となるので、カーネル空間の先頭アドレスはszとなります。
アドレスaddが指定するメモリ領域からアドレスipが指定するメモリ領域へ4バイトのデータをコピーする
*ip = *(int*)(addr);
アドレスaddが指定するメモリ領域からアドレスipが指定するメモリ領域へ4バイトのデータ(int型のデータ)をコピーします。
0を戻り値としてリターンする
return 0;