Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

  1. #1
    Futur Membre du Club Avatar de Folaefolc
    Homme Profil pro
    Étudiant
    Inscrit en
    mai 2018
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : mai 2018
    Messages : 4
    Points : 7
    Points
    7

    Par défaut Lire plusieurs secteurs d'un floppy et les placer côte à côte en RAM

    Bonjour à tous

    J'essaye de charger depuis un floppy disk 32 secteurs de 512 octets chacun, et je connais uniquement le LBA.
    Pour me faciliter la tâche j'ai voulu coder une fonction qui prendrait en paramètre le LBA, la taille et l'androit en RAM où je veux charger les secteurs (plus précisément c'est un Kernel).
    Hélas, la fonction charge bien les secteurs (mais seulement 25 après vérification, et non pas les 32 souhaités) mais au moment du saut à l'emplacement choisi, le système plante et j'ai une exception 0x5 (out of bound). Je pense que j'ai raté la modification de la destination des secteurs chargés (es:bx) mais je ne comprends ni comment ni pourquoi cela a pu être possible.

    Si quelqu'un veut bine m'aider à trouver le problème je lui en serais reconnaissant c:

    filesystem.asm
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
     
    %ifndef filesystem_asm
    %define filesystem_asm
     
    bits 16
     
    ; Macro to read file more easily
    ; INPUT  : AX (LBA number for sector), BX (linear address, where it will be loaded), CX (sectors count)
    ; OUTPUT : CF if an error happen while to find it, ES:BX (where it's loaded)
    %macro load_file 3
        mov ax, %1
        mov bx, %2
        mov cx, %3
        call proj_e_read_file
    %endmacro
     
    ; parameters
    sectors_per_track dw  18
    heads_per_track   dw   2
    bytes_per_sector  dw 512
    drive_number      dw   0
    msg_error_reading_floppy db '[!] Error while reading floppy', 13, 10, 0
    ; variables
    abs_sector        dw   0
    abs_head          dw   0
    abs_track         dw   0
    lba_number        dw   0
    file_size         dw   0
    destination       dw   0
     
    ; Routine to convert a LBA (Logical Block Addresing) to CHS (Cylinder/Head/Sector)
    ; INPUT  : AX (LBA addr), sectors_per_track, heads_per_track
    ; OUTPUT : abs_sector (CHS sector addr), abs_head (CHS head addr), abs_track (CHS track addr)
    proj_e_lbachs:
        xor dx, dx
        div word [sectors_per_track]
        inc dl
        mov byte [abs_sector], dl
     
        xor dx, dx
        div word [heads_per_track]
        mov byte [abs_head], dl
        mov byte [abs_track], al
     
        ret
     
    ; Routine to read files into memory more easily
    ; INPUT  : AX (LBA number for sector), BX (linear address, where it will be loaded), CX (sectors count)
    ; OUTPUT : CF if an error happen while to find it, ES:BX (where it's loaded)
    proj_e_read_file:
    .begin:
        ; save destination
        mov word [destination], bx
     
        ; sectors count starts from 1
        mov word [lba_number], ax
        inc word [lba_number]
    .main:
        mov di, 0x0005  ; retry count
    .loop:
        ; get track, sector, and head
        mov ax, word [lba_number]
        call proj_e_lbachs
     
        ; move forward to avoid overwriting
        push word [destination]
        pop es
        xor bx, bx
     
        ; save counter (for loop)
        push cx
     
        ; read floppy
        mov ah, 0x02
        mov al, 0x01
        mov ch, byte [abs_track]
        mov cl, byte [abs_sector]
        mov dh, byte [abs_head]
        mov dl, byte [drive_number]
        int 0x13
     
        ; restore counter
        pop cx
     
        ; if no error, go to next sector
        jnc .sectordone
     
        ; otherwise reset disk
        xor ax, ax
        int 0x13
        ; decrement number of trials left
        dec di
     
        ; retry
        jnz .loop
        ; we got an error, impossible to read.
        jmp .error
    .sectordone:
        ; move forward
        mov ax, word [destination]
        add ax, 0x10  ;word [bytes_per_sector]
        mov word [destination], ax
     
        ; increment LBA
        inc word [lba_number]
     
        ; decrement ecx, go to label while non-zero
        loop .main
        jmp .quit
    .error:
        ; set carry flag
        stc
        ; optionnal but well it's handy
        print msg_error_reading_floppy
        ; cleaning up things
        jmp .end
    .quit:
        ; if we "quit" it means there were no errors, so clear the carry flag
        clc
    .end:
        ret
     
    %endif
    boot.asm
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
     
    bits 16
    org 0x7c00
     
    start:
        jmp main
     
    %include "std/stdio.asm"
    %include "std/filesystem.asm"
     
    data:
        ; strings
        new_line db 13, 10, 0
        title    db 'Project E', 13, 10, '=========', 13, 10, 13, 10, 0
        message  db '[Bootloader] Press any key to load kernel', 0
        msg_kernel_loaded   db '[Bootloader] Kernel loaded', 13, 10, 0
        msg_kernel_load_err db '[!] [Bootloader] Could not load kernel', 13, 10, 0
     
        ; parameters
        KERNEL_BLOCK_START equ      1
        KERNEL_BLOCKS_SIZE equ     32  ; 32*512B=16384B
        KERNEL_SEGMENT     equ 0x0100  ; 0x0100:0x0000=0x1000
     
    main:
        cli
        xor ax, ax
        mov ds, ax
        mov es, ax
     
        ; init the stack
        mov ss, ax
        mov sp, 0x7c00
        sti
     
        ; display message on startup
        print title
        print message
        call proj_e_waitkeypress16
        print new_line
     
        ; prepare to load the kernel
        load_file KERNEL_BLOCK_START, KERNEL_SEGMENT, KERNEL_BLOCKS_SIZE
        jnc .jump_to_kernel              ; loading success, no error in carry flag
     
    .kernel_loading_error:
        print msg_kernel_load_err
        cli
        hlt
     
    .jump_to_kernel:
        print msg_kernel_loaded
        call KERNEL_SEGMENT:0x0000
     
    ; pad to 510 bytes (boot sector - 2)
    times 510-($-$$) db 0
    ; standard boot signature
    dw 0xAA55
    PS: je n'ai pas trouvé comment modifier la coloration syntaxique, si jamais c'est gênant faites le moi savoir

  2. #2
    Membre confirmé Avatar de bifur
    passe le balais et l'aspirateur
    Inscrit en
    mars 2008
    Messages
    277
    Détails du profil
    Informations personnelles :
    Âge : 33

    Informations professionnelles :
    Activité : passe le balais et l'aspirateur

    Informations forums :
    Inscription : mars 2008
    Messages : 277
    Points : 464
    Points
    464

    Par défaut

    pourquoi dans boot.asm la fonction s'appelle "load_file" et dans filesystem.asm elle s'appelle proj_e_read_file?


    a mon avis un des problèmes viendrait de la:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
        mov ax, word [destination]
        add ax, 0x10  ;word [bytes_per_sector]
        mov word [destination], ax
    si j'ai bien comprit tu incrémente le segment de la mémoire de 16, ce qui fait avance l'adresse de 16*16=256 octet sauf que les secteur de la disquette font 512 octet! ce qui fait que le code recopié a été écrasé par le contenue du secteur suivant (et évite de travailler les adresse sur segment ça n'est pas une bonne habitude)

    a mon avis pour remplacer ces ligne fait:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
        add word[destination],20h

    pour le problème des 25 secteurs copié a la place de 32 je pense que ça peut venir de l'appel de la fonction car "load_file KERNEL_BLOCK_START, KERNEL_SEGMENT, KERNEL_BLOCKS_SIZE" doit peut être empiler les argument (comme c'est fait habituellement en C) au lieu de les mettre dans les registre

  3. #3
    Futur Membre du Club Avatar de Folaefolc
    Homme Profil pro
    Étudiant
    Inscrit en
    mai 2018
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : mai 2018
    Messages : 4
    Points : 7
    Points
    7

    Par défaut

    Oh c'est juste une macro load_file, parce que j'avais un peu "la flemme" de mettre dans les bons registres les différents paramètres, elle permet d'appeler proj_e_read_file.

    Oh bien vu pour l'incrémentation ! De tête j'avais effectivement divisé 256 et par 512 :c Merci beaucoup, quel idiot je suis.

    Pour le coup du
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    add word [destination], 20h
    je crois juste que j'avais oublié qu'on pouvait le faire comme ça c:

    En ayant fait ce correctif, les 32 secteurs sont maintenant lus, mais toujours le même problème, j'ai une exception 0x5 :/
    En tout cas merci pour ton aide, un problème (que je n'avais même pas vu ) de résolu, c'est déjà ça !

    PS: le nouveau code donne donc ceci pour ceux qui se demandent

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
     
    %ifndef filesystem_asm
    %define filesystem_asm
     
    bits 16
     
    ; Macro to read file more easily
    ; INPUT  : AX (LBA number for sector), BX (linear address, where it will be loaded), CX (sectors count)
    ; OUTPUT : CF if an error happen while to find it, ES:BX (where it's loaded)
    %macro load_file 3
        mov ax, %1
        mov bx, %2
        mov cx, %3
        call proj_e_read_file
    %endmacro
     
    ; parameters
    sectors_per_track dw  18
    heads_per_track   dw   2
    bytes_per_sector  dw 512
    drive_number      dw   0
    msg_error_reading_floppy db '[!] Error while reading floppy', 13, 10, 0
    ; variables
    abs_sector        dw   0
    abs_head          dw   0
    abs_track         dw   0
    lba_number        dw   0
    file_size         dw   0
    destination       dw   0
     
    ; Routine to convert a LBA (Logical Block Addresing) to CHS (Cylinder/Head/Sector)
    ; INPUT  : AX (LBA addr), sectors_per_track, heads_per_track
    ; OUTPUT : abs_sector (CHS sector addr), abs_head (CHS head addr), abs_track (CHS track addr)
    proj_e_lbachs:
        xor dx, dx
        div word [sectors_per_track]
        inc dl
        mov byte [abs_sector], dl
     
        xor dx, dx
        div word [heads_per_track]
        mov byte [abs_head], dl
        mov byte [abs_track], al
     
        ret
     
    ; Routine to read files into memory more easily
    ; INPUT  : AX (LBA number for sector), BX (linear address, where it will be loaded), CX (sectors count)
    ; OUTPUT : CF if an error happen while to find it, ES:BX (where it's loaded)
    proj_e_read_file:
    .begin:
        ; save destination
        mov word [destination], bx
     
        ; sectors count starts from 1
        mov word [lba_number], ax
        inc word [lba_number]
    .main:
        mov di, 0x0005  ; retry count
    .loop:
        ; get track, sector, and head
        mov ax, word [lba_number]
        call proj_e_lbachs
     
        ; move forward to avoid overwriting
        push word [destination]
        pop es
        xor bx, bx
     
        ; save counter (for loop)
        push cx
     
        ; read floppy
        mov ah, 0x02
        mov al, 0x01
        mov ch, byte [abs_track]
        mov cl, byte [abs_sector]
        mov dh, byte [abs_head]
        mov dl, byte [drive_number]
        int 0x13
     
        ; restore counter
        pop cx
     
        ; if no error, go to next sector
        jnc .sectordone
     
        ; otherwise reset disk
        xor ax, ax
        int 0x13
        ; decrement number of trials left
        dec di
     
        ; retry
        jnz .loop
        ; we got an error, impossible to read.
        jmp .error
    .sectordone:
        ; move forward
        add word [destination], 0x20
        ; increment LBA
        inc word [lba_number]
        ; decrement ecx, go to label while non-zero
        loop .main
        jmp .quit
    .error:
        ; set carry flag
        stc
        ; optionnal but well it's handy
        print msg_error_reading_floppy
        ; cleaning up things
        jmp .end
    .quit:
        ; if we "quit" it means there were no errors, so clear the carry flag
        clc
    .end:
        ret
     
    %endif

  4. #4
    Membre confirmé Avatar de bifur
    passe le balais et l'aspirateur
    Inscrit en
    mars 2008
    Messages
    277
    Détails du profil
    Informations personnelles :
    Âge : 33

    Informations professionnelles :
    Activité : passe le balais et l'aspirateur

    Informations forums :
    Inscription : mars 2008
    Messages : 277
    Points : 464
    Points
    464

    Par défaut

    si l'exception est généré après le saut vers le code qui vient d'être chargé, c'est peut être que le code qui pose problème et plus le loader. il faudrait a la limite nous montrer ce qui est chargé après

    je me souviens qu'as mes début j'avait un code simple qui écrivait simplement une lettre a l'écran pour valider le passage a certaine étape de mon programme et/ou vérifier que les données avait été bien chargé:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    push ax
    push ds
    mov ax,0B800h ;le segment de l'écran video texte
    mov ds,ax
    mov byte[0],"A" ;0=en haut a gauche
    mov byte[1],07h ;code couleur de la lettre (7=gris clair)
    pop ds
    pop ax
    il ne reste plus qu'a rajouter ce petit bout de code (en changeant la lettre) a différente étape de ton programme pour valider le passage de certaine étape

  5. #5
    Futur Membre du Club Avatar de Folaefolc
    Homme Profil pro
    Étudiant
    Inscrit en
    mai 2018
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : mai 2018
    Messages : 4
    Points : 7
    Points
    7

    Par défaut

    Ah pas bête je vais essayer de faire ça

    Actuellement, le bootloader charge ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
     
    bits 16
    org 0
     
    start:
        jmp main
     
    %include "std/stdio.asm"
    %include "std/string.asm"
    %include "std/video.asm"
    %include "std/filesystem.asm"
     
    data:
        msg_info db 'Project E is developped by SuperFola', 13, 10, 0
        ret_line db 13, 10, 0
        msg_app_load_ok  db '[Kernel] App loaded', 13, 10, 0
        msg_app_load_err db '[!] [Kernel] Could not load app', 13, 10, 0
     
        buffer times 72 db 0
        flag_gdt_installed db 0
     
        shell_cursor       db 'kernel> ',     0
        shell_command_help db 'help',   0
        shell_action_help  db 'help reboot info test', 13, 10, 0
        shell_command_rbt  db 'reboot', 0
        shell_command_info db 'info',   0
        shell_command_test db 'test',   0
     
        shell_error_wrong_command db 'Unknown command', 13, 10, 0
     
        APP_BLOCK_START equ     33
        APP_BLOCKS_SIZE equ      8  ; 8*512B=4096B
        APP_SEGMENT     equ 0x07e0  ; 0x07e0:0x0000=0x8000
     
    main:
        mov ax, cs
        mov ds, ax
     
    shell_begin:
        print ret_line
        print shell_cursor            ; print cursor
     
        ; ask for user input
        input buffer, 72
     
        ; to be able to do the comparisons tests
        mov si, buffer
     
        ; checks if user typed help command
        mov di, shell_command_help
        call proj_e_compare_string16
        jc .command_help
     
        ; check if user typed reboot command
        mov di, shell_command_rbt
        call proj_e_compare_string16
        jc .command_rbt
     
        ; check if user typed info command
        mov di, shell_command_info
        call proj_e_compare_string16
        jc .command_info
     
        mov di, shell_command_test
        call proj_e_compare_string16
        jc .command_test
     
    ; wrong user input (command not recognized)
    .wrong_input_error:
        print shell_error_wrong_command
        jmp shell_begin
     
    ; command help (shell_command_help) selected
    .command_help:
        print shell_action_help
        jmp shell_begin
     
    ; command reboot (shell_command_rbt) selected
    ; this specific subroutine must be placed at the very end to avoid rebooting for nothing
    .command_rbt:
        call proj_e_reboot16
     
    ; command info (shell_command_info) selected
    .command_info:
        print msg_info
        jmp shell_begin
     
    ; command command_test
    .command_test:
        mov ah, CREATE_COLOUR(CHAR_ATTR_CYAN, CHAR_ATTR_RED)  ; cyan on red background
        call proj_e_clear_screen16
        ; move cursor in x=0,y=0
        move_cursor 0x0000
     
        ; prepare to load app
        load_file APP_BLOCK_START, APP_SEGMENT, APP_BLOCKS_SIZE
        jnc .jump_to_app                 ; loading success, no error in carry flag
     
    .app_loading_error:
        print msg_app_load_err
        jmp shell_begin
     
    .jump_to_app:
        print msg_app_load_ok
        jmp APP_SEGMENT:0x0000
     
    ; 16kB kernel
    times 16384-($-$$) db 0
    Mais comme ni le new_line ni le shell_cursor ne sont affichés, j'en déduis qu'il n'arrive pas à sauter sur mon kernel. Et le dernier message affiché (juste avant le call KERNEL_SEGMENT:0x0000) est '[Bootloadr] Kernel loaded', ça veut dire que c'est le call qui ne marche pas (enfin pas comme voulu).

    Le truc c'est qu'avant, ça marchait très bien, j'arrivais à charger mon kernel en faisant comme dans ce fichier : https://github.com/SuperFola/project...f4f9f/boot.asm (c'est le repo github du projet). Mais évidemment ca ne me plait pas trop, parce que je suis très limité sur ce que je peux charger en utilisant cette méthode, c'est pour ça que j'ai fait cette fonction.

  6. #6
    Futur Membre du Club Avatar de Folaefolc
    Homme Profil pro
    Étudiant
    Inscrit en
    mai 2018
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : mai 2018
    Messages : 4
    Points : 7
    Points
    7

    Par défaut Solution trouvé, une bête erreur...

    Bonjour !

    Je poste ici car ça pourrait intéresser d'autres personnes quand même, et je m'excuse du double post d'avance.

    J'ai trouvé le "bogue", cela venait juste du fait que j'incrémentais AX avant de le donner à proj_e_lbchs (les secteurs sont comptés à partir de 1 mais le LBA commence à 0 lui !).

    Tout bête en fait, j'ai du mal à croire que ça marche, c'est super c:

    Merci beaucoup pour ton aide !

  7. #7
    Membre confirmé Avatar de bifur
    passe le balais et l'aspirateur
    Inscrit en
    mars 2008
    Messages
    277
    Détails du profil
    Informations personnelles :
    Âge : 33

    Informations professionnelles :
    Activité : passe le balais et l'aspirateur

    Informations forums :
    Inscription : mars 2008
    Messages : 277
    Points : 464
    Points
    464

    Par défaut

    mais de rien!
    et bon courage pour la suite

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 2
    Dernier message: 13/09/2014, 23h28
  2. [GRAPH] Comment présenter les sous-groupes côte à côte et pas l'un au-dessus de l'autre ?
    Par Françoise_ dans le forum ODS et reporting
    Réponses: 4
    Dernier message: 14/03/2014, 16h05
  3. Réponses: 12
    Dernier message: 18/06/2006, 20h42
  4. Réponses: 5
    Dernier message: 05/01/2006, 19h43

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo