mirror of
https://github.com/limine-bootloader/limine
synced 2024-11-27 02:49:56 +03:00
Add BIOS drive indexing
This commit is contained in:
parent
a9864a0ab4
commit
a82dc582c7
BIN
limine.bin
BIN
limine.bin
Binary file not shown.
@ -2,7 +2,8 @@ CC = i386-elf-gcc
|
||||
LD = i386-elf-gcc
|
||||
OBJCOPY = i386-elf-objcopy
|
||||
|
||||
CFLAGS = -flto -Os -pipe -Wall -Wextra -Werror
|
||||
WERROR = -Werror
|
||||
CFLAGS = -flto -Os -pipe -Wall -Wextra $(WERROR)
|
||||
|
||||
INTERNAL_CFLAGS = \
|
||||
-std=gnu11 \
|
||||
|
@ -5,6 +5,17 @@
|
||||
#include <stdint.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));
|
||||
|
||||
int read(int drive, void *buffer, uint64_t loc, uint64_t count);
|
||||
int read_partition(int drive, struct part *part, void *buffer, uint64_t loc, uint64_t count);
|
||||
|
||||
|
@ -168,7 +168,7 @@ bool string_to_guid(struct guid *guid, const char *s) {
|
||||
guid_convert_le_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 + 8, s + 19, 4);
|
||||
guid_convert_be_cluster((uint8_t *)guid + 10, s + 24, 16);
|
||||
guid_convert_be_cluster((uint8_t *)guid + 10, s + 24, 12);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -4,9 +4,13 @@
|
||||
#include <drivers/disk.h>
|
||||
#include <lib/libc.h>
|
||||
#include <lib/blib.h>
|
||||
#include <lib/real.h>
|
||||
#include <lib/print.h>
|
||||
#include <mm/pmm.h>
|
||||
|
||||
#define NO_PARTITION (-1)
|
||||
#define INVALID_TABLE (-2)
|
||||
#define END_OF_TABLE (-3)
|
||||
|
||||
struct gpt_table_header {
|
||||
// the head
|
||||
@ -53,12 +57,14 @@ static int gpt_get_part(struct part *ret, int drive, int partition) {
|
||||
|
||||
// check the header
|
||||
// 'EFI PART'
|
||||
if (strncmp(header.signature, "EFI PART", 8)) return INVALID_TABLE;
|
||||
if (header.revision != 0x00010000) return NO_PARTITION;
|
||||
if (strncmp(header.signature, "EFI PART", 8))
|
||||
return INVALID_TABLE;
|
||||
if (header.revision != 0x00010000)
|
||||
return END_OF_TABLE;
|
||||
|
||||
// parse the entries if reached here
|
||||
if ((uint32_t)partition >= header.number_of_partition_entries)
|
||||
return NO_PARTITION;
|
||||
return END_OF_TABLE;
|
||||
|
||||
struct gpt_entry entry = {0};
|
||||
read(drive, &entry,
|
||||
@ -71,6 +77,7 @@ static int gpt_get_part(struct part *ret, int drive, int partition) {
|
||||
|
||||
ret->first_sect = entry.starting_lba;
|
||||
ret->sect_count = (entry.ending_lba - entry.starting_lba) + 1;
|
||||
ret->guid = entry.unique_partition_guid;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -91,6 +98,12 @@ static int mbr_get_part(struct part *ret, int drive, int partition) {
|
||||
if (hint && hint != 0x5a5a)
|
||||
return INVALID_TABLE;
|
||||
|
||||
if (partition > 3)
|
||||
return END_OF_TABLE;
|
||||
|
||||
uint32_t disk_signature;
|
||||
read(drive, &disk_signature, 440, sizeof(uint32_t));
|
||||
|
||||
struct mbr_entry entry;
|
||||
size_t entry_offset = 0x1be + sizeof(struct mbr_entry) * partition;
|
||||
|
||||
@ -103,6 +116,13 @@ static int mbr_get_part(struct part *ret, int drive, int partition) {
|
||||
|
||||
ret->first_sect = entry.first_sect;
|
||||
ret->sect_count = entry.sect_count;
|
||||
|
||||
// We use the same method of generating GUIDs for MBR partitions as Linux
|
||||
struct guid empty_guid = {0};
|
||||
ret->guid = empty_guid;
|
||||
ret->guid.a = disk_signature;
|
||||
ret->guid.b = (partition + 1) << 8;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -119,3 +139,58 @@ int get_part(struct part *part, int drive, int partition) {
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static struct part *part_index = NULL;
|
||||
static size_t part_index_i = 0;
|
||||
|
||||
void part_create_index(void) {
|
||||
part_index = conv_mem_alloc(0);
|
||||
|
||||
for (uint8_t drive = 0x80; drive < 0x8f; drive++) {
|
||||
struct rm_regs r = {0};
|
||||
struct bios_drive_params drive_params;
|
||||
|
||||
r.eax = 0x4800;
|
||||
r.edx = drive;
|
||||
r.ds = rm_seg(&drive_params);
|
||||
r.esi = rm_off(&drive_params);
|
||||
|
||||
drive_params.buf_size = sizeof(struct bios_drive_params);
|
||||
|
||||
rm_int(0x13, &r, &r);
|
||||
|
||||
if (r.eflags & EFLAGS_CF)
|
||||
continue;
|
||||
|
||||
print("Found BIOS drive %x\n", drive);
|
||||
print(" ... %X total %u-byte sectors\n",
|
||||
drive_params.lba_count, drive_params.bytes_per_sect);
|
||||
|
||||
size_t part_count = 0;
|
||||
for (int part = 0; ; part++) {
|
||||
struct part p;
|
||||
int ret = get_part(&p, drive, part);
|
||||
|
||||
if (ret == END_OF_TABLE)
|
||||
break;
|
||||
if (ret == NO_PARTITION)
|
||||
continue;
|
||||
|
||||
part_count++;
|
||||
}
|
||||
|
||||
part_index = conv_mem_alloc(sizeof(struct part) * part_count);
|
||||
|
||||
for (int part = 0; ; part++) {
|
||||
struct part p;
|
||||
int ret = get_part(&p, drive, part);
|
||||
|
||||
if (ret == END_OF_TABLE)
|
||||
break;
|
||||
if (ret == NO_PARTITION)
|
||||
continue;
|
||||
|
||||
part_index[part_index_i++] = p;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,12 +2,17 @@
|
||||
#define __LIB__PART_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <lib/blib.h>
|
||||
|
||||
struct part {
|
||||
uint64_t first_sect;
|
||||
uint64_t sect_count;
|
||||
uint64_t first_sect;
|
||||
uint64_t sect_count;
|
||||
struct guid guid;
|
||||
};
|
||||
|
||||
int get_part(struct part *part, int drive, int partition);
|
||||
|
||||
void part_create_index(void);
|
||||
|
||||
#endif
|
||||
|
@ -32,6 +32,8 @@ void entry(uint8_t _boot_drive) {
|
||||
|
||||
print("Boot drive: %x\n", boot_drive);
|
||||
|
||||
part_create_index();
|
||||
|
||||
// Look for config file.
|
||||
print("Searching for config file...\n");
|
||||
struct part parts[4];
|
||||
|
Loading…
Reference in New Issue
Block a user