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 - dietzi

Seiten: [1]
1
Lowlevel-Coding / Re: VESA / VBE Informationen abrufen
« am: 24. March 2017, 00:29 »
So...... Nach viel googlen und viel experimentieren habe ich es endlich geschafft. Oben genannter Code mit der Funktion int32() funktioniert. Hier der Code um die Informationen abzurufen:

typedef struct MODE_INFO
{
unsigned short ModeAttributes       __attribute__ ((packed));
unsigned char  WinAAttributes       __attribute__ ((packed));
unsigned char  WinBAttributes       __attribute__ ((packed));
unsigned short WinGranularity       __attribute__ ((packed));
unsigned short WinSize              __attribute__ ((packed));
unsigned short WinASegment          __attribute__ ((packed));
unsigned short WinBSegment          __attribute__ ((packed));
unsigned long  WinFuncPtr           __attribute__ ((packed));
unsigned short BytesPerScanLine     __attribute__ ((packed));
unsigned short XResolution          __attribute__ ((packed));
unsigned short YResolution          __attribute__ ((packed));
unsigned char  XCharSize            __attribute__ ((packed));
unsigned char  YCharSize            __attribute__ ((packed));
unsigned char  NumberOfPlanes       __attribute__ ((packed));
unsigned char  BitsPerPixel         __attribute__ ((packed));
unsigned char  NumberOfBanks        __attribute__ ((packed));
unsigned char  MemoryModel          __attribute__ ((packed));
unsigned char  BankSize             __attribute__ ((packed));
unsigned char  NumberOfImagePages   __attribute__ ((packed));
unsigned char  Reserved_page        __attribute__ ((packed));
unsigned char  RedMaskSize          __attribute__ ((packed));
unsigned char  RedMaskPos           __attribute__ ((packed));
unsigned char  GreenMaskSize        __attribute__ ((packed));
unsigned char  GreenMaskPos         __attribute__ ((packed));
unsigned char  BlueMaskSize         __attribute__ ((packed));
unsigned char  BlueMaskPos          __attribute__ ((packed));
unsigned char  ReservedMaskSize     __attribute__ ((packed));
unsigned char  ReservedMaskPos      __attribute__ ((packed));
unsigned char  DirectColorModeInfo  __attribute__ ((packed));
unsigned long  PhysBasePtr          __attribute__ ((packed));
unsigned long  OffScreenMemOffset   __attribute__ ((packed));
unsigned short OffScreenMemSize     __attribute__ ((packed));
unsigned char  Reserved[206]        __attribute__ ((packed));
} MODE_INFO;

typedef struct VESA_INFO
{
unsigned char  VESASignature[4]     __attribute__ ((packed));
unsigned short VESAVersion          __attribute__ ((packed));
unsigned long  OEMStringPtr         __attribute__ ((packed));
unsigned char  Capabilities[4]      __attribute__ ((packed));
unsigned long  VideoModePtr         __attribute__ ((packed));
unsigned short TotalMemory          __attribute__ ((packed));
unsigned short OemSoftwareRev       __attribute__ ((packed));
unsigned long  OemVendorNamePtr     __attribute__ ((packed));
unsigned long  OemProductNamePtr    __attribute__ ((packed));
unsigned long  OemProductRevPtr     __attribute__ ((packed));
unsigned char  Reserved[222]        __attribute__ ((packed));
unsigned char  OemData[256]         __attribute__ ((packed));
} VESA_INFO;

uint8_t* vga; //Framebuffer-Adresse

extern void int32(unsigned char intnum, regs16_t *regs);

void get_vesa_modes(void) {
struct VESA_INFO *vesa=(VESA_INFO *)pmm_alloc();
struct MODE_INFO *info=(MODE_INFO *)pmm_alloc();
memcpy(vesa->VESASignature,"VBE2",4);
regs16_t regs;
regs.ax=0x4f00;
regs.di=vesa;
regs.es=0;
int32(0x10,&regs);
if(regs.ax!=0x004f) {
kprintf("VBE Error\n");
return false;
}

uint16_t *modes = ((vesa->VideoModePtr & 0xFFFF0000) >> 12) + (vesa->VideoModePtr & 0xFFFF);
while(*modes!=0xffff) {
regs.ax=0x4f01;
regs.cx=*modes;
regs.es=0;
regs.di=info;
int32(0x10,&regs);
if(regs.ax !=0x004f) {
kprintf(" Error\n");
continue;
}
// Hier überprüfen ob die Auflösung ect. passt - ist ja ausreichend dokumentiert:
// http://www.lowlevel.eu/wiki/VBE
// http://wiki.osdev.org/User:Omarrx024/VESA_Tutorial
// http://wiki.osdev.org/Vesa
*modes++;
}
}

