OS hängt sich auf / Schmiert ab
-
Hi,
wir haben da ein kleines Problem bei den ersten PM schritten, wenn wir mehr als 2 Zeichen auf dem Bildschirm ausgeben schmiert das OS ab bzw. hängt sich auf:
Hier der code:
[BITS 16] org 0x7C00 ; Da in den Speicher ;-------------------------------------------------------------------------------------------------- ; M A I N F U N K T I O N ;-------------------------------------------------------------------------------------------------- START: mov [Bootdrv], dl ; Bootlaufwerk aus dl speichern. Wird von Bios dort abgelegt. call __LoadKernel ; Unseren Kernel laden. cli ; Keine Interrupts xor ax,ax ; 0 setzen mov ds,ax ; DS Register = 0 für LGDT lgdt [gdt_desc] ; GDT Laden mov eax, cr0 ; CR0 ---> eax or eax, 1 ; eax ---> 0 setzen ( so geht man in den PMode) mov cr0, eax ; eax ---> CR0 jmp 0x08:PMODE ; Springe zum Code Segment : Offset (PMODE) mit einem FAR jmp leert man die ganzen Register ; sonst würde es zu Fehler im PMode kommen. ; 1. PUTSTR ---> SI = String PUTSTR: mov ah, 0x0E ; Funktion 0x0E Zeichenausgabe. mov bx, 0x0007 ; Textfarbe MAINLOOP_PUTSTR: lodsb ; BYTE von SI ---> al laden. or al,al jz PUTSTR_ENDE ; Wenn BYTE = 0 ---> Ende INT 0x10 ; BIOS VIDEO INTERRUPT jmp MAINLOOP_PUTSTR ; Nächstes Zeichen PUTSTR_ENDE: retn ;-------------------------------------------------------------------------------------------------- ; 2. __LoadKernel ---> No Parameter __LoadKernel: push ds ; ds sichern. mov ax, 0 ; Funktion 0 (Diskette reseten) mov dl, [Bootdrv] int 0x13 ; BIOS Disketten/Festplatten Interrupt pop ds ; ds wiederherstellen. jc __LoadKernel ; Fehler? Nochmal! LOADL: mov ax, 0x0 ; ES:BX = 0000:1000 --> Pointer auf den Puffer fürs Disketten Laufwerk. mov es, ax mov bx, 0x1000 mov ah, 0x02 ; Funktion 2 (Diskette lesen). mov al, 1 ; Anz zu lesende Sektoren. mov cx, 0x0002 ; 0x00 Cylinder, 0x02 Sektoren mov dl, [Bootdrv] ; Diskettenlaufwerk mov dh, 0x00 ; 0x00 Head INT 0x13 ; Interrupt 0x13 BIOS Disketten/Festplatten Interrupt jc LOADL ; Fehler? Nochmal! mov si, StrLoading ; String "StrLoading" in SI call PUTSTR ; PUTSTR Funktion aufrufen. retn ;-------------------------------------------------------------------------------------------------- [BITS 32] PMODE: mov ax, 0x10 mov ds, ax ; Segmente an andere Adresse mov ss, ax mov esp, 0x090000 ; Stack anlegen. jmp 0x08:0x01000 ; Zum Kernel springen. ;-------------------------------------------------------------------------------------------------- gdt: ; Global Description Table (beschreibt Verhalten im Protected Mode) gdt_null: dd 0 ; 8 Bytes Quad-Word (Erstes Segment reserviert von Intel) dd 0 gdt_code: ; Unsere Globale Description Tabelle: (Code Segment) ; 1st Double word: ; Bits Function Description ; ---- -------- ----------- dw 0x0FFFF ; 0-15 Limit 0:15 First 16 bits in the segment limiter dw 0x0 ; 16-31 Base 0:15 First 16 bits in the base address ; 2nd Double word: ; Bits Function Description ; ---- -------- ----------- db 0x0 ; 0-7 Base 16:23 Bits 16-23 in the base address ; 8-12 Type Segment type and attributes db 10011010b ; 13-14 Privilege Level 0 = Highest privilege (OS), 3 = Lowest privilege (User applications) ; 15 Present flag Set to 1 if segment is present ; 16-19 Limit 16:19 Bits 16-19 in the segment limiter db 11001111b ; 20-22 Attributes Different attributes, depending on the segment type ; 23 Granularity Used together with the limiter, to determine the size of the segment db 0x0 ; 24-31 Base 24:31 The last 24-31 bits in the base address gdt_data: dw 0x0FFFF dw 0x0 db 0 db 10010010b ; Unterschiede (Daten Segment) db 11001111b db 0 gdt_end: gdt_desc: dw gdt_end - gdt - 1 dd gdt Bootdrv db 0 StrLoading db 'Loading NonameOS...',10,13,0 times 510-($-$$) db 0 dw 0xAA55 ;-------------------------------------------------------------------------------------------------- ; E O F ;------------------------------------------------------------------------------------------------------
void clrscr() { /* * */ const long size = 80*25; // VGA Konsole... long loop; // Zählervariable. // Algortihmus zum clearen des VRams for (loop=0; loop<size; loop++) { *vidmem++ = 0; *vidmem++ = 0x0F; } // Cursorposition = 0,0 out(0x3D4, 14); out(0x3D5, 0); out(0x3D4, 15); out(0x3D5, 0); } void putchar(unsigned char _character) { unsigned char *vidmem = (unsigned char *)0xB8000; // Zeiger auf den VRam unsigned short offset = 0; out(0x3D4, 14); offset = in (0x3D5) << 8; out(0x3D4, 15); offset |= in (0X3D5); vidmem += offset*2; *vidmem++ = _character; *vidmem = 0x0F; offset++; out(0x3D4, 15); out(0x3D5, offset); out(0x3D4, 14); out(0x3D5, offset >> 8); }
unsigned char in(unsigned short _port) { /* * Input an einem Hardware Port * %% = danach folgt ein Register * result = eax * edx = port */ unsigned char result; __asm__ ("in %%dx, %%al" : "=a" (result) : "d" (_port)); return result; } void out(unsigned short _port, unsigned char _data) { /* * Output von einem Hardware Port * %% = danach folgt ein Register * eax = _data * edx = _port */ __asm__ ("out %%al, %%dx" : :"a" (_data), "d" (_port)); }
und hier der kernel:
void main() { clrscr(); // Clear Screen Func putchar ('a'); putchar ('b'); putchar ('c'); putchar ('d'); for(;;); // Endless Loop }
-
Hi.
Naja, habe gerade nichts besseres vor, also
=>
Moegliche Probleme:
***Asm-Teil***
1. DS uninitialisiert bei Speicherzugriff in Zeile 10 (mov [mem], dl)
2. Aufruf von "__LoadKernel" in Zeile 12 => DS uninitialisiert bei Speicherzugriff in Zeile 48 (mov dl, [mem])
3. Aufruf von "__LoadKernel" in Zeile 12 => Aufruf von "PUTSTR" in Zeile 67 => DS uninitialisiert bei Speicherzugriff in Zeile 32
4. Falsche Groessenangabe fuer GDTR (1 zu klein)***C++-Teil***
1.*vidmem in clrscr uninitialisiert?So...
Vielleicht solltet ihr dann auch noch ES initialisieren - koennte sein,
dass das sonst Probleme gibt.
Ansonsten jagt das Teil doch mal durch Bochs,
und schaut nach, wo welcher Fehler auftritt.
Ich habe irgendwie keine Lust, euer Geschnippsel da auch noch zu
compilieren etc.