~pmdj/ubuntu/trusty/qemu/2.9+applesmc+fadtv3

« back to all changes in this revision

Viewing changes to roms/u-boot/disk/part_dos.c

  • Committer: Phil Dennis-Jordan
  • Date: 2017-07-21 08:03:43 UTC
  • mfrom: (1.1.1)
  • Revision ID: phil@philjordan.eu-20170721080343-2yr2vdj7713czahv
New upstream release 2.9.0.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * (C) Copyright 2001
 
3
 * Raymond Lo, lo@routefree.com
 
4
 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
 
5
 *
 
6
 * SPDX-License-Identifier:     GPL-2.0+
 
7
 */
 
8
 
 
9
/*
 
10
 * Support for harddisk partitions.
 
11
 *
 
12
 * To be compatible with LinuxPPC and Apple we use the standard Apple
 
13
 * SCSI disk partitioning scheme. For more information see:
 
14
 * http://developer.apple.com/techpubs/mac/Devices/Devices-126.html#MARKER-14-92
 
15
 */
 
16
 
 
17
#include <common.h>
 
18
#include <command.h>
 
19
#include <ide.h>
 
20
#include "part_dos.h"
 
21
 
 
22
#ifdef HAVE_BLOCK_DEVICE
 
23
 
 
24
/* Convert char[4] in little endian format to the host format integer
 
25
 */
 
26
static inline int le32_to_int(unsigned char *le32)
 
27
{
 
28
    return ((le32[3] << 24) +
 
29
            (le32[2] << 16) +
 
30
            (le32[1] << 8) +
 
31
             le32[0]
 
32
           );
 
33
}
 
34
 
 
35
static inline int is_extended(int part_type)
 
36
{
 
37
    return (part_type == 0x5 ||
 
38
            part_type == 0xf ||
 
39
            part_type == 0x85);
 
40
}
 
41
 
 
42
static inline int is_bootable(dos_partition_t *p)
 
43
{
 
44
        return p->boot_ind == 0x80;
 
45
}
 
46
 
 
47
static void print_one_part(dos_partition_t *p, int ext_part_sector,
 
48
                           int part_num, unsigned int disksig)
 
49
{
 
50
        int lba_start = ext_part_sector + le32_to_int (p->start4);
 
51
        int lba_size  = le32_to_int (p->size4);
 
52
 
 
53
        printf("%3d\t%-10d\t%-10d\t%08x-%02x\t%02x%s%s\n",
 
54
                part_num, lba_start, lba_size, disksig, part_num, p->sys_ind,
 
55
                (is_extended(p->sys_ind) ? " Extd" : ""),
 
56
                (is_bootable(p) ? " Boot" : ""));
 
57
}
 
58
 
 
59
static int test_block_type(unsigned char *buffer)
 
60
{
 
61
        int slot;
 
62
        struct dos_partition *p;
 
63
 
 
64
        if((buffer[DOS_PART_MAGIC_OFFSET + 0] != 0x55) ||
 
65
            (buffer[DOS_PART_MAGIC_OFFSET + 1] != 0xaa) ) {
 
66
                return (-1);
 
67
        } /* no DOS Signature at all */
 
68
        p = (struct dos_partition *)&buffer[DOS_PART_TBL_OFFSET];
 
69
        for (slot = 0; slot < 3; slot++) {
 
70
                if (p->boot_ind != 0 && p->boot_ind != 0x80) {
 
71
                        if (!slot &&
 
72
                            (strncmp((char *)&buffer[DOS_PBR_FSTYPE_OFFSET],
 
73
                                     "FAT", 3) == 0 ||
 
74
                             strncmp((char *)&buffer[DOS_PBR32_FSTYPE_OFFSET],
 
75
                                     "FAT32", 5) == 0)) {
 
76
                                return DOS_PBR; /* is PBR */
 
77
                        } else {
 
78
                                return -1;
 
79
                        }
 
80
                }
 
81
        }
 
82
        return DOS_MBR;     /* Is MBR */
 
83
}
 
84
 
 
85
 
 
86
int test_part_dos (block_dev_desc_t *dev_desc)
 
87
{
 
88
        ALLOC_CACHE_ALIGN_BUFFER(unsigned char, buffer, dev_desc->blksz);
 
89
 
 
90
        if (dev_desc->block_read(dev_desc->dev, 0, 1, (ulong *) buffer) != 1)
 
91
                return -1;
 
92
 
 
93
        if (test_block_type(buffer) != DOS_MBR)
 
94
                return -1;
 
95
 
 
96
        return 0;
 
97
}
 
