Autor Thema: Protected Modus funktioniert nicht  (Gelesen 6359 mal)

MrPerfekt

  • Beiträge: 26
    • Profil anzeigen
Gespeichert
« am: 21. April 2010, 01:22 »
Hallo Leute
Wahrscheinlich ist mein Problem ganz einfach zu lösen doch ich schaffe es nicht.
Schreibe in nasm einen Bootloader und will auf 32Bit protected modus schalten
Habe bereits mehrere Codeteile ausprobiert/selbst geschrieben aber immer giebt Virtual Box eine Meldung aus dass ein "schwerwiegender Fehler" aufgetreten ist und qemu macht einfach nichts mehr.

Und zwar immer bei der Stelle wo ich auf cr0 den neuen Wert schreib.

Der code zum umschalten ist 1 zu 1 dieser:
http://www.lowlevel.eu/wiki/Umschalten_in_Protected_Mode

danke für eure hilfe
suche bereits seit monaten verzweifelt um eine Lösung

Jidder

  • Administrator
  • Beiträge: 1 625
    • Profil anzeigen
Gespeichert
« Antwort #1 am: 21. April 2010, 01:28 »
Hi,

Code 1:1 zu übernehmen klappt nie. In diesem Fall wird vermutlich schon das org 0x0000 Probleme verursachen, wenn du den Code in einem Bootloader verwendest.

Wenn du deinen kompletten Code herzeigst, kann dir vielleicht jemand mehr helfen.
Dieser Text wird unter jedem Beitrag angezeigt.

MrPerfekt

  • Beiträge: 26
    • Profil anzeigen
Gespeichert
« Antwort #2 am: 21. April 2010, 10:53 »
natürlich habe mir nur gedacht es ist ein bisschen viel
ok ich hänge direcht an die bienärdatei eine 32bit binaerdatei an und schreibe diese in ein img und boote dies mit qemu und virtual box

[ORG 0] ;ab hier Startet das Programm
[bits 16]

jmp 07C0h:start     ; Goto segment 07C0


start:
        ; Update the segment registers
mov ax, cs
        mov ds, ax
        mov es, ax

call print
mov ax,$
call int2string
call print

;mov ah,86h ;Wartet eine gewisse Zeit ab
;mov al,0
;mov cx,200
;mov dx,0
;int 15h

;================================================================
;Lade das weitere Programm in den Arbeitsspeicher
;================================================================

reset:                      ; Reset the floppy drive
mov ax, 0           ;
mov dl, 0           ; Drive=0 (=A)
int 13h             ;
jc reset            ; ERROR => reset again


read:
mov ax, 1000h ; ES:BX = 1000:0000
mov es, ax ;
mov bx, 0000h ;

mov ah, 2 ; Load disk data to ES:BX
mov al, 3 ; Load 3 sectors
mov ch, 0 ; Cylinder=0
mov cl, 1 ; Sector=1
mov dh, 0 ; Head=0
mov dl, 0 ; Drive=0
int 13h ; Read!

jc read ; ERROR => Try again


;================================================================
;Schalte in den Protected Mode
;================================================================
[BITS 16]
org 0x0000 ; Addiert zu allen Offsets die Start-Adresse dieses Codes

cli ; Interrupts ausschalten
lgdt [gdtr] ; GDT Pointer laden

mov eax,cr0 ; In PMode wechseln, indem das niedrigste
or al,1 ; Steuerungsbit von cr0 geändert wird
mov cr0,eax ; muss über Umweg über ein anderes Register gemacht werden
int 19h

jmp codesel:PMode ; FarJump zu einer 32-Bit PMode Funktion

[BITS 32]
PMode:
mov ax,datasel ; Segmentregister laden
mov ds,ax
mov ss,ax
mov esp,0x90000 ; Stack aufsetzen

jmp $ ; Endlosschleife, wird durch weiteren Code ersetzt
jmp 1000h:0200h


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

