boot-loader (8086 real-mode) ohne segmente?!?



  • Ich mache meine ersten Erfahrungen unter Linux/nasm und möchte einen
    Boot-Loader schreiben.
    Ich benutze das Format "bin" und habe die rechte Segment-Adresse (C700h)
    und erzeuge per BITS 16 8086-Code.

    Ich kenne eine BIOS-Funktion, mit der ich erfolgreich einzelne Buchstaben
    ausgeben kann.

    Ich versuchte eine eine printStr-Funktion zu schreiben, die als Argumente
    die Adresse des Strings und dessen Länge erwartet.
    Ich konnte den String anlegen mit db "bla.." und dessen Länge als Konstante
    speichern.

    Meine Bemühungen, die Funktion printstr zu schreiben scheiterten bislang.
    Bei diesen Bemehüngen versuchte ich mittels mov ah,[ds:pLabel+bx] irgendwie
    die richtige Adresse "zu treffen", aber hatte kein Glück.

    Wie macht man sowas richtig? 😕



  • Du adressierst also ins Nirvana und bekommst nur Mist ausgelesen?

    gorgoyle schrieb:

    ... und habe die rechte Segment-Adresse (C700h)...

    KA, was das genau bedeuten soll, aber wenn das kein Tippfehler ist, liegt es evtl. einfach daran: Das BIOS kopiert einen Bootloader AFAIR nach 7C00h.



  • Angenommen du hast wie folgt den Strig:

    string db "TEST", 0
    

    Dann liegt er an der Adresse ds:string
    maw:

    mov si, string
    mov al, [ds:si]
    ; al == 'T'
    

    fals du kein

    org 0x7c00
    

    hast:

    mov si, string+0x7C00
    mov al, [ds:si]
    ; al == 'T'
    


  • Danke für die Antworten. Kann den Fehler nicht mehr nachvollziehen. klappt aber jetzt. danke nochmals



  • Hier mal mein Bootloader, vllt hilft der dir weiter 😉

    ;### Bootloader ###
    [BITS 16]    
    org 0x7C00    ;Wir starten an der Adresse 0x7C00
    
    ;Segmentregister und Stack aufsetzen
    cli
    xor ax, ax
    mov ds, ax
    mov es, ax
    mov ax, 0x9000    ;Stacksegment
    mov ss, ax
    mov sp, 0
    sti
    
    mov [boot_drive], dl    ;Bootlaufwerk speichern
    
    ;Zur Startfunktionen springen
    jmp 0x0000:start
    
    ;Paar Variablen und Strings
    boot_drive       db 0
    boot_msg         db "tony's Bootloader v0.1.0", 13, 10, 0
    error_reset_msg  db "Couldn't reset bootdrive!", 13, 10, 0
    error_kernel_msg db "Couldn't load kernel!", 13, 10, 0
    
    ;--String aus SI ausgeben
    print:
        lodsb           ;Byte von SI nach AL laden und SI um eins erhöhen
        or al, al       ;Null?
        jz print_end    ;-> Ende!
    
        mov ah, 0x0E    ;BIOS-Funktion
        mov bx, 0x0007  ;Attribute... (grau-auf-schwarz)
        int 0x10        ;Print it, baby!
        jmp print       ;Nächstes Zeichen
    
        print_end:
        retn
    
    ;--PC neustarten
    reboot:
        jmp 0xFFFF:0x0000
    
    ;--Laufwerk aus DL zurücksetzen
    reset_drive
        mov ah, 0x00    ;Funktionsnummer
        int 0x13
        or ah, ah       ;<> 0?
        jnz reset_error ;-> Fehler!
        retn
    
        ;Da ging wohl was falsch... Fehler ausgeben und CPU anhalten
        reset_error:
        mov si, error_reset_msg
        call print
        cli
        hlt
    
    ;--Unseren Kernel laden
    load_kernel:
        mov dl, [boot_drive]
        call reset_drive ;Laufwerk zurücksetzen
    
        mov ax, 0x1000       ;Kernel wird nach 0x1000:0x0000 geladen
        mov es, ax
        mov bx, 0x00
    
        mov ah, 0x02    ;Funktionsnummer
        mov al, 0x05    ;Anzahl der zu lesenden Sektoren
        mov ch, 0x00    ;Zylinder
        mov cl, 0x02    ;Startsektor
        mov dh, 0x00    ;Kopf
    
        int 0x13
        or ah, ah
        jnz kernel_error
        retn
    
        kernel_error:
        mov si, error_kernel_msg
        call print
        cli
        hlt
    
    start:
        mov si, boot_msg
        call print
    
        call load_kernel
    
        mov ax, 0x1000 ;Startadresse laden
        mov es, ax     ;Segmentregister updaten
        mov ds, ax
    
        jmp 0x1000:0x0000
    
    times 512-($-$$)-2 db 0
    dw 0x55AA
    

Anmelden zum Antworten