Autor Thema: PMode geht nicht  (Gelesen 13627 mal)

kotzkroete

  • Beiträge: 29
    • Profil anzeigen
Gespeichert
« Antwort #20 am: 18. May 2007, 15:39 »
Also ich stimme da bitmaster irgendwie zu, aber es ist ja auch erstmal egal.
Ich hab jetzt einen bootloader gefunden (und auch groesstenteils verstanden, ich muss mir trotzdem nochmal einen selbst bauen), aber der funktioniert noch nicht ganz. [bits 16]
[org 0x7C00]

jmp boot
;-------------Data
;-------------GDT Table
GDTR:
GDTsize DW GDT_END-GDT-1
GDTbase DD 0x500

GDT:
NULL_SEL         EQU $-GDT  ; null descriptor is required (64bit per entry)
      DD 0x0
      DD 0x0
CODESEL          EQU $-GDT  ; 4GB Flat Code at 0x0 with max 0xFFFFF limit
      DW     0xFFFF           ; Limit(2):0xFFFF
      DW     0x0              ; Base(3)
      DB     0x0              ; Base(2)
      DB     0x9A             ; Type: present,ring0,code,exec/read/accessed (10011000)
      DB     0xCF             ; Limit(1):0xF | Flags:4Kb inc,32bit (11001111)
      DB     0x0              ; Base(1)
DATASEL          EQU $-GDT  ; 4GB Flat Data at 0x0 with max 0xFFFFF limit
      DW     0xFFFF           ; Limit(2):0xFFFF
      DW     0x0              ; Base(3)
      DB     0x0              ; Base(2)
      DB     0x92             ; Type: present,ring0,data/stack,read/write (10010010)
      DB     0xCF             ; Limit(1):0xF | Flags:4Kb inc,32bit (11001111)
      DB     0x0              ; Base(1)
GDT_END:
;-------------GDT Table End
;-------------Variables
start_s DB 0                  ; starting sector    [0x1-0x12]
total   DB 0                  ; number of sector   [max 2880]
track   DB 0                  ; track number       [max 160]
head    DB 0                  ; head number        [max 2]
drive   DB 0                  ; boot drive number  [usually 0]
bseg    DB 0                  ; memory address segment
boff    DW 0                  ; and offset to load into
loadmsg db "bootsector loaded",13,10,0
;-------------Variables End
;-------------Functions
print: ; print string
lodsb ; load character
or al, al ; check if 0
jz short print_e
mov ah, 0x0e ; print
mov bx, 0x0007
int 0x10
jmp print ; next char
print_e:
ret

wkc:
xor al, al ; set al to 0
in al, 0x64 ; get kbd status through input port 0x64
test al, 2 ; check if second bit is clear
jnz  wkc
ret

wkf:
xor cx, cx
in al, 0x64 ; get kbd status
test al, 1 ; check if first bit is clear
jz wkf
ret

halt: ; halt on error
mov byte [gs:0], al
mov byte [gs:1], 0x04
cli
hlt
;-------------Funtions End
;-------------Data End

boot:
mov [drive], dl
cli                  ; no interrupts
mov ax, cs      
mov ds, ax   
mov es, ax
mov fs, ax
mov ax, 0x1d0 ; stack address
mov ss, ax        ; align stack   
mov sp, 0x200        ; 512 byte stack

mov ax,0xb800           ; setup video segment
mov gs,ax
sti                  ; enable interrupts

jmp init

init:
; enable a20
cli

call wkc ; wait for kbd buffer to clear
mov al, 0xd1 ; write 0xd1
out 0x64, al ; to status
call wkc
mov al, 0xdf ; set settings in kdb (to enable a20)
out 0x60, al ; send the value
call wkc

mov cx, 0x10
kbdwait:
xor ax, ax ; do something
out 0xe0, ax ; more useless stuff
loop kbdwait

; is a20 enabled?
mov al, 0xd0
out 0x64, al
call wkf
in al, 0x60
test al, 2
jnz a20on
mov al, 'A'
call halt
a20on:
sti

; load kernel.bin from floppy at to 0x100000
read:
xor ax, ax ; Floppt reset BIOS function
mov dl, [drive] ; select floppy that was booted from
int 0x13
jc read

mov ax, 0xffff
mov es, ax ; data buffer for file
mov bx, 0x10 ; start of segment
mov ah, 2 ; BIOS function
mov al, 17 ; number of sector to read
mov ch, 1 ; track
mov cl, 1 ; sector
mov dh, 1 ; head
int 0x13 ; call BIOS read dist function

mov dx, 0x3f2 ; stop the motor
mov al, 0x0c ; from spinning
out dx, al

; move GDT to 0x500
xor ax, ax
mov ds, ax
mov es, ax
mov si, GDT ; Move from [ds:si]
mov di, [GDTbase] ; Move to [es:di]
mov cx, [GDTsize] ; size of GDT
cld ; clear the direction flag
rep movsb ; move it

; enter pmode
cli
mov eax, cr0
or al, 1
mov cr0, eax

; load gdt
lgdt[GDTR]

; clear cs/ip/eip
jmp CODESEL:FLUSH

[BITS 32]
FLUSH:
; refresh all segment registers
mov eax, DATASEL
mov ds, eax
mov es, eax
mov fs, eax
mov gs, eax
mov ss, eax
mov esp, 0xffff

