A lot of changes

This commit is contained in:
mintsuki 2021-03-03 22:38:28 +01:00
parent 54862a8269
commit f7a8bbd7f6
9 changed files with 215 additions and 43 deletions

View File

@ -6,17 +6,6 @@
#include <stdbool.h> #include <stdbool.h>
#include <lib/part.h> #include <lib/part.h>
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); size_t disk_create_index(struct volume **ret);
bool disk_read_sectors(struct volume *volume, void *buf, uint64_t block, size_t count); bool disk_read_sectors(struct volume *volume, void *buf, uint64_t block, size_t count);

View File

@ -1,14 +1,29 @@
#if defined(bios)
#include <stdint.h> #include <stdint.h>
#include <stddef.h> #include <stddef.h>
#include <drivers/disk.h> #include <drivers/disk.h>
#include <lib/libc.h> #include <lib/libc.h>
#include <lib/real.h> #if defined (bios)
# include <lib/real.h>
#elif defined (uefi)
# include <efi.h>
#endif
#include <lib/blib.h> #include <lib/blib.h>
#include <lib/print.h> #include <lib/print.h>
#include <mm/pmm.h> #include <mm/pmm.h>
#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 { struct dap {
uint16_t size; uint16_t size;
uint16_t count; uint16_t count;
@ -31,7 +46,7 @@ bool disk_read_sectors(struct volume *volume, void *buf, uint64_t block, size_t
if (dap == NULL) { if (dap == NULL) {
dap = conv_mem_alloc(sizeof(struct dap)); dap = conv_mem_alloc(sizeof(struct dap));
dap->size = 16; dap->size = 16;
} }
dap->count = count; dap->count = count;
@ -91,7 +106,7 @@ size_t disk_create_index(struct volume **ret) {
volume_count++; volume_count++;
struct volume block; struct volume block = {0};
block.drive = drive; block.drive = drive;
block.sector_size = drive_params.bytes_per_sect; 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++) { for (int part = 0; ; part++) {
struct volume p; struct volume p = {0};
int ret = part_get(&p, &block, part); int ret = part_get(&p, &block, part);
if (ret == END_OF_TABLE || ret == INVALID_TABLE) 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++) { 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); int ret = part_get(&p, block, part);
if (ret == END_OF_TABLE || ret == INVALID_TABLE) if (ret == END_OF_TABLE || ret == INVALID_TABLE)

View File

@ -20,6 +20,8 @@
#include <pxe/pxe.h> #include <pxe/pxe.h>
#include <pxe/tftp.h> #include <pxe/tftp.h>
void stage3_common(void);
#if defined (uefi) #if defined (uefi)
__attribute__((ms_abi)) __attribute__((ms_abi))
EFI_STATUS efi_main(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable) { 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; gBS = SystemTable->BootServices;
gRT = SystemTable->RuntimeServices; 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 (;;); for (;;);
//stage3_common();
} }
#endif #endif
#if defined (bios)
__attribute__((section(".stage3_build_id"))) __attribute__((section(".stage3_build_id")))
uint64_t stage3_build_id = BUILD_ID; uint64_t stage3_build_id = BUILD_ID;
@ -48,19 +79,15 @@ void stage3_entry(int boot_from) {
case BOOT_FROM_CD: { case BOOT_FROM_CD: {
struct volume boot_volume = {0}; struct volume boot_volume = {0};
volume_get_by_coord(&boot_volume, boot_drive, -1); volume_get_by_coord(&boot_volume, boot_drive, -1);
struct volume part = boot_volume;
for (int i = 0; ; i++) { if (!volume_iterate_parts(boot_volume,
if (!init_config_disk(&part)) { if (!init_config_disk(&_PART_)) {
print("Config file found and loaded.\n"); print("Config file found and loaded.\n");
boot_partition = i - 1; boot_partition = _PARTNUM_;
break; break;
} }
int ret = part_get(&part, &boot_volume, i); )) {
switch (ret) { panic("Config file not found.");
case INVALID_TABLE:
case END_OF_TABLE:
panic("Config file not found.");
}
} }
break; break;
case BOOT_FROM_PXE: 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 *cmdline;
char *config = menu(&cmdline); char *config = menu(&cmdline);
@ -81,17 +114,19 @@ void stage3_entry(int boot_from) {
panic("PROTOCOL not specified"); panic("PROTOCOL not specified");
} }
if (!strcmp(proto, "stivale")) { if (0) {
} else if (!strcmp(proto, "stivale")) {
stivale_load(config, cmdline); stivale_load(config, cmdline);
} else if (!strcmp(proto, "stivale2")) { } else if (!strcmp(proto, "stivale2")) {
stivale2_load(config, cmdline, booted_from_pxe); stivale2_load(config, cmdline, booted_from_pxe);
#if defined (bios)
} else if (!strcmp(proto, "linux")) { } else if (!strcmp(proto, "linux")) {
linux_load(config, cmdline); linux_load(config, cmdline);
} else if (!strcmp(proto, "chainload")) { } else if (!strcmp(proto, "chainload")) {
chainload(config); chainload(config);
} else { #endif
panic("Invalid protocol specified");
} }
for (;;); panic("Invalid protocol specified");
} }

View File

@ -5,6 +5,7 @@
#include <fs/ext2.h> #include <fs/ext2.h>
#include <fs/fat32.h> #include <fs/fat32.h>
#include <fs/iso9660.h> #include <fs/iso9660.h>
#include <lib/print.h>
#include <lib/blib.h> #include <lib/blib.h>
#include <mm/pmm.h> #include <mm/pmm.h>
#include <lib/part.h> #include <lib/part.h>

View File

@ -15,7 +15,7 @@
#if defined (bios) #if defined (bios)
typedef int drive_t; typedef int drive_t;
#elif defined (uefi) #elif defined (uefi)
typedef EFI_HANDLE drive_t; typedef EFI_BLOCK_IO *drive_t;
#endif #endif
struct volume { 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); 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 #endif

View File

@ -1,9 +1,9 @@
#include <stddef.h> #include <stddef.h>
#include <stdint.h> #include <stdint.h>
#include <lib/part.h> #include <lib/part.h>
#include <drivers/disk.h>
#if defined (bios) #if defined (bios)
# include <drivers/disk.h> # include <lib/real.h>
#include <lib/real.h>
#endif #endif
#include <lib/libc.h> #include <lib/libc.h>
#include <lib/blib.h> #include <lib/blib.h>
@ -295,11 +295,7 @@ static struct volume *volume_index = NULL;
static size_t volume_index_i = 0; static size_t volume_index_i = 0;
void volume_create_index(void) { void volume_create_index(void) {
#if defined (bios)
volume_index_i = disk_create_index(&volume_index); volume_index_i = disk_create_index(&volume_index);
#elif defined (uefi)
#endif
} }
bool volume_get_by_guid(struct volume *part, struct guid *guid) { bool volume_get_by_guid(struct volume *part, struct guid *guid) {

View File

@ -8,6 +8,7 @@ SECTIONS
.text : { .text : {
*(.text*) *(.text*)
*(.realmode*) *(.realmode*)
*(.stage3_entry*)
} }
.rodata : { .rodata : {

View File

@ -8,6 +8,7 @@ SECTIONS
.text : { .text : {
*(.text*) *(.text*)
*(.realmode*) *(.realmode*)
*(.stage3_entry*)
} }
.rodata : { .rodata : {

View File

@ -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 *ext_mem_alloc_aligned_type(size_t count, size_t alignment, uint32_t type) {
(void)type; (void)type;
EFI_STATUS status;
void *ret; void *ret;
if (alignment && alignment % 4096 == 0) { if (alignment && alignment % 4096 == 0) {
uefi_call_wrapper(gBS->AllocatePages, 4, 0, 2, DIV_ROUNDUP(count, 4096), status = uefi_call_wrapper(gBS->AllocatePages, 4, 0, 2,
&ret); DIV_ROUNDUP(count, 4096), &ret);
} else { } 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; return ret;
} }
#endif #endif