struct MODE_INFO *get_vesa_mode_info(uint16_t mode) {
struct MODE_INFO *info=(MODE_INFO *)pmm_alloc();
regs16_t regs;
regs.ax=0x4f01;
regs.cx=mode;
regs.es=0;
regs.di=info;
int32(0x10,&regs);
if(regs.ax !=0x004f) {
kprintf(" Error\n");
return -1;
} else {
kprintf("Mode: %x\n",mode);
}
kprintf(" --> %dx%dx%d Addr: %x\n",info->XResolution,info->YResolution,info->BitsPerPixel,(char*)info->PhysBasePtr);

return info;
}

void set_vesa_mode(uint16_t mode) {
struct MODE_INFO *info=get_vesa_mode_info(mode);
vga=(uint8_t*) (uintptr_t)info->PhysBasePtr;
regs16_t regs;
regs.ax = 0x4f02;
regs.bx = mode;
int32(0x10,&regs);

// Hier wird der gesamte Bildschirm weiß gefärbt
for(int y=0;y<info->YResolution;y++) {
for(int x=0;x<info->XResolution;x++) {
PutPixel(x,y,0xffffff,info->BytesPerScanLine);
}
}
}

void PutPixel(int x, int y, unsigned int color, unsigned short bps) { //Funktioniert nur bei 32 Bit Farbtiefe
*(uint32_t *)(vga + y * bps + x * 4) = color;
}
2
Lowlevel-Coding / [gelöst] VESA / VBE Informationen abrufen
« am: 16. March 2017, 20:55 »
Hallo Leute,

ich stehe vor einem Problem..... Ich möchte gerne die verfügbaren VESA-Modi und die entsprechenden Framebuffer-Adressen abrufen. Für den Bios-Call verwende ich folgenden Code (habe ich im Netz gefunden und kopiert, da ich mich mit Assembler nicht so wirklich anfreunden kann):

;
; Protected Mode BIOS Call Functionailty v2.0 - by Napalm
; -------------------------------------------------------
;
; This is code shows how its POSSIBLE to execute BIOS interrupts
; by switch out to real-mode and then back into protected mode.
;
; If you wish to use all or part of this code you must agree
; to the license at the following URL.
;
; License: http://creativecommons.org/licenses/by-sa/2.0/uk/
;         
; Notes: This file is in NASM syntax.
;        Turn off paging before calling these functions.
;        int32() resets all selectors.
;
; C Prototype:
; void _cdelc int32(unsigned char intnum, regs16_t *regs);
;
; Example of usage:
;   regs.ax = 0x0013;
;   int32(0x10, &regs);
;   memset((char *)0xA0000, 1, (320*200));
;   memset((char *)0xA0000 + (100*320+80), 14, 80);
;   regs.ax = 0x0000;
;   int32(0x16, &regs);
;   regs.ax = 0x0003;
;   int32(0x10, &regs);
;
;
[bits 32]
section .text
global int32, _int32

struc regs16_t
.di resw 1
.si resw 1
.bp resw 1
.sp resw 1
.bx resw 1
.dx resw 1
.cx resw 1
.ax resw 1
.gs resw 1
.fs resw 1
.es resw 1
.ds resw 1
.ef resw 1
endstruc

%define INT32_BASE                             0x7C00
%define REBASE(x)                              (((x) - reloc) + INT32_BASE)
%define GDTENTRY(x)                            ((x) << 3)
%define CODE32                                 GDTENTRY(1) ; 0x08
%define DATA32                                 GDTENTRY(2) ; 0x10
%define CODE16                                 GDTENTRY(3) ; 0x18
%define DATA16                                 GDTENTRY(4) ; 0x20
%define STACK16                                (INT32_BASE - regs16_t_size)


