Autor Thema: Sprung in PMode geht nicht  (Gelesen 3900 mal)

thetrue

  • Beiträge: 216
    • Profil anzeigen
    • http://www.the-true.net
Gespeichert
« am: 18. July 2006, 22:47 »
moin, habe en problem,dass ich nicht lösen kann:

boot.asm:


org 0x7C00h ;Unsere Startadresse


;-----------------------------------------------------;
; Erst brauchen wir einen Stack    ;
;-----------------------------------------------------;
cli
mov ax, 0x9000   ;Stacksegment
mov ss, ax ;Stapelsegment
mov sp, 0 ;Stapelzeiger
sti

;-----------------------------------------------------;
; V A R I A B L E N        ;
;-----------------------------------------------------;
[bits 16]
bootdrv db 0 ;Das Bootlaufwerk
loadmsg db "loading trueOS-kernel v.0.1 ....",13,10,0  ;Die Load-Nachricht
sectors db 14 ;14 Sectors


;-----------------------------------------------------;
mov [bootdrv], dl ;Bootlaufwerk aus DL speichern
;-----------------------------------------------------;
call load ;Lade unseren Kernel
;-----------------------------------------------------;

;-----------------------------------------------------;
; Springe zu diesem Kernel    ;
;-----------------------------------------------------;

mov ax, 0x10000 ;Die Adresse des Programms
mov es, ax
mov ds, ax
push ax
mov ax, 0
push ax
retf

;-----------------------------------------------------;
; Einen String ausgeben        ;
;-----------------------------------------------------;
putstr:
lodsb ;Lade nächstes Zeichen nach AL ...
or al,al
jz short putstrd
mov ah,0x0E ;Die Function 0x0Eh
mov bx,0x0007
int 0x10 ;Den Interrupt 10h bitte
jmp putstr ;Nächste runde ...
putstrd:
retn

;-----------------------------------------------------;
; Lade den Kernel vom Bootlaufwerk          ;
;-----------------------------------------------------;
load:
push ds             ;Sichere DS
mov ax, 0x00           ;Die gewünschte Funktion (reset)
mov dl, [bootdrv]   ;Dieses Laufwerk ist gewünscht
int 0x13             ;Den Interrupt ausführen
pop ds             ;DS wiederherstellen
jc load             ;Geht nicht? -> Noch mal!

load1:
mov ax,0x10000 ;ES:BX = 10000 ...
mov es,ax ;...
mov bx, 0 ;...

;--------------------------------------;
; Sektoren lesen (Interrupt 13h, 2) ;
;--------------------------------------;

mov ah, 0x02       ;Funktion 2 (Lesen)
mov al, [sectors]       ;Lese n Sektoren
mov cx, 2       ;Cylinder=0, Sector=2
mov dx, 0       ;Head=0, Laufwerk=0
int 0x13         ;ES:BX =  Daten vom Laufwerk
jc load1         ;Fehler? Noch mal!

mov si,loadmsg ;Loadmsg nach SI
call putstr ;Nachricht ausgeben
retn             ;Ende!

times 512-($-$$)-2 db 0   ;die Datei soll 512 Bytes groß sein
dw 0AA55h                 ;Dieses Word muss am Ende stehen.


kernel.asm:


[Bits 16]
jmp start ;die Descriptors überschpringen

;-------------------------------------------------------;
; Descriptors ;
;-------------------------------------------------------;
NULL_Desc:
dd 0
dd 0

CODE_Desc:
dw 0xFFFF ;Segmentgröße Byte 0/1
dw 0 ;Segmentbasisadresse Byte 0/1
db 0 ;Segmentbasisadresse Byte 2
db 0x9A ;Zugriffsberechtigungen
db 0xCF ;Zusatz + Segmentgröße Bits 16 - 19
db 0 ;Segmentbasisadresse Byte 3


DATA_Desc:
dw 0xFFFF
dw 0
db 0
db 0x92
db 0xCF
db 0

gdt:
Limit dw 0 ;Größe der GDT (wird später eingetragen)
Base dd 0 ;Adresse der GDT (wird später eingetragen)

;-------------------------------------------------------;
; DER JUMP ETC ;
;-------------------------------------------------------;
start:
cli ;Keine Interrupts
mov eax, cs ;CS nach EAX
mov ds, ax ;AX nach DS

shl eax, 4 ;EAX um 4 Bits nach links verschieben
mov [CODE_Desc+2], ax ;Den ersten Teil der Linearen Adresse eintragen
mov [DATA_Desc+2], ax ;.....
shr eax, 16 ;EAY um 16 Bits nach rechts verschieben
mov [CODE_Desc+4], al ;Den zweiten Teil der Linearen Adresse eintragen
mov [DATA_Desc+4], al ;....

mov eax, cs ;EAX aktualisieren
shl eax, 4 ;Wieder um 4 Bits nach link verschieben
add eax, NULL_Desc ;Zu OFFSET von NULL_Desc adden
mov [Base], eax ;Die Segmentbasisadresse von EAX nach [Base]
mov [Limit], WORD gdt - NULL_Desc - 1 ;Die Größe

