print · rss · source

< Gérer la mémoire physique et la mémoire virtuelle | TutoOS | Utiliser un système de fichier Ext2FS >


Lire et écrire sur un dique IDE

Les sources

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


Écrire et lire sur une disque IDE avec les PIO

Il existe deux méthodes possibles pour écrire et lire sur une unité de disque IDE : l'utilisation des ports du processeurs (PIO) et l'utilisation du DMA. L'implémentation décrite ici utilise les ports du processeurs. Les accès disque sont assez lents avec cette méthode mais avec l'avantage d'une implémentation très simple :

#include "types.h"
#include "io.h"

int bl_common(int drive, int numblock, int count)
{
        outb(0x1F1, 0x00);      /* NULL byte to port 0x1F1 */
        outb(0x1F2, count);     /* Sector count */
        outb(0x1F3, (unsigned char) numblock)/* Low 8 bits of the block address */
        outb(0x1F4, (unsigned char) (numblock >> 8));   /* Next 8 bits of the block address */
        outb(0x1F5, (unsigned char) (numblock >> 16))/* Next 8 bits of the block address */

        /* Drive indicator, magic bits, and highest 4 bits of the block address */
        outb(0x1F6, 0xE0 | (drive << 4) | ((numblock >> 24) & 0x0F));

        return 0;
}

int bl_read(int drive, int numblock, int count, char *buf)
{
        u16 tmpword;
        int idx;

        bl_common(drive, numblock, count);
        outb(0x1F7, 0x20);

        /* Wait for the drive to signal that it's ready: */
        while (!(inb(0x1F7) & 0x08));

        for (idx = 0; idx < 256 * count; idx++) {
                tmpword = inw(0x1F0);
                buf[idx * 2] = (unsigned char) tmpword;
                buf[idx * 2 + 1] = (unsigned char) (tmpword >> 8);
        }

        return count;
}

int bl_write(int drive, int numblock, int count, char *buf)
{
        u16 tmpword;
        int idx;

        bl_common(drive, numblock, count);
        outb(0x1F7, 0x30);

        /* Wait for the drive to signal that it's ready: */
        while (!(inb(0x1F7) & 0x08));

        for (idx = 0; idx < 256 * count; idx++) {
                tmpword = (buf[idx * 2 + 1] << 8) | buf[idx * 2];
                outw(0x1F0, tmpword);
        }

        return count;
}

Créer et utiliser une image d'un disque dur sous Unix

Il faut créer une image d'un disque dur, par exemple en utilisant la commande bximage :

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

Ensuite, il faut ajouter dans le fichier de configuration de bochs une entrée sur ce modèle :

ata0: enabled=1, ioaddr1=0x1f0, ioaddr2=0x3f0, irq=14
ata0-master: type=disk, path="c.img", mode=flat, cylinders=4, heads=16, spt=63

Tester

Le code ci-dessous inscrit une chaîne de caractère sur l'image de disque à l'offset 1024 (bloc numéro 2) avec la fonction bl_write() :

char *buf, *msg = "Hello world\n";
buf = (char *) kmalloc(512);
memcpy((char *) buf, (char *) msg, strlen(msg) + 1);

bl_write(0, 2, 1, buf);

Pour vérifier que l'écriture a bien eu lieu :

$ od -A d -c c.img 
0000000  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0
*
0001024   H   e   l   l   o       w   o   r   l   d  \n  \0  \0  \0  \0
0001040  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0
*
2064384

Pour lire cette inscription, on procède de façon similaire avec la fonction bl_read() :

bl_read(0, 2, 1, buf);
printk("buf: %s\n", buf);

< Gérer la mémoire physique et la mémoire virtuelle | TutoOS | Utiliser un système de fichier Ext2FS >

print · rss · source
Page last modified on December 11, 2008, at 01:55 PM