Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(361)

Side by Side Diff: src/platform/vboot_reference/cgptlib/cgpt.c

Issue 1701017: Add more test cases for GptInit() and fixed some bugs (Closed)
Patch Set: refine for code review Created 10 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* Copyright (c) 2010 The Chromium OS Authors. All rights reserved. 1 /* Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
2 * Use of this source code is governed by a BSD-style license that can be 2 * Use of this source code is governed by a BSD-style license that can be
3 * found in the LICENSE file. 3 * found in the LICENSE file.
4 */ 4 */
5 5
6 #include "cgpt.h" 6 #include "cgpt.h"
7 #include <string.h> 7 #include <string.h>
8 #include "cgpt_internal.h"
9 #include "crc32.h"
8 #include "gpt.h" 10 #include "gpt.h"
11 #include "quick_sort.h"
9 #include "utility.h" 12 #include "utility.h"
10 13
14 /* Macro to invalidate a GPT header/entries */
15 #define INVALIDATE_HEADER(valid_headers, index) \
16 do { \
17 valid_headers &= ~(1<<index); \
18 } while (0)
19 #define INVALIDATE_ENTRIES(valid_entries, index) \
20 do { \
21 valid_entries &= ~(1<<index); \
22 } while (0)
23
24 /* Checks if sector_bytes and drive_sectors are valid values. */
25 int CheckParameters(GptData *gpt) {
26 /* Currently, we only support 512-byte sector. In the future, we may support
27 * larger sector. */
28 if (gpt->sector_bytes != 512)
29 return GPT_ERROR_INVALID_SECTOR_SIZE;
30
31 /* The sector number of a drive should be reasonable. If the given value is
32 * too small to contain basic GPT structure (PMBR + Headers + Entries),
33 * the value is wrong. */
34 if (gpt->drive_sectors < (GPT_PMBR_SECTOR +
35 GPT_HEADER_SECTOR * 2 +
36 GPT_ENTRIES_SECTORS * 2))
37 return GPT_ERROR_INVALID_SECTOR_NUMBER;
38
39 return GPT_SUCCESS;
40 }
41
42 /* Expects header signature should be GPT_HEADER_SIGNATURE. */
43 uint32_t CheckHeaderSignature(GptData *gpt) {
44 uint32_t valid_headers = MASK_BOTH;
45 GptHeader *headers[] = {
46 (GptHeader*)gpt->primary_header,
47 (GptHeader*)gpt->secondary_header,
48 };
49 int i;
50
51 for (i = PRIMARY; i <= SECONDARY; ++i) {
52 if (Memcmp(headers[i]->signature,
53 GPT_HEADER_SIGNATURE,
54 GPT_HEADER_SIGNATURE_SIZE)) {
55 INVALIDATE_HEADER(valid_headers, i);
56 }
57 }
58 return valid_headers;
59 }
60
61 /* The header revision should be GPT_HEADER_REVISION. */
62 uint32_t CheckRevision(GptData *gpt) {
63 uint32_t valid_headers = MASK_BOTH;
64 GptHeader *headers[] = {
65 (GptHeader*)gpt->primary_header,
66 (GptHeader*)gpt->secondary_header,
67 };
68 int i;
69
70 for (i = PRIMARY; i <= SECONDARY; ++i) {
71 if (headers[i]->revision != GPT_HEADER_REVISION)
72 INVALIDATE_HEADER(valid_headers, i);
73 }
74 return valid_headers;
75 }
76
77 /* A valid header size should be between MIN_SIZE_OF_HEADER and
78 * MAX_SIZE_OF_HEADER. */
79 uint32_t CheckSize(GptData *gpt) {
80 uint32_t valid_headers = MASK_BOTH;
81 GptHeader *headers[] = {
82 (GptHeader*)gpt->primary_header,
83 (GptHeader*)gpt->secondary_header,
84 };
85 int i;
86
87 for (i = PRIMARY; i <= SECONDARY; ++i) {
88 if ((headers[i]->size < MIN_SIZE_OF_HEADER) ||
89 (headers[i]->size > MAX_SIZE_OF_HEADER))
90 INVALIDATE_HEADER(valid_headers, i);
91 }
92 return valid_headers;
93 }
94
95 /* Reserved and padding fields should be zero. */
96 uint32_t CheckReservedFields(GptData *gpt) {
97 uint32_t valid_headers = MASK_BOTH;
98 GptHeader *headers[] = {
99 (GptHeader*)gpt->primary_header,
100 (GptHeader*)gpt->secondary_header,
101 };
102 int i;
103
104 for (i = PRIMARY; i <= SECONDARY; ++i) {
105 if (headers[i]->reserved || headers[i]->padding)
106 INVALIDATE_HEADER(valid_headers, i);
107 }
108 return valid_headers;
109 }
110
111 /* my_lba field points to the header itself.
112 * So that the my_lba of primary header should be 1 (right after PMBR).
113 * The my_lba of secondary header should be the last secotr on drive. */
114 uint32_t CheckMyLba(GptData *gpt) {
115 uint32_t valid_headers = MASK_BOTH;
116 GptHeader *primary_header, *secondary_header;
117
118 primary_header = (GptHeader*)gpt->primary_header;
119 secondary_header = (GptHeader*)gpt->secondary_header;
120
121 if (primary_header->my_lba != GPT_PMBR_SECTOR) /* 2nd sector on drive */
122 INVALIDATE_HEADER(valid_headers, PRIMARY);
123 if (secondary_header->my_lba != (gpt->drive_sectors - 1)) /* last sector */
124 INVALIDATE_HEADER(valid_headers, SECONDARY);
125 return valid_headers;
126 }
127
128 /* SizeOfPartitionEntry must be between MIN_SIZE_OF_ENTRY and
129 * MAX_SIZE_OF_ENTRY, and a multiple of SIZE_OF_ENTRY_MULTIPLE. */
130 uint32_t CheckSizeOfPartitionEntry(GptData *gpt) {
131 uint32_t valid_headers = MASK_BOTH;
132 GptHeader *headers[] = {
133 (GptHeader*)gpt->primary_header,
134 (GptHeader*)gpt->secondary_header,
135 };
136 int i;
137
138 for (i = PRIMARY; i <= SECONDARY; ++i) {
139 uint32_t size_of_entry = headers[i]->size_of_entry;
140 if ((size_of_entry < MIN_SIZE_OF_ENTRY) ||
141 (size_of_entry > MAX_SIZE_OF_ENTRY) ||
142 (size_of_entry & (SIZE_OF_ENTRY_MULTIPLE - 1)))
143 INVALIDATE_HEADER(valid_headers, i);
144 }
145 return valid_headers;
146 }
147
148 /* number_of_entries must be between MIN_NUMBER_OF_ENTRIES and
149 * MAX_NUMBER_OF_ENTRIES, and size_of_entry * number_of_entries must be
150 * equal to TOTAL_ENTRIES_SIZE. */
151 uint32_t CheckNumberOfEntries(GptData *gpt) {
152 uint32_t valid_headers = MASK_BOTH;
153 GptHeader *headers[] = {
154 (GptHeader*)gpt->primary_header,
155 (GptHeader*)gpt->secondary_header,
156 };
157 int i;
158
159 for (i = PRIMARY; i <= SECONDARY; ++i) {
160 uint32_t number_of_entries = headers[i]->number_of_entries;
161 if ((number_of_entries < MIN_NUMBER_OF_ENTRIES) ||
162 (number_of_entries > MAX_NUMBER_OF_ENTRIES) ||
163 (number_of_entries * headers[i]->size_of_entry != TOTAL_ENTRIES_SIZE))
164 INVALIDATE_HEADER(valid_headers, i);
165 }
166 return valid_headers;
167 }
168
169 /* Make sure entries_lba is correct.
170 * 2 for primary entries
171 * drive_sectors-1-GPT_ENTRIES_SECTORS for secondary entries. */
172 uint32_t CheckEntriesLba(GptData *gpt) {
173 uint32_t valid_headers = MASK_BOTH;
174 GptHeader *primary_header, *secondary_header;
175
176 primary_header = (GptHeader*)gpt->primary_header;
177 secondary_header = (GptHeader*)gpt->secondary_header;
178
179 /* We assume the primary partition entry table is located at the sector
180 * right after primary partition header. */
181 if (primary_header->entries_lba != (GPT_PMBR_SECTOR + GPT_HEADER_SECTOR))
182 INVALIDATE_HEADER(valid_headers, PRIMARY);
183 /* We assume the secondary partition entry table is the 32 sectors
184 * right before the secondary partition header. */
185 if (secondary_header->entries_lba !=
186 (gpt->drive_sectors - 1 - GPT_ENTRIES_SECTORS))
187 INVALIDATE_HEADER(valid_headers, SECONDARY);
188 return valid_headers;
189 }
190
191 /* FirstUsableLBA must be after the end of the primary GPT table array.
192 * LastUsableLBA must be before the start of the secondary GPT table array.
193 * FirstUsableLBA <= LastUsableLBA. */
194 uint32_t CheckValidUsableLbas(GptData *gpt) {
195 uint32_t valid_headers = MASK_BOTH;
196 uint64_t end_of_primary_entries;
197 uint64_t start_of_secondary_entries;
198 GptHeader *headers[] = {
199 (GptHeader*)gpt->primary_header,
200 (GptHeader*)gpt->secondary_header,
201 };
202 int i;
203
204 end_of_primary_entries = GPT_PMBR_SECTOR + GPT_HEADER_SECTOR +
205 GPT_ENTRIES_SECTORS;
206 start_of_secondary_entries = (gpt->drive_sectors - 1 - GPT_ENTRIES_SECTORS);
207
208 for (i = PRIMARY; i <= SECONDARY; ++i) {
209 if (headers[i]->first_usable_lba < end_of_primary_entries)
210 INVALIDATE_HEADER(valid_headers, i);
211 if (headers[i]->last_usable_lba >= start_of_secondary_entries)
212 INVALIDATE_HEADER(valid_headers, i);
213 if (headers[i]->first_usable_lba > headers[i]->last_usable_lba)
214 INVALIDATE_HEADER(valid_headers, i);
215 }
216
217 if (headers[PRIMARY]->first_usable_lba - headers[PRIMARY]->entries_lba <
218 GPT_ENTRIES_SECTORS)
219 INVALIDATE_HEADER(valid_headers, PRIMARY);
220 if (headers[SECONDARY]->last_usable_lba >= headers[SECONDARY]->entries_lba)
221 INVALIDATE_HEADER(valid_headers, SECONDARY);
222
223 return valid_headers;
224 }
225
226 /* Checks header CRC */
227 uint32_t CheckHeaderCrc(GptData *gpt) {
228 uint32_t crc32, original_crc32;
229 uint32_t valid_headers = MASK_BOTH;
230 GptHeader *headers[] = {
231 (GptHeader*)gpt->primary_header,
232 (GptHeader*)gpt->secondary_header,
233 };
234 int i;
235
236 for (i = PRIMARY; i <= SECONDARY; ++i) {
237 original_crc32 = headers[i]->header_crc32;
238 headers[i]->header_crc32 = 0;
239 crc32 = Crc32((const uint8_t *)headers[i], headers[i]->size);
240 headers[i]->header_crc32 = original_crc32;
241 if (crc32 != original_crc32)
242 INVALIDATE_HEADER(valid_headers, i);
243 }
244 return valid_headers;
245 }
246
247 /* Checks entries CRC */
248 uint32_t CheckEntriesCrc(GptData *gpt) {
249 uint32_t crc32;
250 uint32_t valid_entries = MASK_BOTH;
251 GptHeader *headers[] = {
252 (GptHeader*)gpt->primary_header,
253 (GptHeader*)gpt->secondary_header,
254 };
255 GptEntry *entries[] = {
256 (GptEntry*)gpt->primary_entries,
257 (GptEntry*)gpt->secondary_entries,
258 };
259 int i;
260
261 for (i = PRIMARY; i <= SECONDARY; ++i) {
262 crc32 = Crc32((const uint8_t *)entries[i], TOTAL_ENTRIES_SIZE);
263 if (crc32 != headers[i]->entries_crc32)
264 INVALIDATE_HEADER(valid_entries, i);
265 }
266 return valid_entries;
267 }
268
269 /* Returns non-zero if the given GUID is non-zero. */
270 static int NonZeroGuid(const Guid *guid) {
271 static Guid zero = {{{0, 0, 0, 0, 0, {0, 0, 0, 0, 0, 0}}}};
272 return Memcmp(&zero, guid, sizeof(zero));
273 }
274
275 /* Checks if entries geometry is valid.
276 * All active (non-zero PartitionTypeGUID) partition entries should have:
277 * entry.StartingLBA >= header.FirstUsableLBA
278 * entry.EndingLBA <= header.LastUsableLBA
279 * entry.StartingLBA <= entry.EndingLBA
280 */
281 uint32_t CheckValidEntries(GptData *gpt) {
282 uint32_t valid_entries = MASK_BOTH;
283 GptHeader *headers[] = {
284 (GptHeader*)gpt->primary_header,
285 (GptHeader*)gpt->secondary_header,
286 };
287 GptEntry *entries[] = {
288 (GptEntry*)gpt->primary_entries,
289 (GptEntry*)gpt->secondary_entries,
290 };
291 int copy, entry_index;
292 GptEntry *entry;
293
294 for (copy = PRIMARY; copy <= SECONDARY; ++copy) {
295 for (entry_index = 0;
296 entry_index < headers[copy]->number_of_entries;
297 ++entry_index) {
298 entry = (GptEntry*)&(((uint8_t*)entries[copy])
299 [entry_index * headers[copy]->size_of_entry]);
300 if (NonZeroGuid(&entry->type)) {
301 if ((entry->starting_lba < headers[copy]->first_usable_lba) ||
302 (entry->ending_lba > headers[copy]->last_usable_lba) ||
303 (entry->ending_lba < entry->starting_lba))
304 INVALIDATE_HEADER(valid_entries, copy);
305 }
306 }
307 }
308 return valid_entries;
309 }
310
311 static pair_t pairs[MAX_NUMBER_OF_ENTRIES];
312 /* Callback function for QuickSort(). Returns 1 if 'a_' should precede 'b_'. */
313 int compare_pair(const void *a_, const void *b_) {
314 const pair_t *a = a_;
315 const pair_t *b = b_;
316 if (a->starting <= b->starting) return 1;
317 return 0;
318 }
319
320 /* First sorts by starting_lba, and traverse everyone once if its starting_lba
321 * is between previous starting_lba and ending_lba. If yes, overlapped.
322 * Returns 1 if overlap is found. */
323 int OverlappedEntries(GptEntry *entries, uint32_t number_of_entries) {
324 int i, num_of_pair = 0;
325 for (i = 0; i < number_of_entries; ++i) {
326 if (NonZeroGuid(&entries[i].type)) {
327 pairs[num_of_pair].starting = entries[i].starting_lba;
328 pairs[num_of_pair].ending = entries[i].ending_lba;
329 ++num_of_pair;
330 }
331 }
332 QuickSort(&pairs, num_of_pair, sizeof(pair_t), compare_pair);
333
334 for (i = 1; i < num_of_pair; ++i) {
335 if ((pairs[i].starting >= pairs[i-1].starting) &&
336 (pairs[i].starting <= pairs[i-1].ending))
337 return 1;
338 }
339
340 return 0;
341 }
342
343 /* Checks if any two partitions are overlapped in primary and secondary entries.
344 */
345 uint32_t CheckOverlappedPartition(GptData *gpt) {
346 uint32_t valid_entries = MASK_BOTH;
347 GptHeader *headers[] = {
348 (GptHeader*)gpt->primary_header,
349 (GptHeader*)gpt->secondary_header,
350 };
351 GptEntry *entries[] = {
352 (GptEntry*)gpt->primary_entries,
353 (GptEntry*)gpt->secondary_entries,
354 };
355 int i;
356
357 for (i = PRIMARY; i <= SECONDARY; ++i) {
358 if (OverlappedEntries(entries[i], headers[i]->number_of_entries))
359 INVALIDATE_ENTRIES(valid_entries, i);
360 }
361 return valid_entries;
362 }
363
364 /* Primary entries and secondary entries should be bitwise identical.
365 * If two entries tables are valid, compare them. If not the same,
366 * overwrites secondary with primary (primary always has higher priority),
367 * and marks secondary as modified.
368 * If only one is valid, overwrites invalid one.
369 * If all are invalid, does nothing.
370 * This function returns bit masks for GptData.modified field. */
371 uint8_t RepairEntries(GptData *gpt, const uint32_t valid_entries) {
372 if (valid_entries == MASK_BOTH) {
373 if (Memcmp(gpt->primary_entries, gpt->secondary_entries,
374 TOTAL_ENTRIES_SIZE)) {
375 Memcpy(gpt->secondary_entries, gpt->primary_entries, TOTAL_ENTRIES_SIZE);
376 return GPT_MODIFIED_ENTRIES2;
377 }
378 } else if (valid_entries == MASK_PRIMARY) {
379 Memcpy(gpt->secondary_entries, gpt->primary_entries, TOTAL_ENTRIES_SIZE);
380 return GPT_MODIFIED_ENTRIES2;
381 } else if (valid_entries == MASK_SECONDARY) {
382 Memcpy(gpt->primary_entries, gpt->secondary_entries, TOTAL_ENTRIES_SIZE);
383 return GPT_MODIFIED_ENTRIES1;
384 }
385
386 return 0;
387 }
388
389 /* Two headers are NOT bitwise identical. For example, my_lba pointers to header
390 * itself so that my_lba in primary and secondary is definitely different.
391 * Only the following fields should be identical.
392 *
393 * first_usable_lba
394 * last_usable_lba
395 * number_of_entries
396 * size_of_entry
397 * disk_uuid
398 *
399 * If any of above field are not matched, overwrite secondary with primary since
400 * we always trust primary.
401 * If any one of header is invalid, copy from another. */
402 int IsSynonymous(const GptHeader* a, const GptHeader* b) {
403 if ((a->first_usable_lba == b->first_usable_lba) &&
404 (a->last_usable_lba == b->last_usable_lba) &&
405 (a->number_of_entries == b->number_of_entries) &&
406 (a->size_of_entry == b->size_of_entry) &&
407 (!Memcmp(&a->disk_uuid, &b->disk_uuid, sizeof(Guid))))
408 return 1;
409 return 0;
410 }
411
412 /* The above five fields are shared between primary and secondary headers.
413 * We can recover one header from another through copying those fields. */
414 void CopySynonymousParts(GptHeader* target, const GptHeader* source) {
415 target->first_usable_lba = source->first_usable_lba;
416 target->last_usable_lba = source->last_usable_lba;
417 target->number_of_entries = source->number_of_entries;
418 target->size_of_entry = source->size_of_entry;
419 Memcpy(&target->disk_uuid, &source->disk_uuid, sizeof(Guid));
420 }
421
422 /* This function repairs primary and secondary headers if possible.
423 * If both headers are valid (CRC32 is correct) but
424 * a) indicate inconsistent usable LBA ranges,
425 * b) inconsistent partition entry size and number,
426 * c) inconsistent disk_uuid,
427 * we will use the primary header to overwrite secondary header.
428 * If primary is invalid (CRC32 is wrong), then we repair it from secondary.
429 * If secondary is invalid (CRC32 is wrong), then we repair it from primary.
430 * This function returns the bitmasks for modified header.
431 * Note that CRC value is not re-computed in this function. UpdateCrc() will
432 * do it later.
433 */
434 uint8_t RepairHeader(GptData *gpt, const uint32_t valid_headers) {
435 GptHeader *primary_header, *secondary_header;
436
437 primary_header = (GptHeader*)gpt->primary_header;
438 secondary_header = (GptHeader*)gpt->secondary_header;
439
440 if (valid_headers == MASK_BOTH) {
441 if (!IsSynonymous(primary_header, secondary_header)) {
442 CopySynonymousParts(secondary_header, primary_header);
443 return GPT_MODIFIED_HEADER2;
444 }
445 } else if (valid_headers == MASK_PRIMARY) {
446 Memcpy(secondary_header, primary_header, primary_header->size);
447 secondary_header->my_lba = gpt->drive_sectors - 1; /* the last sector */
448 secondary_header->entries_lba = secondary_header->my_lba -
449 GPT_ENTRIES_SECTORS;
450 return GPT_MODIFIED_HEADER2;
451 } else if (valid_headers == MASK_SECONDARY) {
452 Memcpy(primary_header, secondary_header, secondary_header->size);
453 primary_header->my_lba = GPT_PMBR_SECTOR; /* the second sector on drive */
454 primary_header->entries_lba = primary_header->my_lba + GPT_HEADER_SECTOR;
455 return GPT_MODIFIED_HEADER1;
456 }
457
458 return 0;
459 }
460
461 /* Update CRC value if necessary. */
462 void UpdateCrc(GptData *gpt) {
463 GptHeader *primary_header, *secondary_header;
464
465 primary_header = (GptHeader*)gpt->primary_header;
466 secondary_header = (GptHeader*)gpt->secondary_header;
467
468 if (gpt->modified & GPT_MODIFIED_HEADER1) {
469 primary_header->header_crc32 = 0;
470 primary_header->header_crc32 = Crc32(
471 (const uint8_t *)primary_header, primary_header->size);
472 }
473 if (gpt->modified & GPT_MODIFIED_HEADER2) {
474 secondary_header->header_crc32 = 0;
475 secondary_header->header_crc32 = Crc32(
476 (const uint8_t *)secondary_header, secondary_header->size);
477 }
478 if (gpt->modified & GPT_MODIFIED_ENTRIES1) {
479 primary_header->entries_crc32 =
480 Crc32(gpt->primary_entries, TOTAL_ENTRIES_SIZE);
481 }
482 if (gpt->modified & GPT_MODIFIED_ENTRIES2) {
483 secondary_header->entries_crc32 =
484 Crc32(gpt->secondary_entries, TOTAL_ENTRIES_SIZE);
485 }
486 }
487
488 /* Does every sanity check, and returns if any header/entries needs to be
489 * written back. */
490 int GptInit(GptData *gpt) {
491 uint32_t valid_headers = MASK_BOTH;
492 uint32_t valid_entries = MASK_BOTH;
493 int retval;
494
495 retval = CheckParameters(gpt);
496 if (retval != GPT_SUCCESS)
497 return retval;
498
499 /* Initialize values */
500 gpt->modified = 0;
501
502 /* Start checking if header parameters are valid. */
503 valid_headers &= CheckHeaderSignature(gpt);
504 valid_headers &= CheckRevision(gpt);
505 valid_headers &= CheckSize(gpt);
506 valid_headers &= CheckReservedFields(gpt);
507 valid_headers &= CheckMyLba(gpt);
508 valid_headers &= CheckSizeOfPartitionEntry(gpt);
509 valid_headers &= CheckNumberOfEntries(gpt);
510 valid_headers &= CheckEntriesLba(gpt);
511 valid_headers &= CheckValidUsableLbas(gpt);
512
513 /* Checks if headers are valid. */
514 valid_headers &= CheckHeaderCrc(gpt);
515 gpt->modified |= RepairHeader(gpt, valid_headers);
516
517 /* Checks if entries are valid. */
518 valid_entries &= CheckEntriesCrc(gpt);
519 valid_entries &= CheckValidEntries(gpt);
520 valid_entries &= CheckOverlappedPartition(gpt);
521 gpt->modified |= RepairEntries(gpt, valid_entries);
522
523 /* Returns error if we don't have any valid header/entries to use. */
524 if (!valid_headers)
525 return GPT_ERROR_INVALID_HEADERS;
526 if (!valid_entries)
527 return GPT_ERROR_INVALID_ENTRIES;
528
529 UpdateCrc(gpt);
530
531 /* FIXME: will remove the next line soon. */
532 gpt->current_kernel = 1;
533 return GPT_SUCCESS;
534 }
535
11 /* stub code */ 536 /* stub code */
12 static int start[] = { 34, 10034 }; 537 static int start[] = { 34, 10034 };
13 538
14 int GptInit(GptData_t *gpt) { 539 int GptNextKernelEntry(GptData *gpt, uint64_t *start_sector, uint64_t *size) {
15 int valid_headers[2] = {1, 1};
16
17 /* check header signature */
18 if (Memcmp(gpt->primary_header, GPT_HEADER_SIGNATURE,
19 GPT_HEADER_SIGNATURE_SIZE))
20 valid_headers[0] = 0;
21 if (Memcmp(gpt->secondary_header, GPT_HEADER_SIGNATURE,
22 GPT_HEADER_SIGNATURE_SIZE))
23 valid_headers[1] = 0;
24
25 if (!valid_headers[0] && !valid_headers[1])
26 return GPT_ERROR_INVALID_HEADERS;
27
28 gpt->current_kernel = 1;
29 return GPT_SUCCESS;
30 }
31
32 int GptNextKernelEntry(GptData_t *gpt, uint64_t *start_sector, uint64_t *size) {
33 /* FIXME: the following code is not really code, just returns anything */ 540 /* FIXME: the following code is not really code, just returns anything */
34 gpt->current_kernel ^= 1; 541 gpt->current_kernel ^= 1;
35 if (start_sector) *start_sector = start[gpt->current_kernel]; 542 if (start_sector) *start_sector = start[gpt->current_kernel];
36 if (size) *size = 10000; 543 if (size) *size = 10000;
37 return GPT_SUCCESS; 544 return GPT_SUCCESS;
38 } 545 }
39 546
40 int GptUpdateKernelEntry(GptData_t *gpt, uint32_t update_type) { 547 int GptUpdateKernelEntry(GptData *gpt, uint32_t update_type) {
41 /* FIXME: the following code is not really code, just return anything */ 548 /* FIXME: the following code is not really code, just return anything */
42 gpt->modified |= (GPT_MODIFIED_HEADER1 | GPT_MODIFIED_ENTRIES1) << 549 gpt->modified |= (GPT_MODIFIED_HEADER1 | GPT_MODIFIED_ENTRIES1) <<
43 gpt->current_kernel; 550 gpt->current_kernel;
44 return GPT_SUCCESS; 551 return GPT_SUCCESS;
45 } 552 }
OLDNEW
« no previous file with comments | « src/platform/vboot_reference/cgptlib/cgpt.h ('k') | src/platform/vboot_reference/cgptlib/cgpt_internal.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698