gdtr: ; Desktiptortabelle
dw gdt_end-gdt-1 ; Limit
dd gdt ; Basisadresse
gdt:
dd 0,0 ; Null-Deskriptor
codesel equ $-gdt
dw 0xFFFF ; Segmentgrösse 0..15
dw 0x0000 ; Segmentadresse 0..15
db 0x00 ; Segmentadresse 16..23
db 0x9A ; Zugriffsberechtigung und Typ
db 0xCF ; Zusatzinformationen und Segmentgrösse 16...19
db 0x00 ; Segmentadresse 24..31
datasel equ $-gdt
dw 0xFFFF ; Segmentgrösse 0..15
dw 0x0000 ; Segmentadresse 0..15
db 0x00 ; Segmentadresse 16..23
db 0x92 ; Zugriffsberechtigung und Typ
db 0xCF ; Zusatzinformationen und Segmentgrösse 16...19
db 0x00 ; Segmentadresse 24..31
gdt_end:

;================================================================
; int2string (schreibt eax in den string)
;================================================================
[bits 16]
int2string:
PUSHA
LEA edi,[string]
MOV esi, edi
;MOV eax, 479
MOV ecx, 0x000A
startLoop:

MOV byte [edi], '0'
XOR edx,edx
DIV ecx

ADD [edi],edx
;MOV byte [edi], ebx
;ADD [edi],ebx

INC edi
CMP eax,0
JNE startLoop
MOV byte [edi],0
DEC edi
; vertausche die Richtung
switchLoop:
MOV ah, [esi]
MOV al, [edi]

MOV dl,ah
MOV ah,al
MOV al,dl

MOV [esi], ah
MOV [edi], al

DEC edi
MOV al, [edi]
CMP al,ah
JA ende0

INC esi
MOV ah, [esi]
CMP al,ah
JA ende0

ende0:
POPA
RET

;================================================================
; end int2string
;================================================================

;================================================================
; Print
;================================================================
string DB "Lade Black Window 0.0.0.0.0.0.0.5.0",0
print:
PUSHA
LEA bx,[string]
startOutLoop:
CMP byte [bx],0
JE ende
MOV ah,0eh
MOV al,[bx]
INT 10h
INC bx
JMP startOutLoop
ende:

MOV bh, 0
MOV ah, 03h
INT 10h
MOV ah, 02h
MOV dl, 0
INC dh
INT 10h
POPA
RET
;================================================================
; end Print
;================================================================



;================================================================
;Schreibe die Bootloaderidentifikation
;================================================================
times 510-($-$$) db 0
dw 0AA55h
;================================================================
;ende Schreibe die Bootloaderidentifikation
;================================================================

zum umschalten habe ich noch die alternative:

        lgdt [gdtr]

        mov eax, cr0
        or al, 1
        mov cr0, eax

; Reprogram 8259A interrupt controller chips, taken from skelix.org
mov dx, 011h
mov al, 020h
out dx, al
mov al, 0a0h
out dx, al
mov dx, 020h
        mov     al, 021h
out dx, al
mov dx, 028h
        mov     al, 0a1h
out dx, al
mov dx, 004h
        mov     al, 021h
out dx, al
mov dx, 002h
        mov     al, 0a1h
out dx, al
mov dx, 001h
        mov     al, 021h
out dx, al
        mov     al, 0a1h
out dx, al
mov dx, 0ffh
        mov     al, 021h
out dx, al
        mov     al, 0a1h
out dx, al

        jmp SYS_CODE_SEL:do_pm

[BITS 32]    ; All code from now on will be 32-bit

do_pm:

        mov ax, SYS_DATA_SEL      ; Update the segment registers
        mov ds, ax                ; To complete the transfer to
        mov es, ax                ; 32-bit mode
        mov ss, ax

; Update ESP
mov esp, 9000h

; -------------------------------------------------------
; Execute the binary file that was loaded previously
; -------------------------------------------------------

jmp 08000h


gdtr:
        dw gdt_end - gdt - 1    ; GDT limit
        dd gdt                  ; GDT base

