< 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 >