summaryrefslogtreecommitdiffstats
path: root/cpukit/include/rtems/bdpart.h
blob: f82a3275defbaa88b7eb1b3d2fe1aa94a3709681 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
/**
 * @file
 *
 * @ingroup rtems_bdpart
 *
 * @brief Block Device Partition Management
 */

/*
 * Copyright (C) 2009, 2012 embedded brains GmbH (http://www.embedded-brains.de)
 *
 * The license and distribution terms for this file may be
 * found in the file LICENSE in this distribution or at
 * http://www.rtems.org/license/LICENSE.
 */

#ifndef RTEMS_BDPART_H
#define RTEMS_BDPART_H

#include <uuid/uuid.h>

#include <rtems.h>
#include <rtems/blkdev.h>

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

/**
 * @defgroup rtems_bdpart Block Device Partition Management
 *
 * @ingroup rtems_libblock
 *
 * @brief This module provides functions to manage partitions of a disk device.
 *
 * A @ref rtems_disk "disk" is a set of blocks which are identified by a
 * consecutive set of non-negative integers starting at zero.  There are also
 * logical disks which contain a subset of consecutive disk blocks.  The
 * logical disks are used to represent the partitions of a disk. The disk
 * devices are accessed via the @ref rtems_disk "block device buffer module".
 *
 * The partition format on the physical disk will be converted to an internal
 * representation.  It is possible to convert the internal representation into
 * a specific output format and write it to the physical disk.  One of the
 * constrains for the internal representation was to support the GPT format
 * easily.
 *
 * Currently two physical partition formats are supported.  These are the MBR
 * and the GPT format.  Please note that the GPT support is not implemented.
 * With MBR format we mean the partition format of the wide spread IBM
 * PC-compatible systems.  The GPT format is defined in the Extensible Firmware
 * Interface (EFI).
 *
 * The most common task will be to read the partition information of a disk and
 * register logical disks for each partition.  This can be done with the
 * rtems_bdpart_register_from_disk() function.  Afterwards you can
 * @ref rtems_fsmount "mount" the file systems within the partitions.
 *
 * You can read the partition information from a disk with rtems_bdpart_read()
 * and write it to the disk with rtems_bdpart_write().
 *
 * To create a partition table from scratch for a disk use
 * rtems_bdpart_create().
 *
 * You can access some disk functions with the shell command @c fdisk.
 *
 * References used to create this module:
 *  - <a href="http://en.wikipedia.org/wiki/UUID">Universally Unique Identifier</a>
 *  - <a href="http://en.wikipedia.org/wiki/Globally_Unique_Identifier">Globally Unique Identifier</a>
 *  - <a href="http://en.wikipedia.org/wiki/Disk_partitioning">Disk Paritioning</a>
 *  - <a href="http://en.wikipedia.org/wiki/GUID_Partition_Table">GUID Partition Table</a>
 *  - <a href="http://en.wikipedia.org/wiki/Master_boot_record">Master Boot Record</a>
 *  - <a href="http://en.wikipedia.org/wiki/Extended_boot_record">Extended Boot Record</a>
 *  - <a href="http://en.wikipedia.org/wiki/Cylinder-head-sector">Cylinder Head Sector</a>
 *  - <a href="http://www.win.tue.nl/~aeb/partitions/partition_types-1.html">Partition Types</a>
 */
/**@{**/

/**
 * @name MBR Partition Types and Flags
 */
/**@{**/

#define RTEMS_BDPART_MBR_EMPTY 0x0U

#define RTEMS_BDPART_MBR_FAT_12 0x1U

#define RTEMS_BDPART_MBR_FAT_16 0x4U

#define RTEMS_BDPART_MBR_FAT_16_LBA 0xeU

#define RTEMS_BDPART_MBR_FAT_32 0xbU

#define RTEMS_BDPART_MBR_FAT_32_LBA 0xcU

#define RTEMS_BDPART_MBR_EXTENDED 0x5U

#define RTEMS_BDPART_MBR_DATA 0xdaU

