Zum Inhalt springen

C, Inline Assembler und die GDT


Sebastian2345

Empfohlene Beiträge

Hallo ihr Informatiker da drausen :D

Ich versuche gerade, angelehnt an das Tutorial von Tyndur die GDT zu laden, doch leider bisher ohne Erfolg (Der Rechner / Die VM bootet durch).

Ich habe das Problem soweit eingrenzen können, dass es sich in der Definition befinden müsste aber ich bin leider nicht in der Lage den Fehler zu eleminieren.

Hier der Code:

#include "init.h"

#include "os_look.h"

#include "stdio.h"

#include "stdint.h"


static int c_boot = 0x0e;

static int c_ok = 0x02;

static int c_bad = 0x04;

static int c_ct= 0x07;


void print_status(int status)

{

if(status==1)

{

set_color(c_ok);

printf("DONE\n");

}

else

{

set_color(c_bad);

printf("FAILED\n");

}

set_color(c_boot);

}


int start(void)

{

set_color(c_boot);

int status=0;

clear();

printf("Clearing Screen ");

print_status(1);

printf("Initializing Global Descriptor Tabel ");

print_status(init_gdt());

print_status(0);

status=0;

printf("Initializing Interrupt Descriptor Tabel ");

print_status(init_intr());

status=0;

printf("Printing OS Main Screen ");

print_status(print_look());

status=0;

set_color(c_ct);

return 0;

}


extern void intr_stub_0(void);

extern void intr_stub_1(void);

extern void intr_stub_2(void);

extern void intr_stub_3(void);

extern void intr_stub_4(void);

extern void intr_stub_5(void);

extern void intr_stub_6(void);

extern void intr_stub_7(void);

extern void intr_stub_8(void);

extern void intr_stub_9(void);

extern void intr_stub_10(void);

extern void intr_stub_11(void);

extern void intr_stub_12(void);

extern void intr_stub_13(void);

extern void intr_stub_14(void);

extern void intr_stub_15(void);

extern void intr_stub_16(void);

extern void intr_stub_17(void);

extern void intr_stub_18(void);


extern void intr_stub_32(void);

extern void intr_stub_33(void);


extern void intr_stub_48(void);


[COLOR="Red"]#define GDT_FLAG_DATASEG 0x02

#define GDT_FLAG_CODESEG 0x0a

#define GDT_FLAG_TSS	 0x09


#define GDT_FLAG_SEGMENT 0x10

#define GDT_FLAG_RING0	 0x00

#define GDT_FLAG_RING3	 0x60

#define GDT_FLAG_PRESENT 0x80


#define GDT_FLAG_4K	 0x800

#define GDT_FLAG_32_BIT  0x400


#define GDT_ENTRIES 5

static uint64_t gdt[GDT_ENTRIES];

#define IDT_ENTRIES 256

static long long unsigned int idt[IDT_ENTRIES];


static void gdt_set_entry(int i,unsigned int base,unsigned int limit,int flags)

{

	gdt[i] = limit & 0xffffll;

	gdt[i] |= (base & 0xffffffll) << 16;

	gdt[i] |= (flags & 0xffll) << 40;

	gdt[i] |= ((limit >> 16) & 0xfll) << 48;

	gdt[i] |= ((flags >> 8) & 0xffll) << 52;

	gdt[i] |= ((base >> 24) | 0xffll) << 56;

}



int init_gdt(void)

{

	struct {

	uint16_t limit;

	void* pointer;

	} __attribute__((packed)) gdtp = {.limit = GDT_ENTRIES * 8 - 1,.pointer = gdt,};


gdt_set_entry(0,0,0,0);

gdt_set_entry(1,0,0xfffff,GDT_FLAG_SEGMENT | GDT_FLAG_32_BIT | GDT_FLAG_CODESEG | GDT_FLAG_4K | GDT_FLAG_PRESENT);

gdt_set_entry(2,0,0xfffff,GDT_FLAG_SEGMENT | GDT_FLAG_32_BIT | GDT_FLAG_DATASEG | GDT_FLAG_4K | GDT_FLAG_PRESENT);

gdt_set_entry(3,0,0xfffff,GDT_FLAG_SEGMENT | GDT_FLAG_32_BIT | GDT_FLAG_CODESEG | GDT_FLAG_4K | GDT_FLAG_PRESENT | GDT_FLAG_RING3 );

gdt_set_entry(4,0,0xfffff,GDT_FLAG_SEGMENT | GDT_FLAG_32_BIT | GDT_FLAG_DATASEG | GDT_FLAG_4K | GDT_FLAG_PRESENT | GDT_FLAG_RING3 );[/COLOR]


	[COLOR="Red"]asm volatile("lgdt %0" : : "m" (gdtp));[/COLOR]

	asm volatile(

		"mov $0x10, %ax;"

		"mov %ax, %ds;"

		"mov %ax, %es;"

		"mov %ax, %ss;"

		"ljmp $0x8, $.l;"

		".l:"

		);

return 1;

}


