mirror of
https://github.com/limine-bootloader/limine
synced 2024-12-11 17:24:08 +03:00
A lot of changes
This commit is contained in:
parent
54862a8269
commit
f7a8bbd7f6
@ -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);
|
||||||
|
|
||||||
|
@ -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)
|
||||||
|
@ -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");
|
||||||
}
|
}
|
||||||
|
@ -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>
|
||||||
|
@ -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
|
||||||
|
@ -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) {
|
||||||
|
@ -8,6 +8,7 @@ SECTIONS
|
|||||||
.text : {
|
.text : {
|
||||||
*(.text*)
|
*(.text*)
|
||||||
*(.realmode*)
|
*(.realmode*)
|
||||||
|
*(.stage3_entry*)
|
||||||
}
|
}
|
||||||
|
|
||||||
.rodata : {
|
.rodata : {
|
||||||
|
@ -8,6 +8,7 @@ SECTIONS
|
|||||||
.text : {
|
.text : {
|
||||||
*(.text*)
|
*(.text*)
|
||||||
*(.realmode*)
|
*(.realmode*)
|
||||||
|
*(.stage3_entry*)
|
||||||
}
|
}
|
||||||
|
|
||||||
.rodata : {
|
.rodata : {
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user