📄 arch_selector.c
字号:
/*** Copyright 2002, Michael Noisternig. All rights reserved.** Distributed under the terms of the NewOS License.*/#include <boot/arch/i386/stage2.h>#include <kernel/arch/cpu.h>#include <kernel/smp.h>#include <kernel/int.h>#include <kernel/arch/i386/selector.h>#define MAX_SELECTORS (GDT_LIMIT/8)#define ENTRIES (MAX_SELECTORS/(sizeof(uint32)*8))static uint32 selector_bitmap[ENTRIES] = { 0x000000ff }; // first 8 selectors reservedstatic selector_type *gdt_table;static struct gdt_idt_descr descr = { GDT_LIMIT - 1, NULL };void i386_selector_init( void *gdt ){ gdt_table = (selector_type *)gdt; descr.b = (unsigned int *)gdt_table;}// creates a new selector in the gdt of given type (use SELECTOR macro)// IN: selector type// RET: selector that can be directly used for segment registers// 0 on errorselector_id i386_selector_add( selector_type type ){ static int spinlock; uint32 mask; selector_id id = 0; unsigned i; int_disable_interrupts(); acquire_spinlock( &spinlock ); for ( i = 0; i < ENTRIES; i++ ) if ( selector_bitmap[i] != 0xffffffff ) { // found free place in there id = i*sizeof(uint32)*8; mask = 1; while ( selector_bitmap[i] & mask ) { mask <<= 1; id++; } selector_bitmap[i] |= mask; gdt_table[id] = type; break; } release_spinlock( &spinlock ); int_restore_interrupts(); if ( id ) { asm("lgdt %0;" : : "m" (descr)); } return id*8;}// removes a selector with given id from the gdtvoid i386_selector_remove( selector_id id ){ if ( id < 8*8 || id >= MAX_SELECTORS*8 ) return; id /= 8; gdt_table[id] = 0; atomic_and( &selector_bitmap[id/32], ~(1<<(id&31)) ); asm("lgdt %0;" : : "m" (descr));}// returns the selector type of a given idselector_type i386_selector_get( selector_id id ){ return gdt_table[id/8];}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -