part: Add support for MBR extended and logical partitions
This commit is contained in:
parent
0daaa565f3
commit
34ddbe6f14
@ -100,8 +100,8 @@ resource://root/path
|
||||
The format for `root` changes depending on the resource used.
|
||||
|
||||
A resource can be one of the following:
|
||||
* `boot` - The `root` is the 1-based decimal value representing the partition on the boot drive. If omitted, the partition containing the configuration file on the boot drive is used. For example: `boot://2/...` will use partition 2 of the boot drive and `boot:///...` will use the partition containing the config file on the boot drive.
|
||||
* `bios` - The `root` takes the form of `drive:partition`; for example: `bios://3:1/...` would use BIOS drive 3, partition 1. Partitions and BIOS drives are both 1-based. Omitting the drive is possible; for example: `bios://:2/...`. Omitting the drive makes Limine use the boot drive.
|
||||
* `boot` - The `root` is the 1-based decimal value representing the partition on the boot drive (values of 5+ for MBR logical partitions). If omitted, the partition containing the configuration file on the boot drive is used. For example: `boot://2/...` will use partition 2 of the boot drive and `boot:///...` will use the partition containing the config file on the boot drive.
|
||||
* `bios` - The `root` takes the form of `drive:partition`; for example: `bios://3:1/...` would use BIOS drive 3, partition 1. Partitions and BIOS drives are both 1-based (partition values of 5+ for MBR logical partitions). Omitting the drive is possible; for example: `bios://:2/...`. Omitting the drive makes Limine use the boot drive.
|
||||
* `guid` - The `root` takes the form of a GUID/UUID, such as `guid://736b5698-5ae1-4dff-be2c-ef8f44a61c52/...`. The GUID is that of either a filesystem, when available, or a GPT partition GUID, when using GPT, in a unified namespace.
|
||||
* `uuid` - Alias of `guid`.
|
||||
* `tftp` - The `root` is the IP address of the tftp server to load the file from. If the root is left empty (`tftp:///...`) the file will be loaded from the server Limine booted from. This resource is only available when booting off PXE.
|
||||
|
BIN
limine-pxe.bin
BIN
limine-pxe.bin
Binary file not shown.
BIN
limine.bin
BIN
limine.bin
Binary file not shown.
BIN
stage2.map
BIN
stage2.map
Binary file not shown.
@ -103,6 +103,55 @@ struct mbr_entry {
|
||||
uint32_t sect_count;
|
||||
} __attribute__((packed));
|
||||
|
||||
static int mbr_get_logical_part(struct part *ret, struct part *extended_part,
|
||||
int drive, int partition) {
|
||||
struct mbr_entry entry;
|
||||
|
||||
size_t ebr_sector = 0;
|
||||
|
||||
for (int i = 0; i < partition; i++) {
|
||||
size_t entry_offset = ebr_sector * extended_part->sector_size + 0x1ce;
|
||||
|
||||
int r;
|
||||
r = part_read(extended_part, &entry, entry_offset, sizeof(struct mbr_entry));
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
if (entry.type != 0x0f && entry.type != 0x05)
|
||||
return END_OF_TABLE;
|
||||
|
||||
ebr_sector = entry.first_sect;
|
||||
}
|
||||
|
||||
size_t entry_offset = ebr_sector * extended_part->sector_size + 0x1be;
|
||||
|
||||
int r;
|
||||
r = part_read(extended_part, &entry, entry_offset, sizeof(struct mbr_entry));
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
if (entry.type == 0)
|
||||
return NO_PARTITION;
|
||||
|
||||
ret->drive = drive;
|
||||
ret->partition = partition + 4;
|
||||
ret->sector_size = disk_get_sector_size(drive);
|
||||
ret->first_sect = extended_part->first_sect + ebr_sector + entry.first_sect;
|
||||
ret->sect_count = entry.sect_count;
|
||||
|
||||
struct guid guid;
|
||||
if (!fs_get_guid(&guid, ret)) {
|
||||
ret->guid_valid = false;
|
||||
} else {
|
||||
ret->guid_valid = true;
|
||||
ret->guid = guid;
|
||||
}
|
||||
|
||||
ret->part_guid_valid = false;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mbr_get_part(struct part *ret, int drive, int partition) {
|
||||
// Check if actually valid mbr
|
||||
uint16_t hint;
|
||||
@ -110,13 +159,33 @@ 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;
|
||||
disk_read(drive, &disk_signature, 440, sizeof(uint32_t));
|
||||
|
||||
struct mbr_entry entry;
|
||||
|
||||
if (partition > 3) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
size_t entry_offset = 0x1be + sizeof(struct mbr_entry) * i;
|
||||
|
||||
int r = disk_read(drive, &entry, entry_offset, sizeof(struct mbr_entry));
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
if (entry.type != 0x0f)
|
||||
continue;
|
||||
|
||||
struct part extended_part;
|
||||
|
||||
extended_part.drive = drive;
|
||||
extended_part.partition = i;
|
||||
extended_part.sector_size = disk_get_sector_size(drive);
|
||||
extended_part.first_sect = entry.first_sect;
|
||||
extended_part.sect_count = entry.sect_count;
|
||||
|
||||
return mbr_get_logical_part(ret, &extended_part, drive, partition - 4);
|
||||
}
|
||||
|
||||
return END_OF_TABLE;
|
||||
}
|
||||
|
||||
size_t entry_offset = 0x1be + sizeof(struct mbr_entry) * partition;
|
||||
|
||||
int r = disk_read(drive, &entry, entry_offset, sizeof(struct mbr_entry));
|
||||
|
Loading…
Reference in New Issue
Block a user