📄 gdt.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 "GDT.hxx"#include "TSS.hxx"/* Make sure this does not end up in BSS by using dummy initializers */uint32_t GDT::GDTdescriptor[2];voidGDT::SetupPageSegment(SegEntry::Name entry, uint32_t linearBase, uint32_t nPages){ SegDescriptor& seg = *((SegDescriptor*) &GdtTable[entry*2]); seg.loBase = (linearBase & 0xffffu); seg.midBase = (linearBase >> 16) & 0xffu; seg.hiBase = (linearBase >> 24) & 0xffu; seg.loLimit = (nPages & 0xffffu); seg.hiLimit = ((nPages >> 16) & 0xfu); seg.granularity = 1;}voidGDT::SetupTSS(SegEntry::Name entry, uint32_t base){ SegDescriptor& seg = *((SegDescriptor*) &GdtTable[entry*2]); #ifndef NDEBUG SegDescriptor tssSeg; tssSeg.loLimit = sizeof(i386TSS)-1; tssSeg.loBase = 0; tssSeg.midBase = 0; tssSeg.hiBase = 0; tssSeg.type = 0x9; tssSeg.system = 0; tssSeg.dpl = 0; tssSeg.present = 1; tssSeg.hiLimit = 0; tssSeg.avl = 0; tssSeg.zero = 0; tssSeg.sz = 0; tssSeg.granularity = 0; uint32_t * wTssSeg = (uint32_t *) &tssSeg; uint32_t * wseg = (uint32_t *) &seg; assert(wseg[0] == wTssSeg[0]); assert(wseg[1] == wTssSeg[1]);#endif uint32_t linearBase = KVTOL(base); seg.loBase = linearBase & 0xffffu; seg.midBase = (linearBase >> 16) & 0xffu; seg.hiBase = (linearBase >> 24) & 0xffu;}#define GDT_SIZE (GDT_ENTRIES * 8)voidGDT::Init(){ uint32_t wgdt; wgdt = KVTOL(GdtTable); GDTdescriptor[0] = GDT_SIZE | ((wgdt & 0xffff) << 16); GDTdescriptor[1] = wgdt >> 16; uint32_t klimit = (0u - KVA) >> EROS_PAGE_ADDR_BITS; /* Initialize the GDT so that the kernel segment bases point to the right places. The table as initialized is correct for the user and APM segments. */ SetupPageSegment(SegEntry::KernelCode, KVA, klimit ); SetupPageSegment(SegEntry::KernelData, KVA, 0xfffff /*4G */); SetupPageSegment(SegEntry::KProcCode, KVA, klimit ); SetupPageSegment(SegEntry::KProcData, KVA, 0xfffff /*4G */); SetupPageSegment(SegEntry::DomainCode, KVA, LARGE_SPACE_PAGES ); SetupPageSegment(SegEntry::DomainData, KVA, LARGE_SPACE_PAGES ); lgdt(); ReloadSegRegs();}#ifdef OPTION_DDB#include <arch-kerninc/db_machdep.hxx>#include <ddb/db_output.hxx>voiddb_show_gdt(db_expr_t, int, db_expr_t, char*){ GDT::ddb_dump();}voidGDT::ddb_dump(){ db_printf("GdtTable at 0x%08x\n", &GdtTable); for (int entry = 0; entry < GDT_ENTRIES; entry++) { SegDescriptor& seg = *((SegDescriptor*) &GdtTable[entry*2]); uint32_t base = ((((uint32_t)seg.hiBase) << 24) | (((uint32_t)seg.midBase) << 16) | ((uint32_t)seg.loBase)); uint32_t limit = ((((uint32_t)seg.hiLimit) << 16) | ((uint32_t)seg.loLimit)); if (seg.granularity == 1) limit <<= EROS_PAGE_ADDR_BITS; db_printf("[%02d] base=0x%08x limit=0x%08x [w0=0x%08x w1=0x%08x]\n", entry, base, limit, GdtTable[entry * 2], GdtTable[entry * 2 + 1]); db_printf(" ty=%d sys=%d dpl=%d pres=%d avl=%d gran=%d (%d bit)\n", seg.type, seg.system, seg.dpl, seg.present, seg.avl, seg.granularity, seg.sz ? 32 : 16); }}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -