xv6のブートをRISC-VのISSで再現させている。途中までうまくいっているのだがどこで止まっているのかわからない。そのときは階層トレース機能を使ってどの関数まで飛んできたかをチェックする。
<FunctionCall 183795: main(0x80104ec8)> <FunctionCall 183803: kinit1(0x80103a98)> <FunctionCall 183814: initlock(0x80106d2c)> <Return: initlock> <FunctionCall 183836: freerange(0x80103b38)> <FunctionCall 183857: kfree(0x80103bb0)> <FunctionCall 183873: v2p(0x80103a6c)> <Return: v2p> <FunctionCall 183891: memset(0x80107124)> <FunctionCall 183923: stosl(0x801070c8)> <Return: stosl> <Return: memset> <Return: kfree> <FunctionCall 194222: kfree(0x80103bb0)> <FunctionCall 194238: v2p(0x80103a6c)> <Return: v2p> <FunctionCall 194256: memset(0x80107124)> <FunctionCall 194288: stosl(0x801070c8)> <Return: stosl> <Return: memset> <Return: kfree> <FunctionCall 204587: kfree(0x80103bb0)> <FunctionCall 204603: v2p(0x80103a6c)> <Return: v2p> <FunctionCall 204621: memset(0x80107124)> <FunctionCall 204653: stosl(0x801070c8)> <Return: stosl> <Return: memset>
途中まででGDBを止めて、怪しい部分をトレースさせているのだが、その時にstdoutはバッファを抱えているためトレースを確実に表示させるためにfflushさせたい。
GdbStatus GdbEnv::HandleClientRequest () { ... switch (packet_str.front()) { case '?' : { PutPacket ("S05"); break; } case 'c' : { m_env->SetMaxCycle(1); m_env->StepSimulation (1, LoopType_t::InfLoop); m_env->FlushDbgFile (); m_env->FlushTraceFp (); ...
FlushDbgFile()とFlushTraceFp()を追加した。これによりデバッグ用トレースファイルと階層用トレースファイルが、ブレークポイントに差し掛かった時に自動的にffushされる。
これでデバッグがやりやすくなった。問題だったのはxv6のxchgの部分だった。実装を変更すると、xv6がブートできるようになった。あと少しだ!