From f7a8bbd7f65cdaadc4d373590dd26319ed45d998 Mon Sep 17 00:00:00 2001 From: mintsuki Date: Wed, 3 Mar 2021 22:38:28 +0100 Subject: [PATCH] A lot of changes --- stage23/drivers/disk.h | 11 --- stage23/drivers/disk.s2.c | 136 +++++++++++++++++++++++++++++++++-- stage23/entry.s3.c | 65 +++++++++++++---- stage23/fs/file.s2.c | 1 + stage23/lib/part.h | 21 +++++- stage23/lib/part.s2.c | 8 +-- stage23/linker_nomap_uefi.ld | 1 + stage23/linker_uefi.ld | 1 + stage23/mm/pmm.s2.c | 14 +++- 9 files changed, 215 insertions(+), 43 deletions(-) diff --git a/stage23/drivers/disk.h b/stage23/drivers/disk.h index 3a883d31..1357a315 100644 --- a/stage23/drivers/disk.h +++ b/stage23/drivers/disk.h @@ -6,17 +6,6 @@ #include #include -struct bios_drive_params { - uint16_t buf_size; - uint16_t info_flags; - uint32_t cyl; - uint32_t heads; - uint32_t sects; - uint64_t lba_count; - uint16_t bytes_per_sect; - uint32_t edd; -} __attribute__((packed)); - size_t disk_create_index(struct volume **ret); bool disk_read_sectors(struct volume *volume, void *buf, uint64_t block, size_t count); diff --git a/stage23/drivers/disk.s2.c b/stage23/drivers/disk.s2.c index 92a0ac2c..ab3cc829 100644 --- a/stage23/drivers/disk.s2.c +++ b/stage23/drivers/disk.s2.c @@ -1,14 +1,29 @@ -#if defined(bios) - #include #include #include #include -#include +#if defined (bios) +# include +#elif defined (uefi) +# include +#endif #include #include #include +#if defined(bios) + +struct bios_drive_params { + uint16_t buf_size; + uint16_t info_flags; + uint32_t cyl; + uint32_t heads; + uint32_t sects; + uint64_t lba_count; + uint16_t bytes_per_sect; + uint32_t edd; +} __attribute__((packed)); + struct dap { uint16_t size; uint16_t count; @@ -31,7 +46,7 @@ bool disk_read_sectors(struct volume *volume, void *buf, uint64_t block, size_t if (dap == NULL) { dap = conv_mem_alloc(sizeof(struct dap)); - dap->size = 16; + dap->size = 16; } dap->count = count; @@ -91,7 +106,7 @@ size_t disk_create_index(struct volume **ret) { volume_count++; - struct volume block; + struct volume block = {0}; block.drive = drive; block.sector_size = drive_params.bytes_per_sect; @@ -106,7 +121,7 @@ size_t disk_create_index(struct volume **ret) { } for (int part = 0; ; part++) { - struct volume p; + struct volume p = {0}; int ret = part_get(&p, &block, part); if (ret == END_OF_TABLE || ret == INVALID_TABLE) @@ -155,7 +170,114 @@ size_t disk_create_index(struct volume **ret) { } for (int part = 0; ; part++) { - struct volume p; + struct volume p = {0}; + int ret = part_get(&p, block, part); + + if (ret == END_OF_TABLE || ret == INVALID_TABLE) + break; + if (ret == NO_PARTITION) + continue; + + volume_index[volume_index_i++] = p; + } + } + + *ret = volume_index; + return volume_count; +} + +#endif + +#if defined (uefi) + +bool disk_read_sectors(struct volume *volume, void *buf, uint64_t block, size_t count) { + EFI_STATUS status; + + status = uefi_call_wrapper(volume->drive->ReadBlocks, 5, volume->drive, + volume->drive->Media->MediaId, + block, count * volume->sector_size, buf); + + if (status != 0) { + return false; + } + + return true; +} + +size_t disk_create_index(struct volume **ret) { + 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; + EFI_HANDLE *handles = NULL; + UINTN handles_size = 0; + + uefi_call_wrapper(gBS->LocateHandle, 5, ByProtocol, &block_io_guid, + NULL, &handles_size, handles); + + handles = ext_mem_alloc(handles_size); + + uefi_call_wrapper(gBS->LocateHandle, 5, ByProtocol, &block_io_guid, + NULL, &handles_size, handles); + + for (size_t i = 0; i < handles_size / sizeof(EFI_HANDLE); i++) { + struct volume block = {0}; + + status = uefi_call_wrapper(gBS->HandleProtocol, 3, handles[i], + &block_io_guid, &block.drive); + + if (status != 0 || block.drive == NULL || block.drive->Media->LastBlock == 0) + continue; + + if (block.drive->Media->LogicalPartition) + continue; + + volume_count++; + + block.sector_size = block.drive->Media->BlockSize; + block.first_sect = 0; + block.sect_count = block.drive->Media->LastBlock + 1; + + for (int part = 0; ; part++) { + struct volume p = {0}; + int ret = part_get(&p, &block, part); + + if (ret == END_OF_TABLE || ret == INVALID_TABLE) + break; + if (ret == NO_PARTITION) + continue; + + volume_count++; + } + } + + volume_index = ext_mem_alloc(sizeof(struct volume) * volume_count); + + for (size_t i = 0; i < handles_size / sizeof(EFI_HANDLE); i++) { + EFI_BLOCK_IO *drive; + + status = uefi_call_wrapper(gBS->HandleProtocol, 3, handles[i], + &block_io_guid, &drive); + + if (status != 0 || drive == NULL || drive->Media->LastBlock == 0) + continue; + + if (drive->Media->LogicalPartition) + continue; + + struct volume *block = &volume_index[volume_index_i++]; + + block->drive = drive; + block->partition = -1; + block->sector_size = drive->Media->BlockSize; + block->first_sect = 0; + block->sect_count = drive->Media->LastBlock + 1; + + for (int part = 0; ; part++) { + struct volume p = {0}; int ret = part_get(&p, block, part); if (ret == END_OF_TABLE || ret == INVALID_TABLE) diff --git a/stage23/entry.s3.c b/stage23/entry.s3.c index 8de693ff..30e97c0e 100644 --- a/stage23/entry.s3.c +++ b/stage23/entry.s3.c @@ -20,6 +20,8 @@ #include #include +void stage3_common(void); + #if defined (uefi) __attribute__((ms_abi)) EFI_STATUS efi_main(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable) { @@ -29,12 +31,41 @@ EFI_STATUS efi_main(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable) { gBS = SystemTable->BootServices; gRT = SystemTable->RuntimeServices; - print("hello world\n"); + print("Limine " LIMINE_VERSION "\n\n"); + + //volume_create_index(); + + EFI_GUID loaded_img_prot_guid = EFI_LOADED_IMAGE_PROTOCOL_GUID; + EFI_LOADED_IMAGE_PROTOCOL *loaded_image = NULL; + + uefi_call_wrapper(gBS->HandleProtocol, 3, ImageHandle, &loaded_img_prot_guid, + &loaded_image); + + EFI_GUID block_io_guid = BLOCK_IO_PROTOCOL; + EFI_BLOCK_IO *drive; + + uefi_call_wrapper(gBS->HandleProtocol, 3, loaded_image->DeviceHandle, + &block_io_guid, &drive); + + struct volume boot_volume; + boot_volume.drive = drive; + boot_volume.partition = -1; + boot_volume.sector_size = drive->Media->BlockSize; + boot_volume.first_sect = 0; + boot_volume.sect_count = drive->Media->LastBlock + 1; + + if (!init_config_disk(&boot_volume)) { + print("Config file found and loaded.\n"); + } else { + panic("Config file not found."); + } for (;;); + //stage3_common(); } #endif +#if defined (bios) __attribute__((section(".stage3_build_id"))) uint64_t stage3_build_id = BUILD_ID; @@ -48,19 +79,15 @@ void stage3_entry(int boot_from) { 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 (!init_config_disk(&part)) { + + if (!volume_iterate_parts(boot_volume, + if (!init_config_disk(&_PART_)) { print("Config file found and loaded.\n"); - boot_partition = i - 1; + boot_partition = _PARTNUM_; break; } - int ret = part_get(&part, &boot_volume, i); - switch (ret) { - case INVALID_TABLE: - case END_OF_TABLE: - panic("Config file not found."); - } + )) { + panic("Config file not found."); } break; case BOOT_FROM_PXE: @@ -73,6 +100,12 @@ void stage3_entry(int boot_from) { } } + stage3_common(); +} +#endif + +__attribute__((noreturn)) +void stage3_common(void) { char *cmdline; char *config = menu(&cmdline); @@ -81,17 +114,19 @@ void stage3_entry(int boot_from) { panic("PROTOCOL not specified"); } - if (!strcmp(proto, "stivale")) { + if (0) { + + } else if (!strcmp(proto, "stivale")) { stivale_load(config, cmdline); } else if (!strcmp(proto, "stivale2")) { stivale2_load(config, cmdline, booted_from_pxe); +#if defined (bios) } else if (!strcmp(proto, "linux")) { linux_load(config, cmdline); } else if (!strcmp(proto, "chainload")) { chainload(config); - } else { - panic("Invalid protocol specified"); +#endif } - for (;;); + panic("Invalid protocol specified"); } diff --git a/stage23/fs/file.s2.c b/stage23/fs/file.s2.c index 8fbc65c4..95b328ea 100644 --- a/stage23/fs/file.s2.c +++ b/stage23/fs/file.s2.c @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include diff --git a/stage23/lib/part.h b/stage23/lib/part.h index ddab7085..6bebb57e 100644 --- a/stage23/lib/part.h +++ b/stage23/lib/part.h @@ -15,7 +15,7 @@ #if defined (bios) typedef int drive_t; #elif defined (uefi) -typedef EFI_HANDLE drive_t; +typedef EFI_BLOCK_IO *drive_t; #endif struct volume { @@ -43,4 +43,23 @@ bool volume_get_by_coord(struct volume *part, drive_t 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_; \ +}) + #endif diff --git a/stage23/lib/part.s2.c b/stage23/lib/part.s2.c index 97f35db8..61a4f8f4 100644 --- a/stage23/lib/part.s2.c +++ b/stage23/lib/part.s2.c @@ -1,9 +1,9 @@ #include #include #include +#include #if defined (bios) -# include -#include +# include #endif #include #include @@ -295,11 +295,7 @@ static struct volume *volume_index = NULL; static size_t volume_index_i = 0; void volume_create_index(void) { -#if defined (bios) volume_index_i = disk_create_index(&volume_index); -#elif defined (uefi) - -#endif } bool volume_get_by_guid(struct volume *part, struct guid *guid) { diff --git a/stage23/linker_nomap_uefi.ld b/stage23/linker_nomap_uefi.ld index 2546559f..cd6878a7 100644 --- a/stage23/linker_nomap_uefi.ld +++ b/stage23/linker_nomap_uefi.ld @@ -8,6 +8,7 @@ SECTIONS .text : { *(.text*) *(.realmode*) + *(.stage3_entry*) } .rodata : { diff --git a/stage23/linker_uefi.ld b/stage23/linker_uefi.ld index 6e7b0e01..73a13f8b 100644 --- a/stage23/linker_uefi.ld +++ b/stage23/linker_uefi.ld @@ -8,6 +8,7 @@ SECTIONS .text : { *(.text*) *(.realmode*) + *(.stage3_entry*) } .rodata : { diff --git a/stage23/mm/pmm.s2.c b/stage23/mm/pmm.s2.c index 4baa5414..31e2cc74 100644 --- a/stage23/mm/pmm.s2.c +++ b/stage23/mm/pmm.s2.c @@ -263,15 +263,23 @@ void *ext_mem_alloc_aligned_type(size_t count, size_t alignment, uint32_t type) void *ext_mem_alloc_aligned_type(size_t count, size_t alignment, uint32_t type) { (void)type; + EFI_STATUS status; + void *ret; if (alignment && alignment % 4096 == 0) { - uefi_call_wrapper(gBS->AllocatePages, 4, 0, 2, DIV_ROUNDUP(count, 4096), - &ret); + status = uefi_call_wrapper(gBS->AllocatePages, 4, 0, 2, + DIV_ROUNDUP(count, 4096), &ret); } else { - uefi_call_wrapper(gBS->AllocatePool, 3, 4, count, &ret); + status = uefi_call_wrapper(gBS->AllocatePool, 3, 4, count, &ret); } + if (status) { + panic("Memory allocation error %x\n", status); + } + + memset(ret, 0, count); + return ret; } #endif