⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gdt.c

📁 COS 0.0.1.rar Cos操作系统源代码
💻 C
字号:
/* gdt.c - GDT management   Author:        Paul Barker Part of:       COS Created:       17/04/04 Last Modified: 06/10/04 Copyright (C) 2004 Paul Barker        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 of the License, 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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.                     (See file "Copying")*/#include <cosbase.h>#include <cos/sysinfo.h>#include <cos/init.h>#include <cos/debug.h>#include <cos/mem.h>#include <x86-asm.h>//////////////////////////////////////////////////////////////////////////// private functions// loop through the gdt looking for a free entryu8_t gdt_get_free(){	gdt_entry_t* desc;	count_t i = 1;	// start with 1st entry, since 0 is left blank		while (i < GDT_NUM_ENTRIES)	{		desc = gdt_get(i);		if (desc->avail == 1)		{			return i;		}		++i;	}		// there doesn't seem to be any free GDT entries!	return 0xFF;}//////////////////////////////////////////////////////////////////////////// public functions// initialise the kernel GDTvoid gdt_init(){	TRACE(("Initialising GDT...\n"));	word_t limitAndBase[3];	count_t i;	// firstly, wipe our GDT for safety	memset((ptr_t)sysinfo->gdt, 0, 4096);	// initialise the kernel code segment	gdt_set_simple(1, 0x0A);		// 1010b: code, !conforming, readable, !accessed		// (This line taken from GeekOS)	// initialise the kernel data segment by hand	gdt_set_simple(2, 0x02);		// 0010b: data, expand-up, writable, !accessed		// (This line taken from GeekOS)	// now set every other entry as available	i = 3;	// start with 3rd entry	while (i < GDT_NUM_ENTRIES)	{		sysinfo->gdt->entries[i++].avail = 1;	}	u32_t addr = (u32_t)sysinfo->gdt;	u16_t sz = GDT_NUM_ENTRIES * sizeof(gdt_entry_t);		// cruft together a limit and base, then load the GDT.	//   This bit is taken from GeekOS, with modifications	limitAndBase[0] = sz;	limitAndBase[1] = addr & 0xffff;	limitAndBase[2] = addr >> 16;	TRACE(("Loading GDT at 0x%x, size %d bytes\n", addr, sz));	lgdtr(limitAndBase);		TRACE(("GDT ready, %d free entries of %d total entries\n",	       GDT_NUM_ENTRIES - 3, GDT_NUM_ENTRIES));}// add an entry, returns the entry number// assume interrupts are off otherwise we might have problemsu8_t gdt_add(u8_t type,	     u32_t base /* = 0 */,	     u32_t size /* = 0xFFFFFFFF */,	     u8_t system /* = 1 */,	     u8_t granularity /* = 1 */,	     u8_t dbBit /* = 1 */,	     u8_t dpl /* = 0 */){	TRACE(("gdt_add: Adding GDT entry\n"));	TRACE(("type=%x, base=%x, size=%x\n", type, base, size));	TRACE(("system=%d, granularity=%d, dbBit=%d, dpl=%d\n",		system, granularity, dbBit, dpl));		u32_t i = gdt_get_free();	gdt_entry_t* desc = &(sysinfo->gdt->entries[i]);		if (i == 0xFF)		return 0xFF;		TRACE(("found free entry %d\n", i));		gdt_set_size(desc, size);	gdt_set_base(desc, base);	desc->system = system;	desc->present = 1;	desc->granularity = granularity;	desc->type = type;	desc->dbBit = dbBit;	desc->dpl = dpl;	desc->avail = 0;		TRACE(("gdt_add() done\n"));		return i;}// get an existing entrygdt_entry_t* gdt_get(u8_t entry){	return &(sysinfo->gdt->entries[entry]);}// copy an entry into the table// I expect this will rarely be used, but could reduce the amount of time//    interrupts will be disabled for once memcpy() is optimised.void gdt_put(u8_t entry, gdt_entry_t* desc){	gdt_entry_t* ent = gdt_get(entry);	TRACE(("gdt_put: copying from %x to descriptor %d at %x\n",	       desc, entry, ent));	memcpy(ent, desc, sizeof(gdt_entry_t));}// remove an entry// again interrupts should be disabled, we always assume this will workvoid gdt_remove(u8_t entry){	gdt_entry_t* desc = gdt_get(entry);	TRACE(("gdt_remove: removing entry %d at %x\n", entry, desc));	memset((ptr_t)desc, 0, sizeof(gdt_entry_t));	desc->avail = 1;}// modify an entry, or add an entry at a certain position// assume interrupts are disabled yet againvoid gdt_set(u8_t entry,	    u8_t type,	    u32_t base /* = 0 */,	    u32_t size /* = 0xFFFFFFFF */,	    u8_t system /* = 1 */,	    u8_t granularity /* = 1 */,	    u8_t dbBit /* = 1 */,	    u8_t dpl /* = 0 */){	gdt_entry_t* desc = gdt_get(entry);		TRACE(("gdt_set: Setting GDT entry %d at %x\n", entry, desc));	TRACE(("type=%x, base=%x, size=%x\n", type, base, size));	TRACE(("system=%d, granularity=%d, dbBit=%d, dpl=%d\n",		system, granularity, dbBit, dpl));			memset((ptr_t)desc, 0, sizeof(gdt_entry_t));	gdt_set_size(desc, size);	gdt_set_base(desc, base);	desc->system = system;	desc->present = 1;	desc->granularity = granularity;	desc->type = type;	desc->dbBit = dbBit;	desc->dpl = dpl;	desc->avail = 0;		TRACE(("gdt_set() done\n"));}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -