Lowlevel
Lowlevel => Lowlevel-Coding => Thema gestartet von: sp am 08. December 2004, 19:48
-
Hallo
Ich habe mal versucht einen Deskriptor in C Datenstrukturen umzusetzen. (Als Vorlage diente natürlich teejays tut) Vielleicht kann ja mal jemand drüber schauen und berichten wo sich Fehler eingeschlichen haben oder vielleicht hat ja auch jemand etwas Kritik für mich.
sp
PS: Ich hab es leider, aufgrund techn. Probleme, (noch) nicht testen können.
//---------------------------------------------------------------------------
//
//---------------------------------------------------------------------------
struct s_descriptor_access_type
{
//---------------------------------------------------------------------------
// 1 = CPU arbeitet gerade mit diesem Segment
// 0 = Segment nicht in Nutzung
//---------------------------------------------------------------------------
uint accessed : 1; //B0
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
//
//---------------------------------------------------------------------------
uint type : 3;
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
// 1 = normales Segment
// 0 = System-Segment (TSS, Interrupt-Gate, ...)
//---------------------------------------------------------------------------
uint segment_type : 1;
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
// Deskriptor Privilege Level
// 0,1,2,3
//---------------------------------------------------------------------------
uint dpl : 2;
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
// 1 = Segment befindet sich im Speicher
// 0 = Segment wurde duch OS ausgelagert
//---------------------------------------------------------------------------
uint present : 1; //B7
//---------------------------------------------------------------------------
};
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
//
//---------------------------------------------------------------------------
struct s_descriptor_seg_info
{
//---------------------------------------------------------------------------
// Dieses BIT kann frei genutzt werden, es wird von der CPU
// nicht eingelesen bzw, verarbeitet.
//---------------------------------------------------------------------------
uint available_bit : 1; //B0
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
// Reserviert, sollte immr auf Null gesetzt werden.
//---------------------------------------------------------------------------
uint resv : 1
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
// 1 = 386 (Datensegment max 4 GB, Code = 32 Bit, Stack = 32 Bit)
// 0 = 286 (Datensegment max 64 KB, Code = 16 Bit, Stack = 16 Bit)
//---------------------------------------------------------------------------
uint seg_32bit : 1;
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
// 1 = Segmentgröße wird in 4KB Schritten eingegeben
// 0 = Segmentgröße wird als Bytes gesehen
//---------------------------------------------------------------------------
uint granular : 1; //B3
//---------------------------------------------------------------------------
};
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
//
//---------------------------------------------------------------------------
struct s_descriptor
{
//---------------------------------------------------------------------------
// Segmentgröße: Bit 0 bis 15
//---------------------------------------------------------------------------
word segment_size_low;
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
//
//---------------------------------------------------------------------------
word segment_base_low;
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
//
//---------------------------------------------------------------------------
byte segment_base_middle;
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
//
//---------------------------------------------------------------------------
s_descriptor_access_type access_type;
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
//
//---------------------------------------------------------------------------
uint segment_size_high : 4;
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
//
//---------------------------------------------------------------------------
s_descriptor_seg_info segment_info;
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
//
//---------------------------------------------------------------------------
byte segment_base_high;
//---------------------------------------------------------------------------
};
//---------------------------------------------------------------------------
-
Hiho,
ehrlich gesagt weiß ich jetzt nicht, was ich damit jetzt anfangen soll!
Das einzige, was ich dazu sagen kann ist, das ich vielleicht die einzelnen Bitfelder direkt in Substructs packen würde.
struct eine_struct
{
struct
{
unsigned a : 4;
unsigned b : 4;
} sub_struct;
};
Ob es funktioniert, keine Ahnung...
MfG GhostCoder
-
Ich würde die Bits nicht so anlegen, sondern einfach nur so viele uints anlegen wie ein Deskriptor hat und dort dann mit Hilfe von Macros drauf zugreifen...
Das macht die Sache übersichtlicher.
-
@TeeJay,
so mach ich das auch, aber übersichtlicher is es wohl net. Einfacher mit uints isses, wenn du die Funktion zum anlegen eines neuen Eintrag aufrufst:
Da brauchste nur die Flags in das uint reinschreiben, bei der struct Methode musst du jedes einzelne Flag extra reinschreiben...
descriptor.flags=flags;
descriptor.accessed=flags & ACCESSED;
descriptor.dpl=flags & DPL;
....
Genau aus dem Grund bleib ich bei der oberen Methode,
MfG GhostCoder
-
Ausserdem würd ich auch das attribut _PACKED_ verwenden denn es könnte sein das er sonst die structs falsch im Speicher anordnet
-
Find ich schon, siehe oben...
-
Hiho,
also als erstes definierst du wie der Deskriptor aussehen soll (hier meine idt)
struct GATE
{
WORD wOffset0_15;
WORD wSelector;
WORD wFlags;
WORD wOffset16_31;
};
Danach kommen die Flags, das heißt(welches Bitmuster entsteht, wenn das PRESENT bit gesetzt ist.
#define IDT_PRESENT 0x8000
#define IDT_TRAP 0x0700
#define IDT_INT 0x0600
#define IDT_TASK 0x0500
#define IDT_32 0x0800
#define IDT_DPL0 0x0000
#define IDT_DPL1 0x2000
#define IDT_DPL2 0x4000
#define IDT_DPL3 0x6000
Dann die realisierung:
void idt_SetGate(DWORD dwIndex,WORD wSelector,DWORD dwOffset,WORD wFlags)
{
asGates[dwIndex].wOffset0_15=dwOffset & 0xFFFF;
asGates[dwIndex].wOffset16_31=(dwOffset >> 16) & 0xFFFF;
asGates[dwIndex].wSelector=wSelector;
asGates[dwIndex].wFlags=wFlags;
}
Wenn du jetzt die Funktion aufruft, verkmüpfst du die o.g. flags einfach mit einem binären oder. also z.b.
idt_SetGate(0x20,8,__scheduler,IDT_PRESENT | IDT_32 | IDT_INT | IDT_DPL0);
So einfach geht das...
MfG GhostCoder
-
Ups, du meintest die Macroversion...
Sorry, hab mich verlesen!
Die muss TeeJay dann aber erklären! ;)
MfG GhostCoder
-
void idt_Init()
{
psIDT=(struct IDT*)KernelAlloc(sizeof(struct IDT)*IDT_COUNT);
DWORD dwDesc[2]={(sizeof(struct IDT)*IDT_COUNT) << 16,(DWORD)psIDT};
char *ptr=(char*)dwDesc+2;
memset(psIDT,0,sizeof(struct IDT)*IDT_COUNT);
asm("lidt (%0)"::"r"(ptr));
}
MfG GhostCoder