98
 
 
99
/*  Print a partition that is relative to its Extended partition table
 
100
 */
 
101
static void print_partition_extended(block_dev_desc_t *dev_desc,
 
102
                                     int ext_part_sector, int relative,
 
103
                                     int part_num, unsigned int disksig)
 
104
{
 
105
        ALLOC_CACHE_ALIGN_BUFFER(unsigned char, buffer, dev_desc->blksz);
 
106
        dos_partition_t *pt;
 
107
        int i;
 
108
 
 
109
        if (dev_desc->block_read(dev_desc->dev, ext_part_sector, 1, (ulong *) buffer) != 1) {
 
110
                printf ("** Can't read partition table on %d:%d **\n",
 
111
                        dev_desc->dev, ext_part_sector);
 
112
                return;
 
113
        }
 
114
        i=test_block_type(buffer);
 
115
        if (i != DOS_MBR) {
 
116
                printf ("bad MBR sector signature 0x%02x%02x\n",
 
117
                        buffer[DOS_PART_MAGIC_OFFSET],
 
118
                        buffer[DOS_PART_MAGIC_OFFSET + 1]);
 
119
                return;
 
120
        }
 
121
 
 
122
        if (!ext_part_sector)
 
123
                disksig = le32_to_int(&buffer[DOS_PART_DISKSIG_OFFSET]);
 
124
 
 
125
        /* Print all primary/logical partitions */
 
126
        pt = (dos_partition_t *) (buffer + DOS_PART_TBL_OFFSET);
 
127
        for (i = 0; i < 4; i++, pt++) {
 
128
                /*
 
129
                 * fdisk does not show the extended partitions that
 
130
                 * are not in the MBR
 
131
                 */
 
132
 
 
133
                if ((pt->sys_ind != 0) &&
 
134
                    (ext_part_sector == 0 || !is_extended (pt->sys_ind)) ) {
 
135
                        print_one_part(pt, ext_part_sector, part_num, disksig);
 
136
                }
 
137
 
 
138
                /* Reverse engr the fdisk part# assignment rule! */
 
139
                if ((ext_part_sector == 0) ||
 
140
                    (pt->sys_ind != 0 && !is_extended (pt->sys_ind)) ) {
 
141
                        part_num++;
 
142
                }
 
143
        }
 
144
 
 
145
        /* Follows the extended partitions */
 
146
        pt = (dos_partition_t *) (buffer + DOS_PART_TBL_OFFSET);
 
147
        for (i = 0; i < 4; i++, pt++) {
 
148
                if (is_extended (pt->sys_ind)) {
 
149
                        int lba_start = le32_to_int (pt->start4) + relative;
 
150
 
 
151
                        print_partition_extended(dev_desc, lba_start,
 
152
                                ext_part_sector == 0  ? lba_start : relative,
 
153
                                part_num, disksig);
 
154
                }
 
155
        }
 
156
 
 
157
        return;
 
158
}
 
159
 
 
160
 
 
161
/*  Print a partition that is relative to its Extended partition table
 
162
 */
 
163
static int get_partition_info_extended (block_dev_desc_t *dev_desc, int ext_part_sector,
 
164
                                 int relative, int part_num,
 
165
                                 int which_part, disk_partition_t *info,
 
166
                                 unsigned int disksig)
 