mov eax, 0xb8000
mov byte [eax], 'b'
inc eax
mov byte [eax], 7

;jmp $
jmp CODESEL:0x100000

; stop here
;hlt


times 512-($-$$)-2 db 0
dw 0x0AA55

So sieht er aus.
Fast am Ende gebe ich 'b' aus. Aber wie springe ich jetzt in den Kernel? Der ist also genau nach dem bootsector.
Wenn mir das jetzt noch jemand sagt, hab ich endlich wieder ein Erfolgserlebnis und ich kann weitermachen.

Edit: Also ich hab irgendwie noch ein bisschen rumgespielt...es geht jetzt...Jetzt faengt die Arbeit an.
« Letzte Änderung: 18. May 2007, 16:19 von kotzkroete »

kotzkroete

  • Beiträge: 29
    • Profil anzeigen
Gespeichert
« Antwort #21 am: 18. May 2007, 23:13 »
Argh....sobald ich den Bootloader aufm echten Computer ausfuehre, schreibt er in die obere linke ecke ein rotes A. Wenn ich mal sich den quellcode anguckt, findet man das an der Stelle, wo a20 enabled werden soll. Ist das wirklich dieses A? Und warum gunktionierts unter qemu problemlos?

MNemo

  • Beiträge: 547
    • Profil anzeigen
Gespeichert
« Antwort #22 am: 18. May 2007, 23:52 »
zum enablen vom a20-gate gibt es tausende möglichkeiten und kein funktioniert wirklich auf jedem pc, deshalb rate ich dir mehrer methoden in deinen bootloader einzubauen und die dann da reinach aus zu probieren bis es geht.

weiß leider grad nicht genau wie das ging aber es geht
mit
BIOS-Int(noch bist du ja im RM und kanst die benutzen)
und Auf mehrer arten mit dem KBC
„Wichtig ist nicht, besser zu sein als alle anderen. Wichtig ist, besser zu sein als du gestern warst!“

kotzkroete

  • Beiträge: 29
    • Profil anzeigen
Gespeichert
« Antwort #23 am: 19. May 2007, 08:02 »
Aha...na ich hab noch ein paar andere bootloader....mal sehen, wie die das geloest haben. Danke....

Edit: Hab einfach mal das call halt rausgenommenl...jetzt gehts zwar, aber ob der a20 an is? Ich bin mir nicht sicher. Ich glaube, der ist an, aber code zur ueberfruefung stimmt nicht ganz.
« Letzte Änderung: 19. May 2007, 08:18 von kotzkroete »

Korona

  • Beiträge: 94
    • Profil anzeigen
Gespeichert
« Antwort #24 am: 19. May 2007, 12:18 »
AFAIK funktioniert die Methode über den Keyboard Controller auf jedem PC.

kotzkroete

  • Beiträge: 29
    • Profil anzeigen
Gespeichert
« Antwort #25 am: 19. May 2007, 13:51 »
Ja...vermutlich geht die ueberpruefung nur nicht....naja....ich hab jetzt mein naechsted Problem:
undzwar will ich strings ausgeben. Das wuerde ich so machen: string deklarieren, zeichen fuer zeichen ausgeben. Aber das geht nicht.
mov al, [hello]
muesste eigentlich das erste Zeichen aus dem string speichern, oder?
Macht es aber nicht. Nichts wird augegeben.
hello db "hello, world\n", 0
damit deklariere ich den string. Aber wieso wird er nicht ausgegben?
Wenn ich ein Zeichen "einfach so" nach al schreibe und die Funktion aufrufe, wird es perfekt ausgegeben. Aber wieso nicht eins aus einem String?

Svenska

  • Beiträge: 1 792
    • Profil anzeigen
Gespeichert
« Antwort #26 am: 22. May 2007, 13:18 »
Probiere mal [hello+1]. Da hello eine konstante Adresse hat, müsste es klappen. Ansonsten halt ein INC AL einfügen.
Um einen String auszugeben, musst du dann natürlich in einer Schleife zeichenweise ausgeben; eine Stringausgabefunktion gibt es nicht.

Auch, wenn es dir vielleicht nicht gefällt oder anstößig erscheint... ich habe vor kurzem den Sourcecode von DOS 3.3 gefunden. Der ist vollständig in Assembler (MASM-Syntax) und sehr ausführlich kommentiert. Dafür läuft es ausschließlich im Real Mode. Vielleicht fängst du damit an.

Gruß,
Svenska

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #27 am: 22. May 2007, 15:43 »
Und wie genau hilft der DOS-Source mit dem Protected Mode? Mal abgesehen davon, daß es meines Wissens nicht nur anstößig, sondern auch illegal ist...
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

Svenska

  • Beiträge: 1 792
    • Profil anzeigen
Gespeichert
« Antwort #28 am: 25. May 2007, 14:06 »
Mit dem PM direkt nicht. Eher mit dem Grundverständnis.

Und das es gegen das (c) von MS verstößt, weiß ich selber... ich behaupte aber, dass es einfacher ist, diesen Code zu verstehen als den Code von Linux 0.02. Aber das muss jeder mit sich selbst ausmachen, was ihm wichtiger ist. Es ist ein Vorschlag gewesen.

 

Einloggen