print · rss · source

< Créer et lancer une application au format ELF à partir du système de fichier | TutoOS | Quelques structures élémentaires pour gérer les fichiers >


Booter avec Grub sur un disque IDE

Les sources

Le package contenant les sources est téléchargeable ici : kernel_Grub2.tgz
Pour naviguer dans l'arborescence : Grub2


Créer une image d'un disque IDE partitionné

Le fait de booter sur un disque IDE apporte un changement fondamental par rapport au boot sur une disquette : il faut partitionner le disque. Cela apporte une petite complexité supplémentaire dont le contournement est expliqué ci-dessous...

On commence par créer une image avec bximage :

$ bximage
> hd
> flat
> 2
> c.img

Celà a pour effet de créer un fichier nommé ici c.img et affiche le message suivant à l'écran :

The following line should appear in your bochsrc:
  ata0-master: type=disk, path="c.img", mode=flat, cylinders=4, heads=16, spt=63

Cette ligne est à reporter dans le fichier .bochsrc. N'oublier pas aussi de préciser le périphérique de boot :

boot: disk

Il faut ensuite partitionner l'image du disque. Les commandes c, h et s indiquent quelle est la géométrie du disque :

$ fdisk c.img
> x
> c 4
> h 16
> s 63
> r
> n, p, 1
> a 1
> w

Après ça, il faut obtenir le numéro de secteur de la partition créée :

$ fdisk -l -u c.img
Disk c.img: 0 MB, 0 bytes
16 heads, 63 sectors/track, 0 cylinders, total 0 sectors
Units = sectors of 1 * 512 = 512 bytes
Disk identifier: 0x7337b4ff

Device Boot      Start         End      Blocks   Id  System
c.img1   *          63        4031        1984+  83  Linux

Nous allons maintenant associer la partition créée à un loop device, qui est un pseudo périphérique qui permet à un fichier d'être accédé comme s'il s'agissait d'un périphérique de type bloc. On utilise pour celà la commande losetup avec comme argument l'offset, en octet, où se trouve le début de la partition (c'est la raison de la commande précédente). L'offset calculé est de 63 * 512 = 32356 :

# losetup -o 32256 /dev/loop0 c.img

Note : pour détacher le loop device de l'image :

# losetup -d /dev/loop0

A partir de maintenant, la partition de l'image disque est vue comme un vrai périphérique de type bloc. On peut donc déposer un système de fichiers dessus :

# mke2fs /dev/loop0

Ensuite, pour monter la partition :

# mount -t ext2 /dev/loop0 /mnt/loop

Installer grub sur une image bootable

On ajoute quelques fichiers sur la partition montée :

$ mkdir /mnt/loop/grub
$ cp /boot/grub/stage* /mnt/loop/grub
$ cat > /mnt/loop/grub/menu.lst << EOF
title=Pepin
root (hd0,0)
kernel /kernel
boot
EOF

Ensuite, il faut démonter la partition pour installer grub dessus :

$ umount /mnt/loop
$ grub --device-map=/dev/null << EOF
device (hd0) c.img
root (hd0,0)
setup (hd0)
quit
EOF

Ouf ! C'est fait, maintenant, on peut remonter la partition quelque part pour copier le kernel dessus.

Utiliser un disque logique

La table des partition primaires du MBR permet de gérer jusqu'à 4 partitions. Les informations sur ces partitions sont situés à des offsets prédéfinis par rapport au début du disque :

PartitionOffset
Partition 10x01BE
Partition 20x01CE
Partition 30x01DE
Partition 40x01EE

Chaque entrée de la table fait 16 octets et obéit au format suivant :

struct partition {
        u8      bootable;       /* 0 = no, 0x80 = bootable */
        u8      s_head;         /* Starting head */
        u16     s_sector : 6;   /* Starting sector */
        u16     s_cyl    : 10;  /* Starting cylinder */
        u8      id;             /* System ID */
        u8      e_head;         /* Ending head */
        u16     e_sector : 6;   /* Ending sector */
        u16     e_cyl    : 10;  /* Ending cylinder */
        u32     s_lba;          /* Starting sector (LBA value) */
        u32     size;           /* Total sector number */
} __attribute__ ((packed));

La valeur s_lba permet de connaître l'offset où commence une partition par rapport au début du disque. En l'occurence, les données débuterons à partir de l'offset s_lba*512 (en octets).

Nous avons vu au chapitre sur l'utilisation d'un système de fichiers Ext2 comment lire des données tels que le superbloc, une inode, etc. Quelques changements sont à apporter pour que ces fonctions continuent de fonctionner car les lectures ne se font plus à partir du début du disque mais à partir du début de la partition. Chaque donnée subit donc un décalage de s_lba*512 octets :

struct partition *p1;
struct ext2_super_block *sb;

p1 = (struct partition*) kmalloc(sizeof(struct partition));
disk_read(0, 0x01BE, (char*) p1, 16);

printk("partition 1\n  start: %d, size: %d\n", p1->s_lba, p1->size);

sb = (struct ext2_super_block*) kmalloc(sizeof(struct ext2_super_block));
disk_read(0, (p1.s_lba * 512) + 1024, (char*) sb, sizeof(struct ext2_super_block));

printk("volume name: %s, block size: %d\n", sb->s_volume_name, (1024 << sb->s_log_block_size));

< Créer et lancer une application au format ELF à partir du système de fichier | TutoOS | Quelques structures élémentaires pour gérer les fichiers >

print · rss · source
Page last modified on May 29, 2011, at 07:12 PM