; -----------------------------------------------
;                      GDT
; -----------------------------------------------
gdt:
times 8 db 0            ; NULL Descriptor

SYS_CODE_SEL  equ  $-gdt
        dw 0xFFFF       ; limit 15:0
        dw 0            ; base 15:0
        db 0            ; base 23:16
        db 0x9A         ; type = present, ring 0, code, non-conforming, readable
        db 0xCF         ; page granular, 32-bit
        db 0            ; base 31:24

SYS_DATA_SEL  equ  $-gdt
        dw 0xFFFF       ; limit 15:0
        dw 0            ; base 15:0
        db 0            ; base 23:16
        db 0x92         ; type = present, ring 0, data, expand-up, writable
        db 0xCF         ; page granular, 32-bit
        db 0            ; base 31:24

gdt_end:


danke für die schnelle antwort
« Letzte Änderung: 23. April 2010, 00:34 von MrPerfekt »

Jidder

  • Administrator
  • Beiträge: 1 625
    • Profil anzeigen
Gespeichert
« Antwort #3 am: 21. April 2010, 21:14 »
Hi,

du solltest am Anfang [org 0x7c00] statt [org 0] verwenden. Dadurch wird es einfacher, in der selben Datei 16 Bit und 32 Bit Code zu haben.

Also am Anfang:
[ORG 0x7c00]
[bits 16]

jmp 0000h:start

Außerdem weiter unten die beiden Zeilen [org 0x0000] und int 0x19 löschen. Erstere ist ein Copy&Paste Fehler, die zweite macht keinen Sinn.

Dann sollte es funktionieren.
Dieser Text wird unter jedem Beitrag angezeigt.

MrPerfekt

  • Beiträge: 26
    • Profil anzeigen
Gespeichert
« Antwort #4 am: 23. April 2010, 00:34 »
naja das int 19h war schon fon mir: damit habe ich getestet ob mein Programm über haupt noch lauft
So ich hoffe ihr habt ein bisschen geduld mit mir bin noch neuling auf dem gebiet aber lernwillig!
Mein code Stürzt leider immer noch auf der stelle ab wo ich auf das cr0 register schreibe  :cry:
bin schon richtig verzweifelt weil ich mir sicher sein kann dass der fehler bei dieser codezeile auftritt egal welchen code ich schreibe oder aus dem www copiere

hier mein aktueller:
[ORG 07C0h] ;ab hier Startet das Programm
[bits 16]

jmp 0000h:start     ; Goto segment 07C0


start:
        ; Update the segment registers
mov ax, cs
        mov ds, ax
        mov es, ax

call print
mov ax,$
call int2string
call print

;mov ah,86h ;Wartet eine gewisse Zeit ab
;mov al,0
;mov cx,200
;mov dx,0
;int 15h

;================================================================
;Lade das weitere Programm in den Arbeitsspeicher
;================================================================

reset:                      ; Reset the floppy drive
mov ax, 0           ;
mov dl, 0           ; Drive=0 (=A)
int 13h             ;
jc reset            ; ERROR => reset again


read:
mov ax, 1000h ; ES:BX = 1000:0000
mov es, ax ;
mov bx, 0000h ;

mov ah, 2 ; Load disk data to ES:BX
mov al, 3 ; Load 3 sectors
mov ch, 0 ; Cylinder=0
mov cl, 1 ; Sector=1
mov dh, 0 ; Head=0
mov dl, 0 ; Drive=0
int 13h ; Read!

jc read ; ERROR => Try again


;================================================================
;Schalte in den Protected Mode
;================================================================
[BITS 16]
cli ; Interrupts ausschalten
lgdt [gdtr] ; GDT Pointer laden

mov eax,cr0 ; In PMode wechseln, indem das niedrigste
or al,1 ; Steuerungsbit von cr0 geändert wird
mov cr0,eax ; muss über Umweg über ein anderes Register gemacht werden

jmp codesel:PMode ; FarJump zu einer 32-Bit PMode Funktion

