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: 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. * `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 echfs-test: limine-install test.img
$(MAKE) -C test $(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/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 echfs-utils -m -p0 test.img import test/bg.bmp bg.bmp
./limine-install limine.bin test.img ./limine-install limine.bin test.img
qemu-system-x86_64 -net none -smp 4 -enable-kvm -cpu host -hda test.img -debugcon stdio 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 block_count;
uint64_t dir_length; uint64_t dir_length;
uint64_t block_size; uint64_t block_size;
uint32_t reserved;
struct guid guid;
} __attribute__((packed)); } __attribute__((packed));
#define ROOT_DIR_ID (~((uint64_t)0)) #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; return 0;
} }
int echfs_check_signature(int disk, int partition) { int echfs_check_signature(struct part *part) {
struct part part;
if (get_part(&part, disk, partition)) {
panic("Invalid partition");
}
struct echfs_identity_table id_table; 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)) { if (strncmp(id_table.signature, "_ECH_FS_", 8)) {
return 0; return 0;
@ -56,6 +53,19 @@ int echfs_check_signature(int disk, int partition) {
return 1; 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) { int echfs_open(struct echfs_file_handle *ret, int disk, int partition, const char *path) {
const char *fullpath = path; const char *fullpath = path;

View File

@ -2,7 +2,9 @@
#define __FS__ECHFS_H__ #define __FS__ECHFS_H__
#include <stdint.h> #include <stdint.h>
#include <stdbool.h>
#include <lib/part.h> #include <lib/part.h>
#include <lib/blib.h>
struct echfs_dir_entry { struct echfs_dir_entry {
uint64_t parent_id; uint64_t parent_id;
@ -31,7 +33,8 @@ struct echfs_file_handle {
struct echfs_dir_entry dir_entry; 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_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); 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 // attempts to initialize the ext2 filesystem
// and checks if all features are supported // and checks if all features are supported
int ext2_check_signature(int drive, int partition) { int ext2_check_signature(struct part *part) {
struct part part;
if (get_part(&part, drive, partition))
panic("Invalid partition");
struct ext2_superblock sb; 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) if (sb.s_magic != EXT2_S_MAGIC)
return 0; return 0;
@ -434,3 +430,16 @@ int ext2_check_signature(int drive, int partition) {
return 1; 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 <stdint.h>
#include <stddef.h> #include <stddef.h>
#include <stdbool.h>
#include <lib/part.h> #include <lib/part.h>
#include <lib/blib.h>
struct ext2_linux { struct ext2_linux {
uint8_t frag_num; uint8_t frag_num;
@ -54,7 +56,8 @@ struct ext2_file_handle {
uint64_t block_size; 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_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); 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]; char name3[4];
} __attribute__((packed)); } __attribute__((packed));
static int fat32_init_context(struct fat32_context* context, int disk, int partition) { static int fat32_init_context(struct fat32_context* context, struct part *part) {
context->drive = disk; context->part = *part;
if (get_part(&context->part, disk, partition)) { context->drive = part->drive;
panic("Invalid partition");
}
struct fat32_bpb bpb; 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) { if (bpb.signature != FAT32_VALID_SIGNATURE_1 && bpb.signature != FAT32_VALID_SIGNATURE_2) {
return 1; return 1;
@ -223,14 +221,19 @@ static int fat32_open_in(struct fat32_context* context, struct fat32_directory_e
return -1; return -1;
} }
int fat32_check_signature(int disk, int partition) { int fat32_check_signature(struct part *part) {
struct fat32_context context; 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) { 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; struct fat32_context context;
int r = fat32_init_context(&context, disk, partition); int r = fat32_init_context(&context, &part);
if (r) { if (r) {
print("fat32: context init failure (%d)\n", r); print("fat32: context init failure (%d)\n", r);

View File

@ -24,7 +24,7 @@ struct fat32_file_handle {
uint32_t size_clusters; 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_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); 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 <fs/fat32.h>
#include <lib/blib.h> #include <lib/blib.h>
#include <mm/pmm.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) { 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)); struct echfs_file_handle *fd = conv_mem_alloc(sizeof(struct echfs_file_handle));
int r = echfs_open(fd, disk, partition, filename); 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; 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)); struct ext2_file_handle *fd = conv_mem_alloc(sizeof(struct ext2_file_handle));
int r = ext2_open(fd, disk, partition, filename); 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; 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)); struct fat32_file_handle *fd = conv_mem_alloc(sizeof(struct fat32_file_handle));
int r = fat32_open(fd, disk, partition, filename); int r = fat32_open(fd, disk, partition, filename);

View File

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

View File

@ -10,6 +10,7 @@
#include <sys/e820.h> #include <sys/e820.h>
#include <lib/print.h> #include <lib/print.h>
#include <lib/config.h> #include <lib/config.h>
#include <lib/part.h>
#include <mm/pmm.h> #include <mm/pmm.h>
uint8_t boot_drive; uint8_t boot_drive;
@ -59,14 +60,32 @@ static bool uri_bios_dispatch(struct file_handle *fd, char *loc, char *path) {
return true; 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) { bool uri_open(struct file_handle *fd, char *uri) {
char *resource, *root, *path; char *resource, *root, *path;
config_resolve_uri(uri, &resource, &root, &path); config_resolve_uri(uri, &resource, &root, &path);
if (!strcmp(resource, "bios")) { if (!strcmp(resource, "bios")) {
return uri_bios_dispatch(fd, root, path); return uri_bios_dispatch(fd, root, path);
} else if (!strcmp(resource, "guid")) {
return uri_guid_dispatch(fd, root, path);
} else { } 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) { static void guid_convert_le_cluster(uint8_t *dest, const char *s, int len) {
size_t p = 0; size_t p = 0;
for (int i = len - 1; i >= 0; i--) { 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); i % 2 ? (dest[p] = val) : (dest[p++] |= val << 4);
} }
} }
*/
static void guid_convert_be_cluster(uint8_t *dest, const char *s, int len) { static void guid_convert_be_cluster(uint8_t *dest, const char *s, int len) {
size_t p = 0; size_t p = 0;
for (int i = 0; i < len; i++) { 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)) if (!is_valid_guid(s))
return false; return false;
guid_convert_le_cluster((uint8_t *)guid + 0, s + 0, 8); guid_convert_be_cluster((uint8_t *)guid + 0, s + 0, 8);
guid_convert_le_cluster((uint8_t *)guid + 4, s + 9, 4); guid_convert_be_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 + 6, s + 14, 4);
guid_convert_be_cluster((uint8_t *)guid + 8, s + 19, 4); guid_convert_be_cluster((uint8_t *)guid + 8, s + 19, 4);
guid_convert_be_cluster((uint8_t *)guid + 10, s + 24, 12); 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++) { for (size_t i = 0; ; i++) {
if (uri[i] == 0) if (uri[i] == 0)
return false; return false;
@ -152,9 +153,9 @@ bool config_resolve_uri(char *uri, char **resource, char **root, char **path) {
} }
} }
// Get path
if (*uri == 0) if (*uri == 0)
return false; return false;
*path = uri; *path = uri;
return true; 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))) if (!memcmp(&entry.unique_partition_guid, &empty_guid, sizeof(struct guid)))
return NO_PARTITION; return NO_PARTITION;
ret->drive = drive;
ret->partition = partition;
ret->first_sect = entry.starting_lba; ret->first_sect = entry.starting_lba;
ret->sect_count = (entry.ending_lba - entry.starting_lba) + 1; 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; return 0;
} }
@ -114,14 +123,18 @@ static int mbr_get_part(struct part *ret, int drive, int partition) {
if (entry.type == 0) if (entry.type == 0)
return NO_PARTITION; return NO_PARTITION;
ret->drive = drive;
ret->partition = partition;
ret->first_sect = entry.first_sect; ret->first_sect = entry.first_sect;
ret->sect_count = entry.sect_count; ret->sect_count = entry.sect_count;
// We use the same method of generating GUIDs for MBR partitions as Linux struct guid guid;
struct guid empty_guid = {0}; if (!fs_get_guid(&guid, ret)) {
ret->guid = empty_guid; ret->guid_valid = false;
ret->guid.a = disk_signature; } else {
ret->guid.b = (partition + 1) << 8; ret->guid_valid = true;
ret->guid = guid;
}
return 0; return 0;
} }
@ -189,3 +202,22 @@ load_up:
goto 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> #include <lib/blib.h>
struct part { struct part {
int drive;
int partition;
uint64_t first_sect; uint64_t first_sect;
uint64_t sect_count; uint64_t sect_count;
bool guid_valid;
struct guid guid; struct guid guid;
}; };
int get_part(struct part *part, int drive, int partition); 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); void part_create_index(void);

View File

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