#define IDT_FLAG_INTERRUPT_GATE 0xe

#define IDT_FLAG_PRESENT 0x80

#define IDT_FLAG_RING0 0x00

#define IDT_FLAG_RING3 0x60


static void idt_set_entry(int i,void (*fn)(),unsigned int selector, int flags)

{

	unsigned long int handler = (unsigned long int) fn;

	idt[i] = handler & 0xffffLL;

	idt[i] |= (selector & 0xffffLL) << 16;

	idt[i] |= (flags & 0xffLL) << 40;

	idt[i] |= ((handler>> 16) & 0xffffLL) <<48;

}


static inline void outb(uint16_t port, uint8_t data)

{

	asm volatile("outb %0, %1" : : "a" (data), "Nd" (port));

}


static void init_pic(void)

{

	outb(0x20, 0x11);

	outb(0x21, 0x20);

	outb(0x21, 0x04);

	outb(0x21, 0x01);


	outb(0xa0, 0x11);

	outb(0xa1, 0x28);

	outb(0xa1, 0x02);

	outb(0xa1, 0x01);


	outb(0x20, 0x0);

	outb(0xa0, 0x0);

}


int init_intr(void)

{

	struct 

	{

		unsigned short int limit;

		void* pointer;

	}

	__attribute__((packed)) idtp = { .limit = IDT_ENTRIES * 8 - 1, .pointer = idt,};

init_pic();


idt_set_entry(0, intr_stub_0, 0x8, IDT_FLAG_INTERRUPT_GATE | IDT_FLAG_RING0 | IDT_FLAG_PRESENT);

idt_set_entry(1, intr_stub_1, 0x8, IDT_FLAG_INTERRUPT_GATE | IDT_FLAG_RING0 | IDT_FLAG_PRESENT);

idt_set_entry(2, intr_stub_2, 0x8, IDT_FLAG_INTERRUPT_GATE | IDT_FLAG_RING0 | IDT_FLAG_PRESENT);

idt_set_entry(3, intr_stub_3, 0x8, IDT_FLAG_INTERRUPT_GATE | IDT_FLAG_RING0 | IDT_FLAG_PRESENT);

idt_set_entry(4, intr_stub_4, 0x8, IDT_FLAG_INTERRUPT_GATE | IDT_FLAG_RING0 | IDT_FLAG_PRESENT);

idt_set_entry(5, intr_stub_5, 0x8, IDT_FLAG_INTERRUPT_GATE | IDT_FLAG_RING0 | IDT_FLAG_PRESENT);

idt_set_entry(6, intr_stub_6, 0x8, IDT_FLAG_INTERRUPT_GATE | IDT_FLAG_RING0 | IDT_FLAG_PRESENT);

idt_set_entry(7, intr_stub_7, 0x8, IDT_FLAG_INTERRUPT_GATE | IDT_FLAG_RING0 | IDT_FLAG_PRESENT);

idt_set_entry(8, intr_stub_8, 0x8, IDT_FLAG_INTERRUPT_GATE | IDT_FLAG_RING0 | IDT_FLAG_PRESENT);

idt_set_entry(9, intr_stub_9, 0x8, IDT_FLAG_INTERRUPT_GATE | IDT_FLAG_RING0 | IDT_FLAG_PRESENT);

idt_set_entry(10, intr_stub_10, 0x8, IDT_FLAG_INTERRUPT_GATE | IDT_FLAG_RING0 | IDT_FLAG_PRESENT);

idt_set_entry(11, intr_stub_11, 0x8, IDT_FLAG_INTERRUPT_GATE | IDT_FLAG_RING0 | IDT_FLAG_PRESENT);

idt_set_entry(12, intr_stub_12, 0x8, IDT_FLAG_INTERRUPT_GATE | IDT_FLAG_RING0 | IDT_FLAG_PRESENT);

idt_set_entry(13, intr_stub_13, 0x8, IDT_FLAG_INTERRUPT_GATE | IDT_FLAG_RING0 | IDT_FLAG_PRESENT);

idt_set_entry(14, intr_stub_14, 0x8, IDT_FLAG_INTERRUPT_GATE | IDT_FLAG_RING0 | IDT_FLAG_PRESENT);

idt_set_entry(15, intr_stub_15, 0x8, IDT_FLAG_INTERRUPT_GATE | IDT_FLAG_RING0 | IDT_FLAG_PRESENT);

idt_set_entry(16, intr_stub_16, 0x8, IDT_FLAG_INTERRUPT_GATE | IDT_FLAG_RING0 | IDT_FLAG_PRESENT);

idt_set_entry(17, intr_stub_17, 0x8, IDT_FLAG_INTERRUPT_GATE | IDT_FLAG_RING0 | IDT_FLAG_PRESENT);

idt_set_entry(18, intr_stub_18, 0x8, IDT_FLAG_INTERRUPT_GATE | IDT_FLAG_RING0 | IDT_FLAG_PRESENT);


idt_set_entry(32, intr_stub_32, 0x8, IDT_FLAG_INTERRUPT_GATE | IDT_FLAG_RING0 | IDT_FLAG_PRESENT);

idt_set_entry(33, intr_stub_33, 0x8, IDT_FLAG_INTERRUPT_GATE | IDT_FLAG_RING0 | IDT_FLAG_PRESENT);


idt_set_entry(48, intr_stub_48, 0x8, IDT_FLAG_INTERRUPT_GATE | IDT_FLAG_RING3 | IDT_FLAG_PRESENT);


asm volatile("lidt %0" : : "m" (idtp));

asm volatile("sti");

return 1;

}