[BITS 32]
PMode:
mov ax,datasel ; Segmentregister laden
mov ds,ax
mov ss,ax
mov esp,0x90000 ; Stack aufsetzen
sti

jmp 1000h:0200h
jmp $ ; Endlosschleife, wird durch weiteren Code ersetzt


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

gdtr: ; Desktiptortabelle
dw gdt_end-gdt-1 ; Limit
dd gdt ; Basisadresse
gdt:
dd 0,0 ; Null-Deskriptor
codesel equ $-gdt
dw 0xFFFF ; Segmentgrösse 0..15
dw 0x0000 ; Segmentadresse 0..15
db 0x00 ; Segmentadresse 16..23
db 0x9A ; Zugriffsberechtigung und Typ
db 0xCF ; Zusatzinformationen und Segmentgrösse 16...19
db 0x00 ; Segmentadresse 24..31
datasel equ $-gdt
dw 0xFFFF ; Segmentgrösse 0..15
dw 0x0000 ; Segmentadresse 0..15
db 0x00 ; Segmentadresse 16..23
db 0x92 ; Zugriffsberechtigung und Typ
db 0xCF ; Zusatzinformationen und Segmentgrösse 16...19
db 0x00 ; Segmentadresse 24..31
gdt_end:

;================================================================
; int2string (schreibt eax in den string)
;================================================================
[bits 16]
int2string:
PUSHA
LEA edi,[string]
MOV esi, edi
;MOV eax, 479
MOV ecx, 0x000A
startLoop:

MOV byte [edi], '0'
XOR edx,edx
DIV ecx

ADD [edi],edx
;MOV byte [edi], ebx
;ADD [edi],ebx

INC edi
CMP eax,0
JNE startLoop
MOV byte [edi],0
DEC edi
; vertausche die Richtung
switchLoop:
MOV ah, [esi]
MOV al, [edi]

MOV dl,ah
MOV ah,al
MOV al,dl

MOV [esi], ah
MOV [edi], al

DEC edi
MOV al, [edi]
CMP al,ah
JA ende0

INC esi
MOV ah, [esi]
CMP al,ah
JA ende0

ende0:
POPA
RET

;================================================================
; end int2string
;================================================================

;================================================================
; Print
;================================================================
string DB "Lade Black Window 0.0.0.0.0.0.0.5.0",0
print:
PUSHA
LEA bx,[string]
startOutLoop:
CMP byte [bx],0
JE ende
MOV ah,0eh
MOV al,[bx]
INT 10h
INC bx
JMP startOutLoop
ende:

MOV bh, 0
MOV ah, 03h
INT 10h
MOV ah, 02h
MOV dl, 0
INC dh
INT 10h
POPA
RET
;================================================================
; end Print
;================================================================



;================================================================
;Schreibe die Bootloaderidentifikation
;================================================================
times 510-($-$$) db 0
dw 0AA55h
;================================================================
;ende Schreibe die Bootloaderidentifikation
;================================================================

Jidder

  • Administrator
  • Beiträge: 1 625
    • Profil anzeigen
Gespeichert
« Antwort #5 am: 23. April 2010, 03:15 »
naja das int 19h war schon fon mir: damit habe ich getestet ob mein Programm über haupt noch lauft
Die einzige Reaktion auf diesen Befehl, die dir die CPU gegeben kann, ist ein (vermutlich General Protection) Fault, weil die IDT nicht geladen ist, was in einem Double Fault resultiertiert, der wegen einer nicht geladenen IDT in einem Triple Fault resultiert. Ein Triple Fault ist ein Neustart.

[ORG 07C0h]Wie gesagt [org 7c00h]. Bitte die Nullen zählen und beachten.

Zitat
sti
Warum das eingefügt hast, weiß ich nicht. Ohne geladene IDT führt das zu Abstürzen.

Zitat
jmp 1000h:0200h
Ist natürlich nicht korrekt, weil du im Protected Mode bist. Da lädst du CS nicht mehr mit dem Segment sondern mit dem Selektor. Du müsstest einfach EIP mit dem passendem Offset laden, wenn du Code an 0x10200 ausführen willst.

