Autor Thema: Tastaturtreiber  (Gelesen 18277 mal)

MNemo

  • Beiträge: 547
    • Profil anzeigen
Gespeichert
« Antwort #40 am: 01. April 2012, 14:13 »
Mein Printf (sprintf) habe ich ja selber implementiert, aber komplett in C. und ich glabe nicht, dass da was schief läuft.
ich habe auch nicht erwartet das du da Assmebler benutzt hast ^^
Zitat
die cpu wird doch in einer C-Funktion gesichert.
Nein! Nicht alle; EAX z.B. nicht. Und zumindest bei AMD64 gibt es noch mehr Register um deren Sicherung sich der Aufrufer kümmern muss.

[edit]
Zitat von: i386 ABI
Registers %ebp, %ebx, %edi, %esi, and %esp ‘‘belong’’ to the cal-
ling function. In other words, a called function must preserve these registers’
values for its caller. Remaining registers ‘‘belong’’ to the called function. If a cal-
ling function wants to preserve such a register value across a function call, it must
save the value in its local stack frame.
« Letzte Änderung: 01. April 2012, 14:22 von MNemo »
„Wichtig ist nicht, besser zu sein als alle anderen. Wichtig ist, besser zu sein als du gestern warst!“

micha

  • Beiträge: 141
    • Profil anzeigen
Gespeichert
« Antwort #41 am: 01. April 2012, 19:37 »
Naja, wenn der Handler leer ist
( (Klammer Auf) int_handler_0x21:
    iret
) (Kalmmer zu)
dann kommt die Exeption trotzdem

nnosdev

  • Beiträge: 61
    • Profil anzeigen
Gespeichert
« Antwort #42 am: 03. April 2012, 21:16 »
Hi,

das hier ist keine Antwort sondern eine Frage.

Und zwar.. ich hab meine Interrupt Service Routinen geschrieben und soweit funktioniert das auch.
Wenn ich jetzt eine Taste drücke, dann empfange ich diesen Interrupt nur ein einziges Mal.
Jeder weitere Tastendruck wird dann nicht mehr verarbeitet (IRQ 0 wird jedoch permanent weiter
bearbeitet).

void isr_handler(cpu_state_t status)
{
if(status.int_no <= 0x1F) {
dprint("[ISR] Exception captured. Kernel stopped.");

while(1) {
// Stop CPU
asm volatile ("cli; hlt");
}
}else if (status.int_no >= 0x20 && status.int_no <= 0x2f) {

dprint("[ISR] Hardware interrupt received");

    if (status.int_no >= 0x28) {
        outb(0xA0, 0x20);
    }

    outb(0x20, 0x20); // EOI
}

dprint("[ISR] Received (but unhandled) interrupt: 0x%X", status.int_no);
}

Hat jemand eine Ahnung woran das liegen könnte?

Jidder

  • Administrator
  • Beiträge: 1 625
    • Profil anzeigen
Gespeichert
« Antwort #43 am: 03. April 2012, 21:39 »
Du musst den Scancode mit inb(0x60) lesen, um den Tastaturpuffer zu leeren.
Dieser Text wird unter jedem Beitrag angezeigt.

nnosdev

  • Beiträge: 61
    • Profil anzeigen
Gespeichert
« Antwort #44 am: 03. April 2012, 21:53 »
Danke :D


micha

  • Beiträge: 141
    • Profil anzeigen
Gespeichert
« Antwort #45 am: 04. April 2012, 15:59 »

MNemo

  • Beiträge: 547
    • Profil anzeigen
Gespeichert
« Antwort #46 am: 04. April 2012, 18:28 »
Wie baust du den Kernel? Das mal zu testen zu können würde vermutlich schneller zu Erfolg führen als nur den Quellcode an zu sehen.

Was mir so aufgefallen ist:
cpu.S:
  push-/pop_cpu: rufst du zwar nirgends auf, aber das Funktioniert so natürlich nicht. als Makro würde schon eher gehen.

irq/handler.S:
  irq_handler0x21: ist weder leer, noch werden die Register ordnungsgemäß wieder hergestellt.

syscall:
  int_handler0x30: ignoriert den rückgabe wert von syscall

testhandler:
  das geht so nicht, einfach asm("iret") in ne C-Funktion reinhauen. Guck dir mal `objdum -d testhandler.o` an. Da siehst du dass der stack erst noch dem iret, mit leave wieder aufgeräumt wird.