void handle_interrupt(struct cpu_state* cpu)

{

	if(cpu->intr <=0x1f)

	{

	 printf("Exception %d, Kernel angehalten!\n", cpu->intr);

	while(1)

		{

			asm volatile("cli; hlt");

		}

	}

	else if(cpu->intr >=0x20 && cpu->intr <=0x2f)

	{

		if(cpu->intr >=0x28)

		{

			outb(0xa0,0x20);

		}

		outb(0x20,0x20);

	}

	else

	{

		printf("Unbekannter Interrupt\n");

		while(1)

		{

			asm volatile("cli; hlt");

		}

	}	

}


Zum Schluss noch das System:

SLES 11 Kernel 2.6 als VM

Compiler:

GCC 4.3.2

NASM 2.09rc1

Ich danke euch schonmal sehr und hoffe die Lösung liegt nicht ganz so fern :P:p

Link zu diesem Kommentar
Auf anderen Seiten teilen

Ich habe mich nochmals mehrer Stunden mit dem Programm beschäftigt und mir mal die Einträge des GDT Arrays ausgeben lassen:

GDT[0] 0b0000000000000000 = 0x0000 // Null-Deskriptor

GDT[1] 0b1111111111111111 = 0xffff

GDT[2] 0b1111111111111111 = 0xffff

GDT[3] 0b1111111111111111 = 0xffff

GDT[4] 0b1111111111111111 = 0xffff

Ich habe wohl die Einträgefalschgesetzt ... :(

Link zu diesem Kommentar
Auf anderen Seiten teilen

static void gdt_set_entry(int i,unsigned int base,unsigned int limit,int flags)

{

gdt = limit & 0xffffll;

gdt |= (base & 0xffffffll) << 16;

gdt |= (flags & 0xffll) << 40;

gdt |= ((limit >> 16) & 0xfll) << 48;

gdt |= ((flags >> 8) & 0xffll) << 52;

gdt |= ((base >> 24) | 0xffll) << 56;

}

Es muss natürlich ein & sein...

:old:old:old

Ich danke trotzdem allen die sich dem ganzen angenommen hatten.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Mit einer Sache bin ich etwas verwirrt. Was bedeutet denn für den Compiler das mit dem ll - ist das so wie bei den floats mit dem endenden f? Falls das ein longlong sein soll, ist das doch ohnehin egal, weil die restlichen Operatoren die Größe vorgeben, oder? Das funktioniert zwar, aber ich habe das so noch nie gesehen oder benutzt. Was gibts da noch für Typen in dieser Art?

Link zu diesem Kommentar
Auf anderen Seiten teilen

Dein Kommentar

Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.

Gast
Auf dieses Thema antworten...

×   Du hast formatierten Text eingefügt.   Formatierung wiederherstellen

  Nur 75 Emojis sind erlaubt.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Editor leeren

×   Du kannst Bilder nicht direkt einfügen. Lade Bilder hoch oder lade sie von einer URL.

Fachinformatiker.de, 2024 by SE Internet Services

fidelogo_small.png

Schicke uns eine Nachricht!

Fachinformatiker.de ist die größte IT-Community
rund um Ausbildung, Job, Weiterbildung für IT-Fachkräfte.

Fachinformatiker.de App

Download on the App Store
Get it on Google Play

Kontakt

Hier werben?
Oder sende eine E-Mail an

Social media u. feeds

Jobboard für Fachinformatiker und IT-Fachkräfte

×
×
  • Neu erstellen...