📄 kern_check.cxx
字号:
/* * Copyright (C) 1998, 1999, Jonathan S. Shapiro. * * This file is part of the EROS Operating System. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2, * or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */#include <kerninc/kernel.hxx>#include <kerninc/Check.hxx>#include <kerninc/Thread.hxx>#include <kerninc/ObjectCache.hxx>#include <kerninc/Node.hxx>#include <kerninc/IRQ.hxx>voidCheck::Consistency(const char *msg){ static bool inCheck = false; if (inCheck) return; inCheck = true; Check::DoConsistency(msg); inCheck = false;}extern "C" { extern uint32_t InterruptStackLimit; extern uint32_t InterruptStackTop;}voidCheck::DoConsistency(const char *msg){ /* FIX: I'm not sure what should be replacing the TrapDepth check * here. The idea is to be checking whether we are in the kernel or * not. */#if defined(DBG_WILD_PTR) && 0 if (TrapDepth == 0) { assert ( Thread::Current()->IsKernel() ); KernThread* kt = (KernThread *) Thread::Current(); if ((uint32_t) &msg < (uint32_t) kt->procContext.stackBottom) fatal("Kernel stack overflow\n"); if ((uint32_t) &msg >= (uint32_t) kt->procContext.stackTop) fatal("Kernel stack underflow\n"); } else { if ((uint32_t) &msg < (uint32_t) &InterruptStackLimit) fatal("User stack overflow\n"); if ((uint32_t) &msg >= (uint32_t) &InterruptStackTop) fatal("User stack underflow\n"); }#endif static const char *lastMsg = "(unknown)"; if ( !Check::Pages() || !Check::Nodes() || !Check::Contexts("from checkcnsist") ) fatal("ChkConsistency() fails:\n" "\twhere: %s\n" "\tlast: %s\n", msg, lastMsg); lastMsg = msg;}boolCheck::Nodes(){ bool result = true; IRQ::DISABLE(); for (uint32_t nd = 0; nd < ObjectCache::NumCoreNodeFrames(); nd++) { /* printf("CheckNode(%d)\n", frame); */ Node *pNode = ObjectCache::GetCoreNodeFrame(nd); if (pNode->Validate() == false) result = false; if (result == false) break; } IRQ::ENABLE(); return result;}boolCheck::Pages(){ bool result = true; IRQ::DISABLE(); for (uint32_t pg = 0; pg < ObjectCache::NumCorePageFrames(); pg++) { /* printf("CheckPage(%d)\n", frame); */ ObjectHeader *pPage = ObjectCache::GetCorePageFrame(pg); if (pPage->IsFree()) continue; if (pPage->obType == ObType::PtNewAlloc) continue;#ifndef NDEBUG if ( !pPage->kr.IsValid(pPage) ) { result = false; break; }#endif#ifdef OPTION_OB_MOD_CHECK if (!pPage->GetFlags(OFLG_DIRTY)) { assert (pPage->GetFlags(OFLG_DIRTY) == 0); if (pPage->GetFlags(OFLG_REDIRTY)) printf("Frame %d ty=%d, flg=0x%02x redirty but not dirty!!\n", pg, pPage->obType, pPage->flags); assert (pPage->GetFlags(OFLG_DIRTY) == 0); uint32_t chk = pPage->CalcCheck(); if (pPage->GetFlags(OFLG_DIRTY) != 0) printf("Frame %d Chk=0x%x CalcCheck=0x%x flgs=0x%02x ty=%d on pgHdr 0x%08x\n", pg, pPage->ob.check, chk, pPage->flags, pPage->obType, pPage); assert (pPage->GetFlags(OFLG_DIRTY) == 0); if ( pPage->ob.check != chk ) { printf("Frame %d Chk=0x%x CalcCheck=0x%x flgs=0x%02x ty=%d on pg ", pg, pPage->ob.check, chk, pPage->flags, pPage->obType); printOid(pPage->ob.oid); printf("\n"); printf(" pPage 0x%08x dirty: %c reDirty: %c\n", pPage, (pPage->GetFlags(OFLG_DIRTY) ? 'y' : 'n'), (pPage->GetFlags(OFLG_REDIRTY) ? 'y' : 'n')); result = false; break; } }#endif#ifdef USES_MAPPING_PAGES if (pPage->obType == ObType::PtMappingPage) if ( Check::MappingPage(pPage) == false ) { result = false; break; }#endif } IRQ::ENABLE(); return result;}#ifdef USES_MAPPING_PAGES/* This is x86 specific, and needs to go in an architecture file when * I get it working! */#include <arch-kerninc/PTE.hxx>boolCheck::MappingPage(ObjectHeader *pPage){ if (pPage->producerNdx == EROS_NODE_LGSIZE) return true; PTE* pte = (PTE*) ObjectCache::ObHdrToPage(pPage); for (uint32_t ent = 0; ent < MAPPING_ENTRIES_PER_PAGE; ent++) { PTE& thePTE = pte[ent]; if (PTE_IS(thePTE, PTE_V|PTE_W)) { uint32_t pageFrame = thePTE.PageFrame(); kva_t thePage = PTOV(pageFrame); if (thePage >= KVTOL(KVA_PTEBUF)) continue; ObjectHeader *thePageHdr = ObjectCache::PhysPageToObHdr(pageFrame); if (thePageHdr->GetFlags(OFLG_CKPT)) { printf("Writable PTE=0x%08x (map page 0x%08x), ckpt pg" " 0x%08x%08x\n", thePTE.AsWord(), pte, (uint32_t) (thePageHdr->ob.oid >> 32), (uint32_t) thePageHdr->ob.oid); return false; } if (!thePageHdr->IsDirty()) { printf("Writable PTE=0x%08x (map page 0x%08x), clean pg" " 0x%08x%08x\n", thePTE.AsWord(), pte, (uint32_t) (thePageHdr->ob.oid >> 32), (uint32_t) thePageHdr->ob.oid); return false; } } } return true;}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -