IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
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

Programmation d'OS Assembleur Discussion :

Création d'un mini boot loader


Sujet :

Programmation d'OS Assembleur

  1. #1
    Membre du Club

    Inscrit en
    Décembre 2008
    Messages
    100
    Détails du profil
    Informations forums :
    Inscription : Décembre 2008
    Messages : 100
    Points : 43
    Points
    43
    Par défaut Création d'un mini boot loader
    Bonjour tout le monde!!!

    Alors voila je fais appel à vous pour m'aider dans la création d'un mini boot loader (il me servirai à l'illustration d'un exposé ).
    J'aurais juste voulu savoir quelles sont les lignes à suivre, car j'ai bien compris le principe mais j'ai du mal à voir ce que doit contenir le code en assembleur qui se trouve dans le MBR du disque.

    Doit-t-il simplement proposer les noyaux disponibles et charger, ou y a-t-il plus d'opérations à effectuer??

    Merci d'avance pour vos réponses

  2. #2
    Futur Membre du Club
    Profil pro
    Inscrit en
    Mai 2008
    Messages
    8
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2008
    Messages : 8
    Points : 8
    Points
    8
    Par défaut
    Salut,

    Un mini bootloader doit :
    - Initialiser les segments (ds, es, ss et sp au minimum)
    - Récupérer le numéro de l'unité de boot
    - Permettre ou non de choisir un kernel
    - Copier le kernel en mémoire à partir des secteurs de la disquette
    - Passer ou non en mode protégé
    - Booter sur le kernel.

    Pour ce qui est des messages à l'écran et du clavier, tu peux le réaliser avec les interruptions du BIOS en étant en mode réel.
    Voilà, j'espère t'avoir éclairé
    A+

  3. #3
    Membre du Club

    Inscrit en
    Décembre 2008
    Messages
    100
    Détails du profil
    Informations forums :
    Inscription : Décembre 2008
    Messages : 100
    Points : 43
    Points
    43
    Par défaut
    Merci de ta réponse!

    Je vais un petit peu abuser en te demandant si tu peut m'expliquer n peu plus précisement ces étapes, (je suis en train de me former à l'assembleur), par exemple, que signifie initialiser les segments?

    Merci d'avance

  4. #4
    Membre habitué
    Profil pro
    Inscrit en
    Mai 2008
    Messages
    145
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mai 2008
    Messages : 145
    Points : 170
    Points
    170
    Par défaut
    As-tu consulté les excellents tutoriels de la section "assembleur" ?

  5. #5
    Candidat au Club
    Profil pro
    Inscrit en
    Janvier 2009
    Messages
    3
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2009
    Messages : 3
    Points : 3
    Points
    3
    Par défaut
    Bonsoir,

    Tout dépend de ce que tu veux faire ? Sur quel support ? En quel mode et sur quel processeur ?

    nico

  6. #6
    Membre du Club

    Inscrit en
    Décembre 2008
    Messages
    100
    Détails du profil
    Informations forums :
    Inscription : Décembre 2008
    Messages : 100
    Points : 43
    Points
    43
    Par défaut
    Je suis en train de consulter les tutoriels et c'est vrai qu'ils sont bien faits.

    Pour ce qui est du boot loader, je voudrais le faire pour du x86, un peu à la manière de GRUB (multi OS) mais en beaucoup plus simple car c'est pour le moment uniquement pour illustrer un exposé.

  7. #7
    Membre du Club

    Inscrit en
    Décembre 2008
    Messages
    100
    Détails du profil
    Informations forums :
    Inscription : Décembre 2008
    Messages : 100
    Points : 43
    Points
    43
    Par défaut
    Hello tout le monde!!!

    Alors, j'ai pas mal avancé sur mon projet et j'aurai une petite question à vous poser :

    Je cherche à adapter ce code (trouvé sur un excellent tutoriel )

    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
     
    %define BASE   0x100  
    %define KSIZE  1  ; nombre de secteurs de 512 octets a charger
     
    ...
     
    ; recuparation de l'unite de boot
        mov [bootdrv], dl 
     
    ; charger le noyau
        xor ax, ax
        int 0x13
     
        push es
        mov ax, BASE
        mov es, ax
        mov bx, 0
     
        mov ah, 2
        mov al, KSIZE
        mov ch, 0
        mov cl, 2
        mov dh, 0
        mov dl, [bootdrv]
        int 0x13
        pop es
     
     
    ; saut vers le kernel
        jmp dword BASE:0
     
     
    msgDebut: db "Chargement du kernel", 13, 10, 0
     
    bootdrv: db 0
    C'est donc la partie qui va me permettre de charger le noyau Ubuntu pour ma part.

    Alors, ma question est la suivante :

    Dans le tutoriel, il est indiqué que ce code charge le noyau qui se trouve sur le deuxième secteur d'une disquette, je pense que c'est paramétré dans la "variable" base sauf que si je me trompe pas l'adresse 0x100 correspond à 256 en décimal.

    Je ne comprends donc pas trop le fonctionnement exact, si quelqu'un pouvait me mettre sur la bonne voie

    Merci pour votre aide en tout cas!!

  8. #8
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 374
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 374
    Points : 23 632
    Points
    23 632
    Par défaut
    Le secteur du MBR d'un disque (sur PC) contient ce que tu veux, à ceci près que sur les 512 octets de ce secteur, 4*16 sont réservés pour la table des partitions primaires et 2 autres, à la fin, pour contenir le magic number 55 AA, en hexadécimal. C'est ce nombre qui permet au BIOS de savoir que le secteur contient du code valide (en tout cas, déposé là en toute connaissance de cause) et pas simplement de l'espace non initialisé. Il te reste donc 446 octets pour mettre ce qu'il te plaît.

    Sauf qu'évidemment, tu ne vas pas faire tenir un système d'exploitation entier dans 446 octets. L'idée générale étant de mettre à cette place le code minimum qui permettra de charger un programme un peu plus long qui, lui, va charger le reste du système ou bien te proposer d'en lancer d'autres. Ce programme se trouve soit à la suite du MBR (en considérant que les secteurs de la première piste, qui contient le MBR, ne sont « jamais » utilisés), mais ce n'est pas très propre, soit il se trouve quelque part sur la partition de l'O.S. qui t'as permis de l'installer. Le principe reste le même : donner un emplacement sur le disque et, de là, charger n secteurs.

    Pour ce faire, on fait appel à une interruption du BIOS, la numéro 13h, très documentée, notamment ici : http://en.wikipedia.org/wiki/INT_13 .

    Du coup, tu t'aperçois, que le couple cylindre/secteur est passé dans CH et CL, et que BASE est en fait un symbole qui se réfère à l'emplacement en mémoire où vont être chargés les secteurs lus.

  9. #9
    Membre du Club

    Inscrit en
    Décembre 2008
    Messages
    100
    Détails du profil
    Informations forums :
    Inscription : Décembre 2008
    Messages : 100
    Points : 43
    Points
    43
    Par défaut
    Salut,

    Alors, je bloqu sur une dernière petite chose (enfin j'espère), pour pouvoir booter sur mon noyau, je doit auparavant préciser l'unité de boot, or je ne sais pas comment lui préciser que c'est le disque dur.

    Pour la disquette c'est :

    Est-ce que quelqu'un à une petite idée?

    merci d'avance

  10. #10
    Membre du Club

    Inscrit en
    Décembre 2008
    Messages
    100
    Détails du profil
    Informations forums :
    Inscription : Décembre 2008
    Messages : 100
    Points : 43
    Points
    43
    Par défaut
    Ok, je pense que j'ai peut-être trouvé, l'interruption 13 utilise la valeur de dl pour indiquer l'unité à initialiser, 00h est correspond donc à la disquette et apparemment 80h identifie le disque dur. (arrêtez moi si je me trompe )

    Enfin bon, je vais tester tout ça

  11. #11
    Membre du Club

    Inscrit en
    Décembre 2008
    Messages
    100
    Détails du profil
    Informations forums :
    Inscription : Décembre 2008
    Messages : 100
    Points : 43
    Points
    43
    Par défaut
    Bon, je n'avance plus trop, je pense avoir compris le principe.

    Voici le code de mon bootloader que je place sur le premier secteur du disque dur avec la commande :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    dd if=bootloader of=/dev/sda bs=1
    bootloader :

    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
    %define BASE   0x100  
    %define KSIZE  1  ; nombre de secteurs de 512 octets a charger
    
    [BITS 16]  ; indique a nasm que l'on travaille en 16 bits
    [ORG 0x0]
    
    ; initialisation des segments en 0x07C00
        mov ax, 0x07C0
        mov ds, ax
        mov es, ax
        mov ax, 0x8000
        mov ss, ax
        mov sp, 0xf000    ; stack de 0x8F000 -> 0x80000
    
    ; affiche un msg
        mov si, msgDebut
        call afficher
    
    
    ; affiche un msg
        mov si, msgCharg
        call afficher
    
    ;--- Variables ---
        msgDebut db "Salut ", 13, 10, 0
        msgCharg: db "Le noyau va etre charge", 13, 10, 0
    ;-----------------
    
    afficher:
        push ax
        push bx
    .debut:
        lodsb         ; ds:si -> al
        cmp al, 0     ; 
        jz .fin
        mov ah, 0x0E  ; appel au service 0x0e, int 0x10 du bios
        mov bx, 0x07  ; bx -> attribut, al -> caractere ascii
        int 0x10
        jmp .debut
    
    .fin:
        pop bx
        pop ax
        ret
    
    
    ; charger le noyau
        xor ax, ax
        int 0x13
    
        push es
        mov ax, BASE
        mov es, ax
        mov bx, 0
    
        mov ah, 2
        mov al, KSIZE
        mov ch, 0
        mov cl, 2
        mov dh, 0
        mov dl, 80h
        int 0x13
        pop es
    
    ; saut vers le kernel
        jmp dword BASE:0
    
    bootdrv: db 0
    
    dw 0xAA55
    J'ai bien mis le 80h dans dl pour indiquer le disque dur et je place mon noyau sur le deuxième secteur de ce disque dur.

    dd if=noyau of=/dev/sda bs=512

    Voici le code du noyau:

    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
    [BITS 16]
    [ORG 0x0]
     
    jmp start
     
    start:
    ; initialisation des segments en 0x100
        mov ax, 0x100
        mov ds, ax
        mov es, ax
     
    ; initialisation du segment de pile
        mov ax, 0x8000
        mov ss, ax
        mov sp, 0xf000
     
    ; affiche un msg
        mov si, msg00
        call afficher
     
    msg00: db 'ca a reussi !', 10, 0
     
    ;---------------------------------------------------------
    ; Synopsis: Affiche une chaine de caracteres se terminant par 0x0
    ; Entree:   DS:SI -> pointe sur la chaine a afficher
    ;---------------------------------------------------------
    afficher:
        push ax
        push bx
    .debut:
        lodsb         ; ds:si -> al
        cmp al, 0     ; fin chaine ?
        jz .fin
        mov ah, 0x0E  ; appel au service 0x0e, int 0x10 du bios
        mov bx, 0x07  ; bx -> attribut, al -> caractere ascii
        int 0x10
        jmp .debut
     
    .fin:
        pop bx
        pop ax
        ret
    Quand je place uniquement le bootloader sans le noyau, j'otiens bien au démarrage le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Salut
    Le noyau va etre charge
    Cependant dès lors que je rajoute le noyau, je n'obtiens pas la phrase "ca a reussi" mais plus bizarre, je n'obtiens même plus les messages du bootloader...

    Est-ce que quelqu'un a une petite idée pour m'aider???

  12. #12
    Membre chevronné
    Avatar de Forthman
    Homme Profil pro
    conception mécanique
    Inscrit en
    Janvier 2005
    Messages
    702
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Tarn et Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : conception mécanique
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2005
    Messages : 702
    Points : 1 905
    Points
    1 905
    Par défaut
    Ca va pas de paser la nuit à coder ?

    Sinon, je pense avoir trouvé ton erreur,
    les donnees sont en plein milieu du code.
    Tu devrais les mettre à la fin (juste avant dw 0xAA55 )

    Ou bien faire un jmp pour aller à la suite du code car
    sinon le programme continue à essayer d'exécter les données comme du code

    a+ François

  13. #13
    Membre du Club

    Inscrit en
    Décembre 2008
    Messages
    100
    Détails du profil
    Informations forums :
    Inscription : Décembre 2008
    Messages : 100
    Points : 43
    Points
    43
    Par défaut
    héhé, quand je suis lancé je suis lancé

    Juste une petite précision, quand tu parles de données tu parles bien de

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    ;--- Variables ---
        msgDebut db "Salut ", 13, 10, 0
        msgCharg: db "Le noyau va etre charge", 13, 10, 0
    ;-----------------
    parce que j'ai essayé en mettant

    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
    %define BASE   0x100  
    %define KSIZE  1  ; nombre de secteurs de 512 octets a charger
     
    [BITS 16]  ; indique a nasm que l'on travaille en 16 bits
    [ORG 0x0]
     
    ; initialisation des segments en 0x07C00
        mov ax, 0x07C0
        mov ds, ax
        mov es, ax
        mov ax, 0x8000
        mov ss, ax
        mov sp, 0xf000    ; stack de 0x8F000 -> 0x80000
     
    ; affiche un msg
        mov si, msgDebut
        call afficher
     
     
    ; affiche un msg
        mov si, msgCharg
        call afficher
     
    afficher:
        push ax
        push bx
    .debut:
        lodsb         ; ds:si -> al
        cmp al, 0     ; fin chaine ?
        jz .fin
        mov ah, 0x0E  ; appel au service 0x0e, int 0x10 du bios
        mov bx, 0x07  ; bx -> attribut, al -> caractere ascii
        int 0x10
        jmp .debut
     
    .fin:
        pop bx
        pop ax
        ret
     
     
    ; charger le noyau
        xor ax, ax
        int 0x13
     
        push es
        mov ax, BASE
        mov es, ax
        mov bx, 0
     
        mov ah, 2
        mov al, KSIZE
        mov ch, 0
        mov cl, 2
        mov dh, 0
        mov dl, 80h
        int 0x13
        pop es
     
    ; saut vers le kernel
        jmp dword BASE:0
     
    bootdrv: db 0
     
    ;--- Variables ---
        msgDebut db "Salut Jonathan", 13, 10, 0
        msgCharg: db "Chargement du kernel", 13, 10, 0
    ;-----------------
     
    dw 0xAA55
    et j'ai toujours la même erreur...

  14. #14
    Membre du Club

    Inscrit en
    Décembre 2008
    Messages
    100
    Détails du profil
    Informations forums :
    Inscription : Décembre 2008
    Messages : 100
    Points : 43
    Points
    43
    Par défaut
    Bon shame on me

    mes commandes dd s'écrasaient entres elles,

    c'est corrigés avec

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    dd if=bootloader of=/dev/sda bs=1
    et
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    dd if=noyau of=/dev/sda bs=512 seek=1
    et la je retrouve les jolis message de mon bootloader mais toujours pas celui de mon noyau

  15. #15
    Membre chevronné
    Avatar de Forthman
    Homme Profil pro
    conception mécanique
    Inscrit en
    Janvier 2005
    Messages
    702
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Tarn et Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : conception mécanique
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2005
    Messages : 702
    Points : 1 905
    Points
    1 905
    Par défaut
    Comme pour les données, ta fonction appelée par un CALL
    devrait être placée ailleur
    regardes ici :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    ...
    ; affiche un msg
        mov si, msgCharg
        call afficher
     
    afficher:
        push ax
        push bx
    ...
    Après le "call afficher" le processeur va se retrouver au niveau de "afficher:"
    et donc exécuter le code alors que les données ne sont pas correctes.
    En plus, à la fin, le "ret" va renvoyer le proc on ne sait où

    donc, ou bien tu déplace ta procédure en fin, juste avant les données (par exemple)
    ou alors tu intercales un "jmp" pour aller au début de la partie qui charge le noyau

    a+ François

Discussions similaires

  1. installer un boot loader windows xp
    Par wtfu dans le forum Windows XP
    Réponses: 2
    Dernier message: 27/06/2006, 18h44
  2. Install boot loader sans passer par celui de Windows
    Par DeadiS dans le forum Autres Logiciels
    Réponses: 5
    Dernier message: 07/02/2006, 08h36
  3. Réinstaller le boot loader après réinstall de Windows
    Par roger12 dans le forum Administration système
    Réponses: 1
    Dernier message: 28/10/2005, 11h55
  4. création d'un multi boot
    Par GritNatz dans le forum Autres Logiciels
    Réponses: 5
    Dernier message: 18/01/2005, 23h23
  5. Création d'un OS / Boot / Noyau
    Par the_best dans le forum Programmation d'OS
    Réponses: 19
    Dernier message: 22/08/2004, 00h48

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