Beiträge anzeigen

Diese Sektion erlaubt es dir alle Beiträge dieses Mitglieds zu sehen. Beachte, dass du nur solche Beiträge sehen kannst, zu denen du auch Zugriffsrechte hast.


Nachrichten - boom1

Seiten: [1]
1
Lowlevel-Coding / Re: IDT laden
« am: 24. July 2008, 18:41 »
Danke, du hast recht! Ich trottel... ;-) Deshalb stand in der Ausgabe auch so eine komische Adresse bei der IDT. Zumindest geht es jetzt endlich
2
Lowlevel-Coding / Re: IDT laden
« am: 24. July 2008, 11:05 »
Das idivl ist in der main-Funktion. Und es ist genau da, wo ich in der main Funktion die Exception provoziere, da ich durch 0 teile. Das ist hinter dem Laden den IDT:
Deshalb hab ich vermutet, dass die IDT nicht richtig geladen wurde, weil doch sonst die Exception durch dei isr0() abgefangen worden wäre...

Ich bin gerade nochmal alles Schritt für Schritt durchgegangen, hab den Fehler aber leider nicht gefunden...
3
Lowlevel-Coding / IDT laden
« am: 23. July 2008, 18:08 »
Hi,

Nachdem ich es jetzt hinbekommen habe, die GDT zu laden, habe ich nun versucht die IDT zu laden und die ISRs für die Exceptions zu definieren.  :wink:

Ich habe folgenden Code in meinem C-Kernel:


#include "kernelc.h"

int main()
{
/* Build-up the GDT */
gdt_setup();
/* Build-up the IDT */
idt_setup();
/* Install the first 32 Exception handler in the IDT */
isrs_install();

// Pointer zum Videospeicher
char *video = (char*)0xB8000;

// Pointer auf die Nummer, des nächsten Zeichens im Videospeicher
//int iVideoPtr = 0;

// String zum Ausgeben
char *hello = "Hello World One\r\n";
    char *hello2 = "Hello World Two\r\n";
 
// Zuerst den Speicher leeren
ClearScreen(video);

// String ausgeben
printk(hello);
printk(hello2);

//Exception asulösen
int n = n/((n/n)-1);

// jetzt wo wir schon im Kernel drin sind, wollen wir auch nicht mehr raus ;)
while (1);
return 0;
}

Der Ausschnitt aus meiner kernel.asm, in welchem ich die IDT lade:
[...]
idt_load_asm:
lidt [idtp] ; IDT laden
ret
[...]

Und ich habe eine Datei idt.c, in welcher ich Funktionen etc. zur IDT habe;
/******************** == IDT == ****************/

/* Defines a single IDT entry */
struct idt_entry
{
unsigned short base_low;
unsigned short selector;
unsigned char always0;
unsigned char access;
unsigned short base_high;
} __attribute__((packed));

/* Defines a IDT pointer */
struct idt_ptr
{
unsigned int base;
unsigned short size;
} __attribute__((packed));

struct idt_entry idt[256];
struct idt_ptr idtp;

/* Load the IDT.
Defined in the ASM-Lernel, so declared as extern. */
extern void idt_load_asm ();

/* Setup a new descriptor */
void idt_setup_entry (unsigned char cNum, unsigned int iBase, unsigned short shSelector,
unsigned char cAccess)
{
idt[cNum].base_low = (iBase & 0xFFFF);
idt[cNum].selector = shSelector;
idt[cNum].always0 = 0;
idt[cNum].access = cAccess;
idt[cNum].base_high = ((iBase >> 16) & 0xFFFF);
}

/* Setup the IDT pointer */
void idt_ptr_setup ()
{
idtp.base = (unsigned int) &idt;
idtp.size = (sizeof(struct idt_entry)*256) - 1;
}

/* Declare the MemSet function in kernel/memset.c as extern */
extern void memset (void *pDest, char cValue, unsigned int iCount);

