[syslinux:master] chain: Implement GPT hand-over protocol as documented
syslinux-bot for Shao Miller
shao.miller at yrdsb.edu.on.ca
Fri Jun 25 14:12:34 PDT 2010
Commit-ID: 89b665c55648e2bce662332be5ba60381d9f6cec
Gitweb: http://syslinux.zytor.com/commit/89b665c55648e2bce662332be5ba60381d9f6cec
Author: Shao Miller <shao.miller at yrdsb.edu.on.ca>
AuthorDate: Fri, 25 Jun 2010 06:45:07 -0400
Committer: Shao Miller <shao.miller at yrdsb.edu.on.ca>
CommitDate: Fri, 25 Jun 2010 06:45:07 -0400
chain: Implement GPT hand-over protocol as documented
When a partition was yielded by a GPT partition iterator,
we follow the protocol documented in syslinux/doc/gpt.txt.
Signed-off-by: Shao Miller <shao.miller at yrdsb.edu.on.ca>
---
NEWS | 1 +
com32/modules/chain.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 51 insertions(+), 1 deletions(-)
diff --git a/NEWS b/NEWS
index fdf33cf..93b64a6 100644
--- a/NEWS
+++ b/NEWS
@@ -5,6 +5,7 @@ to all derivatives.
Changes in 4.00:
* chain.c32: support booting GPT partitions by index
* chain.c32: support booting the Syslinux partition with "fs"
+ * chain.c32: implement gpt.txt hand-over protocol
Changes in 3.86:
* chain.c32: fix chainloading the MBR of a hard disk (broken
in 3.85).
diff --git a/com32/modules/chain.c b/com32/modules/chain.c
index 2652de8..6f3729f 100644
--- a/com32/modules/chain.c
+++ b/com32/modules/chain.c
@@ -1419,6 +1419,53 @@ 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 *)
+ (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' */
+#if DEBUG
+ 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;
@@ -1431,8 +1478,10 @@ int main(int argc, char *argv[])
do_boot(data, ndata, ®s);
bail:
- if (cur_part)
+ if (cur_part) {
free(cur_part->block);
+ free((void *)cur_part->record);
+ }
free(cur_part);
free(mbr);
return 255;
More information about the Syslinux-commits
mailing list