qemuでエラー発生。それは一般保護例外だった。原因はfar callにあるっぽい。下のソースのg_GDTManager->setGDTの引数は、インデックス、ベース、リミット、アクセス権の順となっている。g_GDTManager->loadGDTR()はLGDTを呼び出しているだけ。IO::farCallの引数はCSレジスタの値、EIPの値の順。
g_GDTManager->setGDT(1, 0, 0xffffffff, 0x409a); //2〜5は省略 g_GDTManager->loadGDTR(); //いろんな処理省略 g_GDTManager->setGDT(6, 0, 0xffffffff, 0x4092); IO::farCall(6 * 8, entry->getMainAddress());
このIO::farCallで駄目っぽい。それで、試しに
IO::farCall(1 * 8, entry->getMainAddress());
とやってみるとうまくいく。次にg_GDTManager->loadGDTR()をもう一度呼び出してみたが駄目だった
g_GDTManager->setGDT(6, 0, 0xffffffff, 0x4092); g_GDTManager->loadGDTR(); IO::farCall(6 * 8, entry->getMainAddress());
1と6に何の差があるんだ?
6のアクセス権が間違っていた。アクセス権を変えたらうまくいった。なんてことだ…