/* Setup the whole IDT */
void idt_setup ()
{
idt_ptr_setup ();

/* Clear the entire IDT */
memset (&idt, 0, sizeof(struct idt_entry)*256);

idt_load_asm ();
}

Ausserdem habe ich noch eine isr.c und isr.asm, in welcher ich die ISRs definiere.
isr.c:
/********************** == ISR == ************************/

/* declare a function to print on the output as extern */
extern void printk (char *pText);

/* the external function prototypes for all
of the exception handlers. The first 32 entries
in the IDT are reserved by Intel */
extern void isr0();
extern void isr1();
extern void isr2();
extern void isr3();
extern void isr4();
extern void isr5();
extern void isr6();
extern void isr7();
extern void isr8();
extern void isr9();
extern void isr10();
extern void isr11();
extern void isr12();
extern void isr13();
extern void isr14();
extern void isr15();
extern void isr16();
extern void isr17();
extern void isr18();
extern void isr19();
extern void isr20();
extern void isr21();
extern void isr22();
extern void isr23();
extern void isr24();
extern void isr25();
extern void isr26();
extern void isr27();
extern void isr28();
extern void isr29();
extern void isr30();
extern void isr31();

/* Declare the idt_setup_entry function as extern.
This function sets an IDT entry and is defined in
/tables/idt/idt.c */
extern void idt_setup_entry (unsigned char cNum, unsigned int iBase, unsigned short shSelector,
unsigned char cAccess);

/* A structure containing the register */
struct registers
{
unsigned int gs, fs, es, ds;      /* pushed the segs last */
    unsigned int edi, esi, ebp, esp, ebx, edx, ecx, eax;  /* pushed by 'pusha' */
    unsigned int int_no, err_code;    /* our 'push byte #' and ecodes do this */
    unsigned int eip, cs, eflags, useresp, ss;    /* pushed by the processor automatically */
};

/* Install the first 32 ISRs, that handle the first
32 exceptions */
void isrs_install ()
{
idt_setup_entry (0, (unsigned int) isr0, 0x08, 0x8E);
idt_setup_entry (1, (unsigned int) isr1, 0x08, 0x8E);
idt_setup_entry (2, (unsigned int) isr2, 0x08, 0x8E);
idt_setup_entry (3, (unsigned int) isr3, 0x08, 0x8E);
idt_setup_entry (4, (unsigned int) isr4, 0x08, 0x8E);
idt_setup_entry (5, (unsigned int) isr5, 0x08, 0x8E);
idt_setup_entry (6, (unsigned int) isr6, 0x08, 0x8E);
idt_setup_entry (7, (unsigned int) isr7, 0x08, 0x8E);
idt_setup_entry (8, (unsigned int) isr8, 0x08, 0x8E);
idt_setup_entry (9, (unsigned int) isr9, 0x08, 0x8E);
idt_setup_entry (10, (unsigned int) isr10, 0x08, 0x8E);
idt_setup_entry (11, (unsigned int) isr11, 0x08, 0x8E);
idt_setup_entry (12, (unsigned int) isr12, 0x08, 0x8E);
idt_setup_entry (13, (unsigned int) isr13, 0x08, 0x8E);
idt_setup_entry (14, (unsigned int) isr14, 0x08, 0x8E);
idt_setup_entry (15, (unsigned int) isr15, 0x08, 0x8E);
idt_setup_entry (16, (unsigned int) isr16, 0x08, 0x8E);
idt_setup_entry (17, (unsigned int) isr17, 0x08, 0x8E);
idt_setup_entry (18, (unsigned int) isr18, 0x08, 0x8E);
idt_setup_entry (19, (unsigned int) isr19, 0x08, 0x8E);
idt_setup_entry (20, (unsigned int) isr20, 0x08, 0x8E);
idt_setup_entry (21, (unsigned int) isr21, 0x08, 0x8E);
idt_setup_entry (22, (unsigned int) isr22, 0x08, 0x8E);
idt_setup_entry (23, (unsigned int) isr23, 0x08, 0x8E);
idt_setup_entry (24, (unsigned int) isr24, 0x08, 0x8E);
idt_setup_entry (25, (unsigned int) isr25, 0x08, 0x8E);
idt_setup_entry (26, (unsigned int) isr26, 0x08, 0x8E);
idt_setup_entry (27, (unsigned int) isr27, 0x08, 0x8E);
idt_setup_entry (28, (unsigned int) isr28, 0x08, 0x8E);
idt_setup_entry (29, (unsigned int) isr29, 0x08, 0x8E);
idt_setup_entry (30, (unsigned int) isr30, 0x08, 0x8E);
idt_setup_entry (31, (unsigned int) isr31, 0x08, 0x8E);
}