section .text
int32: use32                               ; by Napalm
_int32:
cli                                    ; disable interrupts
pusha                                  ; save register state to 32bit stack
mov  esi, reloc                        ; set source to code below
mov  edi, INT32_BASE                   ; set destination to new base address
mov  ecx, (int32_end - reloc)          ; set copy size to our codes size
cld                                    ; clear direction flag (so we copy forward)
rep  movsb                             ; do the actual copy (relocate code to low 16bit space)
jmp INT32_BASE                         ; jump to new code location
reloc: use32                               ; by Napalm
mov  [REBASE(stack32_ptr)], esp        ; save 32bit stack pointer
sidt [REBASE(idt32_ptr)]               ; save 32bit idt pointer
sgdt [REBASE(gdt32_ptr)]               ; save 32bit gdt pointer
lgdt [REBASE(gdt16_ptr)]               ; load 16bit gdt pointer
lea  esi, [esp+0x24]                   ; set position of intnum on 32bit stack
lodsd                                  ; read intnum into eax
mov  [REBASE(ib)], al                  ; set intrrupt immediate byte from our arguments
mov  esi, [esi]                        ; read regs pointer in esi as source
mov  edi, STACK16                      ; set destination to 16bit stack
mov  ecx, regs16_t_size                ; set copy size to our struct size
mov  esp, edi                          ; save destination to as 16bit stack offset
rep  movsb                             ; do the actual copy (32bit stack to 16bit stack)
jmp  word CODE16:REBASE(p_mode16)      ; switch to 16bit selector (16bit protected mode)
p_mode16: use16
mov  ax, DATA16                        ; get our 16bit data selector
mov  ds, ax                            ; set ds to 16bit selector
mov  es, ax                            ; set es to 16bit selector
mov  fs, ax                            ; set fs to 16bit selector
mov  gs, ax                            ; set gs to 16bit selector
mov  ss, ax                            ; set ss to 16bit selector
mov  eax, cr0                          ; get cr0 so we can modify it
and  al,  ~0x01                        ; mask off PE bit to turn off protected mode
mov  cr0, eax                          ; set cr0 to result
jmp  word 0x0000:REBASE(r_mode16)      ; finally set cs:ip to enter real-mode
r_mode16: use16
xor  ax, ax                            ; set ax to zero
mov  ds, ax                            ; set ds so we can access idt16
mov  ss, ax                            ; set ss so they the stack is valid
lidt [REBASE(idt16_ptr)]               ; load 16bit idt
mov  bx, 0x0870                        ; master 8 and slave 112
call resetpic                          ; set pic's the to real-mode settings
popa                                   ; load general purpose registers from 16bit stack
pop  gs                                ; load gs from 16bit stack
pop  fs                                ; load fs from 16bit stack
pop  es                                ; load es from 16bit stack
pop  ds                                ; load ds from 16bit stack
sti                                    ; enable interrupts
db 0xCD                                ; opcode of INT instruction with immediate byte
ib: db 0x00
cli                                    ; disable interrupts
xor  sp, sp                            ; zero sp so we can reuse it
mov  ss, sp                            ; set ss so the stack is valid
mov  sp, INT32_BASE                    ; set correct stack position so we can copy back
pushf                                  ; save eflags to 16bit stack
push ds                                ; save ds to 16bit stack
push es                                ; save es to 16bit stack
push fs                                ; save fs to 16bit stack
push gs                                ; save gs to 16bit stack
pusha                                  ; save general purpose registers to 16bit stack
mov  bx, 0x2028                        ; master 32 and slave 40
call resetpic                          ; restore the pic's to protected mode settings
mov  eax, cr0                          ; get cr0 so we can modify it
inc  eax                               ; set PE bit to turn on protected mode
mov  cr0, eax                          ; set cr0 to result
jmp  dword CODE32:REBASE(p_mode32)     ; switch to 32bit selector (32bit protected mode)
p_mode32: use32
mov  ax, DATA32                        ; get our 32bit data selector
mov  ds, ax                            ; reset ds selector
mov  es, ax                            ; reset es selector
mov  fs, ax                            ; reset fs selector
mov  gs, ax                            ; reset gs selector
mov  ss, ax                            ; reset ss selector
lgdt [REBASE(gdt32_ptr)]               ; restore 32bit gdt pointer
lidt [REBASE(idt32_ptr)]               ; restore 32bit idt pointer
mov  esp, [REBASE(stack32_ptr)]        ; restore 32bit stack pointer
mov  esi, STACK16                      ; set copy source to 16bit stack
lea  edi, [esp+0x28]                   ; set position of regs pointer on 32bit stack
mov  edi, [edi]                        ; use regs pointer in edi as copy destination
mov  ecx, regs16_t_size                ; set copy size to our struct size
cld                                    ; clear direction flag (so we copy forward)
rep  movsb                             ; do the actual copy (16bit stack to 32bit stack)
popa                                   ; restore registers
sti                                    ; enable interrupts
ret                                    ; return to caller

