Add GUID resource type

This commit is contained in:
mintsuki 2020-11-01 21:25:35 +01:00
parent 28c1538f94
commit 038c041208
16 changed files with 154 additions and 44 deletions

View File

@ -63,3 +63,4 @@ The format for `root` changes depending on the resource used.
A resource can be one of the following:
* `bios` - The `root` takes the form of `drive:partition`; for example: `bios://3:1/...` would use BIOS drive 3, partition 1. Partitions and BIOS drives are both 1-based. Omitting the drive is possible; for example: `bios://:2/...`. Omitting the drive makes Limine use the boot drive.
* `guid` - The `root` takes the form of a GUID/UUID, such as `736b5698-5ae1-4dff-be2c-ef8f44a61c52`. It is a filesystem GUID and not a partition GUID.

View File

@ -43,9 +43,11 @@ test.img:
echfs-test: limine-install test.img
$(MAKE) -C test
echfs-utils -m -p0 test.img quick-format 512
echfs-utils -m -p0 test.img quick-format 512 > part_guid
sed "s/@GUID@/`cat part_guid`/g" < test/limine.cfg > limine.cfg.tmp
echfs-utils -m -p0 test.img import limine.cfg.tmp limine.cfg
rm -f limine.cfg.tmp part_guid
echfs-utils -m -p0 test.img import test/test.elf boot/test.elf
echfs-utils -m -p0 test.img import test/limine.cfg limine.cfg
echfs-utils -m -p0 test.img import test/bg.bmp bg.bmp
./limine-install limine.bin test.img
qemu-system-x86_64 -net none -smp 4 -enable-kvm -cpu host -hda test.img -debugcon stdio

Binary file not shown.

View File