[Edit]
sprintfr:
  du legst nirgends einen puffer für dein rückgabe string an! du verwendest rs uninitialisiert. das ist pures Glück wenn das mal gut geht.
« Letzte Änderung: 04. April 2012, 18:38 von MNemo »
„Wichtig ist nicht, besser zu sein als alle anderen. Wichtig ist, besser zu sein als du gestern warst!“

micha

  • Beiträge: 141
    • Profil anzeigen
Gespeichert
« Antwort #47 am: 04. April 2012, 19:35 »
irq/handler.S:
  irq_handler0x21: ist weder leer, noch werden die Register ordnungsgemäß wieder hergestellt.
Das war ja auch nur zum rumprobieren..

syscall:
  int_handler0x30: ignoriert den rückgabe wert von syscall
Das ist ja noch garni fertig

testhandler:
  das geht so nicht, einfach asm("iret") in ne C-Funktion reinhauen. Guck dir mal `objdum -d testhandler.o` an. Da siehst du dass der stack erst noch dem iret, mit leave wieder aufgeräumt wird.
Da hab ich auch bloß probiert (ich probiere gern  :wink:; vergessen wieder raußzunehmen)

sprintfr:
  du legst nirgends einen puffer für dein rückgabe string an! du verwendest rs uninitialisiert. das ist pures Glück wenn das mal gut geht.
Eingentlich ging das immer

micha

  • Beiträge: 141
    • Profil anzeigen
Gespeichert
« Antwort #48 am: 05. April 2012, 12:04 »
Wie baust du den Kernel? Das mal zu testen zu können würde vermutlich schneller zu Erfolg führen als nur den Quellcode an zu sehen.
src/kernel/Makefile
SRCS = $(shell find -name '*.[cS]')
OBJS = $(addsuffix .o,$(basename $(SRCS)))
CC = gcc
LD = ld

SRC = ..
KERNELSRC = .
IMGSRC = ../../img
KERNEL = $(IMGSRC)/sys/kernel/kernel

INC = -I $(SRC)/include
KERNINC = -I $(KERNELSRC)/include

ASFLAGS = -m32 $(INC)
CFLAGS = -m32 -Wall -fno-stack-protector -nostdinc $(INC)
LDFLAGS = -melf_i386 -Ttext=0x100000

KERNELCF = $(CFLAGS) $(KERNINC)
KERNELASF= $(ASFLAGS) $(KERNINC)

pseudolink: $(OBJS)
#Kernel kompiliert.

%.o: %.c
$(CC) $(KERNELCF) -c -o $@ $^
%.o: %.S
$(CC) $(KERNELASF) -c -o $@ $^
clean:
rm $(OBJS)
.PHONY: clean

Makefile
SRC = ./src
KERNELSRC = $(SRC)/kernel

SRCS = $(shell find -name '*.[cS]')
OBJS = $(addsuffix .o,$(basename $(SRCS)))
CC = gcc
LD = ld

INC = -I $(SRC)/include

IMGSRC = ./img
KERNEL = $(IMGSRC)/sys/kernel/kernel
IMGNAME= OrangePalm0-0-1winterBeta3

ASFLAGS = -m32 $(INC)
CFLAGS = -m32 -Wall -fno-stack-protector -nostdinc $(INC)
LDFLAGS = -melf_i386 -Ttext=0x100000

$(KERNEL): $(OBJS)
$(LD) $(LDFLAGS) -o $@ $^

iso-img:
mkisofs -R -b boot/grub/stage2_eltorito -no-emul-boot -boot-load-size 4 -boot-info-table -o $(IMGNAME).iso $(IMGSRC)
start-iso-qemu:
qemu -d int -cdrom $(IMGNAME).iso
print-src:
echo $(shell find -name '*.[chS]')

clean:
rm $(OBJS)
.PHONY: clean

mkall
# Kernel kompiliern
cd src/kernel
make
cd ../..
# Rest kompilieren & linken
make
# iso-image erstellen
make iso-img
# iso-image mit qemu starten
make start-iso-qemu

MNemo

  • Beiträge: 547
    • Profil anzeigen
Gespeichert
« Antwort #49 am: 05. April 2012, 14:57 »
Du hast 16-Bit Interrupt Desptoren angelegt.

