~hamo/ubuntu/precise/grub2/grub2.hi_res

« back to all changes in this revision

Viewing changes to grub-core/partmap/bsdlabel.c

  • Committer: Bazaar Package Importer
  • Author(s): Colin Watson, Colin Watson, Evan Broder, Mario Limonciello
  • Date: 2010-11-24 13:59:55 UTC
  • mfrom: (1.17.6 upstream) (17.6.15 experimental)
  • Revision ID: james.westby@ubuntu.com-20101124135955-r6ii5sepayr7jt53
Tags: 1.99~20101124-1ubuntu1
[ Colin Watson ]
* Resynchronise with Debian experimental.  Remaining changes:
  - Adjust for default Ubuntu boot options ("quiet splash").
  - Default to hiding the menu; holding down Shift at boot will show it.
  - Set a monochromatic theme for Ubuntu.
  - Apply Ubuntu GRUB Legacy changes to legacy update-grub script: title,
    recovery mode, quiet option, tweak how memtest86+ is displayed, and
    use UUIDs where appropriate.
  - Fix backslash-escaping in merge_debconf_into_conf.
  - Remove "GNU/Linux" from default distributor string.
  - Add crashkernel= options if kdump and makedumpfile are available.
  - If other operating systems are installed, then automatically unhide
    the menu.  Otherwise, if GRUB_HIDDEN_TIMEOUT is 0, then use keystatus
    if available to check whether Shift is pressed.  If it is, show the
    menu, otherwise boot immediately.  If keystatus is not available, then
    fall back to a short delay interruptible with Escape.
  - Allow Shift to interrupt 'sleep --interruptible'.
  - Don't display introductory message about line editing unless we're
    actually offering a shell prompt.  Don't clear the screen just before
    booting if we never drew the menu in the first place.
  - Remove some verbose messages printed before reading the configuration
    file.
  - Suppress progress messages as the kernel and initrd load for
    non-recovery kernel menu entries.
  - Change prepare_grub_to_access_device to handle filesystems
    loop-mounted on file images.
  - Ignore devices loop-mounted from files in 10_linux.
  - Show the boot menu if the previous boot failed, that is if it failed
    to get to the end of one of the normal runlevels.
  - Don't generate /boot/grub/device.map during grub-install or
    grub-mkconfig by default.
  - Adjust upgrade version checks for Ubuntu.
  - Don't display "GRUB loading" unless Shift is held down.
  - Adjust versions of grub-doc and grub-legacy-doc conflicts to tolerate
    our backport of the grub-doc split.
  - Fix LVM/RAID probing in the absence of /boot/grub/device.map.
  - Look for .mo files in /usr/share/locale-langpack as well, in
    preference.
  - Make sure GRUB_TIMEOUT isn't quoted unnecessarily.
  - Probe all devices in 'grub-probe --target=drive' if
    /boot/grub/device.map is missing.
  - Build-depend on qemu-kvm rather than qemu-system for grub-pc tests.
  - Use qemu rather than qemu-system-i386.
  - Program vesafb on BIOS systems rather than efifb.
  - Add a grub-rescue-efi-amd64 package containing a rescue CD-ROM image
    for EFI-AMD64.
  - On Wubi, don't ask for an install device, but just update wubildr
    using the diverted grub-install.
  - When embedding the core image in a post-MBR gap, check for and avoid
    sectors matching any of a list of known signatures.
  - Disable video_bochs and video_cirrus on PC BIOS systems, as probing
    PCI space seems to break on some systems.
* Downgrade "ACPI shutdown failed" error to a debug message, since it can
  cause spurious test failures.

[ Evan Broder ]
* Enable lua from grub-extras.
* Incorporate the bitop library into lua.
* Add enum_pci function to grub module in lua.
* Switch back to gfxpayload=keep by default, unless the video hardware
  is known to not support it.