resetpic:                                  ; reset's 8259 master and slave pic vectors
push ax                                ; expects bh = master vector, bl = slave vector
mov  al, 0x11                          ; 0x11 = ICW1_INIT | ICW1_ICW4
out  0x20, al                          ; send ICW1 to master pic
out  0xA0, al                          ; send ICW1 to slave pic
mov  al, bh                            ; get master pic vector param
out  0x21, al                          ; send ICW2 aka vector to master pic
mov  al, bl                            ; get slave pic vector param
out  0xA1, al                          ; send ICW2 aka vector to slave pic
mov  al, 0x04                          ; 0x04 = set slave to IRQ2
out  0x21, al                          ; send ICW3 to master pic
shr  al, 1                             ; 0x02 = tell slave its on IRQ2 of master
out  0xA1, al                          ; send ICW3 to slave pic
shr  al, 1                             ; 0x01 = ICW4_8086
out  0x21, al                          ; send ICW4 to master pic
out  0xA1, al                          ; send ICW4 to slave pic
pop  ax                                ; restore ax from stack
ret                                    ; return to caller

stack32_ptr:                               ; address in 32bit stack after we
dd 0x00000000                          ;   save all general purpose registers

idt32_ptr:                                 ; IDT table pointer for 32bit access
dw 0x0000                              ; table limit (size)
dd 0x00000000                          ; table base address

gdt32_ptr:                                 ; GDT table pointer for 32bit access
dw 0x0000                              ; table limit (size)
dd 0x00000000                          ; table base address

idt16_ptr:                                 ; IDT table pointer for 16bit access
dw 0x03FF                              ; table limit (size)
dd 0x00000000                          ; table base address

gdt16_base:                                ; GDT descriptor table
.null:                                 ; 0x00 - null segment descriptor
dd 0x00000000                      ; must be left zero'd
dd 0x00000000                      ; must be left zero'd

.code32:                               ; 0x01 - 32bit code segment descriptor 0xFFFFFFFF
dw 0xFFFF                          ; limit  0:15
dw 0x0000                          ; base   0:15
db 0x00                            ; base  16:23
db 0x9A                            ; present, iopl/0, code, execute/read
db 0xCF                            ; 4Kbyte granularity, 32bit selector; limit 16:19
db 0x00                            ; base  24:31

.data32:                               ; 0x02 - 32bit data segment descriptor 0xFFFFFFFF
dw 0xFFFF                          ; limit  0:15
dw 0x0000                          ; base   0:15
db 0x00                            ; base  16:23
db 0x92                            ; present, iopl/0, data, read/write
db 0xCF                            ; 4Kbyte granularity, 32bit selector; limit 16:19
db 0x00                            ; base  24:31

.code16:                               ; 0x03 - 16bit code segment descriptor 0x000FFFFF
dw 0xFFFF                          ; limit  0:15
dw 0x0000                          ; base   0:15
db 0x00                            ; base  16:23
db 0x9A                            ; present, iopl/0, code, execute/read
db 0x0F                            ; 1Byte granularity, 16bit selector; limit 16:19
db 0x00                            ; base  24:31

.data16:                               ; 0x04 - 16bit data segment descriptor 0x000FFFFF
dw 0xFFFF                          ; limit  0:15
dw 0x0000                          ; base   0:15
db 0x00                            ; base  16:23
db 0x92                            ; present, iopl/0, data, read/write
db 0x0F                            ; 1Byte granularity, 16bit selector; limit 16:19
db 0x00                            ; base  24:31