char *exception_name[] =
{
"Division By Zero Exception", /* 0 */
"Debug Exception",
"Non Maskable Interrupt Exception",
"Breakpoint Exception",
"Into Detected Overflow Exception",
"Out of Bounds Exception", /* 5 */
"Invalid Opcode Exception",
"No Coprocessor Exception",
"Double Fault Exception",
"Coprocessor Segment Overrun Exception",
"Bad TSS Exception",
"Segment Not Present Exception",
"Stack Fault Exception",
"General Protection Fault Exception",
"Page Fault Exception",
"Unknown Interrupt Exception",
"Coprocessor Fault Exception",
"Alignment Check Exception (486+)",
"Machine Check Exception (Pentium/586+)",
"Reserved Exception", /* 19 */
"Reserved Exception",
"Reserved Exception",
"Reserved Exception",
"Reserved Exception",
"Reserved Exception",
"Reserved Exception",
"Reserved Exception",
"Reserved Exception",
"Reserved Exception",
"Reserved Exception",
"Reserved Exception",
"Reserved Exception" /* 31 */
};

void fault_handler (struct registers *regs)
{
if (regs->int_no <= 31)
{
/* Display the description of the exception */
printk (exception_name[regs->int_no]);
printk ((char *) " Exception. System will now halt!\r\n");
for (;;) ;
}
}

und hier die isr.asm --> Link
(die ist etwas lang, deshalb will ich die nicht hier posten)


Wenn ich jetzt allerdings, meinen kernel versuche mit qemu zu öffnen, stürtzt er mir ab.
Er zeigt mir folgendes:
qemu: fatal: triple fault
EAX=00000000 EBX=0002d8e4 ECX=0000005f EDX=00000000
ESI=00054527 EDI=00054528 EBP=001fffe8 ESP=001fffd0
EIP=00100942 EFL=00000002 [-------] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0010 00000000 ffffffff 00cf9300
CS =0008 00000000 ffffffff 00cf9a00
SS =0010 00000000 ffffffff 00cf9300
DS =0010 00000000 ffffffff 00cf9300
FS =0010 00000000 ffffffff 00cf9300
GS =0010 00000000 ffffffff 00cf9300
LDT=0000 00000000 0000ffff 00008000
TR =0000 00000000 0000ffff 00008000
GDT=     00102080 00000017
[b]IDT=     07ff0010 000020c0[/b]
CR0=60000011 CR2=00000000 CR3=00000000 CR4=00000000
CCS=00000018 CCD=001fffc0 CCO=ADDL   
FCW=037f FSW=0000 [ST=0] FTW=00 MXCSR=00001f80
FPR0=0000000000000000 0000 FPR1=0000000000000000 0000
FPR2=0000000000000000 0000 FPR3=0000000000000000 0000
FPR4=0000000000000000 0000 FPR5=0000000000000000 0000
FPR6=0000000000000000 0000 FPR7=0000000000000000 0000
XMM00=00000000000000000000000000000000 XMM01=00000000000000000000000000000000
XMM02=00000000000000000000000000000000 XMM03=00000000000000000000000000000000
XMM04=00000000000000000000000000000000 XMM05=00000000000000000000000000000000
XMM06=00000000000000000000000000000000 XMM07=00000000000000000000000000000000
Aborted

