Introduced opportunity to choose an MBR partition number with
struct iso_mbr_partition_request and iso_quick_mbr_entry().
This commit is contained in:
parent
bbd198a81b
commit
85bedae639
@ -776,11 +776,18 @@ int iso_quick_gpt_entry(Ecma119Image *t,
|
|||||||
|
|
||||||
int iso_quick_mbr_entry(Ecma119Image *t,
|
int iso_quick_mbr_entry(Ecma119Image *t,
|
||||||
uint32_t start_block, uint32_t block_count,
|
uint32_t start_block, uint32_t block_count,
|
||||||
uint8_t type_byte, uint8_t status_byte)
|
uint8_t type_byte, uint8_t status_byte,
|
||||||
|
int desired_slot)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
struct iso_mbr_partition_request *entry;
|
struct iso_mbr_partition_request *entry;
|
||||||
|
|
||||||
|
ret = iso_mbr_entry_slot_is_free(t, desired_slot);
|
||||||
|
if (ret < 0)
|
||||||
|
desired_slot = 0;
|
||||||
|
else if (ret == 0)
|
||||||
|
return ISO_BOOT_MBR_COLLISION;
|
||||||
|
|
||||||
entry = calloc(1, sizeof(struct iso_mbr_partition_request));
|
entry = calloc(1, sizeof(struct iso_mbr_partition_request));
|
||||||
if (entry == NULL)
|
if (entry == NULL)
|
||||||
return ISO_OUT_OF_MEM;
|
return ISO_OUT_OF_MEM;
|
||||||
@ -788,14 +795,30 @@ int iso_quick_mbr_entry(Ecma119Image *t,
|
|||||||
entry->block_count = block_count;
|
entry->block_count = block_count;
|
||||||
entry->type_byte = type_byte;
|
entry->type_byte = type_byte;
|
||||||
entry->status_byte = status_byte;
|
entry->status_byte = status_byte;
|
||||||
|
entry->desired_slot = desired_slot;
|
||||||
ret = iso_register_mbr_entry(t, entry, 0);
|
ret = iso_register_mbr_entry(t, entry, 0);
|
||||||
free(entry);
|
free(entry);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int iso_mbr_entry_slot_is_free(Ecma119Image *t, int slot)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (slot < 0 || slot > ISO_MBR_ENTRIES_MAX)
|
||||||
|
return -1;
|
||||||
|
if (slot == 0)
|
||||||
|
return 1;
|
||||||
|
for (i = 0; i < t->mbr_req_count; i++)
|
||||||
|
if (t->mbr_req[i]->desired_slot == slot)
|
||||||
|
return 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compare the start_sectors of two iso_apm_partition_request
|
* Compare the block interval positions of two iso_apm_partition_request
|
||||||
*/
|
*/
|
||||||
static
|
static
|
||||||
int cmp_partition_request(const void *f1, const void *f2)
|
int cmp_partition_request(const void *f1, const void *f2)
|
||||||
@ -1067,17 +1090,17 @@ static int iso_write_apm(Ecma119Image *t, uint32_t img_blocks, uint8_t *buf,
|
|||||||
|
|
||||||
static int iso_write_mbr(Ecma119Image *t, uint32_t img_blocks, uint8_t *buf)
|
static int iso_write_mbr(Ecma119Image *t, uint32_t img_blocks, uint8_t *buf)
|
||||||
{
|
{
|
||||||
int i, ret;
|
int i, ret, req_of_slot[ISO_MBR_ENTRIES_MAX], q, j;
|
||||||
|
|
||||||
#ifdef NIX
|
#ifdef NIX
|
||||||
/* Disabled */
|
/* Disabled */
|
||||||
|
|
||||||
/* <<< Dummy mock-up */
|
/* <<< Dummy mock-up */
|
||||||
if (t->mbr_req_count <= 0) {
|
if (t->mbr_req_count <= 0) {
|
||||||
ret = iso_quick_mbr_entry(t, 0, 0, 0xee, 0);
|
ret = iso_quick_mbr_entry(t, 0, 0, 0xee, 0, 0);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
ret = iso_quick_mbr_entry(t, 100, 0, 0x0c, 0x80);
|
ret = iso_quick_mbr_entry(t, 100, 0, 0x0c, 0x80, 1);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -1110,22 +1133,43 @@ static int iso_write_mbr(Ecma119Image *t, uint32_t img_blocks, uint8_t *buf)
|
|||||||
t->mbr_req[i]->start_block;
|
t->mbr_req[i]->start_block;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* >>> Permutate ? */
|
/* Assign requested entries to slot numbers */
|
||||||
|
for (i = 0; i < ISO_MBR_ENTRIES_MAX; i++)
|
||||||
|
req_of_slot[i] = -1;
|
||||||
|
for (i = 0; i < t->mbr_req_count; i++) {
|
||||||
|
if (t->mbr_req[i]->desired_slot < 1 ||
|
||||||
|
t->mbr_req[i]->desired_slot > ISO_MBR_ENTRIES_MAX)
|
||||||
|
continue;
|
||||||
|
if (req_of_slot[t->mbr_req[i]->desired_slot - 1] >= 0)
|
||||||
|
return ISO_BOOT_MBR_COLLISION;
|
||||||
|
req_of_slot[t->mbr_req[i]->desired_slot - 1] = i;
|
||||||
|
}
|
||||||
|
for (i = 0; i < t->mbr_req_count; i++) {
|
||||||
|
if (t->mbr_req[i]->desired_slot > 0)
|
||||||
|
continue;
|
||||||
|
for (j = 0; j < ISO_MBR_ENTRIES_MAX; j++)
|
||||||
|
if (req_of_slot[j] < 0)
|
||||||
|
break;
|
||||||
|
if (j >= ISO_MBR_ENTRIES_MAX)
|
||||||
|
return ISO_BOOT_TOO_MANY_MBR;
|
||||||
|
req_of_slot[j] = i;
|
||||||
|
}
|
||||||
|
|
||||||
/* Write partition slots */
|
/* Write partition slots */
|
||||||
for (i = 0; i < ISO_MBR_ENTRIES_MAX; i++) {
|
for (i = 0; i < ISO_MBR_ENTRIES_MAX; i++) {
|
||||||
memset(buf + 446 + i * 16, 0, 16);
|
memset(buf + 446 + i * 16, 0, 16);
|
||||||
if (i >= t->mbr_req_count)
|
q = req_of_slot[i];
|
||||||
|
if (q < 0)
|
||||||
continue;
|
continue;
|
||||||
if (t->mbr_req[i]->block_count == 0)
|
if (t->mbr_req[q]->block_count == 0)
|
||||||
continue;
|
continue;
|
||||||
ret = write_mbr_partition_entry(i + 1, (int) t->mbr_req[i]->type_byte,
|
ret = write_mbr_partition_entry(i + 1, (int) t->mbr_req[q]->type_byte,
|
||||||
t->mbr_req[i]->start_block, t->mbr_req[i]->block_count,
|
t->mbr_req[q]->start_block, t->mbr_req[q]->block_count,
|
||||||
t->partition_secs_per_head, t->partition_heads_per_cyl,
|
t->partition_secs_per_head, t->partition_heads_per_cyl,
|
||||||
buf, 0);
|
buf, 0);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
buf[446 + i * 16] = t->mbr_req[i]->status_byte;
|
buf[446 + i * 16] = t->mbr_req[q]->status_byte;
|
||||||
}
|
}
|
||||||
return ISO_SUCCESS;
|
return ISO_SUCCESS;
|
||||||
}
|
}
|
||||||
@ -2152,7 +2196,7 @@ static int partprepend_writer_compute_data_blocks(IsoImageWriter *writer)
|
|||||||
if (t->prep_partition != NULL || t->fat || will_have_gpt ||
|
if (t->prep_partition != NULL || t->fat || will_have_gpt ||
|
||||||
t->mbr_req_count > 0)
|
t->mbr_req_count > 0)
|
||||||
return ISO_BOOT_MBR_OVERLAP;
|
return ISO_BOOT_MBR_OVERLAP;
|
||||||
ret = iso_quick_mbr_entry(t, (uint32_t) 0, (uint32_t) 0, 0x96, 0);
|
ret = iso_quick_mbr_entry(t, (uint32_t) 0, (uint32_t) 0, 0x96, 0, 0);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
return ISO_SUCCESS;
|
return ISO_SUCCESS;
|
||||||
@ -2167,12 +2211,13 @@ static int partprepend_writer_compute_data_blocks(IsoImageWriter *writer)
|
|||||||
if (t->prep_part_size > 0 || t->fat || will_have_gpt) {
|
if (t->prep_part_size > 0 || t->fat || will_have_gpt) {
|
||||||
/* Protecting MBR entry for ISO start or whole ISO */
|
/* Protecting MBR entry for ISO start or whole ISO */
|
||||||
ret = iso_quick_mbr_entry(t, (uint32_t) t->partition_offset,
|
ret = iso_quick_mbr_entry(t, (uint32_t) t->partition_offset,
|
||||||
(uint32_t) 0, will_have_gpt ? 0xee : 0xcd, 0);
|
(uint32_t) 0, will_have_gpt ? 0xee : 0xcd, 0, 0);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
if (t->prep_part_size > 0) {
|
if (t->prep_part_size > 0) {
|
||||||
ret = iso_quick_mbr_entry(t, t->curblock, t->prep_part_size, 0x41, 0);
|
ret = iso_quick_mbr_entry(t, t->curblock, t->prep_part_size, 0x41,
|
||||||
|
0, 0);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
t->curblock += t->prep_part_size;
|
t->curblock += t->prep_part_size;
|
||||||
@ -2180,7 +2225,7 @@ static int partprepend_writer_compute_data_blocks(IsoImageWriter *writer)
|
|||||||
if (t->prep_part_size > 0 || t->fat) {
|
if (t->prep_part_size > 0 || t->fat) {
|
||||||
/* FAT partition or protecting MBR entry for ISO end */
|
/* FAT partition or protecting MBR entry for ISO end */
|
||||||
ret = iso_quick_mbr_entry(t, (uint32_t) t->curblock, (uint32_t) 0,
|
ret = iso_quick_mbr_entry(t, (uint32_t) t->curblock, (uint32_t) 0,
|
||||||
t->fat ? 0x0c : 0xcd, 0);
|
t->fat ? 0x0c : 0xcd, 0, 0);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -67,7 +67,9 @@ int iso_compute_append_partitions(Ecma119Image *t, int flag);
|
|||||||
|
|
||||||
/* The parameter struct for production of a single MBR partition entry.
|
/* The parameter struct for production of a single MBR partition entry.
|
||||||
See also the description of MBR in doc/boot_sectors.txt.
|
See also the description of MBR in doc/boot_sectors.txt.
|
||||||
No sorting and gap filling is done before the System Area gets written.
|
No sorting by start sector and gap filling is done before the System Area
|
||||||
|
gets written. But the entries may get assigned to a desired slot number
|
||||||
|
in the table.
|
||||||
Requested entries with block_count == 0 get expanded to the start of
|
Requested entries with block_count == 0 get expanded to the start of
|
||||||
the next requested entry resp. to image end, if no entry follows.
|
the next requested entry resp. to image end, if no entry follows.
|
||||||
start_block of a follwing entry must be at least a high as the sum of
|
start_block of a follwing entry must be at least a high as the sum of
|
||||||
@ -90,7 +92,15 @@ struct iso_mbr_partition_request {
|
|||||||
/* 0x80 = bootable */
|
/* 0x80 = bootable */
|
||||||
uint8_t status_byte;
|
uint8_t status_byte;
|
||||||
|
|
||||||
/* >>> Is a permutation of entries needed ? */
|
/* If >= 1 && <= 4 : The partition slot number in MBR.
|
||||||
|
If more than one partition desires the same slot, then an error
|
||||||
|
ISO_BOOT_MBR_COLLISION occurs at registration time.
|
||||||
|
Use iso_mbr_entry_slot_is_free() to detect this in advance.
|
||||||
|
If desired_slot is 0, then the partition entry is put into the
|
||||||
|
lowest MBR slot that is not occupied by an entry with desired_slot > 0
|
||||||
|
or by an entry that was registered before this entry.
|
||||||
|
*/
|
||||||
|
int desired_slot;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -106,7 +116,16 @@ int iso_register_mbr_entry(Ecma119Image *t,
|
|||||||
*/
|
*/
|
||||||
int iso_quick_mbr_entry(Ecma119Image *t,
|
int iso_quick_mbr_entry(Ecma119Image *t,
|
||||||
uint32_t start_block, uint32_t block_count,
|
uint32_t start_block, uint32_t block_count,
|
||||||
uint8_t type_byte, uint8_t status_byte);
|
uint8_t type_byte, uint8_t status_byte,
|
||||||
|
int desired_slot);
|
||||||
|
|
||||||
|
/* Peek in advance whether a desired slot number is already occupied by a
|
||||||
|
registered MBR entry.
|
||||||
|
Parameter slot may be between 0 and 4. 0 always returns "free".
|
||||||
|
Return value is 0 if occupied, 1 if free, and -1 if the slot number is
|
||||||
|
out of range.
|
||||||
|
*/
|
||||||
|
int iso_mbr_entry_slot_is_free(Ecma119Image *t, int slot);
|
||||||
|
|
||||||
|
|
||||||
/* The parameter struct for production of a single Apple Partition Map entry.
|
/* The parameter struct for production of a single Apple Partition Map entry.
|
||||||
|
Loading…
Reference in New Issue
Block a user