gdt16_ptr:                                 ; GDT table pointer for 16bit access
dw gdt16_ptr - gdt16_base - 1          ; table limit (size)
dd gdt16_base                          ; table base address

int32_end:                                 ; end marker (so we can copy the code)

Der Code um die Informationen abrufen zu können sieht so aus:
typedef struct __attribute__ ((packed)) {
    unsigned short di, si, bp, sp, bx, dx, cx, ax;
    unsigned short gs, fs, es, ds, eflags;
} regs16_t;

extern void int32(unsigned char intnum, regs16_t *regs);

void get_vesa_modes() {
struct vbe_info_structure info;
struct vbe_mode_info_structure inf;
int i;
regs16_t regs;

memcpy(info.signature, "VBE2", 4);

regs.ax=0x4f00;
regs.es=&info;
regs.di=0;
int32(0x10,&regs);
if(regs.ax!=0x004f) {
kprintf("VBE Error\n");
return false;
} else {
kprintf("VBE OK\n");
}

uint16_t *modes=(uint16_t *)(info.video_modes);
for(i=0;modes[i]!=0xffff;i++) {
regs.ax=0x4f01;
regs.cx=modes[i];
regs.es=&inf;
regs.di=0;
int32(0x10,&regs);
if ( regs.ax != 0x004F ) continue;

if ( (inf.attributes & 0x90) != 0x90 ) continue;

if ( inf.memory_model != 4 && inf.memory_model != 6 ) continue;

kprintf("Resolution: %dx%dx%d\n",inf.width,inf.height,inf.bpp);
}

}

Leider bekomme ich keine Mod-Informationen ausgegeben.... Meine Vermutung ist, dass int32() die Struktur nicht füllt (info.signature ist nach dem Bios-Call immernoch VBE2). Kann mir jemand helfen?

LG Dietzi
3
Lowlevel-Coding / Re: Interrupt-Handling schlägt fehl
« am: 20. February 2017, 20:16 »
Fehler gefunden...... tss war im header als static deklariert. Habe tss jetzt in der isr.c als "nicht-static" deklariert und in der gdt.h habe ich einen Verweis mittels extern auf tss gesetzt. Und schon geht alles wieder. Danke für deine Hilfe
4
Lowlevel-Coding / Re: Interrupt-Handling schlägt fehl
« am: 20. February 2017, 19:20 »
Nun folgende Ausgabe (Breakpoint zu start in irq_stub und direkt vor iret)

<bochs:3> sreg
es:0x0018, dh=0x00cf9300, dl=0x0000ffff, valid=1
        Data segment, base=0x00000000, limit=0xffffffff, Read/Write, Accessed
cs:0x0008, dh=0x00cf9b00, dl=0x0000ffff, valid=1
        Code segment, base=0x00000000, limit=0xffffffff, Execute/Read, Non-Conforming, Accessed, 32-bit
ss:0x0018, dh=0x00cf9300, dl=0x0000ffff, valid=31
        Data segment, base=0x00000000, limit=0xffffffff, Read/Write, Accessed
ds:0x0018, dh=0x00cf9300, dl=0x0000ffff, valid=31
        Data segment, base=0x00000000, limit=0xffffffff, Read/Write, Accessed
fs:0x0018, dh=0x00cf9300, dl=0x0000ffff, valid=1
        Data segment, base=0x00000000, limit=0xffffffff, Read/Write, Accessed
gs:0x0018, dh=0x00cf9300, dl=0x0000ffff, valid=1
        Data segment, base=0x00000000, limit=0xffffffff, Read/Write, Accessed
ldtr:0x0000, dh=0x00008200, dl=0x0000ffff, valid=1
tr:0x0028, dh=0x0000eb10, dl=0x32000080, valid=1
gdtr:base=0x000000000010b840, limit=0x2f
idtr:base=0x000000000010b8e0, limit=0x7ff
<bochs:4> c
00086139138i[CPU0  ] [86139138] Stopped on MAGIC BREAKPOINT
(0) Magic breakpoint
Next at t=86139138
(0) [0x00000010049b] 0008:000000000010049b (unk. ctxt): iret                      ; cf
<bochs:5> sreg
es:0x0023, dh=0x00cff300, dl=0x0000ffff, valid=1
        Data segment, base=0x00000000, limit=0xffffffff, Read/Write, Accessed