« Letzte Änderung: 23. April 2010, 03:20 von PorkChicken »
Dieser Text wird unter jedem Beitrag angezeigt.

MrPerfekt

  • Beiträge: 26
    • Profil anzeigen
Gespeichert
« Antwort #6 am: 23. April 2010, 09:24 »
naja das int 19h war schon fon mir: damit habe ich getestet ob mein Programm über haupt noch lauft
Die einzige Reaktion auf diesen Befehl, die dir die CPU gegeben kann, ist ein (vermutlich General Protection) Fault, weil die IDT nicht geladen ist, was in einem Double Fault resultiertiert, der wegen einer nicht geladenen IDT in einem Triple Fault resultiert. Ein Triple Fault ist ein Neustart.
Das erklärt natürlich einiges.
Kann es sein dass dadurch nach dem setzen des cr0 registers der "int 0x19" anders reagiert als davor?
Kann ich eigentlich die Anderen Bios interupts noch nutzen?
bzw wie kann ich es noch testen ob er nu  hängt oder schon vorbeigelaufen ist

[ORG 07C0h]Wie gesagt [org 7c00h]. Bitte die Nullen zählen und beachten.
Achso natürlich entschuldige habe ich übersehen.

Zitat
sti
Warum das eingefügt hast, weiß ich nicht. Ohne geladene IDT führt das zu Abstürzen.
Ok wenn es nur das währe. Ich habe jetzt das sti entfärnt aber der fehler kommt noch immer.  :-(

Zitat
jmp 1000h:0200h
Ist natürlich nicht korrekt, weil du im Protected Mode bist. Da lädst du CS nicht mehr mit dem Segment sondern mit dem Selektor. Du müsstest einfach EIP mit dem passendem Offset laden, wenn du Code an 0x10200 ausführen willst.
ja ok das leuchtet mir ein. Aber ist die vor a:b danach nicht mehr möglich?

DANKE FÜR DIE HILFE
danke danke danke
wenn du irgentwann etwas brauchst und dir helfen kann dann immer gerne

OK wieder mein aktueller code:
[ORG 07C00h] ;ab hier Startet das Programm
[bits 16]

jmp 0000h:start     ; Goto segment 07C0


start:
        ; Update the segment registers
mov ax, cs
        mov ds, ax
        mov es, ax

call print
mov ax,$
call int2string
call print

;mov ah,86h ;Wartet eine gewisse Zeit ab
;mov al,0
;mov cx,200
;mov dx,0
;int 15h

;================================================================
;Lade das weitere Programm in den Arbeitsspeicher
;================================================================

reset:                      ; Reset the floppy drive
mov ax, 0           ;
mov dl, 0           ; Drive=0 (=A)
int 13h             ;
jc reset            ; ERROR => reset again


read:
mov ax, 1000h ; ES:BX = 1000:0000
mov es, ax ;
mov bx, 0000h ;

mov ah, 2 ; Load disk data to ES:BX
mov al, 3 ; Load 3 sectors
mov ch, 0 ; Cylinder=0
mov cl, 1 ; Sector=1
mov dh, 0 ; Head=0
mov dl, 0 ; Drive=0
int 13h ; Read!

jc read ; ERROR => Try again


;================================================================
;Schalte in den Protected Mode
;================================================================
[BITS 16]
cli ; Interrupts ausschalten
lgdt [gdtr] ; GDT Pointer laden

mov eax,cr0 ; In PMode wechseln, indem das niedrigste
or al,1 ; Steuerungsbit von cr0 geändert wird
mov cr0,eax ; muss über Umweg über ein anderes Register gemacht werden

jmp codesel:PMode ; FarJump zu einer 32-Bit PMode Funktion

[BITS 32]
PMode:
mov ax,datasel ; Segmentregister laden
mov ds,ax
mov ss,ax
mov esp,0x90000 ; Stack aufsetzen

jmp 0x10200 ; 1000h:200h


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

gdtr: ; Desktiptortabelle
dw gdt_end-gdt-1 ; Limit
dd gdt ; Basisadresse
gdt:
dd 0,0 ; Null-Deskriptor
codesel equ $-gdt
dw 0xFFFF ; Segmentgrösse 0..15
dw 0x0000 ; Segmentadresse 0..15
db 0x00 ; Segmentadresse 16..23
db 0x9A ; Zugriffsberechtigung und Typ
db 0xCF ; Zusatzinformationen und Segmentgrösse 16...19
db 0x00 ; Segmentadresse 24..31
datasel equ $-gdt
dw 0xFFFF ; Segmentgrösse 0..15
dw 0x0000 ; Segmentadresse 0..15
db 0x00 ; Segmentadresse 16..23
db 0x92 ; Zugriffsberechtigung und Typ
db 0xCF ; Zusatzinformationen und Segmentgrösse 16...19
db 0x00 ; Segmentadresse 24..31
gdt_end:

;================================================================
; int2string (schreibt eax in den string)
;================================================================
[bits 16]
int2string:
PUSHA
LEA edi,[string]
MOV esi, edi
;MOV eax, 479
MOV ecx, 0x000A
startLoop:

MOV byte [edi], '0'
XOR edx,edx
DIV ecx

ADD [edi],edx
;MOV byte [edi], ebx
;ADD [edi],ebx

INC edi
CMP eax,0
JNE startLoop
MOV byte [edi],0
DEC edi
; vertausche die Richtung
switchLoop:
MOV ah, [esi]
MOV al, [edi]

MOV dl,ah
MOV ah,al
MOV al,dl

MOV [esi], ah
MOV [edi], al

DEC edi
MOV al, [edi]
CMP al,ah
JA ende0

INC esi
MOV ah, [esi]
CMP al,ah
JA ende0

ende0:
POPA
RET

;================================================================
; end int2string
;================================================================

;================================================================
; Print
;================================================================
string DB "Lade Black Window 0.0.0.0.0.0.0.5.1",0
print:
PUSHA
LEA bx,[string]
startOutLoop:
CMP byte [bx],0
JE ende
MOV ah,0eh
MOV al,[bx]
INT 10h
INC bx
JMP startOutLoop
ende:

MOV bh, 0
MOV ah, 03h
INT 10h
MOV ah, 02h
MOV dl, 0
INC dh
INT 10h
POPA
RET
;================================================================
; end Print
;================================================================



;================================================================
;Schreibe die Bootloaderidentifikation
;================================================================
times 510-($-$$) db 0
dw 0AA55h
;================================================================
;ende Schreibe die Bootloaderidentifikation
;================================================================

Svenska

  • Beiträge: 1 792
    • Profil anzeigen
Gespeichert
« Antwort #7 am: 23. April 2010, 13:51 »
Kann es sein dass dadurch nach dem setzen des cr0 registers der "int 0x19" anders reagiert als davor?
Ja. Im Protected Mode laufen Interrupts nicht mehr durch einen simplen Sprung an den Handler ab, sondern über ein Interrupt Gate und damit über die Speicherschutzmechanismen. Darum brauchst du auch die IDT, Interrupt Deskriptor Tabelle.

Kann ich eigentlich die Anderen Bios interupts noch nutzen?
Im Protected Mode nicht. Die BIOS-Funktionen sind zum Protected Mode nicht kompatibel. Du musst dir also alle Treiber selbst schreiben.

bzw wie kann ich es noch testen ob er nu  hängt oder schon vorbeigelaufen ist
Naja, du kannst irgendwelche Lampen blinken lassen (Diskettenlaufwerk). ;-)
Das BIOS setzt die Grafikkarte in einen funktionierenden Modus (80x25 Text), der ändert sich ja nicht schlagartig; auch der Grafikspeicher bleibt ja erhalten und an der gleichen (physikalischen) Adresse. Wenn du also an diese Adresse irgendwie rankommst, kannst du auch weiterhin einfach da reinschreiben und es auf dem Bildschirm anzeigen.

