Misc stuff

This commit is contained in:
mintsuki 2021-03-04 09:15:10 +01:00
parent 7be0b35f6f
commit deac1d7fd1
17 changed files with 202 additions and 186 deletions

View File

@ -10,11 +10,11 @@
#include <efi.h>
bool disk_volume_from_efi_handle(struct volume *ret, EFI_HANDLE *efi_handle);
struct volume *disk_volume_from_efi_handle(EFI_HANDLE *efi_handle);
#endif
size_t disk_create_index(struct volume **ret);
void disk_create_index(void);
bool disk_read_sectors(struct volume *volume, void *buf, uint64_t block, size_t count);
#endif

View File

@ -80,9 +80,8 @@ bool disk_read_sectors(struct volume *volume, void *buf, uint64_t block, size_t
return true;
}
size_t disk_create_index(struct volume **ret) {
struct volume *volume_index;
size_t volume_count = 0, volume_index_i = 0;
void disk_create_index(void) {
size_t volume_count = 0;
for (uint8_t drive = 0x80; drive; drive++) {
struct rm_regs r = {0};
@ -104,8 +103,6 @@ size_t disk_create_index(struct volume **ret) {
print(" ... %X total %u-byte sectors\n",
drive_params.lba_count, drive_params.bytes_per_sect);
volume_count++;
struct volume block = {0};
block.drive = drive;
@ -120,6 +117,8 @@ size_t disk_create_index(struct volume **ret) {
continue;
}
volume_count++;
for (int part = 0; ; part++) {
struct volume p = {0};
int ret = part_get(&p, &block, part);
@ -151,7 +150,7 @@ size_t disk_create_index(struct volume **ret) {
if (r.eflags & EFLAGS_CF)
continue;
struct volume *block = &volume_index[volume_index_i++];
struct volume *block = ext_mem_alloc(sizeof(struct volume));
block->drive = drive;
block->partition = -1;
@ -165,13 +164,15 @@ size_t disk_create_index(struct volume **ret) {
continue;
}
volume_index[volume_index_i++] = block;
if (gpt_get_guid(&block->guid, block)) {
block->guid_valid = true;
}
for (int part = 0; ; part++) {
struct volume p = {0};
int ret = part_get(&p, block, part);
struct volume *p = ext_mem_alloc(sizeof(struct volume));
int ret = part_get(p, block, part);
if (ret == END_OF_TABLE || ret == INVALID_TABLE)
break;
@ -181,17 +182,14 @@ size_t disk_create_index(struct volume **ret) {
volume_index[volume_index_i++] = p;
}
}
*ret = volume_index;
return volume_count;
}
#endif
#if defined (uefi)
bool disk_volume_from_efi_handle(struct volume *ret, EFI_HANDLE *efi_handle) {
bool ok = false;
struct volume *disk_volume_from_efi_handle(EFI_HANDLE *efi_handle) {
struct volume *ret = NULL;
EFI_GUID disk_io_guid = DISK_IO_PROTOCOL;
EFI_GUID block_io_guid = BLOCK_IO_PROTOCOL;
@ -217,20 +215,19 @@ bool disk_volume_from_efi_handle(struct volume *ret, EFI_HANDLE *efi_handle) {
EFI_DISK_IO *cur_disk_io = NULL;
EFI_BLOCK_IO *cur_block_io = NULL;
uefi_call_wrapper(gBS->HandleProtocol, 3, volume_index[i].drive,
uefi_call_wrapper(gBS->HandleProtocol, 3, volume_index[i]->efi_handle,
&disk_io_guid, &cur_disk_io);
uefi_call_wrapper(gBS->HandleProtocol, 3, volume_index[i].drive,
uefi_call_wrapper(gBS->HandleProtocol, 3, volume_index[i]->efi_handle,
&block_io_guid, &cur_block_io);
uefi_call_wrapper(cur_disk_io->ReadDisk, 5, cur_disk_io,
cur_block_io->Media->MediaId,
0 +
volume_index[i].first_sect * volume_index[i].sector_size,
volume_index[i]->first_sect * volume_index[i]->sector_size,
sizeof(uint64_t), &compare);
if (compare == signature) {
*ret = volume_index[i];
ok = true;
ret = volume_index[i];
break;
}
}
@ -238,7 +235,7 @@ bool disk_volume_from_efi_handle(struct volume *ret, EFI_HANDLE *efi_handle) {
uefi_call_wrapper(disk_io->WriteDisk, 5, disk_io, block_io->Media->MediaId, 0,
sizeof(uint64_t), &orig);
return ok;
return ret;
}
bool disk_read_sectors(struct volume *volume, void *buf, uint64_t block, size_t count) {
@ -247,7 +244,7 @@ bool disk_read_sectors(struct volume *volume, void *buf, uint64_t block, size_t
EFI_GUID block_io_guid = BLOCK_IO_PROTOCOL;
EFI_BLOCK_IO *block_io = NULL;
status = uefi_call_wrapper(gBS->HandleProtocol, 3, volume->drive,
status = uefi_call_wrapper(gBS->HandleProtocol, 3, volume->efi_handle,
&block_io_guid, &block_io);
status = uefi_call_wrapper(block_io->ReadBlocks, 5, block_io,
@ -261,11 +258,9 @@ bool disk_read_sectors(struct volume *volume, void *buf, uint64_t block, size_t
return true;
}
size_t disk_create_index(struct volume **ret) {
void disk_create_index(void) {
EFI_STATUS status;
struct volume *volume_index = NULL;
size_t volume_index_i = 0;
size_t volume_count = 0;
EFI_GUID block_io_guid = BLOCK_IO_PROTOCOL;
@ -296,14 +291,14 @@ size_t disk_create_index(struct volume **ret) {
volume_count++;
block.drive = handles[i];
block.efi_handle = handles[i];
block.sector_size = block_io->Media->BlockSize;
block.first_sect = 0;
block.sect_count = block_io->Media->LastBlock + 1;
for (int part = 0; ; part++) {
struct volume p = {0};
int ret = part_get(&p, &block, part);
struct volume trash = {0};
int ret = part_get(&trash, &block, part);
if (ret == END_OF_TABLE || ret == INVALID_TABLE)
break;
@ -316,6 +311,8 @@ size_t disk_create_index(struct volume **ret) {
volume_index = ext_mem_alloc(sizeof(struct volume) * volume_count);
size_t drives_counter = 0x80;
for (size_t i = 0; i < handles_size / sizeof(EFI_HANDLE); i++) {
EFI_BLOCK_IO *drive = NULL;
@ -328,17 +325,20 @@ size_t disk_create_index(struct volume **ret) {
if (drive->Media->LogicalPartition)
continue;
struct volume *block = &volume_index[volume_index_i++];
struct volume *block = ext_mem_alloc(sizeof(struct volume));
block->drive = handles[i];
block->drive = drives_counter++;
block->efi_handle = handles[i];
block->partition = -1;
block->sector_size = drive->Media->BlockSize;
block->first_sect = 0;
block->sect_count = drive->Media->LastBlock + 1;
volume_index[volume_index_i++] = block;
for (int part = 0; ; part++) {
struct volume p = {0};
int ret = part_get(&p, block, part);
struct volume *p = ext_mem_alloc(sizeof(struct volume));
int ret = part_get(p, block, part);
if (ret == END_OF_TABLE || ret == INVALID_TABLE)
break;
@ -348,9 +348,6 @@ size_t disk_create_index(struct volume **ret) {
volume_index[volume_index_i++] = p;
}
}
*ret = volume_index;
return volume_count;
}
#endif

View File

@ -19,11 +19,12 @@
#include <menu.h>
#include <pxe/pxe.h>
#include <pxe/tftp.h>
#include <drivers/disk.h>
extern uint64_t stage3_build_id;
drive_t boot_drive;
int boot_partition = -1;
int boot_drive;
int boot_partition = -1;
bool booted_from_pxe = false;
bool booted_from_cd = false;
@ -79,29 +80,18 @@ void entry(uint8_t _boot_drive, int boot_from) {
init_e820();
init_memmap();
volume_create_index();
disk_create_index();
switch (boot_from) {
case BOOT_FROM_HDD:
case BOOT_FROM_CD: {
struct volume boot_volume = {0};
volume_get_by_coord(&boot_volume, boot_drive, -1);
struct volume part = boot_volume;
for (int i = 0; ; i++) {
if (stage3_init(&part)) {
print("Stage 3 found and loaded.\n");
break;
}
int ret = part_get(&part, &boot_volume, i);
switch (ret) {
case INVALID_TABLE:
case END_OF_TABLE:
panic("Stage 3 not found.");
}
}
struct volume *boot_volume = volume_get_by_coord(boot_drive, -1);
volume_iterate_parts(boot_volume,
if (stage3_init(_PART)) {
break;
}
}
);
if (!stage3_loaded)
panic("Failed to load stage 3.\n");
__attribute__((noreturn))
void (*stage3)(int boot_from) = (void *)stage3_addr;

View File

@ -31,7 +31,7 @@ EFI_STATUS EFIAPI efi_main(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable
print("Limine " LIMINE_VERSION "\n\n", print);
volume_create_index();
disk_create_index();
EFI_GUID loaded_img_prot_guid = EFI_LOADED_IMAGE_PROTOCOL_GUID;
EFI_LOADED_IMAGE_PROTOCOL *loaded_image = NULL;
@ -39,23 +39,54 @@ EFI_STATUS EFIAPI efi_main(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable
uefi_call_wrapper(gBS->HandleProtocol, 3, ImageHandle, &loaded_img_prot_guid,
&loaded_image);
struct volume boot_volume = {0};
if (!disk_volume_from_efi_handle(&boot_volume, loaded_image->DeviceHandle)) {
struct volume *boot_volume = disk_volume_from_efi_handle(loaded_image->DeviceHandle);
if (boot_volume == NULL) {
panic("Can't determine boot disk");
}
if (!volume_iterate_parts(boot_volume,
if (!init_config_disk(&_PART_)) {
print("Config file found and loaded.\n");
boot_partition = _PARTNUM_;
break;
if (boot_volume->backing_dev != NULL) {
boot_volume = boot_volume->backing_dev;
int part_cnt = 0;
for (size_t i = 0; ; i++) {
if (part_cnt > boot_volume->max_partition)
break;
struct volume *volume = volume_get_by_coord(boot_volume->drive, i);
if (volume == NULL)
continue;
part_cnt++;
if (!init_config_disk(volume)) {
print("Config file found and loaded.\n");
boot_partition = i;
boot_drive = boot_volume->drive;
goto config_loaded;
}
}
)) {
panic("Config file not found.");
} else {
struct volume *volume = volume_get_by_coord(boot_volume->drive, -1);
if (volume == NULL)
panic("Config file not found.");
if (!init_config_disk(volume)) {
print("Config file found and loaded.\n");
boot_partition = -1;
boot_drive = boot_volume->drive;
goto config_loaded;
}
panic("Config file not found.");
}
for (;;);
//stage3_common();
config_loaded:
print("Boot drive: %x\n", boot_drive);
print("Boot partition: %d\n", boot_partition);
stage3_common();
}
#endif
@ -66,33 +97,20 @@ uint64_t stage3_build_id = BUILD_ID;
__attribute__((noreturn))
__attribute__((section(".stage3_entry")))
void stage3_entry(int boot_from) {
(void)boot_from;
mtrr_save();
switch (boot_from) {
case BOOT_FROM_HDD:
case BOOT_FROM_CD: {
struct volume boot_volume = {0};
volume_get_by_coord(&boot_volume, boot_drive, -1);
struct volume *boot_volume = volume_get_by_coord(boot_drive, -1);
if (!volume_iterate_parts(boot_volume,
if (!init_config_disk(&_PART_)) {
print("Config file found and loaded.\n");
boot_partition = _PARTNUM_;
break;
}
)) {
panic("Config file not found.");
}
break;
case BOOT_FROM_PXE:
pxe_init();
if (init_config_pxe()) {
panic("Failed to load config file");
}
print("Config loaded via PXE\n");
volume_iterate_parts(boot_volume,
if (!init_config_disk(_PART)) {
print("Config file found and loaded.\n");
boot_partition = _PARTNO;
boot_drive = _PART->drive;
break;
}
}
);
stage3_common();
}

View File

@ -21,7 +21,7 @@ struct echfs_dir_entry {
} __attribute__((packed));
struct echfs_file_handle {
struct volume part;
struct volume *part;
uint64_t block_size;
uint64_t block_count;
uint64_t dir_length;

View File

@ -23,7 +23,7 @@ struct echfs_identity_table {
#define DIR_TYPE 1
static bool read_block(struct echfs_file_handle *file, void *buf, uint64_t block, uint64_t offset, uint64_t count) {
return volume_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) {
@ -69,10 +69,10 @@ bool echfs_get_guid(struct guid *guid, struct volume *part) {
int echfs_open(struct echfs_file_handle *ret, struct volume *part, const char *path) {
const char *fullpath = path;
ret->part = *part;
ret->part = part;
struct echfs_identity_table id_table;
volume_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");
@ -105,7 +105,7 @@ next:;
}
for (uint64_t i = 0; i < ret->dir_length; i += sizeof(struct echfs_dir_entry)) {
volume_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;
@ -135,7 +135,7 @@ found:;
ret->alloc_map[0] = ret->dir_entry.payload;
for (uint64_t i = 1; i < file_block_count; i++) {
// Read the next block.
volume_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));

View File

@ -113,7 +113,7 @@ struct ext2_inode {
} __attribute__((packed));
struct ext2_file_handle {
struct volume part;
struct volume *part;
struct ext2_superblock sb;
int size;
struct ext2_inode root_inode;

View File

@ -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);
volume_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);
volume_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);
}
volume_read(&fd->part, ret, ino_offset, sizeof(struct ext2_inode));
volume_read(fd->part, ret, ino_offset, sizeof(struct ext2_inode));
return true;
}
@ -184,7 +184,7 @@ static uint32_t *create_alloc_map(struct ext2_file_handle *fd,
}
uint32_t indirect_block;
volume_read(
&fd->part, &indirect_block,
fd->part, &indirect_block,
inode->i_blocks[13] * fd->block_size + index * sizeof(uint32_t),
sizeof(uint32_t)
);
@ -192,7 +192,7 @@ static uint32_t *create_alloc_map(struct ext2_file_handle *fd,
if (i + j >= inode->i_blocks_count)
return alloc_map;
volume_read(
&fd->part, &alloc_map[i + j],
fd->part, &alloc_map[i + j],
indirect_block * fd->block_size + j * sizeof(uint32_t),
sizeof(uint32_t)
);
@ -201,7 +201,7 @@ static uint32_t *create_alloc_map(struct ext2_file_handle *fd,
} else {
// Single indirect block
volume_read(
&fd->part, &alloc_map[i],
fd->part, &alloc_map[i],
inode->i_blocks[12] * fd->block_size + block * sizeof(uint32_t),
sizeof(uint32_t)
);
@ -289,9 +289,9 @@ next:
}
int ext2_open(struct ext2_file_handle *ret, struct volume *part, const char *path) {
ret->part = *part;
ret->part = part;
volume_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;
@ -380,7 +380,7 @@ static int inode_read(void *buf, uint64_t loc, uint64_t count,
struct ext4_extent *ext;
int i;
leaf = ext4_find_leaf((struct ext4_extent_header*)inode->i_blocks, block, fd->block_size, &fd->part);
leaf = ext4_find_leaf((struct ext4_extent_header*)inode->i_blocks, block, fd->block_size, fd->part);
if (!leaf)
panic("invalid extent");
@ -407,7 +407,7 @@ static int inode_read(void *buf, uint64_t loc, uint64_t count,
block_index = alloc_map[block];
}
volume_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;
}

View File

@ -5,7 +5,7 @@
#include <lib/part.h>
struct fat32_context {
struct volume part;
struct volume *part;
uint8_t sectors_per_cluster;
uint16_t reserved_sectors;
uint8_t number_of_fats;

View File

@ -68,10 +68,10 @@ struct fat32_lfn_entry {
} __attribute__((packed));
static int fat32_init_context(struct fat32_context* context, struct volume *part) {
context->part = *part;
context->part = part;
struct fat32_bpb bpb;
volume_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;
@ -98,7 +98,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)];
volume_read(&context->part, &clusters[0], (context->fat_start_lba + sector) * FAT32_SECTOR_SIZE, sizeof(clusters));
volume_read(context->part, &clusters[0], (context->fat_start_lba + sector) * FAT32_SECTOR_SIZE, sizeof(clusters));
*out = clusters[offset] & 0x0FFFFFFF;
return 0;
@ -139,7 +139,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;
volume_read(&context->part, buf + progress, base + offset, chunk);
volume_read(context->part, buf + progress, base + offset, chunk);
progress += chunk;
}

View File

@ -7,7 +7,7 @@
#define ISO9660_SECTOR_SIZE (2 << 10)
struct iso9660_context {
struct volume vol;
struct volume *vol;
void* root;
uint32_t root_size;
};

View File

@ -108,14 +108,14 @@ static void iso9660_cache_root(struct volume *vol,
static struct iso9660_context *iso9660_get_context(struct volume *vol) {
struct iso9660_contexts_node *current = contexts;
while (current) {
if (current->context.vol.drive == vol->drive)
if (current->context.vol == vol)
return &current->context;
current = current->next;
}
// The context is not cached at this point
struct iso9660_contexts_node *node = ext_mem_alloc(sizeof(struct iso9660_contexts_node));
node->context.vol = *vol;
node->context.vol = vol;
iso9660_cache_root(vol, &node->context.root, &node->context.root_size);
node->next = contexts;
@ -211,6 +211,6 @@ int iso9660_open(struct iso9660_file_handle *ret, struct volume *vol, const char
}
int iso9660_read(struct iso9660_file_handle *file, void *buf, uint64_t loc, uint64_t count) {
volume_read(&file->context->vol, buf, file->LBA * ISO9660_SECTOR_SIZE + loc, count);
volume_read(file->context->vol, buf, file->LBA * ISO9660_SECTOR_SIZE + loc, count);
return 0;
}

View File

@ -16,8 +16,8 @@ extern EFI_BOOT_SERVICES *gBS;
extern EFI_RUNTIME_SERVICES *gRT;
#endif
extern drive_t boot_drive;
extern int boot_partition;
extern int boot_drive;
extern int boot_partition;
extern bool booted_from_pxe;
extern bool booted_from_cd;

View File

@ -13,57 +13,62 @@
#define INVALID_TABLE (-2)
#define END_OF_TABLE (-3)
#if defined (bios)
typedef int drive_t;
#elif defined (uefi)
typedef EFI_HANDLE drive_t;
struct volume {
#if defined (uefi)
EFI_HANDLE efi_handle;
#endif
struct volume {
drive_t drive;
int drive;
int partition;
int sector_size;
struct volume *backing_dev;
int max_partition;
int cache_status;
uint8_t *cache;
uint64_t cached_block;
uint64_t first_sect;
uint64_t sect_count;
bool guid_valid;
struct guid guid;
bool part_guid_valid;
struct guid part_guid;
};
extern struct volume *volume_index;
extern struct volume **volume_index;
extern size_t volume_index_i;
void volume_create_index(void);
bool gpt_get_guid(struct guid *guid, struct volume *volume);
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, drive_t drive, int partition);
struct volume *volume_get_by_guid(struct guid *guid);
struct volume *volume_get_by_coord(int drive, int partition);
bool volume_read(struct volume *part, void *buffer, uint64_t loc, uint64_t count);
#define volume_iterate_parts(_VOLUME_, _BODY_) ({ \
bool _OK_ = true; \
struct volume _PART_ = _VOLUME_; \
for (int i = 0; ; i++) { \
int _PARTNUM_ = i - 1; \
_BODY_ ; \
switch (part_get(&_PART_, &_VOLUME_, i)) { \
case INVALID_TABLE: \
case END_OF_TABLE: \
_OK_ = false; \
break; \
default: \
continue; \
} \
break; \
} \
_OK_; \
struct volume *_VOLUME = _VOLUME_; \
while (_VOLUME->backing_dev != NULL) { \
_VOLUME = _VOLUME->backing_dev; \
} \
\
int _PART_CNT = -1; \
for (size_t _PARTNO = -1; ; _PARTNO++) { \
if (_PART_CNT > _VOLUME->max_partition) \
break; \
\
struct volume *_PART = volume_get_by_coord(_VOLUME->drive, _PARTNO); \
if (_PART == NULL) \
continue; \
\
_PART_CNT++; \
\
_BODY_ \
} \
})
#endif

View File

@ -147,11 +147,15 @@ static int gpt_get_part(struct volume *ret, struct volume *volume, int partition
if (!memcmp(&entry.unique_partition_guid, &empty_guid, sizeof(struct guid)))
return NO_PARTITION;
#if defined (uefi)
ret->efi_handle = volume->efi_handle;
#endif
ret->drive = volume->drive;
ret->partition = partition;
ret->sector_size = sector_size;
ret->first_sect = entry.starting_lba;
ret->sect_count = (entry.ending_lba - entry.starting_lba) + 1;
ret->backing_dev = volume;
struct guid guid;
if (!fs_get_guid(&guid, ret)) {
@ -200,11 +204,15 @@ static int mbr_get_logical_part(struct volume *ret, struct volume *extended_part
if (entry.type == 0)
return NO_PARTITION;
#if defined (uefi)
ret->efi_handle = extended_part->efi_handle;
#endif
ret->drive = extended_part->drive;
ret->partition = partition + 4;
ret->sector_size = extended_part->sector_size;
ret->first_sect = extended_part->first_sect + ebr_sector + entry.first_sect;
ret->sect_count = entry.sect_count;
ret->backing_dev = extended_part->backing_dev;
struct guid guid;
if (!fs_get_guid(&guid, ret)) {
@ -239,11 +247,15 @@ static int mbr_get_part(struct volume *ret, struct volume *volume, int partition
struct volume extended_part = {0};
#if defined (uefi)
extended_part.efi_handle = volume->efi_handle;
#endif
extended_part.drive = volume->drive;
extended_part.partition = i;
extended_part.sector_size = volume->sector_size;
extended_part.first_sect = entry.first_sect;
extended_part.sect_count = entry.sect_count;
extended_part.backing_dev = volume;
return mbr_get_logical_part(ret, &extended_part, partition - 4);
}
@ -258,11 +270,15 @@ static int mbr_get_part(struct volume *ret, struct volume *volume, int partition
if (entry.type == 0)
return NO_PARTITION;
#if defined (uefi)
ret->efi_handle = volume->efi_handle;
#endif
ret->drive = volume->drive;
ret->partition = partition;
ret->sector_size = volume->sector_size;
ret->first_sect = entry.first_sect;
ret->sect_count = entry.sect_count;
ret->backing_dev = volume;
struct guid guid;
if (!fs_get_guid(&guid, ret)) {
@ -291,41 +307,31 @@ int part_get(struct volume *part, struct volume *volume, int partition) {
return INVALID_TABLE;
}
struct volume *volume_index = NULL;
struct volume **volume_index = NULL;
size_t volume_index_i = 0;
void volume_create_index(void) {
volume_index_i = disk_create_index(&volume_index);
}
bool volume_get_by_guid(struct volume *part, struct guid *guid) {
size_t i;
for (i = 0; i < volume_index_i; i++) {
if (volume_index[i].guid_valid
&& memcmp(&volume_index[i].guid, guid, 16) == 0) {
goto found;
struct volume *volume_get_by_guid(struct guid *guid) {
for (size_t i = 0; i < volume_index_i; i++) {
if (volume_index[i]->guid_valid
&& memcmp(&volume_index[i]->guid, guid, 16) == 0) {
return volume_index[i];
}
if (volume_index[i].part_guid_valid
&& memcmp(&volume_index[i].part_guid, guid, 16) == 0) {
goto found;
if (volume_index[i]->part_guid_valid
&& memcmp(&volume_index[i]->part_guid, guid, 16) == 0) {
return volume_index[i];
}
}
return false;
found:
*part = volume_index[i];
return true;
return NULL;
}
bool volume_get_by_coord(struct volume *part, drive_t 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;
struct volume *volume_get_by_coord(int drive, int partition) {
for (size_t i = 0; i < volume_index_i; i++) {
if (volume_index[i]->drive == drive
&& volume_index[i]->partition == partition) {
return volume_index[i];
}
}
return false;
found:
*part = volume_index[i];
return true;
return NULL;
}

View File

@ -95,14 +95,14 @@ static bool parse_bios_partition(char *loc, uint8_t *drive, uint8_t *partition)
static bool uri_bios_dispatch(struct file_handle *fd, char *loc, char *path) {
uint8_t drive, partition;
struct volume volume = {0};
if (!parse_bios_partition(loc, &drive, &partition))
return false;
if (!volume_get_by_coord(&volume, drive, partition))
struct volume *volume = volume_get_by_coord(drive, partition);
if (volume == NULL)
return false;
if (fopen(fd, &volume, path))
if (fopen(fd, volume, path))
return false;
return true;
@ -114,16 +114,17 @@ 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 volume part = {0};
if (!volume_get_by_guid(&part, &guid)) {
struct volume *volume = volume_get_by_guid(&guid);
if (volume == NULL) {
if (!string_to_guid_mixed(&guid, guid_str))
return false;
if (!volume_get_by_guid(&part, &guid))
volume = volume_get_by_guid(&guid);
if (volume == NULL)
return false;
}
if (fopen(fd, &part, path))
if (fopen(fd, volume, path))
return false;
return true;
@ -174,11 +175,11 @@ static bool uri_boot_dispatch(struct file_handle *fd, char *s_part, char *path)
panic("Boot partition information is unavailable.");
}
struct volume part = {0};
if (!volume_get_by_coord(&part, boot_drive, partition))
struct volume *volume = volume_get_by_coord(boot_drive, partition);
if (volume == NULL)
return false;
if (fopen(fd, &part, path))
if (fopen(fd, volume, path))
return false;
return true;

View File

@ -77,10 +77,9 @@ void chainload(char *config) {
term_deinit();
struct volume p = {0};
volume_get_by_coord(&p, drive, part);
struct volume *p = volume_get_by_coord(drive, part);
volume_read(&p, (void *)0x7c00, 0, 512);
volume_read(p, (void *)0x7c00, 0, 512);
mtrr_restore();