cs:0x0008, dh=0x00cf9b00, dl=0x0000ffff, valid=1
        Code segment, base=0x00000000, limit=0xffffffff, Execute/Read, Non-Conforming, Accessed, 32-bit
ss:0x0018, dh=0x00cf9300, dl=0x0000ffff, valid=31
        Data segment, base=0x00000000, limit=0xffffffff, Read/Write, Accessed
ds:0x0023, dh=0x00cff300, dl=0x0000ffff, valid=1
        Data segment, base=0x00000000, limit=0xffffffff, Read/Write, Accessed
fs:0x0018, dh=0x00cf9300, dl=0x0000ffff, valid=1
        Data segment, base=0x00000000, limit=0xffffffff, Read/Write, Accessed
gs:0x0018, dh=0x00cf9300, dl=0x0000ffff, valid=1
        Data segment, base=0x00000000, limit=0xffffffff, Read/Write, Accessed
ldtr:0x0000, dh=0x00008200, dl=0x0000ffff, valid=1
tr:0x0028, dh=0x0000eb10, dl=0x32000080, valid=1
gdtr:base=0x000000000010b840, limit=0x2f
idtr:base=0x000000000010b8e0, limit=0x7ff
<bochs:6> c
00086139138e[CPU0  ] check_cs(0x0010): not a valid code segment !
00086148003e[CPU0  ] check_cs(0x0010): not a valid code segment !
00086156868e[CPU0  ] check_cs(0x0010): not a valid code segment !
00086381399e[CPU0  ] check_cs(0x0010): not a valid code segment !
00086929429e[CPU0  ] check_cs(0x0010): not a valid code segment !
00087477459e[CPU0  ] check_cs(0x0010): not a valid code segment !
00088025489e[CPU0  ] check_cs(0x0010): not a valid code segment !
00088573519e[CPU0  ] check_cs(0x0010): not a valid code segment !
00089121549e[CPU0  ] check_cs(0x0010): not a valid code segment !
00089536436i[      ] Ctrl-C detected in signal handler.
Next at t=89536436
(0) [0x000000100f70] 0008:0000000000100f70 (unk. ctxt): add ebx, ebx              ; 01db
<bochs:7> sreg
es:0x0010, dh=0x00cf9300, dl=0x0000ffff, valid=1
        Data segment, base=0x00000000, limit=0xffffffff, Read/Write, Accessed
cs:0x0008, dh=0x00cf9b00, dl=0x0000ffff, valid=1
        Code segment, base=0x00000000, limit=0xffffffff, Execute/Read, Non-Conforming, Accessed, 32-bit
ss:0x0018, dh=0x00cf9300, dl=0x0000ffff, valid=31
        Data segment, base=0x00000000, limit=0xffffffff, Read/Write, Accessed
ds:0x0010, dh=0x00cf9300, dl=0x0000ffff, valid=31
        Data segment, base=0x00000000, limit=0xffffffff, Read/Write, Accessed
fs:0x0010, dh=0x00cf9300, dl=0x0000ffff, valid=1
        Data segment, base=0x00000000, limit=0xffffffff, Read/Write, Accessed
gs:0x0010, dh=0x00cf9300, dl=0x0000ffff, valid=1
        Data segment, base=0x00000000, limit=0xffffffff, Read/Write, Accessed
ldtr:0x0000, dh=0x00008200, dl=0x0000ffff, valid=1
tr:0x0028, dh=0x0000eb10, dl=0x32000080, valid=1
gdtr:base=0x000000000010b840, limit=0x2f
idtr:base=0x000000000010b8e0, limit=0x7ff

Nachtrag:
<bochs:8> info gdt
Global Descriptor Table (base=0x000000000010b840, limit=47):
GDT[0x00]=??? descriptor hi=0x00000000, lo=0x00000000
GDT[0x01]=Code segment, base=0x00000000, limit=0xffffffff, Execute/Read, Non-Conforming, Accessed, 32-bit
GDT[0x02]=Data segment, base=0x00000000, limit=0xffffffff, Read/Write
GDT[0x03]=Code segment, base=0x00000000, limit=0xffffffff, Execute/Read, Non-Conforming, 32-bit
GDT[0x04]=Data segment, base=0x00000000, limit=0xffffffff, Read/Write
GDT[0x05]=32-Bit TSS (Busy) at 0x00103200, length 0x00080
5
Lowlevel-Coding / Re: Interrupt-Handling schlägt fehl
« am: 20. February 2017, 18:33 »
Hallo,

