Bootloader Problem



  • Hilfe mein Bootloader ladet den Kernel nicht

    [BITS 16]
    
    [ORG 0x7C00]
       mov ax, [label]
    label:
       dw 0
    
    [ORG 0x7C00]
    
    mov ah, 0Eh
    mov al, 'A'
    mov bh, 0Fh
    mov bl, 0
    int 10h
    
    hang:
    jmp hang
    
    times 510-($-$$) db 0
    dw 0AA55h
    

    Der Kernel

    mov ax, 1000h ; Segmentregister updaten
    mov ds, ax
    mov es, ax
    
    [BITS 16]				;16 Bit Code erstellen
    	jmp		start		;GDT überspringen
    
    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		10011010b	;Zugriffsberechtigungen
    	db		11001111b	;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)
    
    start:					
    
    	cli					;Interrupts ausschalten
    
    	mov		eax, cs		;EAX auf derzeitiges Codesegment setzen
    	mov		ds, ax		;DS auf Codesegment setzen
    
    	shl		eax, 4				;EAX mit 16 multiplizieren (Lineare Adresse 
    								;des Codesegments errechnen)
    	mov		[CODE_Desc+2], ax	;Lineare Adresse des Codesegmentes als 
    	mov		[DATA_Desc+2], ax	;Startadresse des Code- und Datendeskriptors
    	shr		eax, 16				;eintragen
    	mov		[CODE_Desc+4], al
    	mov		[DATA_Desc+4], al
    
    	mov		eax, cs				;Startadresse der GDT errechnen
    	shl		eax, 4
    	add		eax, NULL_Desc
    
    	mov		[Base], eax			;Startadresse der GDT eintragen
    	mov		[Limit], WORD gdt - NULL_Desc -1	;Größe der GDT errechnen und eintragen
    
    	lgdt	[gdt]				;GDT laden
    
    	mov		eax, cr0			;In den Protected Mode schalten,
    	or		eax, 1				;indem Bit 0 des CR0 Registers auf 1
    	mov		cr0, eax			;gesetzt wird
    
    	db		0xea				;FAR-JUMP zum Codesegment
    	dw		PMODE
    	dw		0x8
    
    [BITS 32]						;32 Bit Code erstellen
    
    PMODE:
    	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 + PMODE2	;Sprung in das "neue" Codesegment
    
    PMODE2:	
    	jmp		END						;Zum Ende Springen
    
    times 512-($-$$)	db	0;			;Da der Linker sich nicht mit ungeraden 
    									;Dateigrößen verträgt, wird diese Datei auf 512
    									;gepaddet.
    
    END:
    


  • Kannst du überhaupt Assembler oder ist das einfach nur zusammen kopiert von verschiedenen Quellen?

    Wozu zweimal [ORG 0x7C00]? Einmal reicht vollkommen.

    Ich würde erstmal dein erstes Label überspringen und zu dem Code nach dem zweiten ORG springen.

    Wie soll überhaupt der Kernel geladen werden? Du rufst ja gar keinen Interrupt zum Laden auf. Du rufst nur was zum Ausgeben auf.

    Dann schau dir nochmal das hang an 😃



  • So:

    org 0x7C00 
    
    start:
    
    cli             
    mov ax, 0x9000  
    mov ss, ax      
    mov sp, 0       
    sti             
    
    mov [bootdrv], dl
    
    call load
    
    ;Springe zum Kernel
    mov ax, 0x1000 
    mov es, ax     
    mov ds, ax
    push ax
    mov ax, 0
    push ax
    retf
    
    ; ----------------------------------------------
    ; Funktionen und Variablen
    ; ----------------------------------------------
    
    bootdrv db 0 ;Das Bootlaufwerk
    loadmsg db "Lade MF OS 0.4...",13,10,0
    
    ; Einen String ausgeben:
    putstr:
    lodsb             
    or al,al
    jz short putstrd  
    
    mov ah,0x0E       
    mov bx,0x0007     
    int 0x10          
    jmp putstr        
    putstrd:
    retn
    
    ; Lade den Kernel vom Bootlaufwerk
    load:
    
    ; Diskdrive reset (Interrupt 13h, 0)
    push ds      
    mov ax, 0          
    mov dl, [bootdrv]  
    int 13h            
    pop ds             
    jc load            
    
    ; Sektoren lesen (Interrupt 13h, 2)
    load1:
    mov ax,0x1000
    mov es,ax
    mov bx, 0
    mov ah, 2
    mov al, 5
    mov cx, 2
    mov dx, 0
    int 13h
    jc load1
    mov si,loadmsg 
    call putstr
    retn
    
    times 512-($-$$)-2 db 0   
    dw 0AA55h
    


  • Meinst du nicht, dass ein Thread reicht?
    (Rhetorische Frage, ich erwarte darauf keine Antwort!)
    Auch wenn es manchmal den Anschein haben mag: Das hier ist eigentlich kein Kindergarten, also unterlasse doch bitte solche Scherze, und poste zudem nur unter einem Namen.

    BTW: Es soll ja der Kommunikation idR. auch sehr zutraeglich sein, statt nur einen unuebersichtlichen, vor Fehlern nur so triefenden Brocken code hinzuklatschen, auch mal einige vollstaendige und informative Saetze in Deutscher Sprache geschickt anzubringen.


Anmelden zum Antworten