chainload: Implement MBR_ID config option. Closes #190

This commit is contained in:
mintsuki 2022-07-11 01:30:54 +02:00
parent fb75a6876e
commit 62c029c218
4 changed files with 26 additions and 1 deletions

View File

@ -127,6 +127,7 @@ Editor control options.
* Chainload protocol on BIOS:
* `DRIVE` - The 1-based BIOS drive to chainload, if omitted, assume boot drive.
* `PARTITION` - The 1-based BIOS partition to chainload, if omitted, chainload drive (MBR).
* `MBR_ID` - Optional. If passed, use an MBR ID (32-bit hex value) to identify the volume to chainload.
* Chainload protocol on UEFI:
* `IMAGE_PATH` - URI of the EFI application to chainload.

View File

@ -55,6 +55,7 @@ struct volume {
};
void list_volumes(void);
bool is_valid_mbr(struct volume *volume);
extern struct volume **volume_index;
extern size_t volume_index_i;

View File

@ -244,7 +244,7 @@ struct mbr_entry {
uint32_t sect_count;
} __attribute__((packed));
static bool is_valid_mbr(struct volume *volume) {
bool is_valid_mbr(struct volume *volume) {
// Check if actually valid mbr
uint16_t hint = 0;
volume_read(volume, &hint, 218, sizeof(uint16_t));

View File

@ -99,6 +99,29 @@ void chainload(char *config) {
struct volume *p = volume_get_by_coord(false, drive, part);
char *mbr_id_s = config_get_value(config, 0, "MBR_ID");
if (mbr_id_s != NULL) {
uint32_t mbr_id = strtoui(mbr_id_s, NULL, 16);
for (size_t i = 0; i < volume_index_i; i++) {
p = volume_index[i];
if (!is_valid_mbr(p)) {
continue;
}
uint32_t mbr_id_1;
volume_read(p, &mbr_id_1, 0x1b8, sizeof(uint32_t));
if (mbr_id_1 == mbr_id) {
goto load;
}
}
panic(true, "chainload: No matching MBR ID found");
}
load:
bios_chainload_volume(p);
panic(true, "chainload: Volume is not bootable");