danke für die schnelle Antwort. Bochs zeigt mir keine Adresse an:
00086139136e[CPU0  ] check_cs(0x0010): not a valid code segment !
00086148001e[CPU0  ] check_cs(0x0010): not a valid code segment !
00086156866e[CPU0  ] check_cs(0x0010): not a valid code segment !
00086381397e[CPU0  ] check_cs(0x0010): not a valid code segment !

Ich verstehe auch nicht so ganz wie es hier zu diesem Fehler kommen kann, da ich genau den Status zurück gebe welchen ich bei Aufruf von handle_interrupt() erhalte. Was ich noch vergessen hatte zu erwähnen: es wird ein GP ausgelöst - evtl. hilft das der Lösungsfindung.....

LG Dietzi
6
Lowlevel-Coding / [gelöst] Interrupt-Handling schlägt fehl
« am: 19. February 2017, 21:30 »
Hallo,

ich habe ein Problem mit dem Interrupt-Handling. Ich habe bis jetzt größten teils mit dem Tutorial gearbeitet. Wenn ich meinen Code in Bochs ausführe bekomme ich als Debug-Info "check_cs(0x0010): not a valid code segment !"

Hier mein Code (die betreffenden Zeilen)

Interrupts.S
.macro irq num, map
.global irq\num
irq\num:
    cli
    push $0
    push $\map
jmp irq_stub
.endm


irq 0, 20
irq 1, 21
irq 2, 22
irq 3, 23
irq 4, 24
irq 5, 25
irq 6, 26
irq 7, 27
irq 8, 28
irq 9, 29
irq 10, 30
irq 11, 31
irq 12, 32
irq 13, 33
irq 14, 34
irq 15, 35

.extern handle_interrupt
irq_stub:
    // CPU-Zustand sichern

    push %ebp
    push %edi
    push %esi
    push %edx
    push %ecx
    push %ebx
    push %eax

    // Kernel-Datensegmente laden
    mov $0x10, %ax
    mov %ax, %ds
    mov %ax, %es

    // Handler aufrufen
    push %esp
    call handle_interrupt
    mov %eax, %esp

    // User-Datensegmente laden
    mov $0x23, %ax
    mov %ax, %ds
    mov %ax, %es

    // CPU-Zustand wiederherstellen
    pop %eax
    pop %ebx
    pop %ecx
    pop %edx
    pop %esi
    pop %edi
    pop %ebp

     // Fehlercode und Interruptnummer vom Stack nehmen
    add $8, %esp
 
// Ruecksprung zum unterbrochenen Code
// xchg %bx, %bx
    iret

isr.c
struct cpu_state {
    // Von Hand gesicherte Register
    uint32_t   eax;
    uint32_t   ebx;
    uint32_t   ecx;
    uint32_t   edx;
    uint32_t   esi;
    uint32_t   edi;
    uint32_t   ebp;
 
    uint32_t   intr;
    uint32_t   error;
 
    // Von der CPU gesichert
    uint32_t   eip;
    uint32_t   cs;
    uint32_t   eflags;
    uint32_t   esp;
    uint32_t   ss;
};

struct cpu_state* handle_interrupt(struct cpu_state* cpu)
{
    struct cpu_state* new_cpu = cpu;

if(cpu->intr == 0x21) {
keyboard_handler();
}

if (cpu->intr >= 0x20 && cpu->intr <= 0x2f) {
terminal_writestring("Resetting Master");
if (cpu->intr >= 0x28) {
terminal_writestring("Resetting Slave");
outb(SLAVE_COMMAND, PIC_RESET);
terminal_writestring("Slave resetted");
}
outb(MASTER_COMMAND, PIC_RESET);
terminal_writestring("Master resetted");
}
terminal_writestring("Returning CPU-State");
return new_cpu;
}

handle_interrupt() läuft genau 1 mal durch und wird danach nicht mehr aufgerufen....
Kann mir vielleicht jemand sagen wo der Fehler liegt?

LG Dietzi
Seiten: [1]

Einloggen