volume: Replace concept of partition handle with that of volumes, fix bug in indexing volumes along the way
This commit is contained in:
parent
1e80f131c8
commit
e3d59254b5
BIN
limine-pxe.bin
BIN
limine-pxe.bin
Binary file not shown.
BIN
limine.bin
BIN
limine.bin
Binary file not shown.
BIN
stage2.map
BIN
stage2.map
Binary file not shown.
|
@ -23,7 +23,7 @@ struct echfs_identity_table {
|
|||
#define DIR_TYPE 1
|
||||
|
||||
static int read_block(struct echfs_file_handle *file, void *buf, uint64_t block, uint64_t offset, uint64_t count) {
|
||||
return part_read(&file->part, buf, (file->alloc_map[block] * file->block_size) + offset, count);
|
||||
return volume_read(&file->part, buf, (file->alloc_map[block] * file->block_size) + offset, count);
|
||||
}
|
||||
|
||||
int echfs_read(struct echfs_file_handle *file, void *buf, uint64_t loc, uint64_t count) {
|
||||
|
@ -42,9 +42,9 @@ int echfs_read(struct echfs_file_handle *file, void *buf, uint64_t loc, uint64_t
|
|||
return 0;
|
||||
}
|
||||
|
||||
int echfs_check_signature(struct part *part) {
|
||||
int echfs_check_signature(struct volume *part) {
|
||||
struct echfs_identity_table id_table;
|
||||
part_read(part, &id_table, 0, sizeof(struct echfs_identity_table));
|
||||
volume_read(part, &id_table, 0, sizeof(struct echfs_identity_table));
|
||||
|
||||
if (strncmp(id_table.signature, "_ECH_FS_", 8)) {
|
||||
return 0;
|
||||
|
@ -53,9 +53,9 @@ int echfs_check_signature(struct part *part) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
bool echfs_get_guid(struct guid *guid, struct part *part) {
|
||||
bool echfs_get_guid(struct guid *guid, struct volume *part) {
|
||||
struct echfs_identity_table id_table;
|
||||
part_read(part, &id_table, 0, sizeof(struct echfs_identity_table));
|
||||
volume_read(part, &id_table, 0, sizeof(struct echfs_identity_table));
|
||||
|
||||
if (strncmp(id_table.signature, "_ECH_FS_", 8)) {
|
||||
return false;
|
||||
|
@ -66,14 +66,14 @@ bool echfs_get_guid(struct guid *guid, struct part *part) {
|
|||
return true;
|
||||
}
|
||||
|
||||
int echfs_open(struct echfs_file_handle *ret, struct part *part, const char *path) {
|
||||
int echfs_open(struct echfs_file_handle *ret, struct volume *part, const char *path) {
|
||||
const char *fullpath = path;
|
||||
|
||||
ret->disk = part->drive;
|
||||
ret->part = *part;
|
||||
|
||||
struct echfs_identity_table id_table;
|
||||
part_read(&ret->part, &id_table, 0, sizeof(struct echfs_identity_table));
|
||||
volume_read(&ret->part, &id_table, 0, sizeof(struct echfs_identity_table));
|
||||
|
||||
if (strncmp(id_table.signature, "_ECH_FS_", 8)) {
|
||||
print("echfs: signature invalid\n");
|
||||
|
@ -106,7 +106,7 @@ next:;
|
|||
}
|
||||
|
||||
for (uint64_t i = 0; i < ret->dir_length; i += sizeof(struct echfs_dir_entry)) {
|
||||
part_read(&ret->part, &ret->dir_entry, i + ret->dir_offset, sizeof(struct echfs_dir_entry));
|
||||
volume_read(&ret->part, &ret->dir_entry, i + ret->dir_offset, sizeof(struct echfs_dir_entry));
|
||||
|
||||
if (!ret->dir_entry.parent_id) {
|
||||
break;
|
||||
|
@ -136,7 +136,7 @@ found:;
|
|||
ret->alloc_map[0] = ret->dir_entry.payload;
|
||||
for (uint64_t i = 1; i < file_block_count; i++) {
|
||||
// Read the next block.
|
||||
part_read(&ret->part,
|
||||
volume_read(&ret->part,
|
||||
&ret->alloc_map[i],
|
||||
ret->alloc_table_offset + ret->alloc_map[i-1] * sizeof(uint64_t),
|
||||
sizeof(uint64_t));
|
||||
|
|
|
@ -22,7 +22,7 @@ struct echfs_dir_entry {
|
|||
|
||||
struct echfs_file_handle {
|
||||
int disk;
|
||||
struct part part;
|
||||
struct volume part;
|
||||
uint64_t block_size;
|
||||
uint64_t block_count;
|
||||
uint64_t dir_length;
|
||||
|
@ -33,10 +33,10 @@ struct echfs_file_handle {
|
|||
struct echfs_dir_entry dir_entry;
|
||||
};
|
||||
|
||||
int echfs_check_signature(struct part *part);
|
||||
bool echfs_get_guid(struct guid *guid, struct part *part);
|
||||
int echfs_check_signature(struct volume *part);
|
||||
bool echfs_get_guid(struct guid *guid, struct volume *part);
|
||||
|
||||
int echfs_open(struct echfs_file_handle *ret, struct part *part, const char *filename);
|
||||
int echfs_open(struct echfs_file_handle *ret, struct volume *part, const char *filename);
|
||||
int echfs_read(struct echfs_file_handle *file, void *buf, uint64_t loc, uint64_t count);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -138,7 +138,7 @@ static bool ext2_get_inode(struct ext2_inode *ret,
|
|||
struct ext2_bgd target_descriptor;
|
||||
const uint64_t bgd_offset = bgd_start_offset + (sizeof(struct ext2_bgd) * ino_blk_grp);
|
||||
|
||||
part_read(&fd->part, &target_descriptor, bgd_offset, sizeof(struct ext2_bgd));
|
||||
volume_read(&fd->part, &target_descriptor, bgd_offset, sizeof(struct ext2_bgd));
|
||||
|
||||
ino_offset = ((target_descriptor.bg_inode_table) * block_size) +
|
||||
(ino_size * ino_tbl_idx);
|
||||
|
@ -146,13 +146,13 @@ static bool ext2_get_inode(struct ext2_inode *ret,
|
|||
struct ext4_bgd target_descriptor;
|
||||
const uint64_t bgd_offset = bgd_start_offset + (sizeof(struct ext4_bgd) * ino_blk_grp);
|
||||
|
||||
part_read(&fd->part, &target_descriptor, bgd_offset, sizeof(struct ext4_bgd));
|
||||
volume_read(&fd->part, &target_descriptor, bgd_offset, sizeof(struct ext4_bgd));
|
||||
|
||||
ino_offset = ((target_descriptor.bg_inode_table | (bit64 ? ((uint64_t)target_descriptor.inode_id_hi << 32) : 0)) * block_size) +
|
||||
(ino_size * ino_tbl_idx);
|
||||
}
|
||||
|
||||
part_read(&fd->part, ret, ino_offset, sizeof(struct ext2_inode));
|
||||
volume_read(&fd->part, ret, ino_offset, sizeof(struct ext2_inode));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -183,7 +183,7 @@ static uint32_t *create_alloc_map(struct ext2_file_handle *fd,
|
|||
panic("ext2: triply indirect blocks unsupported");
|
||||
}
|
||||
uint32_t indirect_block;
|
||||
part_read(
|
||||
volume_read(
|
||||
&fd->part, &indirect_block,
|
||||
inode->i_blocks[13] * fd->block_size + index * sizeof(uint32_t),
|
||||
sizeof(uint32_t)
|
||||
|
@ -191,7 +191,7 @@ static uint32_t *create_alloc_map(struct ext2_file_handle *fd,
|
|||
for (uint32_t j = 0; j < entries_per_block; j++) {
|
||||
if (i + j >= inode->i_blocks_count)
|
||||
return alloc_map;
|
||||
part_read(
|
||||
volume_read(
|
||||
&fd->part, &alloc_map[i + j],
|
||||
indirect_block * fd->block_size + j * sizeof(uint32_t),
|
||||
sizeof(uint32_t)
|
||||
|
@ -200,7 +200,7 @@ static uint32_t *create_alloc_map(struct ext2_file_handle *fd,
|
|||
i += entries_per_block - 1;
|
||||
} else {
|
||||
// Single indirect block
|
||||
part_read(
|
||||
volume_read(
|
||||
&fd->part, &alloc_map[i],
|
||||
inode->i_blocks[12] * fd->block_size + block * sizeof(uint32_t),
|
||||
sizeof(uint32_t)
|
||||
|
@ -288,10 +288,10 @@ next:
|
|||
return false;
|
||||
}
|
||||
|
||||
int ext2_open(struct ext2_file_handle *ret, struct part *part, const char *path) {
|
||||
int ext2_open(struct ext2_file_handle *ret, struct volume *part, const char *path) {
|
||||
ret->part = *part;
|
||||
|
||||
part_read(&ret->part, &ret->sb, 1024, sizeof(struct ext2_superblock));
|
||||
volume_read(&ret->part, &ret->sb, 1024, sizeof(struct ext2_superblock));
|
||||
|
||||
struct ext2_superblock *sb = &ret->sb;
|
||||
|
||||
|
@ -330,7 +330,7 @@ int ext2_read(struct ext2_file_handle *file, void *buf, uint64_t loc, uint64_t c
|
|||
return inode_read(buf, loc, count, &file->inode, file, file->alloc_map);
|
||||
}
|
||||
|
||||
static struct ext4_extent_header* ext4_find_leaf(struct ext4_extent_header* ext_block, uint32_t read_block, uint64_t block_size, struct part *part) {
|
||||
static struct ext4_extent_header* ext4_find_leaf(struct ext4_extent_header* ext_block, uint32_t read_block, uint64_t block_size, struct volume *part) {
|
||||
struct ext4_extent_idx* index;
|
||||
void* buf = NULL;
|
||||
|
||||
|
@ -357,7 +357,7 @@ static struct ext4_extent_header* ext4_find_leaf(struct ext4_extent_header* ext_
|
|||
uint64_t block = ((uint64_t)index[i].leaf_hi << 32) | index[i].leaf;
|
||||
if(!buf)
|
||||
buf = ext_mem_alloc(block_size);
|
||||
part_read(part, buf, (block * block_size), block_size);
|
||||
volume_read(part, buf, (block * block_size), block_size);
|
||||
ext_block = buf;
|
||||
}
|
||||
}
|
||||
|
@ -407,7 +407,7 @@ static int inode_read(void *buf, uint64_t loc, uint64_t count,
|
|||
block_index = alloc_map[block];
|
||||
}
|
||||
|
||||
part_read(&fd->part, buf + progress, (block_index * fd->block_size) + offset, chunk);
|
||||
volume_read(&fd->part, buf + progress, (block_index * fd->block_size) + offset, chunk);
|
||||
|
||||
progress += chunk;
|
||||
}
|
||||
|
@ -417,9 +417,9 @@ static int inode_read(void *buf, uint64_t loc, uint64_t count,
|
|||
|
||||
// attempts to initialize the ext2 filesystem
|
||||
// and checks if all features are supported
|
||||
int ext2_check_signature(struct part *part) {
|
||||
int ext2_check_signature(struct volume *part) {
|
||||
struct ext2_superblock sb;
|
||||
part_read(part, &sb, 1024, sizeof(struct ext2_superblock));
|
||||
volume_read(part, &sb, 1024, sizeof(struct ext2_superblock));
|
||||
|
||||
if (sb.s_magic != EXT2_S_MAGIC)
|
||||
return 0;
|
||||
|
@ -437,9 +437,9 @@ int ext2_check_signature(struct part *part) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
bool ext2_get_guid(struct guid *guid, struct part *part) {
|
||||
bool ext2_get_guid(struct guid *guid, struct volume *part) {
|
||||
struct ext2_superblock sb;
|
||||
part_read(part, &sb, 1024, sizeof(struct ext2_superblock));
|
||||
volume_read(part, &sb, 1024, sizeof(struct ext2_superblock));
|
||||
|
||||
if (sb.s_magic != EXT2_S_MAGIC)
|
||||
return false;
|
||||
|
|
|
@ -113,7 +113,7 @@ struct ext2_inode {
|
|||
} __attribute__((packed));
|
||||
|
||||
struct ext2_file_handle {
|
||||
struct part part;
|
||||
struct volume part;
|
||||
struct ext2_superblock sb;
|
||||
int size;
|
||||
struct ext2_inode root_inode;
|
||||
|
@ -122,10 +122,10 @@ struct ext2_file_handle {
|
|||
uint32_t *alloc_map;
|
||||
};
|
||||
|
||||
int ext2_check_signature(struct part *part);
|
||||
bool ext2_get_guid(struct guid *guid, struct part *part);
|
||||
int ext2_check_signature(struct volume *part);
|
||||
bool ext2_get_guid(struct guid *guid, struct volume *part);
|
||||
|
||||
int ext2_open(struct ext2_file_handle *ret, struct part *part, const char *path);
|
||||
int ext2_open(struct ext2_file_handle *ret, struct volume *part, const char *path);
|
||||
int ext2_read(struct ext2_file_handle *file, void *buf, uint64_t loc, uint64_t count);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -67,12 +67,12 @@ struct fat32_lfn_entry {
|
|||
char name3[4];
|
||||
} __attribute__((packed));
|
||||
|
||||
static int fat32_init_context(struct fat32_context* context, struct part *part) {
|
||||
static int fat32_init_context(struct fat32_context* context, struct volume *part) {
|
||||
context->part = *part;
|
||||
context->drive = part->drive;
|
||||
|
||||
struct fat32_bpb bpb;
|
||||
part_read(&context->part, &bpb, 0, sizeof(struct fat32_bpb));
|
||||
volume_read(&context->part, &bpb, 0, sizeof(struct fat32_bpb));
|
||||
|
||||
if (bpb.signature != FAT32_VALID_SIGNATURE_1 && bpb.signature != FAT32_VALID_SIGNATURE_2) {
|
||||
return 1;
|
||||
|
@ -99,7 +99,7 @@ static int fat32_read_cluster_from_map(struct fat32_context* context, uint32_t c
|
|||
const uint32_t offset = cluster % (FAT32_SECTOR_SIZE / 4);
|
||||
|
||||
uint32_t clusters[FAT32_SECTOR_SIZE / sizeof(uint32_t)];
|
||||
int r = part_read(&context->part, &clusters[0], (context->fat_start_lba + sector) * FAT32_SECTOR_SIZE, sizeof(clusters));
|
||||
int r = volume_read(&context->part, &clusters[0], (context->fat_start_lba + sector) * FAT32_SECTOR_SIZE, sizeof(clusters));
|
||||
|
||||
if (r) {
|
||||
return r;
|
||||
|
@ -144,7 +144,7 @@ static bool read_cluster_chain(struct fat32_context *context,
|
|||
chunk = block_size - offset;
|
||||
|
||||
uint64_t base = (context->data_start_lba + (cluster_chain[block] - 2)) * block_size;
|
||||
int r = part_read(&context->part, buf + progress, base + offset, chunk);
|
||||
int r = volume_read(&context->part, buf + progress, base + offset, chunk);
|
||||
|
||||
if (r)
|
||||
return false;
|
||||
|
@ -253,12 +253,12 @@ static int fat32_open_in(struct fat32_context* context, struct fat32_directory_e
|
|||
return -1;
|
||||
}
|
||||
|
||||
int fat32_check_signature(struct part *part) {
|
||||
int fat32_check_signature(struct volume *part) {
|
||||
struct fat32_context context;
|
||||
return fat32_init_context(&context, part) == 0;
|
||||
}
|
||||
|
||||
int fat32_open(struct fat32_file_handle* ret, struct part *part, const char* path) {
|
||||
int fat32_open(struct fat32_file_handle* ret, struct volume *part, const char* path) {
|
||||
struct fat32_context context;
|
||||
int r = fat32_init_context(&context, part);
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
struct fat32_context {
|
||||
int drive;
|
||||
struct part part;
|
||||
struct volume part;
|
||||
uint8_t sectors_per_cluster;
|
||||
uint16_t reserved_sectors;
|
||||
uint8_t number_of_fats;
|
||||
|
@ -25,9 +25,9 @@ struct fat32_file_handle {
|
|||
uint32_t *cluster_chain;
|
||||
};
|
||||
|
||||
int fat32_check_signature(struct part *part);
|
||||
int fat32_check_signature(struct volume *part);
|
||||
|
||||
int fat32_open(struct fat32_file_handle *ret, struct part *part, const char *path);
|
||||
int fat32_open(struct fat32_file_handle *ret, struct volume *part, const char *path);
|
||||
int fat32_read(struct fat32_file_handle *file, void *buf, uint64_t loc, uint64_t count);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
#include <lib/part.h>
|
||||
#include <lib/libc.h>
|
||||
|
||||
bool fs_get_guid(struct guid *guid, struct part *part) {
|
||||
bool fs_get_guid(struct guid *guid, struct volume *part) {
|
||||
if (echfs_check_signature(part)) {
|
||||
return echfs_get_guid(guid, part);
|
||||
}
|
||||
|
@ -20,7 +20,7 @@ bool fs_get_guid(struct guid *guid, struct part *part) {
|
|||
return false;
|
||||
}
|
||||
|
||||
int fopen(struct file_handle *ret, struct part *part, const char *filename) {
|
||||
int fopen(struct file_handle *ret, struct volume *part, const char *filename) {
|
||||
ret->is_memfile = false;
|
||||
|
||||
if (echfs_check_signature(part)) {
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
#include <stdbool.h>
|
||||
#include <lib/part.h>
|
||||
|
||||
bool fs_get_guid(struct guid *guid, struct part *part);
|
||||
bool fs_get_guid(struct guid *guid, struct volume *part);
|
||||
|
||||
struct file_handle {
|
||||
bool is_memfile;
|
||||
|
@ -15,7 +15,7 @@ struct file_handle {
|
|||
uint64_t size;
|
||||
};
|
||||
|
||||
int fopen(struct file_handle *ret, struct part *part, const char *filename);
|
||||
int fopen(struct file_handle *ret, struct volume *part, const char *filename);
|
||||
int fread(struct file_handle *fd, void *buf, uint64_t loc, uint64_t count);
|
||||
void *freadall(struct file_handle *fd, uint32_t type);
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@ bool config_ready = false;
|
|||
|
||||
static char *config_addr;
|
||||
|
||||
int init_config_disk(struct part *part) {
|
||||
int init_config_disk(struct volume *part) {
|
||||
struct file_handle f;
|
||||
|
||||
if (fopen(&f, part, "/limine.cfg")
|
||||
|
|
|
@ -18,7 +18,7 @@ struct menu_entry {
|
|||
|
||||
extern struct menu_entry *menu_tree;
|
||||
|
||||
int init_config_disk(struct part *part);
|
||||
int init_config_disk(struct volume *part);
|
||||
int init_config_pxe(void);
|
||||
int init_config(size_t config_size);
|
||||
bool config_get_entry_name(char *ret, size_t index, size_t limit);
|
||||
|
|
|
@ -46,27 +46,47 @@ struct gpt_entry {
|
|||
uint16_t partition_name[36];
|
||||
} __attribute__((packed));
|
||||
|
||||
static int gpt_get_part(struct part *ret, int drive, int partition) {
|
||||
static bool gpt_get_guid(struct guid *guid, struct volume *volume) {
|
||||
struct gpt_table_header header = {0};
|
||||
|
||||
int sector_size = disk_get_sector_size(drive);
|
||||
int sector_size = disk_get_sector_size(volume->drive);
|
||||
|
||||
// read header, located after the first block
|
||||
disk_read(drive, &header, sector_size * 1, sizeof(header));
|
||||
volume_read(volume, &header, sector_size * 1, sizeof(header));
|
||||
|
||||
// check the header
|
||||
// 'EFI PART'
|
||||
if (strncmp(header.signature, "EFI PART", 8))
|
||||
return false;
|
||||
if (header.revision != 0x00010000)
|
||||
return false;
|
||||
|
||||
*guid = header.disk_guid;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static int gpt_get_part(struct volume *ret, struct volume *volume, int partition) {
|
||||
struct gpt_table_header header = {0};
|
||||
|
||||
int sector_size = disk_get_sector_size(volume->drive);
|
||||
|
||||
// read header, located after the first block
|
||||
volume_read(volume, &header, sector_size * 1, sizeof(header));
|
||||
|
||||
// check the header
|
||||
// 'EFI PART'
|
||||
if (strncmp(header.signature, "EFI PART", 8))
|
||||
return INVALID_TABLE;
|
||||
if (header.revision != 0x00010000)
|
||||
return END_OF_TABLE;
|
||||
return INVALID_TABLE;
|
||||
|
||||
// parse the entries if reached here
|
||||
if ((uint32_t)partition >= header.number_of_partition_entries)
|
||||
return END_OF_TABLE;
|
||||
|
||||
struct gpt_entry entry = {0};
|
||||
disk_read(drive, &entry,
|
||||
volume_read(volume, &entry,
|
||||
(header.partition_entry_lba * sector_size) + (partition * sizeof(entry)),
|
||||
sizeof(entry));
|
||||
|
||||
|
@ -74,7 +94,7 @@ static int gpt_get_part(struct part *ret, int drive, int partition) {
|
|||
if (!memcmp(&entry.unique_partition_guid, &empty_guid, sizeof(struct guid)))
|
||||
return NO_PARTITION;
|
||||
|
||||
ret->drive = drive;
|
||||
ret->drive = volume->drive;
|
||||
ret->partition = partition;
|
||||
ret->sector_size = sector_size;
|
||||
ret->first_sect = entry.starting_lba;
|
||||
|
@ -103,8 +123,8 @@ struct mbr_entry {
|
|||
uint32_t sect_count;
|
||||
} __attribute__((packed));
|
||||
|
||||
static int mbr_get_logical_part(struct part *ret, struct part *extended_part,
|
||||
int drive, int partition) {
|
||||
static int mbr_get_logical_part(struct volume *ret, struct volume *extended_part,
|
||||
int partition) {
|
||||
struct mbr_entry entry;
|
||||
|
||||
size_t ebr_sector = 0;
|
||||
|
@ -113,7 +133,7 @@ static int mbr_get_logical_part(struct part *ret, struct part *extended_part,
|
|||
size_t entry_offset = ebr_sector * extended_part->sector_size + 0x1ce;
|
||||
|
||||
int r;
|
||||
r = part_read(extended_part, &entry, entry_offset, sizeof(struct mbr_entry));
|
||||
r = volume_read(extended_part, &entry, entry_offset, sizeof(struct mbr_entry));
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
|
@ -126,16 +146,16 @@ static int mbr_get_logical_part(struct part *ret, struct part *extended_part,
|
|||
size_t entry_offset = ebr_sector * extended_part->sector_size + 0x1be;
|
||||
|
||||
int r;
|
||||
r = part_read(extended_part, &entry, entry_offset, sizeof(struct mbr_entry));
|
||||
r = volume_read(extended_part, &entry, entry_offset, sizeof(struct mbr_entry));
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
if (entry.type == 0)
|
||||
return NO_PARTITION;
|
||||
|
||||
ret->drive = drive;
|
||||
ret->drive = extended_part->drive;
|
||||
ret->partition = partition + 4;
|
||||
ret->sector_size = disk_get_sector_size(drive);
|
||||
ret->sector_size = disk_get_sector_size(extended_part->drive);
|
||||
ret->first_sect = extended_part->first_sect + ebr_sector + entry.first_sect;
|
||||
ret->sect_count = entry.sect_count;
|
||||
|
||||
|
@ -152,10 +172,10 @@ static int mbr_get_logical_part(struct part *ret, struct part *extended_part,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int mbr_get_part(struct part *ret, int drive, int partition) {
|
||||
static int mbr_get_part(struct volume *ret, struct volume *volume, int partition) {
|
||||
// Check if actually valid mbr
|
||||
uint16_t hint;
|
||||
disk_read(drive, &hint, 444, sizeof(uint16_t));
|
||||
volume_read(volume, &hint, 444, sizeof(uint16_t));
|
||||
if (hint && hint != 0x5a5a)
|
||||
return INVALID_TABLE;
|
||||
|
||||
|
@ -165,22 +185,22 @@ static int mbr_get_part(struct part *ret, int drive, int partition) {
|
|||
for (int i = 0; i < 4; i++) {
|
||||
size_t entry_offset = 0x1be + sizeof(struct mbr_entry) * i;
|
||||
|
||||
int r = disk_read(drive, &entry, entry_offset, sizeof(struct mbr_entry));
|
||||
int r = volume_read(volume, &entry, entry_offset, sizeof(struct mbr_entry));
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
if (entry.type != 0x0f)
|
||||
continue;
|
||||
|
||||
struct part extended_part;
|
||||
struct volume extended_part;
|
||||
|
||||
extended_part.drive = drive;
|
||||
extended_part.drive = volume->drive;
|
||||
extended_part.partition = i;
|
||||
extended_part.sector_size = disk_get_sector_size(drive);
|
||||
extended_part.sector_size = disk_get_sector_size(volume->drive);
|
||||
extended_part.first_sect = entry.first_sect;
|
||||
extended_part.sect_count = entry.sect_count;
|
||||
|
||||
return mbr_get_logical_part(ret, &extended_part, drive, partition - 4);
|
||||
return mbr_get_logical_part(ret, &extended_part, partition - 4);
|
||||
}
|
||||
|
||||
return END_OF_TABLE;
|
||||
|
@ -188,16 +208,16 @@ static int mbr_get_part(struct part *ret, int drive, int partition) {
|
|||
|
||||
size_t entry_offset = 0x1be + sizeof(struct mbr_entry) * partition;
|
||||
|
||||
int r = disk_read(drive, &entry, entry_offset, sizeof(struct mbr_entry));
|
||||
int r = volume_read(volume, &entry, entry_offset, sizeof(struct mbr_entry));
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
if (entry.type == 0)
|
||||
return NO_PARTITION;
|
||||
|
||||
ret->drive = drive;
|
||||
ret->drive = volume->drive;
|
||||
ret->partition = partition;
|
||||
ret->sector_size = disk_get_sector_size(drive);
|
||||
ret->sector_size = disk_get_sector_size(volume->drive);
|
||||
ret->first_sect = entry.first_sect;
|
||||
ret->sect_count = entry.sect_count;
|
||||
|
||||
|
@ -214,24 +234,26 @@ static int mbr_get_part(struct part *ret, int drive, int partition) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int part_get(struct part *part, int drive, int partition) {
|
||||
int part_get(struct volume *part, struct volume *volume, int partition) {
|
||||
int ret;
|
||||
|
||||
ret = gpt_get_part(part, drive, partition);
|
||||
ret = gpt_get_part(part, volume, partition);
|
||||
if (ret != INVALID_TABLE)
|
||||
return ret;
|
||||
|
||||
ret = mbr_get_part(part, drive, partition);
|
||||
ret = mbr_get_part(part, volume, partition);
|
||||
if (ret != INVALID_TABLE)
|
||||
return ret;
|
||||
|
||||
return INVALID_TABLE;
|
||||
}
|
||||
|
||||
static struct part *part_index = NULL;
|
||||
static size_t part_index_i = 0;
|
||||
static struct volume *volume_index = NULL;
|
||||
static size_t volume_index_i = 0;
|
||||
|
||||
void volume_create_index(void) {
|
||||
size_t volume_count = 0;
|
||||
|
||||
void part_create_index(void) {
|
||||
for (uint8_t drive = 0x80; drive < 0x8f; drive++) {
|
||||
struct rm_regs r = {0};
|
||||
struct bios_drive_params drive_params;
|
||||
|
@ -252,51 +274,105 @@ void part_create_index(void) {
|
|||
print(" ... %X total %u-byte sectors\n",
|
||||
drive_params.lba_count, drive_params.bytes_per_sect);
|
||||
|
||||
size_t part_count = 0;
|
||||
volume_count++;
|
||||
|
||||
struct volume block;
|
||||
|
||||
block.drive = drive;
|
||||
block.sector_size = drive_params.bytes_per_sect;
|
||||
block.first_sect = 0;
|
||||
block.sect_count = drive_params.lba_count;
|
||||
|
||||
load_up:
|
||||
for (int part = 0; ; part++) {
|
||||
struct part p;
|
||||
int ret = part_get(&p, drive, part);
|
||||
struct volume p;
|
||||
int ret = part_get(&p, &block, part);
|
||||
|
||||
if (ret == END_OF_TABLE)
|
||||
if (ret == END_OF_TABLE || ret == INVALID_TABLE)
|
||||
break;
|
||||
if (ret == NO_PARTITION)
|
||||
continue;
|
||||
|
||||
if (part_index)
|
||||
part_index[part_index_i++] = p;
|
||||
else
|
||||
part_count++;
|
||||
volume_count++;
|
||||
}
|
||||
}
|
||||
|
||||
volume_index = ext_mem_alloc(sizeof(struct volume) * volume_count);
|
||||
|
||||
for (uint8_t drive = 0x80; drive < 0x8f; drive++) {
|
||||
struct rm_regs r = {0};
|
||||
struct bios_drive_params drive_params;
|
||||
|
||||
r.eax = 0x4800;
|
||||
r.edx = drive;
|
||||
r.ds = rm_seg(&drive_params);
|
||||
r.esi = rm_off(&drive_params);
|
||||
|
||||
drive_params.buf_size = sizeof(struct bios_drive_params);
|
||||
|
||||
rm_int(0x13, &r, &r);
|
||||
|
||||
if (r.eflags & EFLAGS_CF)
|
||||
continue;
|
||||
|
||||
struct volume *block = &volume_index[volume_index_i++];
|
||||
|
||||
block->drive = drive;
|
||||
block->partition = -1;
|
||||
block->sector_size = drive_params.bytes_per_sect;
|
||||
block->first_sect = 0;
|
||||
block->sect_count = drive_params.lba_count;
|
||||
|
||||
if (gpt_get_guid(&block->guid, block)) {
|
||||
block->guid_valid = true;
|
||||
}
|
||||
|
||||
if (part_index)
|
||||
return;
|
||||
for (int part = 0; ; part++) {
|
||||
struct volume p;
|
||||
int ret = part_get(&p, block, part);
|
||||
|
||||
part_index = ext_mem_alloc(sizeof(struct part) * part_count);
|
||||
goto load_up;
|
||||
if (ret == END_OF_TABLE || ret == INVALID_TABLE)
|
||||
break;
|
||||
if (ret == NO_PARTITION)
|
||||
continue;
|
||||
|
||||
volume_index[volume_index_i++] = p;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool part_get_by_guid(struct part *part, struct guid *guid) {
|
||||
bool volume_get_by_guid(struct volume *part, struct guid *guid) {
|
||||
size_t i;
|
||||
for (i = 0; i < part_index_i; i++) {
|
||||
if (part_index[i].guid_valid
|
||||
&& memcmp(&part_index[i].guid, guid, 16) == 0) {
|
||||
for (i = 0; i < volume_index_i; i++) {
|
||||
if (volume_index[i].guid_valid
|
||||
&& memcmp(&volume_index[i].guid, guid, 16) == 0) {
|
||||
goto found;
|
||||
}
|
||||
if (part_index[i].part_guid_valid
|
||||
&& memcmp(&part_index[i].part_guid, guid, 16) == 0) {
|
||||
if (volume_index[i].part_guid_valid
|
||||
&& memcmp(&volume_index[i].part_guid, guid, 16) == 0) {
|
||||
goto found;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
found:
|
||||
*part = part_index[i];
|
||||
*part = volume_index[i];
|
||||
return true;
|
||||
}
|
||||
|
||||
int part_read(struct part *part, void *buffer, uint64_t loc, uint64_t count) {
|
||||
bool volume_get_by_coord(struct volume *part, int drive, int partition) {
|
||||
size_t i;
|
||||
for (i = 0; i < volume_index_i; i++) {
|
||||
if (volume_index[i].drive == drive
|
||||
&& volume_index[i].partition == partition) {
|
||||
goto found;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
found:
|
||||
*part = volume_index[i];
|
||||
return true;
|
||||
}
|
||||
|
||||
int volume_read(struct volume *part, void *buffer, uint64_t loc, uint64_t count) {
|
||||
return disk_read(part->drive, buffer,
|
||||
loc + (part->first_sect * part->sector_size), count);
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
#define INVALID_TABLE (-2)
|
||||
#define END_OF_TABLE (-3)
|
||||
|
||||
struct part {
|
||||
struct volume {
|
||||
int drive;
|
||||
int partition;
|
||||
int sector_size;
|
||||
|
@ -21,11 +21,12 @@ struct part {
|
|||
struct guid part_guid;
|
||||
};
|
||||
|
||||
void part_create_index(void);
|
||||
void volume_create_index(void);
|
||||
|
||||
int part_get(struct part *part, int drive, int partition);
|
||||
bool part_get_by_guid(struct part *part, struct guid *guid);
|
||||
int part_get(struct volume *part, struct volume *volume, int partition);
|
||||
bool volume_get_by_guid(struct volume *part, struct guid *guid);
|
||||
bool volume_get_by_coord(struct volume *part, int drive, int partition);
|
||||
|
||||
int part_read(struct part *part, void *buffer, uint64_t loc, uint64_t count);
|
||||
int volume_read(struct volume *part, void *buffer, uint64_t loc, uint64_t count);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -97,11 +97,11 @@ static bool uri_bios_dispatch(struct file_handle *fd, char *loc, char *path) {
|
|||
if (!parse_bios_partition(loc, &drive, &partition))
|
||||
return false;
|
||||
|
||||
struct part part;
|
||||
if (part_get(&part, drive, partition))
|
||||
struct volume volume;
|
||||
if (!volume_get_by_coord(&volume, drive, partition))
|
||||
return false;
|
||||
|
||||
if (fopen(fd, &part, path))
|
||||
if (fopen(fd, &volume, path))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
|
@ -112,12 +112,12 @@ static bool uri_guid_dispatch(struct file_handle *fd, char *guid_str, char *path
|
|||
if (!string_to_guid_be(&guid, guid_str))
|
||||
return false;
|
||||
|
||||
struct part part;
|
||||
if (!part_get_by_guid(&part, &guid)) {
|
||||
struct volume part;
|
||||
if (!volume_get_by_guid(&part, &guid)) {
|
||||
if (!string_to_guid_mixed(&guid, guid_str))
|
||||
return false;
|
||||
|
||||
if (!part_get_by_guid(&part, &guid))
|
||||
if (!volume_get_by_guid(&part, &guid))
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -170,8 +170,8 @@ static bool uri_boot_dispatch(struct file_handle *fd, char *s_part, char *path)
|
|||
}
|
||||
}
|
||||
|
||||
struct part part;
|
||||
if (part_get(&part, boot_drive, partition))
|
||||
struct volume part;
|
||||
if (!volume_get_by_coord(&part, boot_drive, partition))
|
||||
return false;
|
||||
|
||||
if (fopen(fd, &part, path))
|
||||
|
|
|
@ -39,7 +39,7 @@ void entry(uint8_t _boot_drive, int pxe_boot, void *_tinf_gzip_uncompress) {
|
|||
init_e820();
|
||||
init_memmap();
|
||||
|
||||
part_create_index();
|
||||
volume_create_index();
|
||||
|
||||
if (pxe_boot) {
|
||||
pxe_init();
|
||||
|
@ -52,8 +52,8 @@ void entry(uint8_t _boot_drive, int pxe_boot, void *_tinf_gzip_uncompress) {
|
|||
// Look for config file.
|
||||
print("Searching for config file...\n");
|
||||
for (int i = 0; ; i++) {
|
||||
struct part part;
|
||||
int ret = part_get(&part, boot_drive, i);
|
||||
struct volume part;
|
||||
int ret = volume_get_by_coord(&part, boot_drive, i);
|
||||
switch (ret) {
|
||||
case INVALID_TABLE:
|
||||
panic("Partition table of boot drive is invalid.");
|
||||
|
|
|
@ -75,14 +75,10 @@ void chainload(char *config) {
|
|||
|
||||
term_deinit();
|
||||
|
||||
if (part != -1) {
|
||||
struct part p;
|
||||
part_get(&p, drive, part);
|
||||
struct volume p;
|
||||
volume_get_by_coord(&p, drive, part);
|
||||
|
||||
part_read(&p, (void *)0x7c00, 0, 512);
|
||||
} else {
|
||||
disk_read(drive, (void *)0x7c00, 0, 512);
|
||||
}
|
||||
volume_read(&p, (void *)0x7c00, 0, 512);
|
||||
|
||||
mtrr_restore();
|
||||
|
||||
|
|
Loading…
Reference in New Issue