diff --git a/src/kernel/interrupt/idt.c b/src/kernel/interrupt/idt.c
--- a/src/kernel/interrupt/idt.c
+++ b/src/kernel/interrupt/idt.c
@@ -21,6 +21,7 @@ static void set_interrupt(int i, uint32_
   //obere 32-Bit
   idt[i] |=(
        ( type << 8 )   |
+       ( 1 << 11) |
        ( (dpl&3) << 13 )   |
        ( (present&1) << 15)|
        ( offset & 0xffff0000 )

Ich würde dir übrigens raten sämtliche Compiler-Warnungen  auszumerzen. Dein set_gdt_entry z.B. enthält nen fehler auf den du sogar hingewiesen wirst.
« Letzte Änderung: 05. April 2012, 15:09 von MNemo »
„Wichtig ist nicht, besser zu sein als alle anderen. Wichtig ist, besser zu sein als du gestern warst!“

micha

  • Beiträge: 141
    • Profil anzeigen
Gespeichert
« Antwort #50 am: 05. April 2012, 15:29 »
Du hast 16-Bit Interrupt Desptoren angelegt.
Was hab ich da falsch gemacht? Wie mach ich's richtig?


MNemo

  • Beiträge: 547
    • Profil anzeigen
Gespeichert
« Antwort #51 am: 05. April 2012, 15:33 »
Du hast 16-Bit Interrupt Desptoren angelegt.
Was hab ich da falsch gemacht? Wie mach ich's richtig?

Du hast vergessen das Flag für 32-Bit Descriptoren zu setzen.

Füge die mit '+' gekennzeichnete Zeile in deinen Code ein.
„Wichtig ist nicht, besser zu sein als alle anderen. Wichtig ist, besser zu sein als du gestern warst!“

micha

  • Beiträge: 141
    • Profil anzeigen
Gespeichert
« Antwort #52 am: 05. April 2012, 15:55 »
Ich hab jetzt die zeile eingefügt
( 0x800 ) | // 1 << 11nur leider geht es immernoch nicht :-(

Liegt der Fehler in der GDT? Es kommt ja ein GPF und es werden Segmente übergeben (als Errorcode), die ich garnicht hab!

MNemo

  • Beiträge: 547
    • Profil anzeigen
Gespeichert
« Antwort #53 am: 05. April 2012, 16:13 »
Also die Zeile ist bei mir im Moment der einzige Unterschied zu dem von dir hochgeladenen Code. Und es gibt kein GPF.

Stimmt jetzt wenigsten dein eigener CPU dump mit dem von QEMU überein?
Deine GDT ist zwar falsch(64bit segmente im Protected mode), aber wenn QEMU das stören würde müsste es schon beim neuladen der Segmentregister meckern.
« Letzte Änderung: 05. April 2012, 16:16 von MNemo »
„Wichtig ist nicht, besser zu sein als alle anderen. Wichtig ist, besser zu sein als du gestern warst!“

micha

  • Beiträge: 141
    • Profil anzeigen
Gespeichert
« Antwort #54 am: 05. April 2012, 16:19 »
Also EAX,EBX,ECX und EDX stimmen überein. Nur die anderen (ESP,CS...) nicht.

MNemo

  • Beiträge: 547
    • Profil anzeigen
Gespeichert
« Antwort #55 am: 05. April 2012, 16:39 »
Die sollten jetzt auch übereinstimmen. Testest eventuell noch die alte Version? ('make clean')
„Wichtig ist nicht, besser zu sein als alle anderen. Wichtig ist, besser zu sein als du gestern warst!“

micha

  • Beiträge: 141
    • Profil anzeigen
Gespeichert
« Antwort #56 am: 05. April 2012, 16:46 »
Jetzt wird qemu nach init_idt schwarz :|

micha

  • Beiträge: 141
    • Profil anzeigen
Gespeichert
« Antwort #57 am: 05. April 2012, 16:52 »
komisch.. :| mit deinem iso gehts

MNemo

  • Beiträge: 547
    • Profil anzeigen
Gespeichert
« Antwort #58 am: 05. April 2012, 17:37 »
Jetzt wird qemu nach init_idt schwarz :|

Dann hast du wohl noch andere Änderungen gemacht. Versuch es doch mal mit dem Quellcode den du hier hochgeladen hast.
„Wichtig ist nicht, besser zu sein als alle anderen. Wichtig ist, besser zu sein als du gestern warst!“

micha

  • Beiträge: 141
    • Profil anzeigen
Gespeichert
« Antwort #59 am: 05. April 2012, 17:45 »
Super!!!!! mit dem gehts :-) :-) :-D

 

Einloggen