Wenn ich mir jetzt den EIP Register anschaue, dann zeigt der genau auf dei Stelle, an der ich eine Exception provoziere:

Zitat
10093d:   89 d0                   mov    %edx,%eax
  10093f:   c1 fa 1f                sar    $0x1f,%edx
  100942:   f7 7d f8                idivl  -0x8(%ebp)
  100945:   83 e8 01                sub    $0x1,%eax
  100948:   8b 55 f8                mov    -0x8(%ebp),%edx

Aber eigentlich, habe ich doch eine eigene ISR gemacht, die eben das abfangen soll...
Eventuell liegt das daran, dass die IDT nicht richtig geladen wurde.
(in der Fehlermeldung von qemu gibt es eine Zeile, wo die IDT drinsteht, und da steht eine komische Zahl dran)
Allerdings kann ich es mir nicht erklären, dass die IDT nicht richtig geladen wurde...

Wisst ihr was ich da falsch mache?
4
Lowlevel-Coding / Re: Problem mit GDT - Kernel stürtzt ab
« am: 21. July 2008, 23:38 »
Danke für die Antworten, hat mir sehr weiter geholfen.
Ich hab jetzt, wie empfolen die GDT in C realisiert. Funktioniert und find ich so auch irgendwie besser ;-)
5
Lowlevel-Coding / Re: Problem mit GDT - Kernel stürtzt ab
« am: 21. July 2008, 13:26 »
Hi,

erstmal vielen dank für die Hilfe, mein Kernel funktioniert jetzt. ;-)
Ich hab allerdings noch ein paar Fragen:

Zitat
Was soll das hier machen?
Code:
mov  eax, cs   ; Daten-, Stack und Extrasegment mit Datensegmentdesktriptor laden
shl eax, 4
add eax, gdt
mov ds, ax
mov ss, ax
mov es, ax
mov eax, 0 ; FS und GS mit Null-Deskriptor laden
mov fs, ax
mov gs, ax

Du musst einfach DS, ES,FS, GS, SS mit 0x10 und CS mit 0x8 laden.
ich habe eigentlich versucht die DS, ES, FS, GS, SS Register mit der Adresse der GDT zu laden, da ich das so verstanden habe und es es auch so in einem Code von jemand anderem gesehen habe.
Wieso muss ich genau den Wert 0x10 laden? Führt das nur dazu, dass die Register neu geladen werden?

Ich hab mir auch überlegt ob ich die ganzen Tabellen im C-Kernel laden soll...
Aber ich denke, dass ich das noch im Assembler Kernel mache.

Mit der Ausgabe von qemu kann ich nicht so viel anfangen...
Z.b. der DS Register:
DS =0316 f053f000 0000ff53 f000ff53
Der DS-Register ist doch 16Bit breit, wofür stehen dann die hinteren drei "Pakete"?

6
Hi,

seit letzten Mittwoch hab auch ich vor ein kleines OS zu proggen.
Ich hab mich durch die Tutorials von LowLevel (btw. nette Seite!) durchgewühlt und bin jetzt bei der Global Deskriptor Table hängen geblieben.

Undzwar habe ich folgenden Code:

(alternativer Link)
global loader ; loader für Linker sichtbar machen
extern main   ; main-Funktion des C-Kernels
 
FLAGS    equ 0
MAGIC    equ 0x1BADB002       ; Magicnumber - Erkennungsmerkmal für Grub
CHECKSUM equ -(MAGIC + FLAGS) ; Checksum
 
section .text
align 4
align 4
MultiBootHeader:
dd MAGIC       ; Magic number
dd FLAGS       ; Flags
dd CHECKSUM    ; Checksum
 
loader:
mov esp,0x200000 ; Stack an die 2MB-Grenze platzieren
push eax        ; Multiboot Magicnumber auf den Stack legen
push ebx        ; Adresse der Multiboot-Structure auf den Stack legen
cli

