wok view grub/stuff/gpt.diff @ rev 24987

grub: add gpt support
author Pascal Bellard <pascal.bellard@slitaz.org>
date Thu May 12 07:08:39 2022 +0000 (23 months ago)
parents
children
line source
1 --- grub-0.97/stage2/builtins.c
2 +++ grub-0.97/stage2/builtins.c
3 @@ -1233,14 +1233,15 @@ find_func (char *arg, int flags)
4 for (drive = 0x80; drive < 0x88; drive++)
5 {
6 unsigned long part = 0xFFFFFF;
7 - unsigned long start, len, offset, ext_offset;
8 - int type, entry;
9 + unsigned long start, len, offset, ext_offset, gpt_offset;
10 + int type, entry, gpt_count, gpt_size;
11 char buf[SECTOR_SIZE];
13 current_drive = drive;
14 while (next_partition (drive, 0xFFFFFF, &part, &type,
15 &start, &len, &offset, &entry,
16 - &ext_offset, buf))
17 + &ext_offset, &gpt_offset,
18 + &gpt_count, &gpt_size, buf))
19 {
20 if (type != PC_SLICE_TYPE_NONE
21 && ! IS_PC_SLICE_TYPE_BSD (type)
22 @@ -2815,8 +2816,8 @@ parttype_func (char *arg, int flags)
23 {
24 int new_type;
25 unsigned long part = 0xFFFFFF;
26 - unsigned long start, len, offset, ext_offset;
27 - int entry, type;
28 + unsigned long start, len, offset, ext_offset, gpt_offset;
29 + int entry, type, gpt_count, gpt_size;
30 char mbr[512];
32 /* Get the drive and the partition. */
33 @@ -2853,7 +2854,14 @@ parttype_func (char *arg, int flags)
34 /* Look for the partition. */
35 while (next_partition (current_drive, 0xFFFFFF, &part, &type,
36 &start, &len, &offset, &entry,
37 - &ext_offset, mbr))
38 + &ext_offset, &gpt_offset, &gpt_count, &gpt_size, mbr))
39 + /* The partition may not be a GPT partition. */
40 + if (gpt_offset != 0)
41 + {
42 + errnum = ERR_BAD_ARGUMENT;
43 + return 1;
44 + }
45 +
46 {
47 if (part == current_partition)
48 {
49 --- grub-0.97/stage2/disk_io.c
50 +++ grub-0.97/stage2/disk_io.c
51 @@ -21,6 +21,7 @@
53 #include <shared.h>
54 #include <filesys.h>
55 +#include <gpt.h>
57 #ifdef SUPPORT_NETBOOT
58 # define GRUB 1
59 @@ -502,8 +503,8 @@ int
60 set_partition_hidden_flag (int hidden)
61 {
62 unsigned long part = 0xFFFFFF;
63 - unsigned long start, len, offset, ext_offset;
64 - int entry, type;
65 + unsigned long start, len, offset, ext_offset, gpt_offset;
66 + int entry, type, gpt_count, gpt_size;
67 char mbr[512];
69 /* The drive must be a hard disk. */
70 @@ -524,7 +525,14 @@ set_partition_hidden_flag (int hidden)
71 /* Look for the partition. */
72 while (next_partition (current_drive, 0xFFFFFF, &part, &type,
73 &start, &len, &offset, &entry,
74 - &ext_offset, mbr))
75 + &ext_offset, &gpt_offset, &gpt_count, &gpt_size, mbr))
76 + /* The partition may not be a GPT partition. */
77 + if (gpt_offset != 0)
78 + {
79 + errnum = ERR_BAD_ARGUMENT;
80 + return 1;
81 + }
82 +
83 {
84 if (part == current_partition)
85 {
86 @@ -577,11 +585,14 @@ next_partition (unsigned long drive, uns
87 unsigned long *partition, int *type,
88 unsigned long *start, unsigned long *len,
89 unsigned long *offset, int *entry,
90 - unsigned long *ext_offset, char *buf)
91 + unsigned long *ext_offset,
92 + unsigned long *gpt_offset, int *gpt_count,
93 + int *gpt_size, char *buf)
94 {
95 /* Forward declarations. */
96 auto int next_bsd_partition (void);
97 auto int next_pc_slice (void);
98 + auto int next_gpt_slice(void);
100 /* Get next BSD partition in current PC slice. */
101 int next_bsd_partition (void)
102 @@ -666,6 +677,40 @@ next_partition (unsigned long drive, uns
103 return 0;
104 }
106 + /* If this is a GPT partition table, read it as such. */
107 + if (*entry == -1 && *offset == 0 && PC_SLICE_TYPE (buf, 0) == PC_SLICE_TYPE_GPT)
108 + {
109 + struct grub_gpt_header *hdr = (struct grub_gpt_header *) buf;
110 +
111 + /* Read in the GPT Partition table header. */
112 + if (! rawread (drive, 1, 0, SECTOR_SIZE, buf))
113 + return 0;
114 +
115 + if (hdr->magic == GPT_HEADER_MAGIC && hdr->version == 0x10000)
116 + {
117 + /* Let gpt_offset point to the first entry in the GPT
118 + partition table. This can also be used by callers of
119 + next_partition to determine if a entry comes from a
120 + GPT partition table or not. */
121 + *gpt_offset = hdr->partitions;
122 + *gpt_count = hdr->maxpart;
123 + *gpt_size = hdr->partentry_size;
124 +
125 + return next_gpt_slice();
126 + }
127 + else
128 + {
129 + /* This is not a valid header for a GPT partition table.
130 + Re-read the MBR or the boot sector of the extended
131 + partition. */
132 + if (! rawread (drive, *offset, 0, SECTOR_SIZE, buf))
133 + return 0;
134 + }
135 + }
136 +
137 + /* Not a GPT partition. */
138 + *gpt_offset = 0;
139 +
140 /* Increase the entry number. */
141 (*entry)++;
143 @@ -710,6 +755,43 @@ next_partition (unsigned long drive, uns
144 return 1;
145 }
147 + /* Get the next GPT slice. */
148 + int next_gpt_slice (void)
149 + {
150 + struct grub_gpt_partentry *gptentry = (struct grub_gpt_partentry *) buf;
151 + /* Make GPT partitions show up as PC slices. */
152 + int pc_slice_no = (*partition & 0xFF0000) >> 16;
153 +
154 + /* If this is the first time... */
155 + if (pc_slice_no == 0xFF)
156 + {
157 + pc_slice_no = -1;
158 + *entry = -1;
159 + }
160 +
161 + do {
162 + (*entry)++;
163 +
164 + if (*entry >= *gpt_count)
165 + {
166 + errnum = ERR_NO_PART;
167 + return 0;
168 + }
169 + /* Read in the GPT Partition table entry. */
170 + if (! rawread (drive, (*gpt_offset) + GPT_ENTRY_SECTOR (*gpt_size, *entry), GPT_ENTRY_INDEX (*gpt_size, *entry), *gpt_size, buf))
171 + return 0;
172 + } while (! (gptentry->type1 && gptentry->type2));
173 +
174 + pc_slice_no++;
175 + *start = gptentry->start;
176 + *len = gptentry->end - gptentry->start + 1;
177 + *type = PC_SLICE_TYPE_EXT2FS;
178 + *entry = pc_slice_no;
179 + *partition = (*entry << 16) | 0xFFFF;
180 +
181 + return 1;
182 + }
183 +
184 /* Start the body of this function. */
186 #ifndef STAGE1_5
187 @@ -717,6 +799,9 @@ next_partition (unsigned long drive, uns
188 return 0;
189 #endif
191 + if (*partition != 0xFFFFFF && *gpt_offset != 0)
192 + return next_gpt_slice ();
193 +
194 /* If previous partition is a BSD partition or a PC slice which
195 contains BSD partitions... */
196 if ((*partition != 0xFFFFFF && IS_PC_SLICE_TYPE_BSD (*type & 0xff))
197 @@ -755,6 +840,9 @@ real_open_partition (int flags)
198 unsigned long dest_partition = current_partition;
199 unsigned long part_offset;
200 unsigned long ext_offset;
201 + unsigned long gpt_offset;
202 + int gpt_count;
203 + int gpt_size;
204 int entry;
205 char buf[SECTOR_SIZE];
206 int bsd_part, pc_slice;
207 @@ -766,7 +854,8 @@ real_open_partition (int flags)
208 int ret = next_partition (current_drive, dest_partition,
209 &current_partition, &current_slice,
210 &part_start, &part_length,
211 - &part_offset, &entry, &ext_offset, buf);
212 + &part_offset, &entry, &ext_offset,
213 + &gpt_offset, &gpt_count, &gpt_size, buf);
214 bsd_part = (current_partition >> 8) & 0xFF;
215 pc_slice = current_partition >> 16;
216 return ret;
217 --- grub-0.97/stage2/gpt.h
218 +++ grub-0.97/stage2/gpt.h
219 @@ -0,0 +1,68 @@
220 +/*
221 + * GRUB -- GRand Unified Bootloader
222 + * Copyright (C) 2002,2005,2006 Free Software Foundation, Inc.
223 + *
224 + * This program is free software; you can redistribute it and/or modify
225 + * it under the terms of the GNU General Public License as published by
226 + * the Free Software Foundation; either version 2 of the License, or
227 + * (at your option) any later version.
228 + *
229 + * This program is distributed in the hope that it will be useful,
230 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
231 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
232 + * GNU General Public License for more details.
233 + *
234 + * You should have received a copy of the GNU General Public License
235 + * along with this program; if not, write to the Free Software
236 + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
237 + */
238 +
239 +#ifndef _GPT_H
240 +#define _GPT_H
241 +
242 +typedef signed char grub_int8_t;
243 +typedef signed short grub_int16_t;
244 +typedef signed int grub_int32_t;
245 +typedef signed long long int grub_int64_t;
246 +typedef unsigned char grub_uint8_t;
247 +typedef unsigned short grub_uint16_t;
248 +typedef unsigned int grub_uint32_t;
249 +typedef unsigned long long int grub_uint64_t;
250 +
251 +struct grub_gpt_header
252 +{
253 + grub_uint64_t magic;
254 + grub_uint32_t version;
255 + grub_uint32_t headersize;
256 + grub_uint32_t crc32;
257 + grub_uint32_t unused1;
258 + grub_uint64_t primary;
259 + grub_uint64_t backup;
260 + grub_uint64_t start;
261 + grub_uint64_t end;
262 + grub_uint8_t guid[16];
263 + grub_uint64_t partitions;
264 + grub_uint32_t maxpart;
265 + grub_uint32_t partentry_size;
266 + grub_uint32_t partentry_crc32;
267 +} __attribute__ ((packed));
268 +
269 +struct grub_gpt_partentry
270 +{
271 + grub_uint64_t type1;
272 + grub_uint64_t type2;
273 + grub_uint8_t guid[16];
274 + grub_uint64_t start;
275 + grub_uint64_t end;
276 + grub_uint8_t attrib;
277 + char name[72];
278 +} __attribute__ ((packed));
279 +
280 +#define GPT_HEADER_MAGIC 0x5452415020494645UL
281 +
282 +#define GPT_ENTRY_SECTOR(size,entry) \
283 + ((((entry) * (size) + 1) & ~(SECTOR_SIZE - 1)) >> SECTOR_BITS)
284 +#define GPT_ENTRY_INDEX(size,entry) \
285 + ((((entry) * (size) + 1) & (SECTOR_SIZE - 1)) - 1)
286 +
287 +#endif /* _GPT_H */
288 --- grub-0.97/stage2/pc_slice.h
289 +++ grub-0.97/stage2/pc_slice.h
290 @@ -115,6 +115,7 @@
291 #define PC_SLICE_TYPE_LINUX_EXTENDED 0x85
292 #define PC_SLICE_TYPE_VSTAFS 0x9e
293 #define PC_SLICE_TYPE_DELL_UTIL 0xde
294 +#define PC_SLICE_TYPE_GPT 0xee
295 #define PC_SLICE_TYPE_LINUX_RAID 0xfd
298 --- grub-0.97/stage2/shared.h
299 +++ grub-0.97/stage2/shared.h
300 @@ -934,7 +934,9 @@ int next_partition (unsigned long drive,
301 unsigned long *partition, int *type,
302 unsigned long *start, unsigned long *len,
303 unsigned long *offset, int *entry,
304 - unsigned long *ext_offset, char *buf);
305 + unsigned long *ext_offset,
306 + unsigned long *gpt_offset, int *gpt_count,
307 + int *gpt_size, char *buf);
309 /* Sets device to the one represented by the SAVED_* parameters. */
310 int make_saved_active (void);