uboot/include/part.h
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0+ */
   2/*
   3 * (C) Copyright 2000-2004
   4 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
   5 */
   6#ifndef _PART_H
   7#define _PART_H
   8
   9#include <blk.h>
  10#include <ide.h>
  11#include <uuid.h>
  12#include <linux/list.h>
  13
  14struct block_drvr {
  15        char *name;
  16        int (*select_hwpart)(int dev_num, int hwpart);
  17};
  18
  19#define LOG2(x) (((x & 0xaaaaaaaa) ? 1 : 0) + ((x & 0xcccccccc) ? 2 : 0) + \
  20                 ((x & 0xf0f0f0f0) ? 4 : 0) + ((x & 0xff00ff00) ? 8 : 0) + \
  21                 ((x & 0xffff0000) ? 16 : 0))
  22#define LOG2_INVALID(type) ((type)((sizeof(type)<<3)-1))
  23
  24/* Part types */
  25#define PART_TYPE_UNKNOWN       0x00
  26#define PART_TYPE_MAC           0x01
  27#define PART_TYPE_DOS           0x02
  28#define PART_TYPE_ISO           0x03
  29#define PART_TYPE_AMIGA         0x04
  30#define PART_TYPE_EFI           0x05
  31
  32/* maximum number of partition entries supported by search */
  33#define DOS_ENTRY_NUMBERS       8
  34#define ISO_ENTRY_NUMBERS       64
  35#define MAC_ENTRY_NUMBERS       64
  36#define AMIGA_ENTRY_NUMBERS     8
  37/*
  38 * Type string for U-Boot bootable partitions
  39 */
  40#define BOOT_PART_TYPE  "U-Boot"        /* primary boot partition type  */
  41#define BOOT_PART_COMP  "PPCBoot"       /* PPCBoot compatibility type   */
  42
  43/* device types */
  44#define DEV_TYPE_UNKNOWN        0xff    /* not connected */
  45#define DEV_TYPE_HARDDISK       0x00    /* harddisk */
  46#define DEV_TYPE_TAPE           0x01    /* Tape */
  47#define DEV_TYPE_CDROM          0x05    /* CD-ROM */
  48#define DEV_TYPE_OPDISK         0x07    /* optical disk */
  49
  50#define PART_NAME_LEN 32
  51#define PART_TYPE_LEN 32
  52#define MAX_SEARCH_PARTITIONS 64
  53
  54#define PART_BOOTABLE                   ((int)BIT(0))
  55#define PART_EFI_SYSTEM_PARTITION       ((int)BIT(1))
  56
  57struct disk_partition {
  58        lbaint_t        start;  /* # of first block in partition        */
  59        lbaint_t        size;   /* number of blocks in partition        */
  60        ulong   blksz;          /* block size in bytes                  */
  61        uchar   name[PART_NAME_LEN];    /* partition name                       */
  62        uchar   type[PART_TYPE_LEN];    /* string type description              */
  63        /*
  64         * The bootable is a bitmask with the following fields:
  65         *
  66         * PART_BOOTABLE                the MBR bootable flag is set
  67         * PART_EFI_SYSTEM_PARTITION    the partition is an EFI system partition
  68         */
  69        int     bootable;
  70#if CONFIG_IS_ENABLED(PARTITION_UUIDS)
  71        char    uuid[UUID_STR_LEN + 1]; /* filesystem UUID as string, if exists */
  72#endif
  73#ifdef CONFIG_PARTITION_TYPE_GUID
  74        char    type_guid[UUID_STR_LEN + 1];    /* type GUID as string, if exists       */
  75#endif
  76#ifdef CONFIG_DOS_PARTITION
  77        uchar   sys_ind;        /* partition type                       */
  78#endif
  79};
  80
  81struct disk_part {
  82        int partnum;
  83        struct disk_partition gpt_part_info;
  84        struct list_head list;
  85};
  86
  87/* Misc _get_dev functions */
  88#ifdef CONFIG_PARTITIONS
  89/**
  90 * blk_get_dev() - get a pointer to a block device given its type and number
  91 *
  92 * Each interface allocates its own devices and typically struct blk_desc is
  93 * contained with the interface's data structure. There is no global
  94 * numbering for block devices, so the interface name must be provided.
  95 *
  96 * @ifname:     Interface name (e.g. "ide", "scsi")
  97 * @dev:        Device number (0 for first device on that interface, 1 for
  98 *              second, etc.
  99 * @return pointer to the block device, or NULL if not available, or an
 100 *         error occurred.
 101 */
 102struct blk_desc *blk_get_dev(const char *ifname, int dev);
 103
 104struct blk_desc *mg_disk_get_dev(int dev);
 105int host_get_dev_err(int dev, struct blk_desc **blk_devp);
 106
 107/* disk/part.c */
 108int part_get_info(struct blk_desc *dev_desc, int part,
 109                  struct disk_partition *info);
 110/**
 111 * part_get_info_whole_disk() - get partition info for the special case of
 112 * a partition occupying the entire disk.
 113 */
 114int part_get_info_whole_disk(struct blk_desc *dev_desc,
 115                             struct disk_partition *info);
 116
 117void part_print(struct blk_desc *dev_desc);
 118void part_init(struct blk_desc *dev_desc);
 119void dev_print(struct blk_desc *dev_desc);
 120
 121/**
 122 * blk_get_device_by_str() - Get a block device given its interface/hw partition
 123 *
 124 * Each interface allocates its own devices and typically struct blk_desc is
 125 * contained with the interface's data structure. There is no global
 126 * numbering for block devices, so the interface name must be provided.
 127 *
 128 * The hardware parition is not related to the normal software partitioning
 129 * of a device - each hardware partition is effectively a separately
 130 * accessible block device. When a hardware parition is selected on MMC the
 131 * other hardware partitions become inaccessible. The same block device is
 132 * used to access all hardware partitions, but its capacity may change when a
 133 * different hardware partition is selected.
 134 *
 135 * When a hardware partition number is given, the block device switches to
 136 * that hardware partition.
 137 *
 138 * @ifname:     Interface name (e.g. "ide", "scsi")
 139 * @dev_str:    Device and optional hw partition. This can either be a string
 140 *              containing the device number (e.g. "2") or the device number
 141 *              and hardware partition number (e.g. "2.4") for devices that
 142 *              support it (currently only MMC).
 143 * @dev_desc:   Returns a pointer to the block device on success
 144 * @return block device number (local to the interface), or -1 on error
 145 */
 146int blk_get_device_by_str(const char *ifname, const char *dev_str,
 147                          struct blk_desc **dev_desc);
 148
 149/**
 150 * blk_get_device_part_str() - Get a block device and partition
 151 *
 152 * This calls blk_get_device_by_str() to look up a device. It also looks up
 153 * a partition and returns information about it.
 154 *
 155 * @dev_part_str is in the format:
 156 *      <dev>.<hw_part>:<part> where <dev> is the device number,
 157 *      <hw_part> is the optional hardware partition number and
 158 *      <part> is the partition number
 159 *
 160 * If ifname is "hostfs" then this function returns the sandbox host block
 161 * device.
 162 *
 163 * If ifname is ubi, then this function returns 0, with @info set to a
 164 * special UBI device.
 165 *
 166 * If @dev_part_str is NULL or empty or "-", then this function looks up
 167 * the "bootdevice" environment variable and uses that string instead.
 168 *
 169 * If the partition string is empty then the first partition is used. If the
 170 * partition string is "auto" then the first bootable partition is used.
 171 *
 172 * @ifname:     Interface name (e.g. "ide", "scsi")
 173 * @dev_part_str:       Device and partition string
 174 * @dev_desc:   Returns a pointer to the block device on success
 175 * @info:       Returns partition information
 176 * @allow_whole_dev:    true to allow the user to select partition 0
 177 *              (which means the whole device), false to require a valid
 178 *              partition number >= 1
 179 * @return partition number, or -1 on error
 180 *
 181 */
 182int blk_get_device_part_str(const char *ifname, const char *dev_part_str,
 183                            struct blk_desc **dev_desc,
 184                            struct disk_partition *info, int allow_whole_dev);
 185
 186/**
 187 * part_get_info_by_name_type() - Search for a partition by name
 188 *                                for only specified partition type
 189 *
 190 * @param dev_desc - block device descriptor
 191 * @param gpt_name - the specified table entry name
 192 * @param info - returns the disk partition info
 193 * @param part_type - only search in partitions of this type
 194 *
 195 * @return - the partition number on match (starting on 1), -1 on no match,
 196 * otherwise error
 197 */
 198int part_get_info_by_name_type(struct blk_desc *dev_desc, const char *name,
 199                               struct disk_partition *info, int part_type);
 200
 201/**
 202 * part_get_info_by_name() - Search for a partition by name
 203 *                           among all available registered partitions
 204 *
 205 * @param dev_desc - block device descriptor
 206 * @param gpt_name - the specified table entry name
 207 * @param info - returns the disk partition info
 208 *
 209 * @return - the partition number on match (starting on 1), -1 on no match,
 210 * otherwise error
 211 */
 212int part_get_info_by_name(struct blk_desc *dev_desc,
 213                              const char *name, struct disk_partition *info);
 214
 215/**
 216 * Get partition info from dev number + part name, or dev number + part number.
 217 *
 218 * Parse a device number and partition description (either name or number)
 219 * in the form of device number plus partition name separated by a "#"
 220 * (like "device_num#partition_name") or a device number plus a partition number
 221 * separated by a ":". For example both "0#misc" and "0:1" can be valid
 222 * partition descriptions for a given interface. If the partition is found, sets
 223 * dev_desc and part_info accordingly with the information of the partition.
 224 *
 225 * @param[in] dev_iface Device interface
 226 * @param[in] dev_part_str Input partition description, like "0#misc" or "0:1"
 227 * @param[out] dev_desc Place to store the device description pointer
 228 * @param[out] part_info Place to store the partition information
 229 * @return 0 on success, or a negative on error
 230 */
 231int part_get_info_by_dev_and_name_or_num(const char *dev_iface,
 232                                         const char *dev_part_str,
 233                                         struct blk_desc **dev_desc,
 234                                         struct disk_partition *part_info);
 235
 236/**
 237 * part_set_generic_name() - create generic partition like hda1 or sdb2
 238 *
 239 * Helper function for partition tables, which don't hold partition names
 240 * (DOS, ISO). Generates partition name out of the device type and partition
 241 * number.
 242 *
 243 * @dev_desc:   pointer to the block device
 244 * @part_num:   partition number for which the name is generated
 245 * @name:       buffer where the name is written
 246 */
 247void part_set_generic_name(const struct blk_desc *dev_desc,
 248        int part_num, char *name);
 249
 250extern const struct block_drvr block_drvr[];
 251#else
 252static inline struct blk_desc *blk_get_dev(const char *ifname, int dev)
 253{ return NULL; }
 254static inline struct blk_desc *mg_disk_get_dev(int dev) { return NULL; }
 255
 256static inline int part_get_info(struct blk_desc *dev_desc, int part,
 257                                struct disk_partition *info) { return -1; }
 258static inline int part_get_info_whole_disk(struct blk_desc *dev_desc,
 259                                           struct disk_partition *info)
 260{ return -1; }
 261static inline void part_print(struct blk_desc *dev_desc) {}
 262static inline void part_init(struct blk_desc *dev_desc) {}
 263static inline void dev_print(struct blk_desc *dev_desc) {}
 264static inline int blk_get_device_by_str(const char *ifname, const char *dev_str,
 265                                        struct blk_desc **dev_desc)
 266{ return -1; }
 267static inline int blk_get_device_part_str(const char *ifname,
 268                                          const char *dev_part_str,
 269                                          struct blk_desc **dev_desc,
 270                                          struct disk_partition *info,
 271                                          int allow_whole_dev)
 272{ *dev_desc = NULL; return -1; }
 273#endif
 274
 275/*
 276 * We don't support printing partition information in SPL and only support
 277 * getting partition information in a few cases.
 278 */
 279#ifdef CONFIG_SPL_BUILD
 280# define part_print_ptr(x)      NULL
 281# if defined(CONFIG_SPL_FS_EXT4) || defined(CONFIG_SPL_FS_FAT) || \
 282        defined(CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION)
 283#  define part_get_info_ptr(x)  x
 284# else
 285#  define part_get_info_ptr(x)  NULL
 286# endif
 287#else
 288#define part_print_ptr(x)       x
 289#define part_get_info_ptr(x)    x
 290#endif
 291
 292
 293struct part_driver {
 294        const char *name;
 295        int part_type;
 296        const int max_entries;  /* maximum number of entries to search */
 297
 298        /**
 299         * get_info() - Get information about a partition
 300         *
 301         * @dev_desc:   Block device descriptor
 302         * @part:       Partition number (1 = first)
 303         * @info:       Returns partition information
 304         */
 305        int (*get_info)(struct blk_desc *dev_desc, int part,
 306                        struct disk_partition *info);
 307
 308        /**
 309         * print() - Print partition information
 310         *
 311         * @dev_desc:   Block device descriptor
 312         */
 313        void (*print)(struct blk_desc *dev_desc);
 314
 315        /**
 316         * test() - Test if a device contains this partition type
 317         *
 318         * @dev_desc:   Block device descriptor
 319         * @return 0 if the block device appears to contain this partition
 320         *         type, -ve if not
 321         */
 322        int (*test)(struct blk_desc *dev_desc);
 323};
 324
 325/* Declare a new U-Boot partition 'driver' */
 326#define U_BOOT_PART_TYPE(__name)                                        \
 327        ll_entry_declare(struct part_driver, __name, part_driver)
 328
 329#include <part_efi.h>
 330
 331#if CONFIG_IS_ENABLED(EFI_PARTITION)
 332/* disk/part_efi.c */
 333/**
 334 * write_gpt_table() - Write the GUID Partition Table to disk
 335 *
 336 * @param dev_desc - block device descriptor
 337 * @param gpt_h - pointer to GPT header representation
 338 * @param gpt_e - pointer to GPT partition table entries
 339 *
 340 * @return - zero on success, otherwise error
 341 */
 342int write_gpt_table(struct blk_desc *dev_desc,
 343                  gpt_header *gpt_h, gpt_entry *gpt_e);
 344
 345/**
 346 * gpt_fill_pte(): Fill the GPT partition table entry
 347 *
 348 * @param dev_desc - block device descriptor
 349 * @param gpt_h - GPT header representation
 350 * @param gpt_e - GPT partition table entries
 351 * @param partitions - list of partitions
 352 * @param parts - number of partitions
 353 *
 354 * @return zero on success
 355 */
 356int gpt_fill_pte(struct blk_desc *dev_desc,
 357                 gpt_header *gpt_h, gpt_entry *gpt_e,
 358                 struct disk_partition *partitions, int parts);
 359
 360/**
 361 * gpt_fill_header(): Fill the GPT header
 362 *
 363 * @param dev_desc - block device descriptor
 364 * @param gpt_h - GPT header representation
 365 * @param str_guid - disk guid string representation
 366 * @param parts_count - number of partitions
 367 *
 368 * @return - error on str_guid conversion error
 369 */
 370int gpt_fill_header(struct blk_desc *dev_desc, gpt_header *gpt_h,
 371                char *str_guid, int parts_count);
 372
 373/**
 374 * gpt_restore(): Restore GPT partition table
 375 *
 376 * @param dev_desc - block device descriptor
 377 * @param str_disk_guid - disk GUID
 378 * @param partitions - list of partitions
 379 * @param parts - number of partitions
 380 *
 381 * @return zero on success
 382 */
 383int gpt_restore(struct blk_desc *dev_desc, char *str_disk_guid,
 384                struct disk_partition *partitions, const int parts_count);
 385
 386/**
 387 * is_valid_gpt_buf() - Ensure that the Primary GPT information is valid
 388 *
 389 * @param dev_desc - block device descriptor
 390 * @param buf - buffer which contains the MBR and Primary GPT info
 391 *
 392 * @return - '0' on success, otherwise error
 393 */
 394int is_valid_gpt_buf(struct blk_desc *dev_desc, void *buf);
 395
 396/**
 397 * write_mbr_and_gpt_partitions() - write MBR, Primary GPT and Backup GPT
 398 *
 399 * @param dev_desc - block device descriptor
 400 * @param buf - buffer which contains the MBR and Primary GPT info
 401 *
 402 * @return - '0' on success, otherwise error
 403 */
 404int write_mbr_and_gpt_partitions(struct blk_desc *dev_desc, void *buf);
 405
 406/**
 407 * gpt_verify_headers() - Function to read and CRC32 check of the GPT's header
 408 *                        and partition table entries (PTE)
 409 *
 410 * As a side effect if sets gpt_head and gpt_pte so they point to GPT data.
 411 *
 412 * @param dev_desc - block device descriptor
 413 * @param gpt_head - pointer to GPT header data read from medium
 414 * @param gpt_pte - pointer to GPT partition table enties read from medium
 415 *
 416 * @return - '0' on success, otherwise error
 417 */
 418int gpt_verify_headers(struct blk_desc *dev_desc, gpt_header *gpt_head,
 419                       gpt_entry **gpt_pte);
 420
 421/**
 422 * gpt_verify_partitions() - Function to check if partitions' name, start and
 423 *                           size correspond to '$partitions' env variable
 424 *
 425 * This function checks if on medium stored GPT data is in sync with information
 426 * provided in '$partitions' environment variable. Specificially, name, start
 427 * and size of the partition is checked.
 428 *
 429 * @param dev_desc - block device descriptor
 430 * @param partitions - partition data read from '$partitions' env variable
 431 * @param parts - number of partitions read from '$partitions' env variable
 432 * @param gpt_head - pointer to GPT header data read from medium
 433 * @param gpt_pte - pointer to GPT partition table enties read from medium
 434 *
 435 * @return - '0' on success, otherwise error
 436 */
 437int gpt_verify_partitions(struct blk_desc *dev_desc,
 438                          struct disk_partition *partitions, int parts,
 439                          gpt_header *gpt_head, gpt_entry **gpt_pte);
 440
 441
 442/**
 443 * get_disk_guid() - Function to read the GUID string from a device's GPT
 444 *
 445 * This function reads the GUID string from a block device whose descriptor
 446 * is provided.
 447 *
 448 * @param dev_desc - block device descriptor
 449 * @param guid - pre-allocated string in which to return the GUID
 450 *
 451 * @return - '0' on success, otherwise error
 452 */
 453int get_disk_guid(struct blk_desc *dev_desc, char *guid);
 454
 455#endif
 456
 457#if CONFIG_IS_ENABLED(DOS_PARTITION)
 458/**
 459 * is_valid_dos_buf() - Ensure that a DOS MBR image is valid
 460 *
 461 * @param buf - buffer which contains the MBR
 462 *
 463 * @return - '0' on success, otherwise error
 464 */
 465int is_valid_dos_buf(void *buf);
 466
 467/**
 468 * write_mbr_partition() - write DOS MBR
 469 *
 470 * @param dev_desc - block device descriptor
 471 * @param buf - buffer which contains the MBR
 472 *
 473 * @return - '0' on success, otherwise error
 474 */
 475int write_mbr_partition(struct blk_desc *dev_desc, void *buf);
 476
 477#endif
 478
 479
 480#endif /* _PART_H */
 481