Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:24:13

0001 /* SPDX-License-Identifier: BSD-2-Clause */
0002 
0003 /**
0004  * @file
0005  *
0006  * @ingroup rtems_bdpart
0007  *
0008  * @brief Block Device Partition Management
0009  */
0010 
0011 /*
0012  * Copyright (C) 2009, 2012 embedded brains GmbH & Co. KG
0013  *
0014  * Redistribution and use in source and binary forms, with or without
0015  * modification, are permitted provided that the following conditions
0016  * are met:
0017  * 1. Redistributions of source code must retain the above copyright
0018  *    notice, this list of conditions and the following disclaimer.
0019  * 2. Redistributions in binary form must reproduce the above copyright
0020  *    notice, this list of conditions and the following disclaimer in the
0021  *    documentation and/or other materials provided with the distribution.
0022  *
0023  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0024  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0025  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0026  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0027  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0028  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0029  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0030  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0031  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0032  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0033  * POSSIBILITY OF SUCH DAMAGE.
0034  */
0035 
0036 #ifndef RTEMS_BDPART_H
0037 #define RTEMS_BDPART_H
0038 
0039 #include <uuid/uuid.h>
0040 
0041 #include <rtems.h>
0042 #include <rtems/blkdev.h>
0043 
0044 #ifdef __cplusplus
0045 extern "C" {
0046 #endif /* __cplusplus */
0047 
0048 /**
0049  * @defgroup rtems_bdpart Block Device Partition Management
0050  *
0051  * @ingroup rtems_libblock
0052  *
0053  * @brief This module provides functions to manage partitions of a disk device.
0054  *
0055  * A @ref rtems_disk "disk" is a set of blocks which are identified by a
0056  * consecutive set of non-negative integers starting at zero.  There are also
0057  * logical disks which contain a subset of consecutive disk blocks.  The
0058  * logical disks are used to represent the partitions of a disk. The disk
0059  * devices are accessed via the @ref rtems_disk "block device buffer module".
0060  *
0061  * The partition format on the physical disk will be converted to an internal
0062  * representation.  It is possible to convert the internal representation into
0063  * a specific output format and write it to the physical disk.  One of the
0064  * constrains for the internal representation was to support the GPT format
0065  * easily.
0066  *
0067  * Currently two physical partition formats are supported.  These are the MBR
0068  * and the GPT format.  Please note that the GPT support is not implemented.
0069  * With MBR format we mean the partition format of the wide spread IBM
0070  * PC-compatible systems.  The GPT format is defined in the Extensible Firmware
0071  * Interface (EFI).
0072  *
0073  * The most common task will be to read the partition information of a disk and
0074  * register logical disks for each partition.  This can be done with the
0075  * rtems_bdpart_register_from_disk() function.  Afterwards you can
0076  * @ref rtems_fsmount "mount" the file systems within the partitions.
0077  *
0078  * You can read the partition information from a disk with rtems_bdpart_read()
0079  * and write it to the disk with rtems_bdpart_write().
0080  *
0081  * To create a partition table from scratch for a disk use
0082  * rtems_bdpart_create().
0083  *
0084  * You can access some disk functions with the shell command @c fdisk.
0085  *
0086  * References used to create this module:
0087  *  - <a href="http://en.wikipedia.org/wiki/UUID">Universally Unique Identifier</a>
0088  *  - <a href="http://en.wikipedia.org/wiki/Globally_Unique_Identifier">Globally Unique Identifier</a>
0089  *  - <a href="http://en.wikipedia.org/wiki/Disk_partitioning">Disk Paritioning</a>
0090  *  - <a href="http://en.wikipedia.org/wiki/GUID_Partition_Table">GUID Partition Table</a>
0091  *  - <a href="http://en.wikipedia.org/wiki/Master_boot_record">Master Boot Record</a>
0092  *  - <a href="http://en.wikipedia.org/wiki/Extended_boot_record">Extended Boot Record</a>
0093  *  - <a href="http://en.wikipedia.org/wiki/Cylinder-head-sector">Cylinder Head Sector</a>
0094  *  - <a href="http://www.win.tue.nl/~aeb/partitions/partition_types-1.html">Partition Types</a>
0095  */
0096 /**@{**/
0097 
0098 /**
0099  * @name MBR Partition Types and Flags
0100  */
0101 /**@{**/
0102 
0103 #define RTEMS_BDPART_MBR_EMPTY 0x0U
0104 
0105 #define RTEMS_BDPART_MBR_FAT_12 0x1U
0106 
0107 #define RTEMS_BDPART_MBR_FAT_16 0x4U
0108 
0109 #define RTEMS_BDPART_MBR_FAT_16_LBA 0xeU
0110 
0111 #define RTEMS_BDPART_MBR_FAT_32 0xbU
0112 
0113 #define RTEMS_BDPART_MBR_FAT_32_LBA 0xcU
0114 
0115 #define RTEMS_BDPART_MBR_EXTENDED 0x5U
0116 
0117 #define RTEMS_BDPART_MBR_DATA 0xdaU
0118 
0119 #define RTEMS_BDPART_MBR_GPT 0xeeU
0120 
0121 #define RTEMS_BDPART_MBR_FLAG_ACTIVE 0x80U
0122 
0123 /** @} */
0124 
0125 /**
0126  * Recommended maximum partition table size.
0127  */
0128 #define RTEMS_BDPART_PARTITION_NUMBER_HINT 16
0129 
0130 /**
0131  * Partition description.
0132  */
0133 typedef struct rtems_bdpart_partition {
0134   /**
0135    * Block index for partition begin.
0136    */
0137   rtems_blkdev_bnum begin;
0138 
0139   /**
0140    * Block index for partition end (this block is not a part of the partition).
0141    */
0142   rtems_blkdev_bnum end;
0143 
0144   /**
0145    * Partition type.
0146    */
0147   uuid_t type;
0148 
0149   /**
0150    * Partition ID.
0151    */
0152   uuid_t id;
0153 
0154   /**
0155    * Partition flags.
0156    */
0157   uint64_t flags;
0158 } rtems_bdpart_partition;
0159 
0160 /**
0161  * Disk format for the partition tables.
0162  */
0163 typedef enum {
0164   /**
0165    * Type value for MBR format.
0166    */
0167   RTEMS_BDPART_FORMAT_MBR,
0168 
0169   /**
0170    * Type value for GPT format.
0171    */
0172   RTEMS_BDPART_FORMAT_GPT
0173 } rtems_bdpart_format_type;
0174 
0175 /**
0176  * Disk format description.
0177  */
0178 typedef union {
0179   /**
0180    * Format type.
0181    */
0182   rtems_bdpart_format_type type;
0183 
0184   /**
0185    * MBR format fields.
0186    */
0187   struct {
0188     rtems_bdpart_format_type type;
0189 
0190     /**
0191      * Disk ID in MBR at offset 440.
0192      */
0193     uint32_t disk_id;
0194 
0195     /**
0196      * This option is used for partition table creation and validation checks
0197      * before a write to the disk.  It ensures that the first primary
0198      * partition and the logical partitions start at head one and sector one
0199      * under the virtual one head and 63 sectors geometry.  Each begin and
0200      * end of a partition will be aligned to the virtual cylinder boundary.
0201      */
0202     bool dos_compatibility;
0203   } mbr;
0204 
0205   /**
0206    * GPT format fields.
0207    */
0208   struct {
0209     rtems_bdpart_format_type type;
0210 
0211     /**
0212      * Disk ID in GPT header.
0213      */
0214     uuid_t disk_id;
0215   } gpt;
0216 } rtems_bdpart_format;
0217 
0218 /**
0219  * @brief Reads the partition information from the physical disk device with
0220  * name @a disk_name.
0221  *
0222  * The partition information will be stored in the partition table
0223  * @a partitions with a maximum of @a count partitions.  The number of actual
0224  * partitions will be stored in @a count.  If there are more partitions than
0225  * space for storage an error status will be returned.  The partition table
0226  * format recognized on the disk will be stored in @a format.
0227  */
0228 rtems_status_code rtems_bdpart_read(
0229   const char *disk_name,
0230   rtems_bdpart_format *format,
0231   rtems_bdpart_partition *partitions,
0232   size_t *count
0233 );
0234 
0235 /**
0236  * @brief Sorts the partition table @a partitions with @a count partitions to
0237  * have ascending begin blocks
0238  */
0239 void rtems_bdpart_sort( rtems_bdpart_partition *partitions, size_t count);
0240 
0241 /**
0242  * @brief Writes the partition table to the physical disk device with name
0243  * @a disk_name.
0244  *
0245  * The partition table @a partitions with @a count partitions will be written
0246  * to the disk.  The output format for the partition table on the disk is
0247  * specified by @a format.  There are some consistency checks applied to the
0248  * partition table.  The partition table must be sorted such that the begin
0249  * blocks are in ascending order.  This can be done with the
0250  * rtems_bdpart_sort() function.  The partitions must not overlap.  The
0251  * partitions must have a positive size.  The partitions must be within the
0252  * disk.  Depending on the output format there are additional constrains.
0253  */
0254 rtems_status_code rtems_bdpart_write(
0255   const char *disk_name,
0256   const rtems_bdpart_format *format,
0257   const rtems_bdpart_partition *partitions,
0258   size_t count
0259 );
0260 
0261 /**
0262  * @brief Creates a partition table in @a partitions with @a count partitions
0263  * for the physical disk device with name @a disk_name.
0264  *
0265  * The array of positive integer weights in @a distribution must have exactly
0266  * @a count elements.  The weights in the distribution array are summed up.
0267  * Each weight is then divided by the sum to obtain the disk fraction which
0268  * forms the corresponding partition.  The partition boundaries are generated
0269  * with respect to the output format in @a format.
0270  */
0271 rtems_status_code rtems_bdpart_create(
0272   const char *disk_name,
0273   const rtems_bdpart_format *format,
0274   rtems_bdpart_partition *partitions,
0275   const unsigned *distribution,
0276   size_t count
0277 );
0278 
0279 /**
0280  * @brief Registers the partitions as logical disks for the physical disk
0281  * device with name @a disk_name.
0282  *
0283  * For each partition of the partition table @a partitions with @a count
0284  * partitions a logical disk is registered.  The partition number equals the
0285  * partition table index plus one.  The name of the logical disk device is the
0286  * concatenation of the physical disk device name and the partition number.
0287  *
0288  * @see rtems_blkdev_create_partition().
0289  */
0290 rtems_status_code rtems_bdpart_register(
0291   const char *disk_name,
0292   const rtems_bdpart_partition *partitions,
0293   size_t count
0294 );
0295 
0296 /**
0297  * @a brief Reads the partition table from the disk device with name @a
0298  * disk_name and registers the partitions as logical disks.
0299  *
0300  * @see rtems_bdpart_register() and rtems_fsmount().
0301  */
0302 rtems_status_code rtems_bdpart_register_from_disk( const char *disk_name);
0303 
0304 /**
0305  * @brief Deletes the logical disks associated with the partitions of the disk
0306  * device with name @a disk_name.
0307  *
0308  * The partition table @a partitions with @a count partitions will be used to
0309  * determine which disks need to be deleted.  It may be obtained from
0310  * rtems_bdpart_read().
0311  */
0312 rtems_status_code rtems_bdpart_unregister(
0313   const char *disk_name,
0314   const rtems_bdpart_partition *partitions,
0315   size_t count
0316 );
0317 
0318 /**
0319  * @brief Prints the partition table @a partitions with @a count partitions to
0320  * standard output.
0321  */
0322 void rtems_bdpart_dump( const rtems_bdpart_partition *partitions, size_t count);
0323 
0324 /**
0325  * @brief Returns the partition type for the MBR partition type value
0326  * @a mbr_type in @a type.
0327  */
0328 void rtems_bdpart_to_partition_type( uint8_t mbr_type, uuid_t type);
0329 
0330 /**
0331  * @brief Converts the partition type in @a type to the MBR partition type.
0332  *
0333  * The result will be stored in @a mbr_type.  Returns @c true in case of a
0334  * successful convertion and otherwise @c false.  Both arguments must not be
0335  * @c NULL.
0336  */
0337 bool rtems_bdpart_to_mbr_partition_type(
0338   const uuid_t type,
0339   uint8_t *mbr_type
0340 );
0341 
0342 /** @} */
0343 
0344 #define RTEMS_BDPART_MBR_CYLINDER_SIZE 63
0345 
0346 #define RTEMS_BDPART_NUMBER_SIZE 4
0347 
0348 #define RTEMS_BDPART_BLOCK_SIZE 512
0349 
0350 #define RTEMS_BDPART_MBR_TABLE_ENTRY_SIZE 16
0351 
0352 #define RTEMS_BDPART_MBR_OFFSET_TABLE_0 446
0353 
0354 #define RTEMS_BDPART_MBR_OFFSET_TABLE_1 \
0355   (RTEMS_BDPART_MBR_OFFSET_TABLE_0 + RTEMS_BDPART_MBR_TABLE_ENTRY_SIZE)
0356 
0357 #define RTEMS_BDPART_MBR_OFFSET_DISK_ID 440
0358 
0359 #define RTEMS_BDPART_MBR_OFFSET_SIGNATURE_0 510
0360 
0361 #define RTEMS_BDPART_MBR_OFFSET_SIGNATURE_1 511
0362 
0363 #define RTEMS_BDPART_MBR_SIGNATURE_0 0x55U
0364 
0365 #define RTEMS_BDPART_MBR_SIGNATURE_1 0xaaU
0366 
0367 #define RTEMS_BDPART_MBR_OFFSET_BEGIN 8
0368 
0369 #define RTEMS_BDPART_MBR_OFFSET_SIZE 12
0370 
0371 #define RTEMS_BDPART_MBR_OFFSET_TYPE 4
0372 
0373 #define RTEMS_BDPART_MBR_OFFSET_FLAGS 0
0374 
0375 static inline uint8_t rtems_bdpart_mbr_partition_type(
0376   const uuid_t type
0377 )
0378 {
0379   return type [0];
0380 }
0381 
0382 rtems_status_code rtems_bdpart_get_disk_data(
0383   const char *disk_name,
0384   int *fd_ptr,
0385   rtems_disk_device **dd_ptr,
0386   rtems_blkdev_bnum *disk_end
0387 );
0388 
0389 #ifdef __cplusplus
0390 }
0391 #endif /* __cplusplus */
0392 
0393 #endif /* RTEMS_BDPART_H */