Gruß,
Svenska

PS: Der Name ist Programm, oder? ;-)

XanClic

  • Beiträge: 261
    • Profil anzeigen
    • github
Gespeichert
« Antwort #8 am: 23. April 2010, 16:20 »
Das BIOS setzt die Grafikkarte in einen funktionierenden Modus (80x25 Text), der ändert sich ja nicht schlagartig; auch der Grafikspeicher bleibt ja erhalten und an der gleichen (physikalischen) Adresse. Wenn du also an diese Adresse irgendwie rankommst, [...].
„Irgendwie“ ist gut, 0xB8000 ist die (s. auch Wiki – Textausgabe). :-D

Zitat von: MrPerfekt
ja ok das leuchtet mir ein. Aber ist die vor a:b danach nicht mehr möglich?
In der Annahme, dass du „Form“ statt „vor“ meinst: Doch, aber wie PorkChicken bereits sagte, ist der Wert vor dem Doppelpunkt dann eben ein Protected-Mode-Selektor und kein Real-Mode-Segment mehr.

erik.vikinger

  • Beiträge: 1 277
    • Profil anzeigen
Gespeichert
« Antwort #9 am: 23. April 2010, 20:23 »
Hallo,


lgdt [gdtr] ; GDT Pointer laden

;......

gdtr: ; Desktiptortabelle
dw gdt_end-gdt-1 ; Limit
dd gdt ; Basisadresse
gdt:
dd 0,0 ; Null-Deskriptor
codesel equ $-gdt
dw 0xFFFF ; Segmentgrösse 0..15
dw 0x0000 ; Segmentadresse 0..15
db 0x00 ; Segmentadresse 16..23
db 0x9A ; Zugriffsberechtigung und Typ
db 0xCF ; Zusatzinformationen und Segmentgrösse 16...19
db 0x00 ; Segmentadresse 24..31
datasel equ $-gdt
dw 0xFFFF ; Segmentgrösse 0..15
dw 0x0000 ; Segmentadresse 0..15
db 0x00 ; Segmentadresse 16..23
db 0x92 ; Zugriffsberechtigung und Typ
db 0xCF ; Zusatzinformationen und Segmentgrösse 16...19
db 0x00 ; Segmentadresse 24..31
gdt_end:
ich würde sagen der lgdt-Befehl lädt die Adresse Deines GDT-Pointers, also die Adresse von 'gdtr' und nicht den Inhalt, und das ist natürlich nicht sinnvoll. Außerdem sieht ein Real-Mode-Pointer im Speicher anders aus.
Falls ich mich irre dann Bitte einfach meinen Post ignorieren.


