SDB:在大型磁盘上安装

跳转到:导航搜索
Icon-cleanup.png
这篇文章需要关注,因为它不符合我们的维基指南
如果您想贡献,请阅读此维基的规则,如果您有任何问题,请随时联系维基团队,我们非常乐意帮助您!:-)
Icon-obsolete.png
本文或章节参考的是 'GRUB 0.97' 版本,现在已经过时!
请参阅本文的页面以获取更多信息。


当您的磁盘阵列大于 2TB 时,您可能会遇到问题。如果您想从 2TB 阵列启动,您将会遇到问题。以下是如何使其工作。


GRUB 问题

如果没有补丁,GRUB 将无法从大型磁盘阵列启动(因为您需要使用 GPT 磁盘标签),因此您的安装将会很复杂。首先,获取一台 32 位机器。您需要使 GRUB 成为 32 位,如果您有一台 32 位机器,这将更容易。获取 0.97 源代码树并使用上述文章中提到的两个补丁对其进行修补。

构建 grub。我将其构建为安装在 /opt/grub 中。在您的构建机器上安装它,并将该树(在我的例子中为 /opt/grub)复制到 USB 存储设备或 CD 或其他介质上。

YaST 安装

默认情况下,YaST 会使用 MSDOS 磁盘标签对您的磁盘进行分区。这不起作用,因为存在 2TB 的限制。在进入分区程序之前,切换 VT 以获取 shell。运行 gpart 并将 GPT 磁盘标签放在磁盘上。如果您愿意,也可以创建一些分区。

在 YaST-2 安装程序中,完成您的分区。YaST 会很好地保留 GPT 磁盘标签。

正常进行安装。YaST 会警告您并告诉您 grub 将无法工作。确实如此。点击通过。当安装的第一阶段完成后,系统将重新启动,但不会走太远。

此时,启动到救援系统。将您的根磁盘挂载到 /mnt。chroot 到 /mnt。手动 mknod 您的磁盘阵列和分区的 /dev 文件(/dev/sda 是 b 8 0,/dev/sda1 是 b 8 1,等等)。挂载您的 /boot。将您修补的 grub 树从您保存它的介质复制到 /opt/grub(或者您在运行 Configure 时所说的位置)。然后,cd /opt/grub/sbin。./grub-install /dev/sda。

现在 umount 您的 /boot,并删除您创建的 /dev/sda* 文件。

退出 chroot 并 umount 您的根目录。

reboot

您的机器应该从这个大型磁盘阵列启动,并且 YaST 应该正常继续。

补丁

GRUB 0.97 的 Initrd 补丁

    Date: 2005-11-11
    Author: Otavio Salvador
    Comment: Stolen from SuSE grub package.
     It fix the max address of initrd image and include a safe
     default in case of it isn't available

--- grub-0.94/stage2/boot.c.orig        2004-01-11 09:49:05.000000000 +0100
+++ grub-0.94/stage2/boot.c     2004-03-04 16:11:21.857403508 +0100
@@ -810,8 +810,11 @@
     moveto = (mbi.mem_upper + 0x400) << 10;
   
   moveto = (moveto - len) & 0xfffff000;
-  max_addr = (lh->header == LINUX_MAGIC_SIGNATURE && lh->version >= 0x0203
-             ? lh->initrd_addr_max : LINUX_INITRD_MAX_ADDRESS);
+  max_addr = LINUX_INITRD_MAX_ADDRESS;
+  if (lh->header == LINUX_MAGIC_SIGNATURE &&
+      lh->version >= 0x0203 &&
+      lh->initrd_addr_max < max_addr)
+    max_addr = lh->initrd_addr_max;
   if (moveto + len >= max_addr)
     moveto = (max_addr - len) & 0xfffff000;

GRUB 0.96 的 GPT 补丁(适用于 0.97)

--- 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_s
ize, *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);