316 lines
10 KiB
Diff
316 lines
10 KiB
Diff
diff -ruBbd --unidirectional-new-file grub-0.96/stage2/builtins.c grub-0.96-patched/stage2/builtins.c
|
|
--- grub-0.96/stage2/builtins.c 2004-06-20 09:33:04.000000000 -0400
|
|
+++ grub-0.96-patched/stage2/builtins.c 2007-01-04 13:56:06.000000000 -0500
|
|
@@ -1229,14 +1229,15 @@
|
|
for (drive = 0x80; drive < 0x88; drive++)
|
|
{
|
|
unsigned long part = 0xFFFFFF;
|
|
- unsigned long start, len, offset, ext_offset;
|
|
- int type, entry;
|
|
+ unsigned long start, len, offset, ext_offset, gpt_offset;
|
|
+ int type, entry, gpt_count, gpt_size;
|
|
char buf[SECTOR_SIZE];
|
|
|
|
current_drive = drive;
|
|
while (next_partition (drive, 0xFFFFFF, &part, &type,
|
|
&start, &len, &offset, &entry,
|
|
- &ext_offset, buf))
|
|
+ &ext_offset, &gpt_offset,
|
|
+ &gpt_count, &gpt_size, buf))
|
|
{
|
|
if (type != PC_SLICE_TYPE_NONE
|
|
&& ! IS_PC_SLICE_TYPE_BSD (type)
|
|
@@ -2806,8 +2807,8 @@
|
|
{
|
|
int new_type;
|
|
unsigned long part = 0xFFFFFF;
|
|
- unsigned long start, len, offset, ext_offset;
|
|
- int entry, type;
|
|
+ unsigned long start, len, offset, ext_offset, gpt_offset;
|
|
+ int entry, type, gpt_count, gpt_size;
|
|
char mbr[512];
|
|
|
|
/* Get the drive and the partition. */
|
|
@@ -2844,7 +2845,14 @@
|
|
/* Look for the partition. */
|
|
while (next_partition (current_drive, 0xFFFFFF, &part, &type,
|
|
&start, &len, &offset, &entry,
|
|
- &ext_offset, mbr))
|
|
+ &ext_offset, &gpt_offset, &gpt_count, &gpt_size, mbr))
|
|
+ /* The partition may not be a GPT partition. */
|
|
+ if (gpt_offset != 0)
|
|
+ {
|
|
+ errnum = ERR_BAD_ARGUMENT;
|
|
+ return 1;
|
|
+ }
|
|
+
|
|
{
|
|
if (part == current_partition)
|
|
{
|
|
diff -ruBbd --unidirectional-new-file grub-0.96/stage2/disk_io.c grub-0.96-patched/stage2/disk_io.c
|
|
--- grub-0.96/stage2/disk_io.c 2004-05-23 12:35:24.000000000 -0400
|
|
+++ grub-0.96-patched/stage2/disk_io.c 2007-01-04 14:01:08.000000000 -0500
|
|
@@ -21,6 +21,7 @@
|
|
|
|
#include <shared.h>
|
|
#include <filesys.h>
|
|
+#include <gpt.h>
|
|
|
|
#ifdef SUPPORT_NETBOOT
|
|
# define GRUB 1
|
|
@@ -502,8 +503,8 @@
|
|
set_partition_hidden_flag (int hidden)
|
|
{
|
|
unsigned long part = 0xFFFFFF;
|
|
- unsigned long start, len, offset, ext_offset;
|
|
- int entry, type;
|
|
+ unsigned long start, len, offset, ext_offset, gpt_offset;
|
|
+ int entry, type, gpt_count, gpt_size;
|
|
char mbr[512];
|
|
|
|
/* The drive must be a hard disk. */
|
|
@@ -524,7 +525,14 @@
|
|
/* Look for the partition. */
|
|
while (next_partition (current_drive, 0xFFFFFF, &part, &type,
|
|
&start, &len, &offset, &entry,
|
|
- &ext_offset, mbr))
|
|
+ &ext_offset, &gpt_offset, &gpt_count, &gpt_size, mbr))
|
|
+ /* The partition may not be a GPT partition. */
|
|
+ if (gpt_offset != 0)
|
|
+ {
|
|
+ errnum = ERR_BAD_ARGUMENT;
|
|
+ return 1;
|
|
+ }
|
|
+
|
|
{
|
|
if (part == current_partition)
|
|
{
|
|
@@ -577,11 +585,14 @@
|
|
unsigned long *partition, int *type,
|
|
unsigned long *start, unsigned long *len,
|
|
unsigned long *offset, int *entry,
|
|
- unsigned long *ext_offset, char *buf)
|
|
+ unsigned long *ext_offset,
|
|
+ unsigned long *gpt_offset, int *gpt_count,
|
|
+ int *gpt_size, char *buf)
|
|
{
|
|
/* Forward declarations. */
|
|
auto int next_bsd_partition (void);
|
|
auto int next_pc_slice (void);
|
|
+ auto int next_gpt_slice(void);
|
|
|
|
/* Get next BSD partition in current PC slice. */
|
|
int next_bsd_partition (void)
|
|
@@ -666,6 +677,40 @@
|
|
return 0;
|
|
}
|
|
|
|
+ /* If this is a GPT partition table, read it as such. */
|
|
+ if (*entry == -1 && *offset == 0 && PC_SLICE_TYPE (buf, 0) == PC_SLICE_TYPE_GPT)
|
|
+ {
|
|
+ struct grub_gpt_header *hdr = (struct grub_gpt_header *) buf;
|
|
+
|
|
+ /* Read in the GPT Partition table header. */
|
|
+ if (! rawread (drive, 1, 0, SECTOR_SIZE, buf))
|
|
+ return 0;
|
|
+
|
|
+ if (hdr->magic == GPT_HEADER_MAGIC && hdr->version == 0x10000)
|
|
+ {
|
|
+ /* Let gpt_offset point to the first entry in the GPT
|
|
+ partition table. This can also be used by callers of
|
|
+ next_partition to determine if a entry comes from a
|
|
+ GPT partition table or not. */
|
|
+ *gpt_offset = hdr->partitions;
|
|
+ *gpt_count = hdr->maxpart;
|
|
+ *gpt_size = hdr->partentry_size;
|
|
+
|
|
+ return next_gpt_slice();
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ /* This is not a valid header for a GPT partition table.
|
|
+ Re-read the MBR or the boot sector of the extended
|
|
+ partition. */
|
|
+ if (! rawread (drive, *offset, 0, SECTOR_SIZE, buf))
|
|
+ return 0;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ /* Not a GPT partition. */
|
|
+ *gpt_offset = 0;
|
|
+
|
|
/* Increase the entry number. */
|
|
(*entry)++;
|
|
|
|
@@ -710,6 +755,43 @@
|
|
return 1;
|
|
}
|
|
|
|
+ /* Get the next GPT slice. */
|
|
+ int next_gpt_slice (void)
|
|
+ {
|
|
+ struct grub_gpt_partentry *gptentry = (struct grub_gpt_partentry *) buf;
|
|
+ /* Make GPT partitions show up as PC slices. */
|
|
+ int pc_slice_no = (*partition & 0xFF0000) >> 16;
|
|
+
|
|
+ /* If this is the first time... */
|
|
+ if (pc_slice_no == 0xFF)
|
|
+ {
|
|
+ pc_slice_no = -1;
|
|
+ *entry = -1;
|
|
+ }
|
|
+
|
|
+ do {
|
|
+ (*entry)++;
|
|
+
|
|
+ if (*entry >= *gpt_count)
|
|
+ {
|
|
+ errnum = ERR_NO_PART;
|
|
+ return 0;
|
|
+ }
|
|
+ /* Read in the GPT Partition table entry. */
|
|
+ if (! rawread (drive, (*gpt_offset) + GPT_ENTRY_SECTOR (*gpt_size, *entry), GPT_ENTRY_INDEX (*gpt_size, *entry), *gpt_size, buf))
|
|
+ return 0;
|
|
+ } while (! (gptentry->type1 && gptentry->type2));
|
|
+
|
|
+ pc_slice_no++;
|
|
+ *start = gptentry->start;
|
|
+ *len = gptentry->end - gptentry->start + 1;
|
|
+ *type = PC_SLICE_TYPE_EXT2FS;
|
|
+ *entry = pc_slice_no;
|
|
+ *partition = (*entry << 16) | 0xFFFF;
|
|
+
|
|
+ return 1;
|
|
+ }
|
|
+
|
|
/* Start the body of this function. */
|
|
|
|
#ifndef STAGE1_5
|
|
@@ -717,6 +799,9 @@
|
|
return 0;
|
|
#endif
|
|
|
|
+ if (*partition != 0xFFFFFF && *gpt_offset != 0)
|
|
+ return next_gpt_slice ();
|
|
+
|
|
/* If previous partition is a BSD partition or a PC slice which
|
|
contains BSD partitions... */
|
|
if ((*partition != 0xFFFFFF && IS_PC_SLICE_TYPE_BSD (*type & 0xff))
|
|
@@ -755,6 +840,9 @@
|
|
unsigned long dest_partition = current_partition;
|
|
unsigned long part_offset;
|
|
unsigned long ext_offset;
|
|
+ unsigned long gpt_offset;
|
|
+ int gpt_count;
|
|
+ int gpt_size;
|
|
int entry;
|
|
char buf[SECTOR_SIZE];
|
|
int bsd_part, pc_slice;
|
|
@@ -766,7 +854,8 @@
|
|
int ret = next_partition (current_drive, dest_partition,
|
|
¤t_partition, ¤t_slice,
|
|
&part_start, &part_length,
|
|
- &part_offset, &entry, &ext_offset, buf);
|
|
+ &part_offset, &entry, &ext_offset,
|
|
+ &gpt_offset, &gpt_count, &gpt_size, buf);
|
|
bsd_part = (current_partition >> 8) & 0xFF;
|
|
pc_slice = current_partition >> 16;
|
|
return ret;
|
|
diff -ruBbd --unidirectional-new-file grub-0.96/stage2/gpt.h grub-0.96-patched/stage2/gpt.h
|
|
--- grub-0.96/stage2/gpt.h 1969-12-31 19:00:00.000000000 -0500
|
|
+++ grub-0.96-patched/stage2/gpt.h 2007-01-04 13:52:14.000000000 -0500
|
|
@@ -0,0 +1,68 @@
|
|
+/*
|
|
+ * GRUB -- GRand Unified Bootloader
|
|
+ * Copyright (C) 2002,2005,2006 Free Software Foundation, Inc.
|
|
+ *
|
|
+ * This program is free software; you can redistribute it and/or modify
|
|
+ * it under the terms of the GNU General Public License as published by
|
|
+ * the Free Software Foundation; either version 2 of the License, or
|
|
+ * (at your option) any later version.
|
|
+ *
|
|
+ * This program is distributed in the hope that it will be useful,
|
|
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
+ * GNU General Public License for more details.
|
|
+ *
|
|
+ * You should have received a copy of the GNU General Public License
|
|
+ * along with this program; if not, write to the Free Software
|
|
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
+ */
|
|
+
|
|
+#ifndef _GPT_H
|
|
+#define _GPT_H
|
|
+
|
|
+typedef signed char grub_int8_t;
|
|
+typedef signed short grub_int16_t;
|
|
+typedef signed int grub_int32_t;
|
|
+typedef signed long long int grub_int64_t;
|
|
+typedef unsigned char grub_uint8_t;
|
|
+typedef unsigned short grub_uint16_t;
|
|
+typedef unsigned int grub_uint32_t;
|
|
+typedef unsigned long long int grub_uint64_t;
|
|
+
|
|
+struct grub_gpt_header
|
|
+{
|
|
+ grub_uint64_t magic;
|
|
+ grub_uint32_t version;
|
|
+ grub_uint32_t headersize;
|
|
+ grub_uint32_t crc32;
|
|
+ grub_uint32_t unused1;
|
|
+ grub_uint64_t primary;
|
|
+ grub_uint64_t backup;
|
|
+ grub_uint64_t start;
|
|
+ grub_uint64_t end;
|
|
+ grub_uint8_t guid[16];
|
|
+ grub_uint64_t partitions;
|
|
+ grub_uint32_t maxpart;
|
|
+ grub_uint32_t partentry_size;
|
|
+ grub_uint32_t partentry_crc32;
|
|
+} __attribute__ ((packed));
|
|
+
|
|
+struct grub_gpt_partentry
|
|
+{
|
|
+ grub_uint64_t type1;
|
|
+ grub_uint64_t type2;
|
|
+ grub_uint8_t guid[16];
|
|
+ grub_uint64_t start;
|
|
+ grub_uint64_t end;
|
|
+ grub_uint8_t attrib;
|
|
+ char name[72];
|
|
+} __attribute__ ((packed));
|
|
+
|
|
+#define GPT_HEADER_MAGIC 0x5452415020494645UL
|
|
+
|
|
+#define GPT_ENTRY_SECTOR(size,entry) \
|
|
+ ((((entry) * (size) + 1) & ~(SECTOR_SIZE - 1)) >> SECTOR_BITS)
|
|
+#define GPT_ENTRY_INDEX(size,entry) \
|
|
+ ((((entry) * (size) + 1) & (SECTOR_SIZE - 1)) - 1)
|
|
+
|
|
+#endif /* _GPT_H */
|
|
diff -ruBbd --unidirectional-new-file grub-0.96/stage2/pc_slice.h grub-0.96-patched/stage2/pc_slice.h
|
|
--- grub-0.96/stage2/pc_slice.h 2003-07-09 07:45:53.000000000 -0400
|
|
+++ grub-0.96-patched/stage2/pc_slice.h 2007-01-04 13:52:14.000000000 -0500
|
|
@@ -115,6 +115,7 @@
|
|
#define PC_SLICE_TYPE_LINUX_EXTENDED 0x85
|
|
#define PC_SLICE_TYPE_VSTAFS 0x9e
|
|
#define PC_SLICE_TYPE_DELL_UTIL 0xde
|
|
+#define PC_SLICE_TYPE_GPT 0xee
|
|
#define PC_SLICE_TYPE_LINUX_RAID 0xfd
|
|
|
|
|
|
diff -ruBbd --unidirectional-new-file grub-0.96/stage2/shared.h grub-0.96-patched/stage2/shared.h
|
|
--- grub-0.96/stage2/shared.h 2004-06-19 12:40:09.000000000 -0400
|
|
+++ grub-0.96-patched/stage2/shared.h 2007-01-04 13:52:15.000000000 -0500
|
|
@@ -934,7 +934,9 @@
|
|
unsigned long *partition, int *type,
|
|
unsigned long *start, unsigned long *len,
|
|
unsigned long *offset, int *entry,
|
|
- unsigned long *ext_offset, char *buf);
|
|
+ unsigned long *ext_offset,
|
|
+ unsigned long *gpt_offset, int *gpt_count,
|
|
+ int *gpt_size, char *buf);
|
|
|
|
/* Sets device to the one represented by the SAVED_* parameters. */
|
|
int make_saved_active (void);
|