From 475fe593d238f6b1c8edd78d2d819be7e79d6305 Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Fri, 25 Jun 2010 13:56:19 -0700 Subject: [PATCH] chain.c32: correctly set the length of the GPT handover structure We need to make sure the entire GPT handover structure is mapped correctly by the shuffler. Signed-off-by: H. Peter Anvin --- com32/modules/chain.c | 107 +++++++++++++++++++++++++++----------------------- 1 file changed, 57 insertions(+), 50 deletions(-) diff --git a/com32/modules/chain.c b/com32/modules/chain.c index 6f3729f..b4fe3ef 100644 --- a/com32/modules/chain.c +++ b/com32/modules/chain.c @@ -1419,60 +1419,67 @@ int main(int argc, char *argv[]) ndata++; } - /* Do GPT hand-over, if applicable (as per syslinux/doc/gpt.txt) */ - if (cur_part && (cur_part->next == next_gpt_part)) { - struct part_entry *record; - /* Look at the GPT partition */ - const struct gpt_part *gp = (const struct gpt_part *) + if (cur_part) { + if (cur_part->next == next_gpt_part) { + /* Do GPT hand-over, if applicable (as per syslinux/doc/gpt.txt) */ + struct part_entry *record; + /* Look at the GPT partition */ + const struct gpt_part *gp = (const struct gpt_part *) (cur_part->block + (cur_part->private.gpt.size * cur_part->private.gpt.index)); - /* Note the partition length */ - uint64_t lba_count = gp->lba_last - gp->lba_first + 1; - /* The length of the hand-over */ - int synth_size = - sizeof(struct part_entry) + sizeof(uint32_t) + - cur_part->private.gpt.size; - /* Will point to the partition record length in the hand-over */ - uint32_t *plen; - - /* Allocate the hand-over record */ - record = malloc(synth_size); - if (!record) { - error("Could not build GPT hand-over record!\n"); - goto bail; - } - /* Synthesize the record */ - memset(record, 0, synth_size); - record->active_flag = 0x80; - record->ostype = 0xED; - /* All bits set by default */ - record->start_lba = ~(uint32_t) 0; - record->length = ~(uint32_t) 0; - /* If these fit the precision, pass them on */ - if (cur_part->lba_data < record->start_lba) - record->start_lba = cur_part->lba_data; - if (lba_count < record->length) - record->length = lba_count; - /* Next comes the GPT partition record length */ - plen = (uint32_t *) (record + 1); - plen[0] = cur_part->private.gpt.size; - /* Next comes the GPT partition record copy */ - memcpy(plen + 1, gp, plen[0]); - cur_part->record = record; - regs.eax.l = 0x54504721; /* '!GPT' */ + /* Note the partition length */ + uint64_t lba_count = gp->lba_last - gp->lba_first + 1; + /* The length of the hand-over */ + int synth_size = + sizeof(struct part_entry) + sizeof(uint32_t) + + cur_part->private.gpt.size; + /* Will point to the partition record length in the hand-over */ + uint32_t *plen; + + /* Allocate the hand-over record */ + record = malloc(synth_size); + if (!record) { + error("Could not build GPT hand-over record!\n"); + goto bail; + } + /* Synthesize the record */ + memset(record, 0, synth_size); + record->active_flag = 0x80; + record->ostype = 0xED; + /* All bits set by default */ + record->start_lba = ~(uint32_t) 0; + record->length = ~(uint32_t) 0; + /* If these fit the precision, pass them on */ + if (cur_part->lba_data < record->start_lba) + record->start_lba = cur_part->lba_data; + if (lba_count < record->length) + record->length = lba_count; + /* Next comes the GPT partition record length */ + plen = (uint32_t *) (record + 1); + plen[0] = cur_part->private.gpt.size; + /* Next comes the GPT partition record copy */ + memcpy(plen + 1, gp, plen[0]); + cur_part->record = record; + + regs.eax.l = 0x54504721; /* '!GPT' */ + data[ndata].base = 0x7be; + data[ndata].size = synth_size; + data[ndata].data = (void *)record; + ndata++; + regs.esi.w[0] = 0x7be; #if DEBUG - mbr_part_dump(record); - gpt_part_dump((struct gpt_part *)(plen + 1)); + mbr_part_dump(record); + gpt_part_dump((struct gpt_part *)(plen + 1)); #endif - } - - if (cur_part && cur_part->record) { - /* 0x7BE is the canonical place for the first partition entry. */ - data[ndata].data = (void *)cur_part->record; - data[ndata].base = 0x7be; - data[ndata].size = sizeof(*cur_part->record); - ndata++; - regs.esi.w[0] = 0x7be; + } else if (cur_part->record) { + /* MBR handover protocol */ + + data[ndata].base = 0x7be; + data[ndata].size = sizeof(*cur_part->record); + data[ndata].data = (void *)cur_part->record; + ndata++; + regs.esi.w[0] = 0x7be; + } } do_boot(data, ndata, ®s); -- 2.7.4