Select Git revision
Forked from
IVMI / Ivmi-Builder
Source project has a limited visibility.
-
Florent Berthaut authoredFlorent Berthaut authored
vol.c 6.37 KiB
#include <stdio.h>
#include <ctype.h>
#include <assert.h>
#include <string.h>
#include "hardware.h"
#include "drive.h"
#include "vol.h"
void load_mbr()
{
unsigned char buffer[sizeof(mbr_t)];
/* read_sector(buffer, 0, 0); */
read_sector_n(buffer, 0, 0, sizeof(mbr_t));
memcpy(&mbr, buffer, sizeof(mbr_t));
if (mbr.magic != MAGIC)
{
mbr.magic = MAGIC;
mbr.nb_vols = 0;
}
}
void save_mbr()
{
unsigned char buffer[sizeof(mbr_t)];
memcpy(buffer, &mbr, sizeof(mbr_t));
write_sector(0, 0, buffer);
}
void get_sector_cylinder(unsigned int vol, unsigned int nbloc, unsigned int *sector_cylinder)
{
int absolute_nbloc;
vol_t volume;
assert(vol < mbr.nb_vols);
volume = mbr.vols[vol];
assert(nbloc < volume.nb_blocs);
absolute_nbloc = (volume.cylinder * HDA_MAXSECTOR + volume.sector + nbloc);
sector_cylinder[0] = absolute_nbloc % HDA_MAXSECTOR;
sector_cylinder[1] = absolute_nbloc / HDA_MAXSECTOR;
}
void read_bloc(unsigned int vol, unsigned int nbloc, unsigned char *buffer)
{
unsigned int sector_cylinder[2];
get_sector_cylinder(vol, nbloc, sector_cylinder); /* [sector, cylinder] */
printf("%d %d\n", sector_cylinder[0], sector_cylinder[1]);
read_sector(buffer, sector_cylinder[1], sector_cylinder[0]);
}
void write_bloc(unsigned int vol, unsigned int nbloc, unsigned char *buffer)
{
unsigned int sector_cylinder[2];
get_sector_cylinder(vol, nbloc, sector_cylinder); /* [sector, cylinder] */
write_sector(sector_cylinder[1], sector_cylinder[0], buffer);
}
void format_vol(unsigned int vol)
{
unsigned int nbloc, sector_cylinder[2];
vol_t volume = mbr.vols[vol];
for (nbloc = 0; nbloc < volume.nb_blocs; nbloc++)
{
get_sector_cylinder(vol, nbloc, sector_cylinder); /* [sector, cylinder] */
format_sector(sector_cylinder[1], sector_cylinder[1], FMT_SIZE, FMT_DATA);
}
}
void create_vol(unsigned int nb_blocs, unsigned int cylinder, unsigned int sector)
{
int i, abs_nbloc, remaining_blocs;
vol_t *volume;
if (mbr.nb_vols == VOLS_MAX)
{
fprintf(stderr, "Le nombre de volumes maximal est atteint \n");
return;
}
if (cylinder + sector == 0 ||
cylinder >= HDA_MAXCYLINDER ||
sector >= HDA_MAXSECTOR)
{
fprintf(stderr, "Impossible d'ecrire à cet endroit \n");
return;
}
abs_nbloc = cylinder * HDA_MAXSECTOR + sector;
remaining_blocs = HDA_MAXSECTOR * HDA_MAXCYLINDER - abs_nbloc;
if (abs_nbloc > remaining_blocs)
nb_blocs = remaining_blocs;
for (i = 0; i < mbr.nb_vols; i++)
{
vol_t vol = mbr.vols[i];
int vol_abs_nbloc = vol.cylinder * HDA_MAXSECTOR + vol.sector;
/*
* Les deux commencent sur le même bloc
* Les deux se terminent sur le même bloc
* Si le debut de l'un se trouve entre le debut et la fin de l'autre
*/
printf("%d %d %d %d\n", abs_nbloc, abs_nbloc + nb_blocs, vol_abs_nbloc, vol_abs_nbloc + vol.nb_blocs);
if (abs_nbloc == vol_abs_nbloc ||
(abs_nbloc + nb_blocs) == (vol_abs_nbloc + vol.nb_blocs) ||
((abs_nbloc < vol_abs_nbloc) && (vol_abs_nbloc < abs_nbloc + nb_blocs)) ||
((vol_abs_nbloc < abs_nbloc) && (abs_nbloc < vol_abs_nbloc + vol.nb_blocs)))
{
fprintf(stderr, "Le volume %d occupe déjà cet emplacement \n", i);
return;
}
}
volume = mbr.vols + (mbr.nb_vols++);
volume->nb_blocs = nb_blocs;
volume->cylinder = cylinder;
volume->sector = sector;
volume->type = BASE;
}
void display_vols()
{
int vol;
char *vtype_names[3] = {"BASE", "ANNEXE", "OTHER"};
vol_t volume;
if (mbr.nb_vols == 0)
{
printf("Il n'y aucun volume.\n");
return;
}
printf("--------------------------\n");
for (vol = 0; vol < mbr.nb_vols; vol++)
{
volume = mbr.vols[vol];
printf("Volume: %d (%s)\n", vol, vtype_names[volume.type]);
printf("> Sector: %d \n", volume.sector);
printf("> Cylinder: %d \n", volume.cylinder);
printf("> Nb blocs: %d \n", volume.nb_blocs);
printf("--------------------------\n");
}
}
void remove_vol(int vol)
{
int i;
if (vol >= mbr.nb_vols)
{
fprintf(stderr, "Ce volume n'existe pas. \n");
return;
}
for (i = vol; i < mbr.nb_vols - 1; i++)
mbr.vols[i] = mbr.vols[i + 1];
mbr.nb_vols--;
}
void init_volume(unsigned int vol, char name[32])
{
int i;
vsuper_t super;
vol_t volume;
unsigned char buffer[sizeof(vsuper_t)];
super.magic = MAGIC;
super.serie = vol;
strcpy(super.name, name);
super.id = vol;
super.first_free = 1;
super.nb_free_blocs = HDA_SECTORSIZE - 1;
memcpy(buffer, &super, sizeof(vsuper_t));
write_bloc(vol, SUPER_BLOC, buffer);
volume = mbr.vols[vol];
for (i = 1; i < volume.nb_blocs; i++)
{
vblockchain_t blockchain;
unsigned char buf[sizeof(vblockchain_t)];
blockchain.next = (i + 1) % volume.nb_blocs;
memcpy(buf, &blockchain, sizeof(vblockchain_t));
write_bloc(vol, i, buf);
}
}
int load_super(unsigned int vol)
{
unsigned char buffer[sizeof(vsuper_t)];
read_bloc(vol, SUPER_BLOC, buffer);
memcpy(&super, buffer, sizeof(vsuper_t));
/* printf("%d %d %d %d %d %s\n", super.id, super.first_free, super.magic, super.nb_free_blocs, super.serie, super.name); */
/* assert(super.magic == MAGIC); */
return 0;
}
void save_super()
{
unsigned char buffer[sizeof(vsuper_t)];
memcpy(buffer, &super, sizeof(vsuper_t));
write_bloc(super.id, SUPER_BLOC, buffer);
}
unsigned int new_bloc()
{
unsigned int new_bloc;
unsigned char buffer[sizeof(vblockchain_t)];
vblockchain_t blockchain;
if (!super.first_free)
{
fprintf(stderr, "Il n'y a pas de bloc libre");
return 0;
}
read_bloc(super.id, super.first_free, buffer);
memcpy(&blockchain, buffer, sizeof(vblockchain_t));
new_bloc = super.first_free;
super.first_free = blockchain.next;
super.nb_free_blocs--;
return new_bloc;
}
void free_bloc(unsigned int bloc)
{
unsigned char buffer[sizeof(vblockchain_t)];
vblockchain_t blockchain;
blockchain.next = super.first_free;
memcpy(buffer, &blockchain, sizeof(vblockchain_t));
write_bloc(super.id, bloc, buffer);
super.first_free = bloc;
super.nb_free_blocs++;
}