167
{
 
168
        ALLOC_CACHE_ALIGN_BUFFER(unsigned char, buffer, dev_desc->blksz);
 
169
        dos_partition_t *pt;
 
170
        int i;
 
171
 
 
172
        if (dev_desc->block_read (dev_desc->dev, ext_part_sector, 1, (ulong *) buffer) != 1) {
 
173
                printf ("** Can't read partition table on %d:%d **\n",
 
174
                        dev_desc->dev, ext_part_sector);
 
175
                return -1;
 
176
        }
 
177
        if (buffer[DOS_PART_MAGIC_OFFSET] != 0x55 ||
 
178
                buffer[DOS_PART_MAGIC_OFFSET + 1] != 0xaa) {
 
179
                printf ("bad MBR sector signature 0x%02x%02x\n",
 
180
                        buffer[DOS_PART_MAGIC_OFFSET],
 
181
                        buffer[DOS_PART_MAGIC_OFFSET + 1]);
 
182
                return -1;
 
183
        }
 
184
 
 
185
#ifdef CONFIG_PARTITION_UUIDS
 
186
        if (!ext_part_sector)
 
187
                disksig = le32_to_int(&buffer[DOS_PART_DISKSIG_OFFSET]);
 
188
#endif
 
189
 
 
190
        /* Print all primary/logical partitions */
 
191
        pt = (dos_partition_t *) (buffer + DOS_PART_TBL_OFFSET);
 
192
        for (i = 0; i < 4; i++, pt++) {
 
193
                /*
 
194
                 * fdisk does not show the extended partitions that
 
195
                 * are not in the MBR
 
196
                 */
 
197
                if (((pt->boot_ind & ~0x80) == 0) &&
 
198
                    (pt->sys_ind != 0) &&
 
199
                    (part_num == which_part) &&
 
200
                    (is_extended(pt->sys_ind) == 0)) {
 
201
                        info->blksz = 512;
 
202
                        info->start = ext_part_sector + le32_to_int (pt->start4);
 
203
                        info->size  = le32_to_int (pt->size4);
 
204
                        switch(dev_desc->if_type) {
 
205
                                case IF_TYPE_IDE:
 
206
                                case IF_TYPE_SATA:
 
207
                                case IF_TYPE_ATAPI:
 
208
                                        sprintf ((char *)info->name, "hd%c%d",
 
209
                                                'a' + dev_desc->dev, part_num);
 
210
                                        break;
 
211
                                case IF_TYPE_SCSI:
 
212
                                        sprintf ((char *)info->name, "sd%c%d",
 
213
                                                'a' + dev_desc->dev, part_num);
 
214
                                        break;
 
215
                                case IF_TYPE_USB:
 
216
                                        sprintf ((char *)info->name, "usbd%c%d",
 
217
                                                'a' + dev_desc->dev, part_num);
 
218
                                        break;
 
219
                                case IF_TYPE_DOC:
 
220
                                        sprintf ((char *)info->name, "docd%c%d",
 
221
                                                'a' + dev_desc->dev, part_num);
 
222
                                        break;
 
223
                                default:
 
224
                                        sprintf ((char *)info->name, "xx%c%d",
 
225
                                                'a' + dev_desc->dev, part_num);
 
226
                                        break;
 
227
                        }
 
228
                        /* sprintf(info->type, "%d, pt->sys_ind); */
 
229
                        sprintf ((char *)info->type, "U-Boot");
 
230
                        info->bootable = is_bootable(pt);
 
231
#ifdef CONFIG_PARTITION_UUIDS
 
232
                        sprintf(info->uuid, "%08x-%02x", disksig, part_num);
 
233
#endif
 
234
                        return 0;
 
235
                }
 
236
 
 
237
                /* Reverse engr the fdisk part# assignment rule! */
 
238
                if ((ext_part_sector == 0) ||
 
239
                    (pt->sys_ind != 0 && !is_extended (pt->sys_ind)) ) {
 
240
                        part_num++;
 
241
                }
 
242
        }
 
243
 
 
244
        /* Follows the extended partitions */
 
245
        pt = (dos_partition_t *) (buffer + DOS_PART_TBL_OFFSET);
 
246
        for (i = 0; i < 4; i++, pt++) {
 
247
                if (is_extended (pt->sys_ind)) {
 
248
                        int lba_start = le32_to_int (pt->start4) + relative;
 
249
 
 
250
                        return get_partition_info_extended (dev_desc, lba_start,
 
251
                                 ext_part_sector == 0 ? lba_start : relative,
 
252
                                 part_num, which_part, info, disksig);
 
253
                }
 
254
        }
 
255
        return -1;
 
256
}
 
257
 
 
258
void print_part_dos (block_dev_desc_t *dev_desc)
 
259
{
 
260
        printf("Part\tStart Sector\tNum Sectors\tUUID\t\tType\n");
 
261
        print_partition_extended(dev_desc, 0, 0, 1, 0);
 
262
}
 
263
 
 
264
int get_partition_info_dos (block_dev_desc_t *dev_desc, int part, disk_partition_t * info)
 
265
{
 
266
        return get_partition_info_extended(dev_desc, 0, 0, 1, part, info, 0);
 
267
}
 
268
 
 
269
 
 
270
#endif