lgdt [gdt] ;Die GDT laden ...

;-------------------------;
; PMode einschalten      ;
;-------------------------;
mov eax, cr0 ;Das CR0 Register in EAX laden
or eax, 1 ;Das erste Bit (PE Bit) auf 1 setzen
mov eax, cr0 ;Das CR0 Register mit dem neuen Wert laden
;-------------------------;
; FAR-JUMP      ;
;-------------------------;
db 0xea ;Bitmuster für einen FAR JUMP
dw MAIN_F ;Angabe des Offsets zu dem gesprungen werden soll
dw 0x8 ;Selektor zu dem gesprungen werden soll

[Bits 32]
;-------------------------------------------------------;
; DIE MAIN FUNCTION ;
;-------------------------------------------------------;
MAIN_F:
mov WORD [CODE_Desc+2], 0 ;Code Segmentstartaddresse auf 0 setzen
mov WORD [DATA_Desc+2], 0 ;Daten Segmentstartadresse auf 0 setzen
mov BYTE [CODE_Desc+4], 0 ;Code Segmentstartaddresse auf 0 setzen
mov BYTE [DATA_Desc+4], 0 ;Daten Segmentstartadresse auf 0 setzen

mov eax, 2 ;Selektor für das Datensegment erstellen
shl eax, 3

mov ds, ax ;Daten- Stack- und Extrasegment mit
mov ss, ax ;Datensegmentdeskriptor laden
mov es, ax
mov eax, 0 ;FS und GS mit Null-Deskriptor laden
mov fs, ax
mov gs, ax
mov esp, 0x1FFFFF ;Stack auf unterhalb der 2 MB Grenze setzen

jmp 0x8:0x10000 + MAIN ;Sprung in das "neue" Codesegment

MAIN:
mov esi, 0
text:
;-----text ausgabe-----;
mov [0xB8000+esi], byte '*'
inc esi
mov [0xB8000+esi], byte 1Bh
inc esi
cmp esi, 3840
jl text
cli
hlt

times 512-($-$$) db 0;



das problem ist, es pasier nix ^^, aber eigentlich sollte ja * ausgegebenn werden ... viele male :D
thetrue way is my way

Jidder

  • Administrator
  • Beiträge: 1 625
    • Profil anzeigen
Gespeichert
« Antwort #1 am: 18. July 2006, 23:12 »
Zitat von: thetrue
...

mov ax, 0x10000                               ;Die Adresse des Programms

...

load1:
   mov ax,0x10000                            ;ES:BX = 10000 ...


Erstmal alle 0x10000 im 16 Bit Code durch 0x1000 ersetzen, denn du lädst da Segmentregister, die 16 Bit groß sind. Die lineare Adresse 0x10000 ergibt sich durch Segment * 16 + Offset = ES * 16 + BX = 0x1000 * 16 + 0 = 0x10000. Wenn das noch unklar ist, solltest du dir noch ein wenig über die Programmierung im Real Mode informieren.
Dieser Text wird unter jedem Beitrag angezeigt.

DarkThing

  • Beiträge: 652
    • Profil anzeigen
Gespeichert
« Antwort #2 am: 18. July 2006, 23:14 »
Hi,
ein Problem ist auf jeden Fall, dass du die Variablen im Bootsector da erstellst, wo sie auch ausgeführt werden. Du solltest den Variablen-Teil also ans Ende, direkt vor den times-Befehl verschieben.
Evtl. musst du dich auch noch um die Segment Register kümmern. Wobei das anscheinend nicht immer nötig ist.

thetrue

  • Beiträge: 216
    • Profil anzeigen
    • http://www.the-true.net
Gespeichert
« Antwort #3 am: 18. July 2006, 23:46 »
ok, nun kommt die nachricht ans licht, doch der kernel wird komischerweise nicht geladen ...
die Adresse ist nun 0x1000
und die Variablen vor dem Times ...
thetrue way is my way

thetrue

  • Beiträge: 216
    • Profil anzeigen
    • http://www.the-true.net
Gespeichert
« Antwort #4 am: 19. July 2006, 00:38 »
so, der BootLoader ladet den Kernel und führt ihn auch aus, jtzt liegt der Fehler beim Kernel ...
http://pastebin.de/9270
thetrue way is my way

bitmaster

  • Troll
  • Beiträge: 1 138
    • Profil anzeigen
    • OS-64 = 64 Bit Operating System
Gespeichert
« Antwort #5 am: 19. July 2006, 00:53 »
paar Fehler gefunden:

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


sollte doch wohl eher heißen:

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


Und noch was:

jmp 0x8:0x1000 + MAIN

sollte doch wohl eher heißen:

jmp 0x8:0x10000 + MAIN

bitmaster
In the Future everyone will need OS-64!!!

thetrue

  • Beiträge: 216
    • Profil anzeigen
    • http://www.the-true.net
Gespeichert
« Antwort #6 am: 19. July 2006, 00:55 »
danke

MfG thetrue
thetrue way is my way

 

Einloggen