#define RTEMS_BDPART_MBR_GPT 0xeeU

#define RTEMS_BDPART_MBR_FLAG_ACTIVE 0x80U

/** @} */

/**
 * Recommended maximum partition table size.
 */
#define RTEMS_BDPART_PARTITION_NUMBER_HINT 16

/**
 * Partition description.
 */
typedef struct rtems_bdpart_partition {
  /**
   * Block index for partition begin.
   */
  rtems_blkdev_bnum begin;

  /**
   * Block index for partition end (this block is not a part of the partition).
   */
  rtems_blkdev_bnum end;

  /**
   * Partition type.
   */
  uuid_t type;

  /**
   * Partition ID.
   */
  uuid_t id;

  /**
   * Partition flags.
   */
  uint64_t flags;
} rtems_bdpart_partition;

/**
 * Disk format for the partition tables.
 */
typedef enum {
  /**
   * Type value for MBR format.
   */
  RTEMS_BDPART_FORMAT_MBR,

  /**
   * Type value for GPT format.
   */
  RTEMS_BDPART_FORMAT_GPT
} rtems_bdpart_format_type;

/**
 * Disk format description.
 */
typedef union {
  /**
   * Format type.
   */
  rtems_bdpart_format_type type;

  /**
   * MBR format fields.
   */
  struct {
    rtems_bdpart_format_type type;

    /**
     * Disk ID in MBR at offset 440.
     */
    uint32_t disk_id;

    /**
     * This option is used for partition table creation and validation checks
     * before a write to the disk.  It ensures that the first primary
     * partition and the logical partitions start at head one and sector one
     * under the virtual one head and 63 sectors geometry.  Each begin and
     * end of a partition will be aligned to the virtual cylinder boundary.
     */
    bool dos_compatibility;
  } mbr;

  /**
   * GPT format fields.
   */
  struct {
    rtems_bdpart_format_type type;

    /**
     * Disk ID in GPT header.
     */
    uuid_t disk_id;
  } gpt;
} rtems_bdpart_format;

/**
 * @brief Reads the partition information from the physical disk device with
 * name @a disk_name.
 *
 * The partition information will be stored in the partition table
 * @a partitions with a maximum of @a count partitions.  The number of actual
 * partitions will be stored in @a count.  If there are more partitions than
 * space for storage an error status will be returned.  The partition table
 * format recognized on the disk will be stored in @a format.
 */
rtems_status_code rtems_bdpart_read(
  const char *disk_name,
  rtems_bdpart_format *format,
  rtems_bdpart_partition *partitions,
  size_t *count
);

/**
 * @brief Sorts the partition table @a partitions with @a count partitions to
 * have ascending begin blocks
 */
void rtems_bdpart_sort( rtems_bdpart_partition *partitions, size_t count);

/**
 * @brief Writes the partition table to the physical disk device with name
 * @a disk_name.
 *
 * The partition table @a partitions with @a count partitions will be written
 * to the disk.  The output format for the partition table on the disk is
 * specified by @a format.  There are some consistency checks applied to the
 * partition table.  The partition table must be sorted such that the begin
 * blocks are in ascending order.  This can be done with the
 * rtems_bdpart_sort() function.  The partitions must not overlap.  The
 * partitions must have a positive size.  The partitions must be within the
 * disk.  Depending on the output format there are additional constrains.
 */
rtems_status_code rtems_bdpart_write(
  const char *disk_name,
  const rtems_bdpart_format *format,
  const rtems_bdpart_partition *partitions,
  size_t count
);

/**
 * @brief Creates a partition table in @a partitions with @a count partitions
 * for the physical disk device with name @a disk_name.
 *
 * The array of positive integer weights in @a distribution must have exactly
 * @a count elements.  The weights in the distribution array are summed up.
 * Each weight is then divided by the sum to obtain the disk fraction which
 * forms the corresponding partition.  The partition boundaries are generated
 * with respect to the output format in @a format.
 */
