A lot of changes
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 <stdbool.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);
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 <stdint.h>
#include <stddef.h>
#include <drivers/disk.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/print.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 {
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 <pxe/pxe.h>
#include <pxe/tftp.h>
+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 <fs/ext2.h>
#include <fs/fat32.h>
#include <fs/iso9660.h>
+#include <lib/print.h>
#include <lib/blib.h>
#include <mm/pmm.h>
#include <lib/part.h>
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 <stddef.h>
#include <stdint.h>
#include <lib/part.h>
+#include <drivers/disk.h>
#if defined (bios)
-# include <drivers/disk.h>
-#include <lib/real.h>
+# include <lib/real.h>
#endif
#include <lib/libc.h>
#include <lib/blib.h>
@@ -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