@ -13,6 +13,8 @@ struct echfs_identity_table {
uint64_t block_count;
uint64_t dir_length;
uint64_t block_size;
uint32_t reserved;
struct guid guid;
} __attribute__((packed));
#define ROOT_DIR_ID (~((uint64_t)0))
@ -40,14 +42,9 @@ int echfs_read(struct echfs_file_handle *file, void *buf, uint64_t loc, uint64_t
return 0;
}
int echfs_check_signature(int disk, int partition) {
struct part part;
if (get_part(&part, disk, partition)) {
panic("Invalid partition");
}
int echfs_check_signature(struct part *part) {
struct echfs_identity_table id_table;
read_partition(disk, &part, &id_table, 0, sizeof(struct echfs_identity_table));
read_partition(part->drive, part, &id_table, 0, sizeof(struct echfs_identity_table));
if (strncmp(id_table.signature, "_ECH_FS_", 8)) {
return 0;
@ -56,6 +53,19 @@ int echfs_check_signature(int disk, int partition) {
return 1;
}
bool echfs_get_guid(struct guid *guid, struct part *part) {
struct echfs_identity_table id_table;
read_partition(part->drive, part, &id_table, 0, sizeof(struct echfs_identity_table));
if (strncmp(id_table.signature, "_ECH_FS_", 8)) {
return false;
}
*guid = id_table.guid;
return true;
}
int echfs_open(struct echfs_file_handle *ret, int disk, int partition, const char *path) {
const char *fullpath = path;

View File

@ -2,7 +2,9 @@
#define __FS__ECHFS_H__
#include <stdint.h>
#include <stdbool.h>
#include <lib/part.h>
#include <lib/blib.h>
struct echfs_dir_entry {
uint64_t parent_id;
@ -31,7 +33,8 @@ struct echfs_file_handle {
struct echfs_dir_entry dir_entry;
};
int echfs_check_signature(int disk, int partition);
int echfs_check_signature(struct part *part);
bool echfs_get_guid(struct guid *guid, struct part *part);
int echfs_open(struct echfs_file_handle *ret, int disk, int partition, const char *filename);
int echfs_read(struct echfs_file_handle *file, void *buf, uint64_t loc, uint64_t count);

View File

@ -411,13 +411,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(int drive, int partition) {
struct part part;
if (get_part(&part, drive, partition))
panic("Invalid partition");
int ext2_check_signature(struct part *part) {
struct ext2_superblock sb;
read_partition(drive, &part, &sb, 1024, sizeof(struct ext2_superblock));
read_partition(part->drive, part, &sb, 1024, sizeof(struct ext2_superblock));
if (sb.s_magic != EXT2_S_MAGIC)
return 0;
@ -434,3 +430,16 @@ int ext2_check_signature(int drive, int partition) {
return 1;
}
bool ext2_get_guid(struct guid *guid, struct part *part) {
struct ext2_superblock sb;
read_partition(part->drive, part, &sb, 1024, sizeof(struct ext2_superblock));
if (sb.s_magic != EXT2_S_MAGIC)
return false;
((uint64_t *)guid)[0] = sb.s_uuid[0];
((uint64_t *)guid)[1] = sb.s_uuid[1];
return true;
}

View File

@ -3,7 +3,9 @@
#include <stdint.h>
#include <stddef.h>
#include <stdbool.h>
#include <lib/part.h>
#include <lib/blib.h>
struct ext2_linux {
uint8_t frag_num;
@ -54,7 +56,8 @@ struct ext2_file_handle {
uint64_t block_size;
};
int ext2_check_signature(int drive, int partition);
int ext2_check_signature(struct part *part);
bool ext2_get_guid(struct guid *guid, struct part *part);
int ext2_open(struct ext2_file_handle *ret, int drive, int partition, const char *path);
int ext2_read(struct ext2_file_handle *file, void *buf, uint64_t loc, uint64_t count);

View File

@ -66,14 +66,12 @@ struct fat32_lfn_entry {
char name3[4];
} __attribute__((packed));
static int fat32_init_context(struct fat32_context* context, int disk, int partition) {
context->drive = disk;
if (get_part(&context->part, disk, partition)) {
panic("Invalid partition");
}
static int fat32_init_context(struct fat32_context* context, struct part *part) {
context->part = *part;
context->drive = part->drive;
struct fat32_bpb bpb;
read_partition(disk, &context->part, &bpb, 0, sizeof(struct fat32_bpb));
read_partition(part->drive, &context->part, &bpb, 0, sizeof(struct fat32_bpb));
if (bpb.signature != FAT32_VALID_SIGNATURE_1 && bpb.signature != FAT32_VALID_SIGNATURE_2) {
return 1;
@ -223,14 +221,19 @@ static int fat32_open_in(struct fat32_context* context, struct fat32_directory_e
return -1;
}
int fat32_check_signature(int disk, int partition) {
int fat32_check_signature(struct part *part) {
struct fat32_context context;
return fat32_init_context(&context, disk, partition) == 0;
return fat32_init_context(&context, part) == 0;
}
int fat32_open(struct fat32_file_handle* ret, int disk, int partition, const char* path) {
struct part part;
if (get_part(&part, disk, partition)) {
panic("Invalid partition");
}
struct fat32_context context;
int r = fat32_init_context(&context, disk, partition);
int r = fat32_init_context(&context, &part);
if (r) {
print("fat32: context init failure (%d)\n", r);

View File

@ -24,7 +24,7 @@ struct fat32_file_handle {
uint32_t size_clusters;
};
int fat32_check_signature(int disk, int partition);
int fat32_check_signature(struct part *part);
int fat32_open(struct fat32_file_handle *ret, int disk, int partition, const char *path);
int fat32_read(struct fat32_file_handle *file, void *buf, uint64_t loc, uint64_t count);

View File

@ -6,9 +6,26 @@
#include <fs/fat32.h>
#include <lib/blib.h>
#include <mm/pmm.h>
#include <lib/part.h>
bool fs_get_guid(struct guid *guid, struct part *part) {
if (echfs_check_signature(part)) {
return echfs_get_guid(guid, part);
}
if (ext2_check_signature(part)) {
return ext2_get_guid(guid, part);
}
return false;
}
int fopen(struct file_handle *ret, int disk, int partition, const char *filename) {
if (echfs_check_signature(disk, partition)) {
struct part part;
if (get_part(&part, disk, partition)) {
panic("Invalid partition");
}
if (echfs_check_signature(&part)) {
struct echfs_file_handle *fd = conv_mem_alloc(sizeof(struct echfs_file_handle));
int r = echfs_open(fd, disk, partition, filename);
@ -24,7 +41,7 @@ int fopen(struct file_handle *ret, int disk, int partition, const char *filename
return 0;
}
if (ext2_check_signature(disk, partition)) {
if (ext2_check_signature(&part)) {
struct ext2_file_handle *fd = conv_mem_alloc(sizeof(struct ext2_file_handle));
int r = ext2_open(fd, disk, partition, filename);
@ -40,7 +57,7 @@ int fopen(struct file_handle *ret, int disk, int partition, const char *filename
return 0;
}
if (fat32_check_signature(disk, partition)) {
if (fat32_check_signature(&part)) {
struct fat32_file_handle *fd = conv_mem_alloc(sizeof(struct fat32_file_handle));
int r = fat32_open(fd, disk, partition, filename);

View File

@ -2,6 +2,12 @@
#define __FS__FILE_H__
#include <stdint.h>
#include <stdbool.h>
struct part;
struct guid;
bool fs_get_guid(struct guid *guid, struct part *part);
struct file_handle {
int disk;

View File

@ -10,6 +10,7 @@
#include <sys/e820.h>
#include <lib/print.h>
#include <lib/config.h>
#include <lib/part.h>
#include <mm/pmm.h>
uint8_t boot_drive;
@ -59,14 +60,32 @@ static bool uri_bios_dispatch(struct file_handle *fd, char *loc, char *path) {
return true;
}
static bool uri_guid_dispatch(struct file_handle *fd, char *guid_str, char *path) {
struct guid guid;
if (!string_to_guid(&guid, guid_str))
panic("Invalid GUID format");
int drive, partition;
if (!part_get_by_guid(&drive, &partition, &guid))
panic("No partition found for GUID: %s", guid_str);
if (fopen(fd, drive, partition, path))
return false;
return true;
}
bool uri_open(struct file_handle *fd, char *uri) {
char *resource, *root, *path;
config_resolve_uri(uri, &resource, &root, &path);
if (!strcmp(resource, "bios")) {
return uri_bios_dispatch(fd, root, path);
} else if (!strcmp(resource, "guid")) {
return uri_guid_dispatch(fd, root, path);
} else {
panic("Resource `%s` not valid.");
panic("Resource `%s` not valid.", resource);
}
}
@ -148,7 +167,7 @@ static bool is_valid_guid(const char *s) {
}
}
}
/*
static void guid_convert_le_cluster(uint8_t *dest, const char *s, int len) {
size_t p = 0;
for (int i = len - 1; i >= 0; i--) {
@ -157,7 +176,7 @@ static void guid_convert_le_cluster(uint8_t *dest, const char *s, int len) {
i % 2 ? (dest[p] = val) : (dest[p++] |= val << 4);
}
}
*/
static void guid_convert_be_cluster(uint8_t *dest, const char *s, int len) {
size_t p = 0;
for (int i = 0; i < len; i++) {
@ -171,9 +190,9 @@ bool string_to_guid(struct guid *guid, const char *s) {
if (!is_valid_guid(s))
return false;
guid_convert_le_cluster((uint8_t *)guid + 0, s + 0, 8);
guid_convert_le_cluster((uint8_t *)guid + 4, s + 9, 4);
guid_convert_le_cluster((uint8_t *)guid + 6, s + 14, 4);
guid_convert_be_cluster((uint8_t *)guid + 0, s + 0, 8);
guid_convert_be_cluster((uint8_t *)guid + 4, s + 9, 4);
guid_convert_be_cluster((uint8_t *)guid + 6, s + 14, 4);
guid_convert_be_cluster((uint8_t *)guid + 8, s + 19, 4);
guid_convert_be_cluster((uint8_t *)guid + 10, s + 24, 12);

View File

@ -140,6 +140,7 @@ bool config_resolve_uri(char *uri, char **resource, char **root, char **path) {
}
}
// Get root
for (size_t i = 0; ; i++) {
if (uri[i] == 0)
return false;
@ -152,9 +153,9 @@ bool config_resolve_uri(char *uri, char **resource, char **root, char **path) {
}
}
// Get path
if (*uri == 0)
return false;
*path = uri;
return true;

View File

@ -75,9 +75,18 @@ 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->partition = partition;
ret->first_sect = entry.starting_lba;
ret->sect_count = (entry.ending_lba - entry.starting_lba) + 1;
ret->guid = entry.unique_partition_guid;
struct guid guid;
if (!fs_get_guid(&guid, ret)) {
ret->guid_valid = false;
} else {
ret->guid_valid = true;
ret->guid = guid;
}
return 0;
}
@ -114,14 +123,18 @@ static int mbr_get_part(struct part *ret, int drive, int partition) {
if (entry.type == 0)
return NO_PARTITION;
ret->drive = drive;
ret->partition = partition;
ret->first_sect = entry.first_sect;
ret->sect_count = entry.sect_count;
// We use the same method of generating GUIDs for MBR partitions as Linux
struct guid empty_guid = {0};
ret->guid = empty_guid;
ret->guid.a = disk_signature;
ret->guid.b = (partition + 1) << 8;
struct guid guid;
if (!fs_get_guid(&guid, ret)) {
ret->guid_valid = false;
} else {
ret->guid_valid = true;
ret->guid = guid;
}
return 0;
}
@ -189,3 +202,22 @@ load_up:
goto load_up;
}
}
bool part_get_by_guid(int *drive, int *part, struct guid *guid) {
for (size_t i = 0; i < part_index_i; i++) {
if (!part_index[i].guid_valid)
continue;
print("%X %X\n",
((uint64_t*)&part_index[i].guid)[0],
((uint64_t*)&part_index[i].guid)[1]);
print("%X %X\n",
((uint64_t*)guid)[0],
((uint64_t*)guid)[1]);
if (!memcmp(&part_index[i].guid, guid, 16)) {
*drive = part_index[i].drive;
*part = part_index[i].partition;
return true;
}
}
return false;
}

View File

@ -6,12 +6,16 @@
#include <lib/blib.h>
struct part {
int drive;
int partition;
uint64_t first_sect;
uint64_t sect_count;
bool guid_valid;
struct guid guid;
};
int get_part(struct part *part, int drive, int partition);
bool part_get_by_guid(int *drive, int *part, struct guid *guid);
void part_create_index(void);

View File

@ -20,7 +20,7 @@ BACKGROUND_PATH=bg.bmp
:Stivale Test
PROTOCOL=stivale
KERNEL_PATH=bios://:1/boot/test.elf
KERNEL_PATH=guid://@GUID@/boot/test.elf
KERNEL_CMDLINE=Hi! This is an example!
:Stivale2 Test