User Tools

Site Tools


archi:x86

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
archi:x86 [2016/03/11 21:17] orelarchi:x86 [2024/03/18 15:06] (current) – external edit 127.0.0.1
Line 18: Line 18:
   * [[https://en.wikibooks.org/wiki/X86_Assembly/GAS_Syntax|Syntaxe GAS]]    * [[https://en.wikibooks.org/wiki/X86_Assembly/GAS_Syntax|Syntaxe GAS]] 
   * [[https://en.wikibooks.org/wiki/X86_Assembly|Assembleur x86]]   * [[https://en.wikibooks.org/wiki/X86_Assembly|Assembleur x86]]
 +  * Compiler Explorer: https://gcc.godbolt.org
  
 ====Exemple Hello World en GAS ==== ====Exemple Hello World en GAS ====
Line 62: Line 63:
 </code>   </code>  
  
-==== Bootloader ====+==== Bootloader au format multiboot ====
  
-Considérons le code assembleur x86 suivant d'un //bootloader// minimaliste en 32 bits. Le code se compose du //bootloader// à proprement parler (fichier //boot.s//), qui appelle la fonction //main// du //kernel// (fichier //kernel.s//).+Considérons le code assembleur x86 suivant d'un //bootloader// minimaliste en 32 bits au format //multiboot//. Le code se compose du //bootloader// à proprement parler (fichier //boot.s//), qui appelle la fonction //main// du //kernel// (fichier //kernel.s//).
  
 <code c boot.s> <code c boot.s>
Line 102: Line 103:
 Pour aller plus loin :  Pour aller plus loin : 
   * https://www.gnu.org/software/grub/manual/multiboot/multiboot.html (multiboot format)   * https://www.gnu.org/software/grub/manual/multiboot/multiboot.html (multiboot format)
-  * https://www.gnu.org/software/grub/manual/multiboot/multiboot.html#OS-image-format (multiboot header)+  * https://www.gnu.org/software/grub/manual/multiboot/multiboot.html#OS-image-format (multiboot header: 0x1BADB002)
   * https://en.wikibooks.org/wiki/X86_Assembly/Bootloaders   * https://en.wikibooks.org/wiki/X86_Assembly/Bootloaders
   * http://wiki.osdev.org/Bare_bones   * http://wiki.osdev.org/Bare_bones
Line 128: Line 129:
 </code> </code>
  
-Lors de l'édition de lien, il est important de préciser que le point d'entrée est le symbole '_start' et de placer la séquence magique de 12 octets du //bootloader// à une adresse supérieure à 0x100000. En effet, les adresses < 1MiB sont réservées pour le BIOS, la RAM Video, etc. +Lors de l'édition de lien, il est important de préciser que le point d'entrée est le symbole '_start' et de placer la séquence magique de 12 octets du //bootloader// à une adresse supérieure à 0x100000, suivi du code (segment .text). En effet, les adresses < 1MiB sont réservées pour le BIOS, la RAM Video, etc. 
  
 On peut aussi utiliser un //external linker script// pour compiler notre //kernel// :  On peut aussi utiliser un //external linker script// pour compiler notre //kernel// : 
Line 175: Line 176:
  
   qemu-system-i386 -enable-kvm -kernel kernel   qemu-system-i386 -enable-kvm -kernel kernel
 +  
 +L'option //-kernel// permet de "booter" directement sur un noyau linux au format //bzimage// ou sur un code au format //multiboot// comme celui décrit dans cette section. Notons que c'est le format standard supporté par GRUB.
      
 ==== Kernel en C ==== ==== Kernel en C ====
Line 293: Line 296:
   qemu-system-i386 -cdrom mykernel.iso   qemu-system-i386 -cdrom mykernel.iso
  
-Chercher comment se passer de GRUB ? Un peu de lecture...+==== Booter son Kernel depuis un disque (sans GRUB) ====
  
-  * http://wiki.osdev.org/Bare_bones +Pour booter son Kernel depuis un disque (//floppy//, //hard disk// ou //usb disk//), il faut tout d'abord modifier la séquence de boot du BIOS pour qu'il puisse amorcer le système depuis ce périphérique au démarrage de l'ordinateurCes 3 types de disque utilisent la même organisation en secteur de 512 octets. Pour rendre un disque bootable, il faut ajouter la signature de boot (i.e. //0x55aa//) à la fin du secteur 0. 
-  * http://wiki.osdev.org/El-Torito + 
-  * https://wiki.archlinux.org/index.php/GRUB +<code hello.s> 
-  * http://www.syslinux.org/wiki/index.php?title=ISOLINUX +.code16                  # generate 16-bit code 
-  * http://wiki.osdev.org/Mkisofs +.text                    # executable code location 
-  * http://wiki.osdev.org/Bootable_CD +     .globl _start; 
-  * http://stackoverflow.com/questions/34268518/creating-a-bootable-iso-image-with-custom-bootloader+ 
 +_start                 # code entry point 
 + 
 +     #print letter 'H' onto the screen 
 +     movb $'H' , %al 
 +     movb $0x0e, %ah 
 +     int  $0x10 
 + 
 +     #print letter 'e' onto the screen 
 +     movb $'e' , %al 
 +     movb $0x0e, %ah 
 +     int  $0x10 
 + 
 +     #print letter 'l' onto the screen 
 +     movb $'l' , %al 
 +     movb $0x0e, %ah 
 +     int  $0x10 
 + 
 +     #print letter 'l' onto the screen 
 +     movb $'l' , %al 
 +     movb $0x0e, %ah 
 +     int  $0x10 
 + 
 +     #print letter 'o' onto the screen 
 +     movb $'o' , %al 
 +     movb $0x0e, %ah 
 +     int  $0x10 
 + 
 +     hlt # halt 
 + 
 +     . = _start + 510      #mov to 510th byte from 0 pos 
 +     .byte 0x55            #append boot signature 
 +     .byte 0xaa            #append boot signature  
 + 
 +</code> 
 + 
 +Attention, dans ce cas précis, le BIOS recopie en mémoire physique le secteur 0 (512 octets) et passe la main au CPU pour qu'il commence à exécuter en //mode real// (16 bits) les instructions au début du secteur 0... Notons que dans ce cas, il est possible de faire appel aux interruptions du BIOS pour écrire en mémoire VGA (//int 0x10//).  
 + 
 +Il faut ensuite compiler ce programme //en flat binary// (et non en ELF) puis le copier sur sa disquette : 
 + 
 +  as hello.s -o hello.o 
 +  ld --oformat=binary hello.o -o hello.bin 
 +  dd if=/dev/zero of=floppy.img bs=512 count=2880  # standard floppy disk (1.44MB) 
 +  dd if=hello.bin of=floppy.img 
 + 
 +On peut facilement tester ce programme depuis son disque avec QEMU : 
 + 
 +  qemu-system-i386 -fda floppy.img -boot a   # boot on floppy disk 
 +  qemu-system-i386 -hda floppy.img           # boot on hard disk   
 +   
 +On peut également mettre son bootloader sur le premier secteur d'une clef USB : /dev/sdc sur ma machine (fdisk -l)Mais, attention de ne pas se tromper au risque de perdre toutes vos données !    
 + 
 +  cat hello.bin > /dev/sdc 
 +   
 +Puis on reboote la "vraie" machine avec la clef USB et voici le résultatNotons que nous n'avons pas préparé de table des partitions, d'où le message affiché par le BIOS : //Invalid Partition Table// avant notre fameux //Hello World// :-) 
 + 
 +{{ :archi:helloboot-laptop.jpg?direct&300 |}} 
 + 
 +Pour aller plus loin :  
 +  * http://www.codeproject.com/Articles/664165/Writing-a-boot-loader-in-Assembly-and-C-Part 
 +  * http://www.codeproject.com/Articles/668422/Writing-a-boot-loader-in-Assembly-and-C-Part 
 +  * http://www.codeproject.com/Articles/737545/Writing-a-bit-dummy-kernel-in-C-Cplusplus
  
  
Line 312: Line 376:
  
  
-==== Pour aller plus loin ====+==== Pour aller encore plus loin ====
  
-  * http://www.codeproject.com/Articles/664165/Writing-a-boot-loader-in-Assembly-and-C-Part 
-  * http://www.codeproject.com/Articles/668422/Writing-a-boot-loader-in-Assembly-and-C-Part 
-  * http://www.codeproject.com/Articles/737545/Writing-a-bit-dummy-kernel-in-C-Cplusplus 
   * http://viralpatel.net/taj/operating-system-tutorial.php   * http://viralpatel.net/taj/operating-system-tutorial.php
   * http://wiki.osdev.org/Main_Page   * http://wiki.osdev.org/Main_Page
 +  * http://wiki.osdev.org/Bare_bones
 +  * http://wiki.osdev.org/El-Torito
 +  * https://wiki.archlinux.org/index.php/GRUB
 +  * http://www.syslinux.org/wiki/index.php?title=ISOLINUX
 +  * http://wiki.osdev.org/Mkisofs
 +  * http://wiki.osdev.org/Bootable_CD
 +  * http://stackoverflow.com/questions/34268518/creating-a-bootable-iso-image-with-custom-bootloader
 +
 +
archi/x86.1457731065.txt.gz · Last modified: 2024/03/18 15:05 (external edit)