Grüße
Erik
Reality is that which, when you stop believing in it, doesn't go away.

Jidder

  • Administrator
  • Beiträge: 1 625
    • Profil anzeigen
Gespeichert
« Antwort #10 am: 23. April 2010, 20:30 »
OK wieder mein aktueller code:
...

Funktioniert bei mir einwandfrei. Ich vermute der Fehler liegt jetzt in dem Code, den du lädst.

Übrigens irrt sich erik. ;)
Dieser Text wird unter jedem Beitrag angezeigt.

erik.vikinger

  • Beiträge: 1 277
    • Profil anzeigen
Gespeichert
« Antwort #11 am: 23. April 2010, 21:55 »
Hallo,


Übrigens irrt sich erik. ;)
Okay, der Code sieht mir irgendwie nicht geheuer aus. Das letzte mal wo ich sowas programmiert habe ist aber schon einige Jahre her.
Sorry das ich Euch Zeit gekostet habe.


Grüße
Erik
Reality is that which, when you stop believing in it, doesn't go away.

MrPerfekt

  • Beiträge: 26
    • Profil anzeigen
Gespeichert
« Antwort #12 am: 24. April 2010, 01:02 »
OK wieder mein aktueller code:
...

Funktioniert bei mir einwandfrei. Ich vermute der Fehler liegt jetzt in dem Code, den du lädst.

