source: MondoRescue/branches/3.3/mindi-busybox/util-linux/fdisk_gpt.c@ 3625

Last change on this file since 3625 was 3621, checked in by Bruno Cornec, 10 years ago

New 3?3 banch for incorporation of latest busybox 1.25. Changing minor version to handle potential incompatibilities.

  • Property svn:eol-style set to native
File size: 4.5 KB
Line 
1#if ENABLE_FEATURE_GPT_LABEL
2/*
3 * Copyright (C) 2010 Kevin Cernekee <cernekee@gmail.com>
4 *
5 * Licensed under GPLv2, see file LICENSE in this source tree.
6 */
7
8#define GPT_MAGIC 0x5452415020494645ULL
9enum {
10 LEGACY_GPT_TYPE = 0xee,
11 GPT_MAX_PARTS = 256,
12 GPT_MAX_PART_ENTRY_LEN = 4096,
13 GUID_LEN = 16,
14};
15
16typedef struct {
17 uint64_t magic;
18 uint32_t revision;
19 uint32_t hdr_size;
20 uint32_t hdr_crc32;
21 uint32_t reserved;
22 uint64_t current_lba;
23 uint64_t backup_lba;
24 uint64_t first_usable_lba;
25 uint64_t last_usable_lba;
26 uint8_t disk_guid[GUID_LEN];
27 uint64_t first_part_lba;
28 uint32_t n_parts;
29 uint32_t part_entry_len;
30 uint32_t part_array_crc32;
31} gpt_header;
32
33typedef struct {
34 uint8_t type_guid[GUID_LEN];
35 uint8_t part_guid[GUID_LEN];
36 uint64_t lba_start;
37 uint64_t lba_end;
38 uint64_t flags;
39 uint16_t name[36];
40} gpt_partition;
41
42static gpt_header *gpt_hdr;
43
44static char *part_array;
45static unsigned int n_parts;
46static unsigned int part_array_len;
47static unsigned int part_entry_len;
48
49static inline gpt_partition *
50gpt_part(int i)
51{
52 if (i >= n_parts) {
53 return NULL;
54 }
55 return (gpt_partition *)&part_array[i * part_entry_len];
56}
57
58static uint32_t
59gpt_crc32(void *buf, int len)
60{
61 return ~crc32_block_endian0(0xffffffff, buf, len, global_crc32_table);
62}
63
64static void
65gpt_print_guid(uint8_t *buf)
66{
67 printf(
68 "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
69 buf[3], buf[2], buf[1], buf[0],
70 buf[5], buf[4],
71 buf[7], buf[6],
72 buf[8], buf[9],
73 buf[10], buf[11], buf[12], buf[13], buf[14], buf[15]);
74}
75
76/* TODO: real unicode support */
77static void
78gpt_print_wide(uint16_t *s, int max_len)
79{
80 int i = 0;
81
82 while (i < max_len) {
83 if (*s == 0)
84 return;
85 fputc(*s, stdout);
86 s++;
87 }
88}
89
90static void
91gpt_list_table(int xtra UNUSED_PARAM)
92{
93 int i;
94 char numstr6[6];
95
96 smart_ulltoa5(total_number_of_sectors * sector_size, numstr6, " KMGTPEZY")[0] = '\0';
97 printf("Disk %s: %llu sectors, %s\n", disk_device,
98 (unsigned long long)total_number_of_sectors,
99 numstr6);
100 printf("Logical sector size: %u\n", sector_size);
101 printf("Disk identifier (GUID): ");
102 gpt_print_guid(gpt_hdr->disk_guid);
103 printf("\nPartition table holds up to %u entries\n",
104 (int)SWAP_LE32(gpt_hdr->n_parts));
105 printf("First usable sector is %llu, last usable sector is %llu\n\n",
106 (unsigned long long)SWAP_LE64(gpt_hdr->first_usable_lba),
107 (unsigned long long)SWAP_LE64(gpt_hdr->last_usable_lba));
108
109 puts("Number Start (sector) End (sector) Size Code Name");
110 for (i = 0; i < n_parts; i++) {
111 gpt_partition *p = gpt_part(i);
112 if (p->lba_start) {
113 smart_ulltoa5((1 + SWAP_LE64(p->lba_end) - SWAP_LE64(p->lba_start)) * sector_size,
114 numstr6, " KMGTPEZY")[0] = '\0';
115 printf("%4u %15llu %15llu %11s %04x ",
116 i + 1,
117 (unsigned long long)SWAP_LE64(p->lba_start),
118 (unsigned long long)SWAP_LE64(p->lba_end),
119 numstr6,
120 0x0700 /* FIXME */);
121 gpt_print_wide(p->name, 18);
122 bb_putchar('\n');
123 }
124 }
125}
126
127static int
128check_gpt_label(void)
129{
130 struct partition *first = pt_offset(MBRbuffer, 0);
131 struct pte pe;
132 uint32_t crc;
133
134 /* LBA 0 contains the legacy MBR */
135
136 if (!valid_part_table_flag(MBRbuffer)
137 || first->sys_ind != LEGACY_GPT_TYPE
138 ) {
139 current_label_type = 0;
140 return 0;
141 }
142
143 /* LBA 1 contains the GPT header */
144
145 read_pte(&pe, 1);
146 gpt_hdr = (void *)pe.sectorbuffer;
147
148 if (gpt_hdr->magic != SWAP_LE64(GPT_MAGIC)) {
149 current_label_type = 0;
150 return 0;
151 }
152
153 if (!global_crc32_table) {
154 global_crc32_table = crc32_filltable(NULL, 0);
155 }
156
157 crc = SWAP_LE32(gpt_hdr->hdr_crc32);
158 gpt_hdr->hdr_crc32 = 0;
159 if (gpt_crc32(gpt_hdr, SWAP_LE32(gpt_hdr->hdr_size)) != crc) {
160 /* FIXME: read the backup table */
161 puts("\nwarning: GPT header CRC is invalid\n");
162 }
163
164 n_parts = SWAP_LE32(gpt_hdr->n_parts);
165 part_entry_len = SWAP_LE32(gpt_hdr->part_entry_len);
166 if (n_parts > GPT_MAX_PARTS
167 || part_entry_len > GPT_MAX_PART_ENTRY_LEN
168 || SWAP_LE32(gpt_hdr->hdr_size) > sector_size
169 ) {
170 puts("\nwarning: unable to parse GPT disklabel\n");
171 current_label_type = 0;
172 return 0;
173 }
174
175 part_array_len = n_parts * part_entry_len;
176 part_array = xmalloc(part_array_len);
177 seek_sector(SWAP_LE64(gpt_hdr->first_part_lba));
178 if (full_read(dev_fd, part_array, part_array_len) != part_array_len) {
179 fdisk_fatal(unable_to_read);
180 }
181
182 if (gpt_crc32(part_array, part_array_len) != gpt_hdr->part_array_crc32) {
183 /* FIXME: read the backup table */
184 puts("\nwarning: GPT array CRC is invalid\n");
185 }
186
187 puts("Found valid GPT with protective MBR; using GPT\n");
188
189 current_label_type = LABEL_GPT;
190 return 1;
191}
192
193#endif /* GPT_LABEL */
Note: See TracBrowser for help on using the repository browser.