call load_gdt

  call main        ; main-Funktion des C-Kernels aufrufen
 
  cli ; falls der Kernel bis hier her kommt, CPU anhalten
  hlt

load_gdt:
lgdt [gdtable] ; GDT laden
mov eax, cs ; Daten-, Stack und Extrasegment mit Datensegmentdesktriptor laden
shl eax, 4
add eax, gdt
mov ds, ax
mov ss, ax
mov es, ax
mov eax, 0 ; FS und GS mit Null-Deskriptor laden
mov fs, ax
mov gs, ax

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;; == GDT == ;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

gdtable: ; Deskriptortabelle
dw gdt_end-gdt-1 ; Limit
dd gdt ; Basis
gdt:
Null_Desc:
dd 0 ; Nulldeskriptor, bestehend aus Nullen
dd 0 ; Das gleiche. Insgesamt 8 Byte

Code_Desc: ; Code Deskriptor, erstreckt sich über den ganzen Speicher
dw 0xFFFF ; Segmentgrösse: 0xFFFFF (zusammen mit dem zweitletzten Byte)
dw 0 ; Segmentbasisadresse
db 0
db 0x9A
db 0xCF
db 0

Data_Desc: ; Daten Deskriptor, entspricht in etwa dem Code Deskriptor
dw 0xFFFF
dw 0
db 0
db 0x92
db 0xCF
db 0
gdt_end: ; GDT End


Der Kernel (naja ist mir etwas peinlich das schon Kernel zu nennen ;-)) wird von GRUB geladen und ruft diese load_gdt-funktion auf, die eine Standard-GDT laden soll. (Danach ruft er den C-Kernel auf, der in einer anderen Datei liegt, für mein Problem aber unwichtig ist).

Wenn ich den Kernel allerdings wie gewohnt in ein Image schreibe und mit qemu öffne, stürtzt er mir ab und gibt mir einen Triple Fault (was üblich sein soll, wenn was an der GDT faul ist). Ich bin mir ziemlich sicher, dass es am GDT-Teil liegt, da der Kernel ohne die GDT einwandfrei lief.

Die Ausgabe von qemu ist:
EAX=00100316 EBX=0002d8e4 ECX=00008c79 EDX=00000001
ESI=00054527 EDI=00054528 EBP=00067eac ESP=001ffff4
EIP=00100283 EFL=00000002 [-------] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0010 00000000 ffffffff 00cf9300
CS =0008 00000000 ffffffff 00cf9a00
SS =0010 00000000 ffffffff 00cf9300
DS =0316 f053f000 0000ff53 f000ff53
FS =0010 00000000 ffffffff 00cf9300
GS =0010 00000000 ffffffff 00cf9300
LDT=0000 00000000 0000ffff 00008000
TR =0000 00000000 0000ffff 00008000
GDT=     00100296 00000017
IDT=     00000000 000003ff
CR0=60000011 CR2=00000000 CR3=00000000 CR4=00000000
CCS=00100296 CCD=00100316 CCO=ADDL   
FCW=037f FSW=0000 [ST=0] FTW=00 MXCSR=00001f80
FPR0=0000000000000000 0000 FPR1=0000000000000000 0000
FPR2=0000000000000000 0000 FPR3=0000000000000000 0000
FPR4=0000000000000000 0000 FPR5=0000000000000000 0000
FPR6=0000000000000000 0000 FPR7=0000000000000000 0000
XMM00=00000000000000000000000000000000 XMM01=00000000000000000000000000000000
XMM02=00000000000000000000000000000000 XMM03=00000000000000000000000000000000
XMM04=00000000000000000000000000000000 XMM05=00000000000000000000000000000000
XMM06=00000000000000000000000000000000 XMM07=00000000000000000000000000000000
Aborted

Ich benutzte Ubuntu 8.04, den gcc, nasm, und als linker ld.

Könnt ihr mir weiterhelfen?

Danke im Voraus  :wink:
Seiten: [1]

Einloggen