Übrigens irrt sich erik. ;)

aber natürlich
das muss es sein jetzt habe ich den fehler nicht mehr mit int 19h ausgetestet sondern mit jmp $ und bin daraufgekommen dass der fehler nach dem Sprung sein muss. ich Idiot
danke an alle die mir beim fehlersuchen geholfen haben

wenn ich noch ein paar fragen stellen darf:
wie kann ich zb auf eine festplatte ohne bios interupts zugreifen?


kann es sein dass ich meinen kernel den ich laden will falsch linke/kompiliere?

so kompiliere ich:
gcc -m32 -Iinclude $i -c -o $e || exit 1
nasm $i -f elf32 -o $home/$e.o || exit 1

so linke ich:
ld -melf_i386 -e entrypoint -o $home/$entrypoint -Ttext 0x8000 home/*.[oh] &&
objcopy -R .note -R .comment -S -O binary $home/$entrypoint $home/entrypoint.bin || exit 0

« Letzte Änderung: 24. April 2010, 01:13 von MrPerfekt »

Svenska

  • Beiträge: 1 792
    • Profil anzeigen
Gespeichert
« Antwort #13 am: 24. April 2010, 03:26 »
Zitat von: XanClic
„Irgendwie“ ist gut, 0xB8000 ist die
Die physische Adresse des Videospeichers liegt fest, aber virtuell kann die ja sonstwo hingemappt sein... das muss man schon wissen. ;)

Auf die Festplatte greifst du ohne BIOS-Interrupts über den IDE-Controller zu. Wenn die Platte per SATA angeschlossen ist, natürlich über den SATA-Controller. Du brauchst also eine sinnvolle Abstraktion des Plattencontrollers und einen Treiber dafür.

Gruß,
Svenska

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #14 am: 24. April 2010, 08:45 »
Zitat von: XanClic
„Irgendwie“ ist gut, 0xB8000 ist die
Die physische Adresse des Videospeichers liegt fest, aber virtuell kann die ja sonstwo hingemappt sein... das muss man schon wissen. ;)
Naja, wenn er Paging nicht explizit einschaltet, ist es aus. Und dann ist es relativ einfach, die virtuelle Adresse rauszufinden. ;)

Wenn man überhaupt Erbsen zählen will, hätte man darauf verweisen können, dass es auch mal 0xb0000 gab, für schwarz-weiß.
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

MrPerfekt

  • Beiträge: 26
    • Profil anzeigen
Gespeichert
« Antwort #15 am: 29. April 2010, 23:32 »
ok sorry wenn ich jetzt noch einmal störe.
bin echt noch ein bisschen unfähig

kann es sein dass ich meinen c code falsch compiliere?
bzw wie compiliere ich ihn richtig

mein c code:
void entrypoint()
{
int x = 10, y = 5;
char*videoPosition;
videoPosition = (char*)(0xB8000 + (y * 80 + x)*2);
*videoPosition = 'h';
*((char*)(0xB8000)) = 'a';
}

compilieren:
mit gcc
schon viele verschiedene möglichkeiten  probiert
am liebsten währe es mir wenn ich gleich einige datei durch das linken in eine binärdatei bekommen würde aber für den anfang is es einmal das wichtigste das etwas lauft (ohne fehler)

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #16 am: 30. April 2010, 08:58 »
Wenn du auch noch sagen würdest, was das Problem/die Fehlermeldung genau ist, könnte man vielleicht helfen...
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

MrPerfekt

  • Beiträge: 26
    • Profil anzeigen
Gespeichert
« Antwort #17 am: 30. April 2010, 23:00 »
Naja ich lade in virtual box mit meinem assembler programm das c programm.
Die binärdatei des c programms ist direct an die binärdatei des assembler programmes angehengt.
Das laden funktioniert da ich es bereits mit dem selbigen assembler programm stadt dem c programm probiert habe.
Nur kommt beim laden in virtual box ein schweerer systemfehler.
bitte kann mir jemand helfen
Danke

 

Einloggen