grub-luks2-improved-stable/grub-0.97-gpt.patch
2008-04-06 01:17:02 +00:00

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,
&current_partition, &current_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);