Problem beim schreiben in den Grafikspeicher
-
Hallo,
ich habe im RM in folgenden Grafikmodus gewechselt 640x480x8, bin dann in den PMODE gegangen und will nun in den Grafikspeicher schreiben, ich bin das auf zwei Wegen angegangen:1. mov [0A0000h], 0FFh 2. mov byte [0A0000h], 0FFh
NASM. Das Ganz wird auch erfolgreich assembliert, aber wenn ich dann boote erwarte ich ja einen weißen Punkt in der oberen linken Ecke, aber leider ist da keiner, auch mit anderen Werten wie z.B 0A0002h klappt das leider nicht.
Wäre über Tipps und Hilfen sehr dankbar
mfg
SeVo
-
Spontan fällt mir da ein, dass die Segmentbasisadresse des Segmentdeskriptors auf den ds zeigt, nicht als Basis 0 hat. Ist das bei dir der Fall?
btw. eigentlich sollte bei der ersten Methode ein Fehler kommen, da NASM nicht wissen kann welche Größe der zweite Operand hat.
-
hum, du könntest recht haben, wie setzt ich denn jetztds naträglich auf 0?
einfach:mov ds, 00h
oder bekomme ich dann Probleme (PC startet unerwartet neu oder ähnliches)
-
Nachträglich auf 0 setzen ist nicht wirklich ne gute Idee. Du solltest von Anfang an 0 als Basis für alle Deskriptoren in deiner GDT hernehmen, das macht das Programmieren bei weitem einfacher.
;Wenn dann, da es nur "mov sreg, reg16" gibt und kein "mov sreg, imm16" mov ax, 0x00 mov ds, ax
Aber ich glaube du hast da was beim Protected-Mode nicht ganz verstanden
In den Segmentregistern befindet sich nur der Segmentselektor und dieser zeigt auf den Segmentdeskriptor in der GDT. Du kannst nicht einfach hergehen und den Selektor auf 0 setzten (was ohnehin ein ungültiger Index in die GDT ist), sondern musst den Segmentdeskriptor in der GDT verändern. Wenn du deine GDT (oder den ges. Code bzw die relevaten Ausschnitte) postest, dann könnte man dir evtl. besser helfen
-
gdt start_gdt flat_code desc 0, 0xFFBFF, D_CODE+D_READ+D_BIG+D_BIG_LIM flat_data desc 0, 0xFFFFF, D_DATA+D_WRITE+D_BIG+D_BIG_LIM end_gdt D_LDT EQU 200h D_TASK EQU 500h D_TSS EQU 900h D_CALL EQU 0C00h D_INT EQU 0E00h D_TRAP EQU 0F00h D_DATA EQU 1000h D_CODE EQU 1800h D_DPL3 EQU 6000h D_DPL2 EQU 4000h D_DPL1 EQU 2000h D_PRESENT EQU 8000h D_NOT_PRESENT EQU 8000h D_ACC EQU 100h D_WRITE EQU 200h D_READ EQU 200h D_BUSY EQU 200h D_EXDOWN EQU 400h D_CONFORM EQU 400h D_BIG EQU 40h D_BIG_LIM EQU 80h
Ich hoffe, dass euch das ein wenig weiter hilft.
-
Mh, ich bin irgendwie verwundert: Eigentlich darf der erste Eintrag in der GDT nicht benutzt werden, aber so wies aussieht benutzt du den als Codedeskriptor. Könntest du auch noch das Makro "desc" posten? Und vllt. auch noch den Code nachdem du das PE bit im Cr0 setzt.
-
Das Macro:
%macro desc %ifid %00 %00 equ $-%$startoftable %endif GLOBAL ?fixD%%sl ?fixD%%sl: dd (%2) + ( ( (%3) ^ D_PRESENT ) << 16 ) , (%1) %endmacro
der Code nach dem PE:
in al, 0x64 test al, 2 jnz .5 mov al, 0xD1 out 0x64, al .6: in al, 0x64 and ax, byte 2 jnz .6 mov al, 0xDF out 0x60, al mov al, flat_data mov ds, ax mov es, ax dec cx mov CR0, ecx mov [boot], dl mov sp, 0x800 xor eax, eax mov ds, ax mov ss, ax mov es, sp mov al, [boot+BB_fats] mul byte [boot+BB_fat] add ax, [boot+BB_res] movzx edi,word [boot+BB_root] push di dec di shr di, 4 inc di call read_sectors lea ebp, [eax+edi] pop bx xor di, di .20: mov si, file_name xor ecx, ecx mov cl, 11 a32 rep cmpsb je found add cl, 21 add edi, ecx dec bx jnz .20 boot_error: disk_error: mov ax, 0xE07 int 10h jmp short $ found: push word [es:edi+0xF] mov di, [boot+BB_fat] mov ax, [boot+BB_res] call read_sectors mov bx, 0x4000 mov es, bx mov edi, 0x100000-0x40000 .10: xor eax, eax pop si mov bx, si cmp si, 0xFF8 jae eof rcr bx, 1 mov bx, [bx+si] jnc .11 shr bx, 4 .11: and bh, 0xF push bx push di mov al, [boot+BB_clu] mov di, ax dec si dec si mul esi add eax, ebp call read_sectors mov cx, di xchg ch, cl pop di es a32 rep movsw jmp short .10 eof: mov dx, 0x9C00 mov es, dx xor di, di mov dh, 4096/256 .10: mov cx, 1024 mov al, 7 .20: stosd add eax, edx int 8 loop .20 shr eax, 2 neg bl jns .10 cli mov eax, 0x9C007 stosd mov ax, (1024-3)*2 xchg ax, cx rep stosw mov ax, 0xD007 stosd mov ah, 0xE0 stosd mov al, 0 mov CR3, eax mov eax, CR0 or eax, 0x80000001 mov CR0, eax mov cl, flat_data push cx pop ds mov es, cx jmp dword 8:0xFF800000 read_sectors: push eax push di push es .10: push eax cdq movzx ebx, byte [boot+BB_sec] div ebx mov cx, dx sub bl, dl cmp di, bx ja .20 mov bx, di .20: mov esi, ebx inc cx xor dx, dx mov bl, [boot+BB_head] div ebx mov dh, dl mov dl, [boot] xchg ch, al shr ax, 2 or cl, al mov ax, si mov ah, 2 xor bx, bx push ax int 13h pop ax jnc .30 int 13h jc near disk_error .30: pop eax add eax, esi push si shl si, 5 mov bx, es add bx, si mov es, bx pop si sub di, si ja .10 pop es pop di pop eax xor si, si ret file_name db 'KERNEL BIN'
so und in der Kernel.bin versuche ich halt wie ganz oben beschrieben eine Pixel zu setzen. Textausgeben geht auch mit folgender Funktion, aber Pixel geht irgendwie net:
SEGMENT .data message db "SeVo Kernel 1.0",0 SEGMENT .text start: mov edi, 0xB8000 mov esi, message mov ah, 7 ;Text attribut .again: lodsb stosw test al, al jnz .again jmp short $ ;Hier anhalten
so jetzt hab ich ziemlich allen Code gepostet, außer der vor dem PE Bit, aber da passiert net viel, außer Auflösung ändern^^
-
Mh, ich seh grad, dass du Paging aktivierst. Hast du auch 0xA0000 korrekt gemapped?
-
Hi,
alles was ich gemacht habe habe ich auch gepostet, d.h. was da oben nicht im Code steht habe ich auch nicht gemacht, aber an welcher Stelle und vor allem wie müsste ich es denn mappen?EDIT:
hab auch mal dien nichtempfohlenen Tipp ausprobiert:mov ax, 0x00 mov ds, ax
Allerdings startet der Rechner dabei sofort neu.