rtems_status_code rtems_bdpart_create(
  const char *disk_name,
  const rtems_bdpart_format *format,
  rtems_bdpart_partition *partitions,
  const unsigned *distribution,
  size_t count
);

/**
 * @brief Registers the partitions as logical disks for the physical disk
 * device with name @a disk_name.
 *
 * For each partition of the partition table @a partitions with @a count
 * partitions a logical disk is registered.  The partition number equals the
 * partition table index plus one.  The name of the logical disk device is the
 * concatenation of the physical disk device name and the partition number.
 *
 * @see rtems_blkdev_create_partition().
 */
rtems_status_code rtems_bdpart_register(
  const char *disk_name,
  const rtems_bdpart_partition *partitions,
  size_t count
);

/**
 * @a brief Reads the partition table from the disk device with name @a
 * disk_name and registers the partitions as logical disks.
 *
 * @see rtems_bdpart_register() and rtems_fsmount().
 */
rtems_status_code rtems_bdpart_register_from_disk( const char *disk_name);

/**
 * @brief Deletes the logical disks associated with the partitions of the disk
 * device with name @a disk_name.
 *
 * The partition table @a partitions with @a count partitions will be used to
 * determine which disks need to be deleted.  It may be obtained from
 * rtems_bdpart_read().
 */
rtems_status_code rtems_bdpart_unregister(
  const char *disk_name,
  const rtems_bdpart_partition *partitions,
  size_t count
);

/**
 * @brief Prints the partition table @a partitions with @a count partitions to
 * standard output.
 */
void rtems_bdpart_dump( const rtems_bdpart_partition *partitions, size_t count);

/**
 * @brief Returns the partition type for the MBR partition type value
 * @a mbr_type in @a type.
 */
void rtems_bdpart_to_partition_type( uint8_t mbr_type, uuid_t type);

/**
 * @brief Converts the partition type in @a type to the MBR partition type.
 *
 * The result will be stored in @a mbr_type.  Returns @c true in case of a
 * successful convertion and otherwise @c false.  Both arguments must not be
 * @c NULL.
 */
bool rtems_bdpart_to_mbr_partition_type(
  const uuid_t type,
  uint8_t *mbr_type
);

/** @} */

#define RTEMS_BDPART_MBR_CYLINDER_SIZE 63

#define RTEMS_BDPART_NUMBER_SIZE 4

#define RTEMS_BDPART_BLOCK_SIZE 512

#define RTEMS_BDPART_MBR_TABLE_ENTRY_SIZE 16

#define RTEMS_BDPART_MBR_OFFSET_TABLE_0 446

#define RTEMS_BDPART_MBR_OFFSET_TABLE_1 \
  (RTEMS_BDPART_MBR_OFFSET_TABLE_0 + RTEMS_BDPART_MBR_TABLE_ENTRY_SIZE)

#define RTEMS_BDPART_MBR_OFFSET_DISK_ID 440

#define RTEMS_BDPART_MBR_OFFSET_SIGNATURE_0 510

#define RTEMS_BDPART_MBR_OFFSET_SIGNATURE_1 511

#define RTEMS_BDPART_MBR_SIGNATURE_0 0x55U

#define RTEMS_BDPART_MBR_SIGNATURE_1 0xaaU

#define RTEMS_BDPART_MBR_OFFSET_BEGIN 8

#define RTEMS_BDPART_MBR_OFFSET_SIZE 12

#define RTEMS_BDPART_MBR_OFFSET_TYPE 4

#define RTEMS_BDPART_MBR_OFFSET_FLAGS 0

static inline uint8_t rtems_bdpart_mbr_partition_type(
  const uuid_t type
)
{
  return type [0];
}

rtems_status_code rtems_bdpart_get_disk_data(
  const char *disk_name,
  int *fd_ptr,
  rtems_disk_device **dd_ptr,
  rtems_blkdev_bnum *disk_end
);

#ifdef __cplusplus
}
#endif /* __cplusplus */

#endif /* RTEMS_BDPART_H */