[ Mario Limonciello ]
* Built part_msdos and vfat into bootx64.efi (LP: #677758)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* bsdlabel.c - Read BSD style partition tables.  */
 
2
/*
 
3
 *  GRUB  --  GRand Unified Bootloader
 
4
 *  Copyright (C) 2002,2004,2005,2006,2007,2008,2009  Free Software Foundation, Inc.
 
5
 *
 
6
 *  GRUB is free software: you can redistribute it and/or modify
 
7
 *  it under the terms of the GNU General Public License as published by
 
8
 *  the Free Software Foundation, either version 3 of the License, or
 
9
 *  (at your option) any later version.
 
10
 *
 
11
 *  GRUB is distributed in the hope that it will be useful,
 
12
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
14
 *  GNU General Public License for more details.
 
15
 *
 
16
 *  You should have received a copy of the GNU General Public License
 
17
 *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
 
18
 */
 
19
 
 
20
#include <grub/partition.h>
 
21
#include <grub/bsdlabel.h>
 
22
#include <grub/disk.h>
 
23
#include <grub/mm.h>
 
24
#include <grub/misc.h>
 
25
#include <grub/dl.h>
 
26
#include <grub/msdos_partition.h>
 
27
 
 
28
#ifdef GRUB_UTIL
 
29
#include <grub/util/misc.h>
 
30
#endif
 
31
 
 
32
static struct grub_partition_map grub_bsdlabel_partition_map;
 
33
static struct grub_partition_map grub_netbsdlabel_partition_map;
 
34
static struct grub_partition_map grub_openbsdlabel_partition_map;
 
35
 
 
36
 
 
37
 
 
38
static grub_err_t
 
39
iterate_real (grub_disk_t disk, grub_disk_addr_t sector, int freebsd,
 
40
              struct grub_partition_map *pmap,
 
41
              int (*hook) (grub_disk_t disk,
 
42
                           const grub_partition_t partition))
 
43
{
 
44
  struct grub_partition_bsd_disk_label label;
 
45
  struct grub_partition p;
 
46
  grub_disk_addr_t delta = 0;
 
47
  grub_disk_addr_t pos;
 
48
 
 
49
  /* Read the BSD label.  */
 
50
  if (grub_disk_read (disk, sector, 0, sizeof (label), &label))
 
51
    return grub_errno;
 
52
 
 
53
  /* Check if it is valid.  */
 
54
  if (label.magic != grub_cpu_to_le32 (GRUB_PC_PARTITION_BSD_LABEL_MAGIC))
 
55
    return grub_error (GRUB_ERR_BAD_PART_TABLE, "no signature");
 
56
 
 
57
  /* A kludge to determine a base of be.offset.  */
 
58
  if (GRUB_PC_PARTITION_BSD_LABEL_WHOLE_DISK_PARTITION
 
59
      < grub_cpu_to_le16 (label.num_partitions) && freebsd)
 
60
    {
 
61
      struct grub_partition_bsd_entry whole_disk_be;
 
62
 
 
63
      pos = sizeof (label) + sector * GRUB_DISK_SECTOR_SIZE
 
64
        + sizeof (struct grub_partition_bsd_entry)
 
65
        * GRUB_PC_PARTITION_BSD_LABEL_WHOLE_DISK_PARTITION;
 
66
 
 
67
      if (grub_disk_read (disk, pos / GRUB_DISK_SECTOR_SIZE,
 
68
                          pos % GRUB_DISK_SECTOR_SIZE, sizeof (whole_disk_be),
 
69
                          &whole_disk_be))
 
70
        return grub_errno;
 
71
 
 
72
      delta = grub_le_to_cpu32 (whole_disk_be.offset);
 
73
    }
 
74
 
 
75
  pos = sizeof (label) + sector * GRUB_DISK_SECTOR_SIZE;
 
76
 
 
77
  for (p.number = 0;
 
78
       p.number < grub_cpu_to_le16 (label.num_partitions);
 
79
       p.number++, pos += sizeof (struct grub_partition_bsd_entry))
 
80
    {
 
81
      struct grub_partition_bsd_entry be;
 
82
 
 
83
      if (p.number == GRUB_PC_PARTITION_BSD_LABEL_WHOLE_DISK_PARTITION)
 
84
        continue;
 
85
 
 
86
      p.offset = pos / GRUB_DISK_SECTOR_SIZE;
 
87
      p.index = pos % GRUB_DISK_SECTOR_SIZE;
 
88
 
 
89
      if (grub_disk_read (disk, p.offset, p.index, sizeof (be),  &be))
 
90
        return grub_errno;
 
91
 
 
92
      p.start = grub_le_to_cpu32 (be.offset);
 
93
      p.len = grub_le_to_cpu32 (be.size);
 
94
      p.partmap = pmap;
 
95
 
 
96
      if (p.len == 0)
 
97
        continue;
 
98
 
 
99
      if (p.start < delta)
 
100
        {
 
101
#ifdef GRUB_UTIL
 
102
          char *partname;
 
103
          /* disk->partition != NULL as 0 < delta */
 
104
          partname = grub_partition_get_name (disk->partition);
 
105
          grub_util_warn ("Discarding improperly nested partition (%s,%s,%s%d)",
 
106
                          disk->name, partname, p.partmap->name, p.number + 1);
 
107
          grub_free (partname);
 
108
#endif
 
109
          continue;
 
110
        }
 
111
 
 
112
      p.start -= delta;
 
113
 
 
114
      if (hook (disk, &p))
 
115
        return grub_errno;
 
116
    }
 
117
  return GRUB_ERR_NONE;
 
118
}
 
119
 
 
120
static grub_err_t
 
121
bsdlabel_partition_map_iterate (grub_disk_t disk,
 
122
                                int (*hook) (grub_disk_t disk,
 
123
                                             const grub_partition_t partition))
 
124
{
 
125
 
 
126
  if (disk->partition && grub_strcmp (disk->partition->partmap->name, "msdos")
 
127
      == 0 && disk->partition->msdostype == GRUB_PC_PARTITION_TYPE_FREEBSD)
 
128
    return iterate_real (disk, GRUB_PC_PARTITION_BSD_LABEL_SECTOR, 1,
 
129
                         &grub_bsdlabel_partition_map, hook);
 
130
 
 
131
  if (disk->partition 
 
132
      && (grub_strcmp (disk->partition->partmap->name, "msdos") == 0
 
133
          || disk->partition->partmap == &grub_bsdlabel_partition_map
 
134
          || disk->partition->partmap == &grub_netbsdlabel_partition_map
 
135
          || disk->partition->partmap == &grub_openbsdlabel_partition_map))
 
136
      return grub_error (GRUB_ERR_BAD_PART_TABLE, "no embedding supported");
 
137
 
 
138
  return iterate_real (disk, GRUB_PC_PARTITION_BSD_LABEL_SECTOR, 0, 
 
139
                       &grub_bsdlabel_partition_map, hook);
 
140
}
 
141
 
 
142
/* This is a total breakage. Even when net-/openbsd label is inside partition
 
143
   it actually describes the whole disk.
 
144
 */
 
145
static grub_err_t
 
146
netopenbsdlabel_partition_map_iterate (grub_disk_t disk, grub_uint8_t type,
 
147
                                       struct grub_partition_map *pmap,
 
148
                                       int (*hook) (grub_disk_t disk,
 
149
                                                    const grub_partition_t partition))
 
150
{
 
151
  int count = 0;
 
152
 
 
153
  auto int check_msdos (grub_disk_t dsk,
 
154
                        const grub_partition_t partition);
 
155
 
 
156
  int check_msdos (grub_disk_t dsk,
 
157
                   const grub_partition_t partition)
 
158
  {
 
159
    grub_err_t err;
 
160
 
 
161
    if (partition->msdostype != type)
 
162
      return 0;
 
163
 
 
164
    err = iterate_real (dsk, partition->start
 
165
                        + GRUB_PC_PARTITION_BSD_LABEL_SECTOR, 0, pmap, hook);
 
166
    if (err == GRUB_ERR_NONE)
 
167
      {
 
168
        count++;
 
169
        return 1;
 
170
      }
 
171
    if (err == GRUB_ERR_BAD_PART_TABLE)
 
172
      {
 
173
        grub_errno = GRUB_ERR_NONE;
 
174
        return 0;
 
175
      }
 
176
    grub_print_error ();
 
177
    return 0;
 
178
  }
 
179
 
 
180
  if (disk->partition && grub_strcmp (disk->partition->partmap->name, "msdos")
 
181
      == 0)
 
182
    return grub_error (GRUB_ERR_BAD_PART_TABLE, "no embedding supported");
 
183
 
 
184
  {
 
185
    grub_err_t err;
 
186
    err = grub_partition_msdos_iterate (disk, check_msdos);
 
187
 
 
188
    if (err)
 
189
      return err;
 
190
    if (!count)
 
191
      return grub_error (GRUB_ERR_BAD_PART_TABLE, "no bsdlabel found");
 
192
  }
 
193
  return GRUB_ERR_NONE;
 
194
}
 
195
 
 
196
static grub_err_t
 
197
netbsdlabel_partition_map_iterate (grub_disk_t disk,
 
198
                                   int (*hook) (grub_disk_t disk,
 
199
                                                const grub_partition_t partition))
 
200
{
 
201
  return netopenbsdlabel_partition_map_iterate (disk,
 
202
                                                GRUB_PC_PARTITION_TYPE_NETBSD,
 
203
                                                &grub_netbsdlabel_partition_map,
 
204
                                                hook);
 
205
}
 
206
 
 
207
static grub_err_t
 
208
openbsdlabel_partition_map_iterate (grub_disk_t disk,
 
209
                                   int (*hook) (grub_disk_t disk,
 
210
                                                const grub_partition_t partition))
 
211
{
 
212
  return netopenbsdlabel_partition_map_iterate (disk,
 
213
                                                GRUB_PC_PARTITION_TYPE_OPENBSD,
 
214
                                                &grub_openbsdlabel_partition_map,
 
215
                                                hook);
 
216
}
 
217
 
 
218
 
 
219
static struct grub_partition_map grub_bsdlabel_partition_map =
 
220
  {
 
221
    .name = "bsd",
 
222
    .iterate = bsdlabel_partition_map_iterate,
 
223
  };
 
224
 
 
225
static struct grub_partition_map grub_openbsdlabel_partition_map =
 
226
  {
 
227
    .name = "openbsd",
 
228
    .iterate = openbsdlabel_partition_map_iterate,
 
229
  };
 
230
 
 
231
static struct grub_partition_map grub_netbsdlabel_partition_map =
 
232
  {
 
233
    .name = "netbsd",
 
234
    .iterate = netbsdlabel_partition_map_iterate,
 
235
  };
 
236
 
 
237
 
 
238
 
 
239
GRUB_MOD_INIT(part_bsd)
 
240
{
 
241
  grub_partition_map_register (&grub_bsdlabel_partition_map);
 
242
  grub_partition_map_register (&grub_netbsdlabel_partition_map);
 
243
  grub_partition_map_register (&grub_openbsdlabel_partition_map);
 
244
}
 
245
 
 
246
GRUB_MOD_FINI(part_bsd)
 
247
{
 
248
  grub_partition_map_unregister (&grub_bsdlabel_partition_map);
 
249
  grub_partition_map_unregister (&grub_netbsdlabel_partition_map);
 
250
  grub_partition_map_unregister (&grub_openbsdlabel_partition_map);
 
251
}