- implemented reading MBR from file (TODO: read boot sector)
- value of 'sectors_per_fat' must be 32 bit (for FAT32) - some other small fixes
This commit is contained in:
parent
2946d0ac26
commit
6d0b6c69b9
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: vvfat.cc,v 1.6 2010-12-30 12:30:58 vruppert Exp $
|
||||
// $Id: vvfat.cc,v 1.7 2010-12-31 15:39:27 vruppert Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2010 The Bochs Project
|
||||
@ -25,11 +25,12 @@
|
||||
// ADDITIONS:
|
||||
// - win32 specific directory functions (required for MSVC)
|
||||
// - configurable disk geometry
|
||||
// - read MBR from file
|
||||
|
||||
// TODO:
|
||||
// - write support
|
||||
// - FAT32 support
|
||||
// - read MBR and boot sector from file
|
||||
// - read boot sector from file
|
||||
|
||||
// Define BX_PLUGGABLE in files that can be compiled into plugins. For
|
||||
// platforms that require a special tag on exported symbols, BX_PLUGGABLE
|
||||
@ -1001,7 +1002,7 @@ int vvfat_image_t::init_directories(const char* dirname)
|
||||
infosector = (infosector_t*)(first_sectors + (offset_to_bootsector + 1) * 0x200);
|
||||
infosector->signature1 = htod32(0x41615252);
|
||||
infosector->signature2 = htod32(0x61417272);
|
||||
infosector->free_clusters = htod32(cluster_count - cluster - 2);
|
||||
infosector->free_clusters = htod32(cluster_count - cluster + 2);
|
||||
infosector->mra_cluster = htod32(2);
|
||||
infosector->magic[0] = 0x55;
|
||||
infosector->magic[1] = 0xaa;
|
||||
@ -1010,21 +1011,77 @@ int vvfat_image_t::init_directories(const char* dirname)
|
||||
return 0;
|
||||
}
|
||||
|
||||
bx_bool vvfat_image_t::read_sector_from_file(const char *path, Bit8u *buffer, Bit32u sector)
|
||||
{
|
||||
int fd = ::open(path, O_RDONLY
|
||||
#ifdef O_BINARY
|
||||
| O_BINARY
|
||||
#endif
|
||||
#ifdef O_LARGEFILE
|
||||
| O_LARGEFILE
|
||||
#endif
|
||||
);
|
||||
if (fd < 0)
|
||||
return 0;
|
||||
int offset = sector * 0x200;
|
||||
if (::lseek(fd, offset, SEEK_SET) != offset) {
|
||||
return 0;
|
||||
::close(fd);
|
||||
}
|
||||
int result = ::read(fd, buffer, 0x200);
|
||||
::close(fd);
|
||||
bx_bool bootsig = ((buffer[0x1fe] == 0x55) && (buffer[0x1ff] == 0xaa));
|
||||
|
||||
return (result == 0x200) && bootsig;
|
||||
}
|
||||
|
||||
int vvfat_image_t::open(const char* dirname)
|
||||
{
|
||||
Bit32u size_in_mb;
|
||||
char path[BX_PATHNAME_LEN];
|
||||
Bit8u sector_buffer[0x200];
|
||||
|
||||
// TODO: read MBR file (if present) and use it's values
|
||||
if (cylinders == 0) {
|
||||
cylinders = 1024;
|
||||
heads = 16;
|
||||
sectors = 63;
|
||||
use_mbr_file = 0;
|
||||
use_boot_file = 0;
|
||||
fat_type = 0;
|
||||
snprintf(path, BX_PATHNAME_LEN, "%s/%s", dirname, VVFAT_MBR);
|
||||
if (read_sector_from_file(path, sector_buffer, 0)) {
|
||||
mbr_t* real_mbr = (mbr_t*)sector_buffer;
|
||||
partition_t* partition = &(real_mbr->partition[0]);
|
||||
if ((partition->fs_type != 0) && (partition->length_sector_long > 0)) {
|
||||
if ((partition->fs_type == 0x06) || (partition->fs_type == 0x0e)) {
|
||||
fat_type = 16;
|
||||
} else if ((partition->fs_type == 0x0b) || (partition->fs_type == 0x0c)) {
|
||||
fat_type = 32;
|
||||
} else {
|
||||
BX_ERROR(("MBR file: unsupported FS type = 0x%02x", partition->fs_type));
|
||||
}
|
||||
if (fat_type != 0) {
|
||||
sector_count = partition->start_sector_long + partition->length_sector_long;
|
||||
sectors = partition->start_sector_long;
|
||||
if (partition->end_CHS.head > 16) {
|
||||
heads = 16;
|
||||
} else {
|
||||
heads = partition->end_CHS.head + 1;
|
||||
}
|
||||
cylinders = sector_count / (heads * sectors);
|
||||
memcpy(&first_sectors[0], sector_buffer, 0x200);
|
||||
use_mbr_file = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!use_mbr_file) {
|
||||
if (cylinders == 0) {
|
||||
cylinders = 1024;
|
||||
heads = 16;
|
||||
sectors = 63;
|
||||
}
|
||||
sector_count = cylinders * heads * sectors;
|
||||
}
|
||||
offset_to_bootsector = sectors;
|
||||
sector_count = cylinders * heads * sectors;
|
||||
hd_size = sector_count * 512;
|
||||
size_in_mb = (Bit32u)(hd_size >> 20);
|
||||
if (size_in_mb >= 2047) {
|
||||
if ((size_in_mb >= 2047) || (fat_type == 32)) {
|
||||
fat_type = 32;
|
||||
sectors_per_cluster = 8;
|
||||
first_cluster_of_root_dir = 2;
|
||||
@ -1039,8 +1096,10 @@ int vvfat_image_t::open(const char* dirname)
|
||||
sectors_per_cluster = 32;
|
||||
} else if (size_in_mb >= 255) {
|
||||
sectors_per_cluster = 16;
|
||||
} else {
|
||||
} else if (size_in_mb >= 127) {
|
||||
sectors_per_cluster = 8;
|
||||
} else {
|
||||
sectors_per_cluster = 4;
|
||||
}
|
||||
first_cluster_of_root_dir = 0;
|
||||
root_entries = 512;
|
||||
@ -1050,7 +1109,7 @@ int vvfat_image_t::open(const char* dirname)
|
||||
current_cluster = 0xffff;
|
||||
current_fd = 0;
|
||||
|
||||
if (offset_to_bootsector > 0)
|
||||
if ((!use_mbr_file) && (offset_to_bootsector > 0))
|
||||
init_mbr();
|
||||
|
||||
init_directories(dirname);
|
||||
@ -1242,7 +1301,7 @@ ssize_t vvfat_image_t::write(const void* buf, size_t count)
|
||||
{
|
||||
Bit32u scount = (Bit32u)(count / 512);
|
||||
|
||||
if (sector_num < (offset_to_bootsector + 1))
|
||||
if (sector_num < (offset_to_bootsector + reserved_sectors))
|
||||
return -1;
|
||||
|
||||
BX_ERROR(("VVFAT write not supported yet: sector=%d, count=%d", sector_num, scount));
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: vvfat.h,v 1.3 2010-12-30 12:30:58 vruppert Exp $
|
||||
// $Id: vvfat.h,v 1.4 2010-12-31 15:39:27 vruppert Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2010 The Bochs Project
|
||||
@ -135,6 +135,7 @@ class vvfat_image_t : public device_image_t
|
||||
int find_mapping_for_cluster_aux(int cluster_num, int index1, int index2);
|
||||
mapping_t* find_mapping_for_cluster(int cluster_num);
|
||||
int read_cluster(int cluster_num);
|
||||
bx_bool read_sector_from_file(const char *path, Bit8u *buffer, Bit32u sector);
|
||||
|
||||
Bit8u *first_sectors;
|
||||
Bit32u offset_to_bootsector;
|
||||
@ -144,7 +145,7 @@ class vvfat_image_t : public device_image_t
|
||||
|
||||
Bit16u cluster_size;
|
||||
Bit8u sectors_per_cluster;
|
||||
Bit8u sectors_per_fat;
|
||||
Bit32u sectors_per_fat;
|
||||
Bit32u sector_count;
|
||||
Bit32u cluster_count; // total number of clusters of this partition
|
||||
Bit32u max_fat_value;
|
||||
@ -163,6 +164,9 @@ class vvfat_image_t : public device_image_t
|
||||
|
||||
const char *path;
|
||||
Bit32u sector_num;
|
||||
|
||||
bx_bool use_mbr_file;
|
||||
bx_bool use_boot_file;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user