2010年3月19日 星期五

ARM System call in SimpleScalar

對ARM的認知大致上都是從課堂跟GCC的md檔來的

但是對於這些OS底層實作相關的知識還真是薄弱

說正確一點是弱到不行

SimpleScalar 的 system call實作上大致上是在

target-arm/syscall.c裡面

有時候遇到

warning: invalid/unimplemented syscall xxx, PC=0x0001c454, winging it

的時候可以直接略過沒關係,但是...事情總不會那麼順利

而且SimpleScalar早就沒在更新了,也大概不用期待下一版會解決這種事發生

以rename來當例子好了,忘記是哪個benchmark需要用到,少了就不能正常運作

rename 的 system call 編號是 38

所以其實要補system call的第一步是先查出缺什麼,並且它是不是必要的,
(必要的定義在於沒補齊就會跑不出數據...

接著把編號拿去syscall.c裡面查查看是啥

以38為例

#define ARM_SYS_rename 38

由此可知編號38是rename,接著丟到Google大神去查一下各參數的功能是啥

int rename ( const char * oldname, const char * newname );

rename就如他名字一般,就是拿來改檔案的

所以我們其實只要把參數在丟到對應的system call就好

第一個參數會放在R0

第二個則在R1

所以直覺上我們這樣寫

regs->regs_R[MD_REG_R0] =
rename(regs->regs_R[MD_REG_R0], regs->regs_R[MD_REG_R1]);

不過會發現一件事,regs->regs_R[MD_REG_R0]所存的指標不是host所用的address

直接傳進去可能會segment fault,或是發生其他不可預期的事

參考一下其他system call的實作可以發現有一個函數可以用

char buf[MAXBUFSIZE];
mem_strcpy(mem_fn, mem, Read, /*fname*/regs->regs_R[MD_REG_R0], buf);

從simulator 所用的記憶體中搬出東西來,第二個參數也照做就行了

接著補上頭跟尾
case ARM_SYS_rename:
{
char buf[MAXBUFSIZE];
char buf2[MAXBUFSIZE];
/* copy filename to host memory */
mem_strcpy(mem_fn, mem, Read, /*fname*/regs->regs_R[MD_REG_R0], buf);
mem_strcpy(mem_fn, mem, Read, /*fname*/regs->regs_R[MD_REG_R1], buf2);
/* chmod the file */
/*result*/
regs->regs_R[MD_REG_R0] =
rename(buf, buf2);

break;
}


然後補上錯誤處理部份

case ARM_SYS_rename:
{
char buf[MAXBUFSIZE];
char buf2[MAXBUFSIZE];
/* copy filename to host memory */
mem_strcpy(mem_fn, mem, Read, /*fname*/regs->regs_R[MD_REG_R0], buf);
mem_strcpy(mem_fn, mem, Read, /*fname*/regs->regs_R[MD_REG_R1], buf2);
/* chmod the file */
/*result*/
regs->regs_R[MD_REG_R0] =
rename(buf, buf2);

/* check for an error condition */
if (regs->regs_R[MD_REG_R0] == (qword_t)-1)
/* got an error, return details */
regs->regs_R[MD_REG_R0] = -errno;
break;
}

會用qword_t則是有一些歷史原因,simplescalar最原本是porting到alpha上用的,大概是因此沿用下來的慣例

俗話說的好要入境隨俗,所以留著吧

然後再把這段code插入sys_syscall的那個超大switch中的某個適合的地方就可以了



後記:

其實最讓我驚訝的還是在

system call的時候

第五個參數竟然就直接放在r4,這跟原本認知第五個參數以後要丟stack不一樣

至於第六個或更多參數呢...目前還沒看到,遇到再補完這邊文章