Add BIOS drive indexing

This commit is contained in:
mintsuki 2020-10-18 06:23:39 +02:00
parent a9864a0ab4
commit a82dc582c7
7 changed files with 101 additions and 7 deletions

Binary file not shown.

View File

@ -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 \

View File

@ -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);

View File

@ -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;
}

View File

@ -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;
}
}
}

View File

@ -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

View File

@ -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];