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. 😉


Anmelden zum Antworten