GK SDK 源码库: XMIPCLinuxV100R005C00SPC030 (kernel/tools/open_source excluded)

This commit is contained in:
lai
2026-09-06 03:52:57 +08:00
commit b1928b41c0
21813 changed files with 4413081 additions and 0 deletions
@@ -0,0 +1,139 @@
menu "Partition Types"
config PARTITIONS
bool "Enable Partition Labels (disklabels) support"
default y
select SPL_SPRINTF if SPL
select TPL_SPRINTF if TPL
select SPL_STRTO if SPL
select TPL_STRTO if TPL
help
Partition Labels (disklabels) Supported:
Zero or more of the following:
- CONFIG_MAC_PARTITION Apple's MacOS partition table.
- CONFIG_DOS_PARTITION MS Dos partition table, traditional on the
Intel architecture, USB sticks, etc.
- CONFIG_ISO_PARTITION ISO partition table, used on CDROM etc.
- CONFIG_EFI_PARTITION GPT partition table, common when EFI is the
bootloader. Note 2TB partition limit; see
disk/part_efi.c
- CONFIG_MTD_PARTITIONS Memory Technology Device partition table.
If IDE or SCSI support is enabled (CONFIG_CMD_IDE or CONFIG_SCSI)
you must configure support for at least one non-MTD partition type
as well.
config MAC_PARTITION
bool "Enable Apple's MacOS partition table"
depends on PARTITIONS
help
Say Y here if you would like to use device under U-Boot which
were partitioned on a Macintosh.
config SPL_MAC_PARTITION
bool "Enable Apple's MacOS partition table for SPL"
depends on SPL && PARTITIONS
default y if MAC_PARTITION
config DOS_PARTITION
bool "Enable MS Dos partition table"
depends on PARTITIONS
default y if DISTRO_DEFAULTS
default y if x86 || CMD_FAT || USB_STORAGE
help
traditional on the Intel architecture, USB sticks, etc.
config SPL_DOS_PARTITION
bool "Enable MS Dos partition table for SPL"
depends on SPL && PARTITIONS
default y if DOS_PARTITION
config ISO_PARTITION
bool "Enable ISO partition table"
depends on PARTITIONS
default y if DISTRO_DEFAULTS
default y if MIPS || TEGRA
config SPL_ISO_PARTITION
bool "Enable ISO partition table for SPL"
depends on SPL && PARTITIONS
config AMIGA_PARTITION
bool "Enable AMIGA partition table"
depends on PARTITIONS
help
Say Y here if you would like to use device under U-Boot which
were partitioned under AmigaOS.
config SPL_AMIGA_PARTITION
bool "Enable AMIGA partition table for SPL"
depends on SPL && PARTITIONS
default y if AMIGA_PARTITION
config EFI_PARTITION
bool "Enable EFI GPT partition table"
depends on PARTITIONS
default y if DISTRO_DEFAULTS
default y if TEGRA
select LIB_UUID
help
Say Y here if you would like to use device under U-Boot which
were partitioned using EFI GPT.
common when EFI is the bootloader. Note 2TB partition limit;
see disk/part_efi.c
config EFI_PARTITION_ENTRIES_NUMBERS
int "Number of the EFI partition entries"
depends on EFI_PARTITION
default 56 if ARCH_SUNXI
default 128
help
Specify the number of partition entries in the GPT. This is
meant to allow less than the standard specifies for devices
that might need to place their first-stage bootloader in the
middle of a regular GPT.
If unsure, leave at 128 entries, which is the standard
number.
config EFI_PARTITION_ENTRIES_OFF
int "Offset (in bytes) of the EFI partition entries"
depends on EFI_PARTITION
default 0
help
Specify an earliest location (in bytes) where the partition
entries may be located. This is meant to allow "punching a
hole into a device" to create a gap for an SPL, its payload
and the U-Boot environment.
If unsure, leave at 0 (which will locate the partition
entries at the first possible LBA following the GPT header).
config SPL_EFI_PARTITION
bool "Enable EFI GPT partition table for SPL"
depends on SPL && PARTITIONS
default y if EFI_PARTITION
config PARTITION_UUIDS
bool "Enable support of UUID for partition"
depends on PARTITIONS
default y if DISTRO_DEFAULTS
default y if EFI_PARTITION
select LIB_UUID
help
Activate the configuration of UUID for partition
config SPL_PARTITION_UUIDS
bool "Enable support of UUID for partition in SPL"
depends on SPL && PARTITIONS
default y if SPL_EFI_PARTITION
config PARTITION_TYPE_GUID
bool "Enable support of GUID for partition type"
depends on PARTITIONS
depends on EFI_PARTITION
help
Activate the configuration of GUID type
for EFI partition
endmenu
@@ -0,0 +1,13 @@
# SPDX-License-Identifier: GPL-2.0+
#
# (C) Copyright 2000-2006
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
#ccflags-y += -DET_DEBUG -DDEBUG
obj-$(CONFIG_PARTITIONS) += part.o
obj-$(CONFIG_$(SPL_)MAC_PARTITION) += part_mac.o
obj-$(CONFIG_$(SPL_)DOS_PARTITION) += part_dos.o
obj-$(CONFIG_$(SPL_)ISO_PARTITION) += part_iso.o
obj-$(CONFIG_$(SPL_)AMIGA_PARTITION) += part_amiga.o
obj-$(CONFIG_$(SPL_)EFI_PARTITION) += part_efi.o
@@ -0,0 +1,776 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* (C) Copyright 2001
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*/
#include <common.h>
#include <command.h>
#include <env.h>
#include <errno.h>
#include <ide.h>
#include <malloc.h>
#include <part.h>
#include <ubifs_uboot.h>
#undef PART_DEBUG
#ifdef PART_DEBUG
#define PRINTF(fmt,args...) printf (fmt ,##args)
#else
#define PRINTF(fmt,args...)
#endif
/* Check all partition types */
#define PART_TYPE_ALL -1
static struct part_driver *part_driver_lookup_type(struct blk_desc *dev_desc)
{
struct part_driver *drv =
ll_entry_start(struct part_driver, part_driver);
const int n_ents = ll_entry_count(struct part_driver, part_driver);
struct part_driver *entry;
if (dev_desc->part_type == PART_TYPE_UNKNOWN) {
for (entry = drv; entry != drv + n_ents; entry++) {
int ret;
ret = entry->test(dev_desc);
if (!ret) {
dev_desc->part_type = entry->part_type;
return entry;
}
}
} else {
for (entry = drv; entry != drv + n_ents; entry++) {
if (dev_desc->part_type == entry->part_type)
return entry;
}
}
/* Not found */
return NULL;
}
#ifdef CONFIG_HAVE_BLOCK_DEVICE
static struct blk_desc *get_dev_hwpart(const char *ifname, int dev, int hwpart)
{
struct blk_desc *dev_desc;
int ret;
dev_desc = blk_get_devnum_by_typename(ifname, dev);
if (!dev_desc) {
debug("%s: No device for iface '%s', dev %d\n", __func__,
ifname, dev);
return NULL;
}
ret = blk_dselect_hwpart(dev_desc, hwpart);
if (ret) {
debug("%s: Failed to select h/w partition: err-%d\n", __func__,
ret);
return NULL;
}
return dev_desc;
}
struct blk_desc *blk_get_dev(const char *ifname, int dev)
{
return get_dev_hwpart(ifname, dev, 0);
}
#else
struct blk_desc *get_dev_hwpart(const char *ifname, int dev, int hwpart)
{
return NULL;
}
struct blk_desc *blk_get_dev(const char *ifname, int dev)
{
return NULL;
}
#endif
#ifdef CONFIG_HAVE_BLOCK_DEVICE
/* ------------------------------------------------------------------------- */
/*
* reports device info to the user
*/
#ifdef CONFIG_LBA48
typedef uint64_t lba512_t;
#else
typedef lbaint_t lba512_t;
#endif
/*
* Overflowless variant of (block_count * mul_by / 2**div_by)
* when div_by > mul_by
*/
static lba512_t lba512_muldiv(lba512_t block_count, lba512_t mul_by, int div_by)
{
lba512_t bc_quot, bc_rem;
/* x * m / d == x / d * m + (x % d) * m / d */
bc_quot = block_count >> div_by;
bc_rem = block_count - (bc_quot << div_by);
return bc_quot * mul_by + ((bc_rem * mul_by) >> div_by);
}
void dev_print (struct blk_desc *dev_desc)
{
lba512_t lba512; /* number of blocks if 512bytes block size */
if (dev_desc->type == DEV_TYPE_UNKNOWN) {
puts ("not available\n");
return;
}
switch (dev_desc->if_type) {
case IF_TYPE_SCSI:
printf ("(%d:%d) Vendor: %s Prod.: %s Rev: %s\n",
dev_desc->target,dev_desc->lun,
dev_desc->vendor,
dev_desc->product,
dev_desc->revision);
break;
case IF_TYPE_ATAPI:
case IF_TYPE_IDE:
case IF_TYPE_SATA:
printf ("Model: %s Firm: %s Ser#: %s\n",
dev_desc->vendor,
dev_desc->revision,
dev_desc->product);
break;
case IF_TYPE_SD:
case IF_TYPE_MMC:
case IF_TYPE_USB:
case IF_TYPE_NVME:
printf ("Vendor: %s Rev: %s Prod: %s\n",
dev_desc->vendor,
dev_desc->revision,
dev_desc->product);
break;
case IF_TYPE_VIRTIO:
printf("%s VirtIO Block Device\n", dev_desc->vendor);
break;
case IF_TYPE_DOC:
puts("device type DOC\n");
return;
case IF_TYPE_UNKNOWN:
puts("device type unknown\n");
return;
default:
printf("Unhandled device type: %i\n", dev_desc->if_type);
return;
}
puts (" Type: ");
if (dev_desc->removable)
puts ("Removable ");
switch (dev_desc->type & 0x1F) {
case DEV_TYPE_HARDDISK:
puts ("Hard Disk");
break;
case DEV_TYPE_CDROM:
puts ("CD ROM");
break;
case DEV_TYPE_OPDISK:
puts ("Optical Device");
break;
case DEV_TYPE_TAPE:
puts ("Tape");
break;
default:
printf ("# %02X #", dev_desc->type & 0x1F);
break;
}
puts ("\n");
if (dev_desc->lba > 0L && dev_desc->blksz > 0L) {
ulong mb, mb_quot, mb_rem, gb, gb_quot, gb_rem;
lbaint_t lba;
lba = dev_desc->lba;
lba512 = (lba * (dev_desc->blksz/512));
/* round to 1 digit */
/* 2048 = (1024 * 1024) / 512 MB */
mb = lba512_muldiv(lba512, 10, 11);
mb_quot = mb / 10;
mb_rem = mb - (10 * mb_quot);
gb = mb / 1024;
gb_quot = gb / 10;
gb_rem = gb - (10 * gb_quot);
#ifdef CONFIG_LBA48
if (dev_desc->lba48)
printf (" Supports 48-bit addressing\n");
#endif
#if defined(CONFIG_SYS_64BIT_LBA)
printf (" Capacity: %lu.%lu MB = %lu.%lu GB (%llu x %lu)\n",
mb_quot, mb_rem,
gb_quot, gb_rem,
lba,
dev_desc->blksz);
#else
printf (" Capacity: %lu.%lu MB = %lu.%lu GB (%lu x %lu)\n",
mb_quot, mb_rem,
gb_quot, gb_rem,
(ulong)lba,
dev_desc->blksz);
#endif
} else {
puts (" Capacity: not available\n");
}
}
#endif
#ifdef CONFIG_HAVE_BLOCK_DEVICE
void part_init(struct blk_desc *dev_desc)
{
struct part_driver *drv =
ll_entry_start(struct part_driver, part_driver);
const int n_ents = ll_entry_count(struct part_driver, part_driver);
struct part_driver *entry;
blkcache_invalidate(dev_desc->if_type, dev_desc->devnum);
dev_desc->part_type = PART_TYPE_UNKNOWN;
for (entry = drv; entry != drv + n_ents; entry++) {
int ret;
ret = entry->test(dev_desc);
debug("%s: try '%s': ret=%d\n", __func__, entry->name, ret);
if (!ret) {
dev_desc->part_type = entry->part_type;
break;
}
}
}
static void print_part_header(const char *type, struct blk_desc *dev_desc)
{
#if CONFIG_IS_ENABLED(MAC_PARTITION) || \
CONFIG_IS_ENABLED(DOS_PARTITION) || \
CONFIG_IS_ENABLED(ISO_PARTITION) || \
CONFIG_IS_ENABLED(AMIGA_PARTITION) || \
CONFIG_IS_ENABLED(EFI_PARTITION)
puts ("\nPartition Map for ");
switch (dev_desc->if_type) {
case IF_TYPE_IDE:
puts ("IDE");
break;
case IF_TYPE_SATA:
puts ("SATA");
break;
case IF_TYPE_SCSI:
puts ("SCSI");
break;
case IF_TYPE_ATAPI:
puts ("ATAPI");
break;
case IF_TYPE_USB:
puts ("USB");
break;
case IF_TYPE_DOC:
puts ("DOC");
break;
case IF_TYPE_MMC:
puts ("MMC");
break;
case IF_TYPE_HOST:
puts ("HOST");
break;
case IF_TYPE_NVME:
puts ("NVMe");
break;
case IF_TYPE_VIRTIO:
puts("VirtIO");
break;
default:
puts ("UNKNOWN");
break;
}
printf (" device %d -- Partition Type: %s\n\n",
dev_desc->devnum, type);
#endif /* any CONFIG_..._PARTITION */
}
void part_print(struct blk_desc *dev_desc)
{
struct part_driver *drv;
drv = part_driver_lookup_type(dev_desc);
if (!drv) {
printf("## Unknown partition table type %x\n",
dev_desc->part_type);
return;
}
PRINTF("## Testing for valid %s partition ##\n", drv->name);
print_part_header(drv->name, dev_desc);
if (drv->print)
drv->print(dev_desc);
}
#endif /* CONFIG_HAVE_BLOCK_DEVICE */
int part_get_info(struct blk_desc *dev_desc, int part,
disk_partition_t *info)
{
#ifdef CONFIG_HAVE_BLOCK_DEVICE
struct part_driver *drv;
#if CONFIG_IS_ENABLED(PARTITION_UUIDS)
/* The common case is no UUID support */
info->uuid[0] = 0;
#endif
#ifdef CONFIG_PARTITION_TYPE_GUID
info->type_guid[0] = 0;
#endif
drv = part_driver_lookup_type(dev_desc);
if (!drv) {
debug("## Unknown partition table type %x\n",
dev_desc->part_type);
return -EPROTONOSUPPORT;
}
if (!drv->get_info) {
PRINTF("## Driver %s does not have the get_info() method\n",
drv->name);
return -ENOSYS;
}
if (drv->get_info(dev_desc, part, info) == 0) {
PRINTF("## Valid %s partition found ##\n", drv->name);
return 0;
}
#endif /* CONFIG_HAVE_BLOCK_DEVICE */
return -1;
}
int part_get_info_whole_disk(struct blk_desc *dev_desc, disk_partition_t *info)
{
info->start = 0;
info->size = dev_desc->lba;
info->blksz = dev_desc->blksz;
info->bootable = 0;
strcpy((char *)info->type, BOOT_PART_TYPE);
strcpy((char *)info->name, "Whole Disk");
#if CONFIG_IS_ENABLED(PARTITION_UUIDS)
info->uuid[0] = 0;
#endif
#ifdef CONFIG_PARTITION_TYPE_GUID
info->type_guid[0] = 0;
#endif
return 0;
}
int blk_get_device_by_str(const char *ifname, const char *dev_hwpart_str,
struct blk_desc **dev_desc)
{
char *ep;
char *dup_str = NULL;
const char *dev_str, *hwpart_str;
int dev, hwpart;
hwpart_str = strchr(dev_hwpart_str, '.');
if (hwpart_str) {
dup_str = strdup(dev_hwpart_str);
dup_str[hwpart_str - dev_hwpart_str] = 0;
dev_str = dup_str;
hwpart_str++;
} else {
dev_str = dev_hwpart_str;
hwpart = 0;
}
dev = simple_strtoul(dev_str, &ep, 16);
if (*ep) {
printf("** Bad device specification %s %s **\n",
ifname, dev_str);
dev = -EINVAL;
goto cleanup;
}
if (hwpart_str) {
hwpart = simple_strtoul(hwpart_str, &ep, 16);
if (*ep) {
printf("** Bad HW partition specification %s %s **\n",
ifname, hwpart_str);
dev = -EINVAL;
goto cleanup;
}
}
*dev_desc = get_dev_hwpart(ifname, dev, hwpart);
if (!(*dev_desc) || ((*dev_desc)->type == DEV_TYPE_UNKNOWN)) {
debug("** Bad device %s %s **\n", ifname, dev_hwpart_str);
dev = -ENOENT;
goto cleanup;
}
#ifdef CONFIG_HAVE_BLOCK_DEVICE
/*
* Updates the partition table for the specified hw partition.
* Always should be done, otherwise hw partition 0 will return stale
* data after displaying a non-zero hw partition.
*/
part_init(*dev_desc);
#endif
cleanup:
free(dup_str);
return dev;
}
#define PART_UNSPECIFIED -2
#define PART_AUTO -1
int blk_get_device_part_str(const char *ifname, const char *dev_part_str,
struct blk_desc **dev_desc,
disk_partition_t *info, int allow_whole_dev)
{
int ret = -1;
const char *part_str;
char *dup_str = NULL;
const char *dev_str;
int dev;
char *ep;
int p;
int part;
disk_partition_t tmpinfo;
#ifdef CONFIG_SANDBOX
/*
* Special-case a pseudo block device "hostfs", to allow access to the
* host's own filesystem.
*/
if (0 == strcmp(ifname, "hostfs")) {
*dev_desc = NULL;
info->start = 0;
info->size = 0;
info->blksz = 0;
info->bootable = 0;
strcpy((char *)info->type, BOOT_PART_TYPE);
strcpy((char *)info->name, "Sandbox host");
#if CONFIG_IS_ENABLED(PARTITION_UUIDS)
info->uuid[0] = 0;
#endif
#ifdef CONFIG_PARTITION_TYPE_GUID
info->type_guid[0] = 0;
#endif
return 0;
}
#endif
#ifdef CONFIG_CMD_UBIFS
/*
* Special-case ubi, ubi goes through a mtd, rather than through
* a regular block device.
*/
if (0 == strcmp(ifname, "ubi")) {
if (!ubifs_is_mounted()) {
printf("UBIFS not mounted, use ubifsmount to mount volume first!\n");
return -1;
}
*dev_desc = NULL;
memset(info, 0, sizeof(*info));
strcpy((char *)info->type, BOOT_PART_TYPE);
strcpy((char *)info->name, "UBI");
#if CONFIG_IS_ENABLED(PARTITION_UUIDS)
info->uuid[0] = 0;
#endif
return 0;
}
#endif
/* If no dev_part_str, use bootdevice environment variable */
if (!dev_part_str || !strlen(dev_part_str) ||
!strcmp(dev_part_str, "-"))
dev_part_str = env_get("bootdevice");
/* If still no dev_part_str, it's an error */
if (!dev_part_str) {
printf("** No device specified **\n");
goto cleanup;
}
/* Separate device and partition ID specification */
part_str = strchr(dev_part_str, ':');
if (part_str) {
dup_str = strdup(dev_part_str);
dup_str[part_str - dev_part_str] = 0;
dev_str = dup_str;
part_str++;
} else {
dev_str = dev_part_str;
}
/* Look up the device */
dev = blk_get_device_by_str(ifname, dev_str, dev_desc);
if (dev < 0)
goto cleanup;
/* Convert partition ID string to number */
if (!part_str || !*part_str) {
part = PART_UNSPECIFIED;
} else if (!strcmp(part_str, "auto")) {
part = PART_AUTO;
} else {
/* Something specified -> use exactly that */
part = (int)simple_strtoul(part_str, &ep, 16);
/*
* Less than whole string converted,
* or request for whole device, but caller requires partition.
*/
if (*ep || (part == 0 && !allow_whole_dev)) {
printf("** Bad partition specification %s %s **\n",
ifname, dev_part_str);
goto cleanup;
}
}
/*
* No partition table on device,
* or user requested partition 0 (entire device).
*/
if (((*dev_desc)->part_type == PART_TYPE_UNKNOWN) ||
(part == 0)) {
if (!(*dev_desc)->lba) {
printf("** Bad device size - %s %s **\n", ifname,
dev_str);
goto cleanup;
}
/*
* If user specified a partition ID other than 0,
* or the calling command only accepts partitions,
* it's an error.
*/
if ((part > 0) || (!allow_whole_dev)) {
printf("** No partition table - %s %s **\n", ifname,
dev_str);
goto cleanup;
}
(*dev_desc)->log2blksz = LOG2((*dev_desc)->blksz);
part_get_info_whole_disk(*dev_desc, info);
ret = 0;
goto cleanup;
}
/*
* Now there's known to be a partition table,
* not specifying a partition means to pick partition 1.
*/
if (part == PART_UNSPECIFIED)
part = 1;
/*
* If user didn't specify a partition number, or did specify something
* other than "auto", use that partition number directly.
*/
if (part != PART_AUTO) {
ret = part_get_info(*dev_desc, part, info);
if (ret) {
printf("** Invalid partition %d **\n", part);
goto cleanup;
}
} else {
/*
* Find the first bootable partition.
* If none are bootable, fall back to the first valid partition.
*/
part = 0;
for (p = 1; p <= MAX_SEARCH_PARTITIONS; p++) {
ret = part_get_info(*dev_desc, p, info);
if (ret)
continue;
/*
* First valid partition, or new better partition?
* If so, save partition ID.
*/
if (!part || info->bootable)
part = p;
/* Best possible partition? Stop searching. */
if (info->bootable)
break;
/*
* We now need to search further for best possible.
* If we what we just queried was the best so far,
* save the info since we over-write it next loop.
*/
if (part == p)
tmpinfo = *info;
}
/* If we found any acceptable partition */
if (part) {
/*
* If we searched all possible partition IDs,
* return the first valid partition we found.
*/
if (p == MAX_SEARCH_PARTITIONS + 1)
*info = tmpinfo;
} else {
printf("** No valid partitions found **\n");
ret = -1;
goto cleanup;
}
}
if (strncmp((char *)info->type, BOOT_PART_TYPE, sizeof(info->type)) != 0) {
printf("** Invalid partition type \"%.32s\""
" (expect \"" BOOT_PART_TYPE "\")\n",
info->type);
ret = -1;
goto cleanup;
}
(*dev_desc)->log2blksz = LOG2((*dev_desc)->blksz);
ret = part;
goto cleanup;
cleanup:
free(dup_str);
return ret;
}
int part_get_info_by_name_type(struct blk_desc *dev_desc, const char *name,
disk_partition_t *info, int part_type)
{
struct part_driver *part_drv;
int ret;
int i;
part_drv = part_driver_lookup_type(dev_desc);
if (!part_drv)
return -1;
for (i = 1; i < part_drv->max_entries; i++) {
ret = part_drv->get_info(dev_desc, i, info);
if (ret != 0) {
/* no more entries in table */
break;
}
if (strcmp(name, (const char *)info->name) == 0) {
/* matched */
return i;
}
}
return -1;
}
int part_get_info_by_name(struct blk_desc *dev_desc, const char *name,
disk_partition_t *info)
{
return part_get_info_by_name_type(dev_desc, name, info, PART_TYPE_ALL);
}
/**
* Get partition info from device number and partition name.
*
* Parse a device number and partition name string in the form of
* "device_num#partition_name", for example "0#misc". If the partition
* is found, sets dev_desc and part_info accordingly with the information
* of the partition with the given partition_name.
*
* @param[in] dev_iface Device interface
* @param[in] dev_part_str Input string argument, like "0#misc"
* @param[out] dev_desc Place to store the device description pointer
* @param[out] part_info Place to store the partition information
* @return 0 on success, or a negative on error
*/
static int part_get_info_by_dev_and_name(const char *dev_iface,
const char *dev_part_str,
struct blk_desc **dev_desc,
disk_partition_t *part_info)
{
char *ep;
const char *part_str;
int dev_num;
part_str = strchr(dev_part_str, '#');
if (!part_str || part_str == dev_part_str)
return -EINVAL;
dev_num = simple_strtoul(dev_part_str, &ep, 16);
if (ep != part_str) {
/* Not all the first part before the # was parsed. */
return -EINVAL;
}
part_str++;
*dev_desc = blk_get_dev(dev_iface, dev_num);
if (!*dev_desc) {
printf("Could not find %s %d\n", dev_iface, dev_num);
return -EINVAL;
}
if (part_get_info_by_name(*dev_desc, part_str, part_info) < 0) {
printf("Could not find \"%s\" partition\n", part_str);
return -EINVAL;
}
return 0;
}
int part_get_info_by_dev_and_name_or_num(const char *dev_iface,
const char *dev_part_str,
struct blk_desc **dev_desc,
disk_partition_t *part_info)
{
/* Split the part_name if passed as "$dev_num#part_name". */
if (!part_get_info_by_dev_and_name(dev_iface, dev_part_str,
dev_desc, part_info))
return 0;
/*
* Couldn't lookup by name, try looking up the partition description
* directly.
*/
if (blk_get_device_part_str(dev_iface, dev_part_str,
dev_desc, part_info, 1) < 0) {
printf("Couldn't find partition %s %s\n",
dev_iface, dev_part_str);
return -EINVAL;
}
return 0;
}
void part_set_generic_name(const struct blk_desc *dev_desc,
int part_num, char *name)
{
char *devtype;
switch (dev_desc->if_type) {
case IF_TYPE_IDE:
case IF_TYPE_SATA:
case IF_TYPE_ATAPI:
devtype = "hd";
break;
case IF_TYPE_SCSI:
devtype = "sd";
break;
case IF_TYPE_USB:
devtype = "usbd";
break;
case IF_TYPE_DOC:
devtype = "docd";
break;
case IF_TYPE_MMC:
case IF_TYPE_SD:
devtype = "mmcsd";
break;
default:
devtype = "xx";
break;
}
sprintf(name, "%s%c%d", devtype, 'a' + dev_desc->devnum, part_num);
}
@@ -0,0 +1,390 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* (C) Copyright 2001
* Hans-Joerg Frieden, Hyperion Entertainment
* Hans-JoergF@hyperion-entertainment.com
*/
#include <common.h>
#include <command.h>
#include <env.h>
#include <ide.h>
#include "part_amiga.h"
#ifdef CONFIG_HAVE_BLOCK_DEVICE
#undef AMIGA_DEBUG
#ifdef AMIGA_DEBUG
#define PRINTF(fmt, args...) printf(fmt ,##args)
#else
#define PRINTF(fmt, args...)
#endif
struct block_header
{
u32 id;
u32 summed_longs;
s32 chk_sum;
};
static unsigned char block_buffer[DEFAULT_SECTOR_SIZE];
static struct rigid_disk_block rdb = {0};
static struct bootcode_block bootcode = {0};
/*
* Copy a bcpl to a c string
*/
static void bcpl_strcpy(char *to, char *from)
{
int len = *from++;
while (len)
{
*to++ = *from++;
len--;
}
*to = 0;
}
/*
* Print a BCPL String. BCPL strings start with a byte with the length
* of the string, and don't contain a terminating nul character
*/
static void bstr_print(char *string)
{
int len = *string++;
char buffer[256];
int i;
i = 0;
while (len)
{
buffer[i++] = *string++;
len--;
}
buffer[i] = 0;
printf("%-10s", buffer);
}
/*
* Sum a block. The checksum of a block must end up at zero
* to be valid. The chk_sum field is selected so that adding
* it yields zero.
*/
int sum_block(struct block_header *header)
{
s32 *block = (s32 *)header;
u32 i;
s32 sum = 0;
for (i = 0; i < header->summed_longs; i++)
sum += *block++;
return (sum != 0);
}
/*
* Print an AmigaOS disk type. Disk types are a four-byte identifier
* describing the file system. They are usually written as a three-letter
* word followed by a backslash and a version number. For example,
* DOS\0 would be the original file system. SFS\0 would be SmartFileSystem.
* DOS\1 is FFS.
*/
static void print_disk_type(u32 disk_type)
{
char buffer[6];
buffer[0] = (disk_type & 0xFF000000)>>24;
buffer[1] = (disk_type & 0x00FF0000)>>16;
buffer[2] = (disk_type & 0x0000FF00)>>8;
buffer[3] = '\\';
buffer[4] = (disk_type & 0x000000FF) + '0';
buffer[5] = 0;
printf("%s", buffer);
}
/*
* Print the info contained within the given partition block
*/
static void print_part_info(struct partition_block *p)
{
struct amiga_part_geometry *g;
g = (struct amiga_part_geometry *)&(p->environment);
bstr_print(p->drive_name);
printf("%6d\t%6d\t",
g->low_cyl * g->block_per_track * g->surfaces ,
(g->high_cyl - g->low_cyl + 1) * g->block_per_track * g->surfaces - 1);
print_disk_type(g->dos_type);
printf("\t%5d\n", g->boot_priority);
}
/*
* Search for the Rigid Disk Block. The rigid disk block is required
* to be within the first 16 blocks of a drive, needs to have
* the ID AMIGA_ID_RDISK ('RDSK') and needs to have a valid
* sum-to-zero checksum
*/
struct rigid_disk_block *get_rdisk(struct blk_desc *dev_desc)
{
int i;
int limit;
char *s;
s = env_get("amiga_scanlimit");
if (s)
limit = simple_strtoul(s, NULL, 10);
else
limit = AMIGA_BLOCK_LIMIT;
for (i=0; i<limit; i++)
{
ulong res = blk_dread(dev_desc, i, 1, (ulong *)block_buffer);
if (res == 1)
{
struct rigid_disk_block *trdb = (struct rigid_disk_block *)block_buffer;
if (trdb->id == AMIGA_ID_RDISK)
{
PRINTF("Rigid disk block suspect at %d, checking checksum\n",i);
if (sum_block((struct block_header *)block_buffer) == 0)
{
PRINTF("FOUND\n");
memcpy(&rdb, trdb, sizeof(struct rigid_disk_block));
return (struct rigid_disk_block *)&rdb;
}
}
}
}
PRINTF("Done scanning, no RDB found\n");
return NULL;
}
/*
* Search for boot code
* Again, the first boot block must be located somewhere in the first 16 blocks, or rooted in the
* Ridgid disk block
*/
struct bootcode_block *get_bootcode(struct blk_desc *dev_desc)
{
int i;
int limit;
char *s;
s = env_get("amiga_scanlimit");
if (s)
limit = simple_strtoul(s, NULL, 10);
else
limit = AMIGA_BLOCK_LIMIT;
PRINTF("Scanning for BOOT from 0 to %d\n", limit);
for (i = 0; i < limit; i++)
{
ulong res = blk_dread(dev_desc, i, 1, (ulong *)block_buffer);
if (res == 1)
{
struct bootcode_block *boot = (struct bootcode_block *)block_buffer;
if (boot->id == AMIGA_ID_BOOT)
{
PRINTF("BOOT block at %d, checking checksum\n", i);
if (sum_block((struct block_header *)block_buffer) == 0)
{
PRINTF("Found valid bootcode block\n");
memcpy(&bootcode, boot, sizeof(struct bootcode_block));
return &bootcode;
}
}
}
}
PRINTF("No boot code found on disk\n");
return 0;
}
/*
* Test if the given partition has an Amiga partition table/Rigid
* Disk block
*/
static int part_test_amiga(struct blk_desc *dev_desc)
{
struct rigid_disk_block *rdb;
struct bootcode_block *bootcode;
PRINTF("part_test_amiga: Testing for an Amiga RDB partition\n");
rdb = get_rdisk(dev_desc);
if (rdb)
{
bootcode = get_bootcode(dev_desc);
if (bootcode)
PRINTF("part_test_amiga: bootable Amiga disk\n");
else
PRINTF("part_test_amiga: non-bootable Amiga disk\n");
return 0;
}
else
{
PRINTF("part_test_amiga: no RDB found\n");
return -1;
}
}
/*
* Find partition number partnum on the given drive.
*/
static struct partition_block *find_partition(struct blk_desc *dev_desc,
int partnum)
{
struct rigid_disk_block *rdb;
struct partition_block *p;
u32 block;
PRINTF("Trying to find partition block %d\n", partnum);
rdb = get_rdisk(dev_desc);
if (!rdb)
{
PRINTF("find_partition: no rdb found\n");
return NULL;
}
PRINTF("find_partition: Scanning partition list\n");
block = rdb->partition_list;
PRINTF("find_partition: partition list at 0x%x\n", block);
while (block != 0xFFFFFFFF)
{
ulong res = blk_dread(dev_desc, block, 1, (ulong *)block_buffer);
if (res == 1)
{
p = (struct partition_block *)block_buffer;
if (p->id == AMIGA_ID_PART)
{
PRINTF("PART block suspect at 0x%x, checking checksum\n",block);
if (sum_block((struct block_header *)p) == 0)
{
if (partnum == 0) break;
else
{
partnum--;
block = p->next;
}
}
} else block = 0xFFFFFFFF;
} else block = 0xFFFFFFFF;
}
if (block == 0xFFFFFFFF)
{
PRINTF("PART block not found\n");
return NULL;
}
return (struct partition_block *)block_buffer;
}
/*
* Get info about a partition
*/
static int part_get_info_amiga(struct blk_desc *dev_desc, int part,
disk_partition_t *info)
{
struct partition_block *p = find_partition(dev_desc, part-1);
struct amiga_part_geometry *g;
u32 disk_type;
if (!p) return -1;
g = (struct amiga_part_geometry *)&(p->environment);
info->start = g->low_cyl * g->block_per_track * g->surfaces;
info->size = (g->high_cyl - g->low_cyl + 1) * g->block_per_track * g->surfaces - 1;
info->blksz = rdb.block_bytes;
bcpl_strcpy((char *)info->name, p->drive_name);
disk_type = g->dos_type;
info->type[0] = (disk_type & 0xFF000000)>>24;
info->type[1] = (disk_type & 0x00FF0000)>>16;
info->type[2] = (disk_type & 0x0000FF00)>>8;
info->type[3] = '\\';
info->type[4] = (disk_type & 0x000000FF) + '0';
info->type[5] = 0;
return 0;
}
static void part_print_amiga(struct blk_desc *dev_desc)
{
struct rigid_disk_block *rdb;
struct bootcode_block *boot;
struct partition_block *p;
u32 block;
int i = 1;
rdb = get_rdisk(dev_desc);
if (!rdb)
{
PRINTF("part_print_amiga: no rdb found\n");
return;
}
PRINTF("part_print_amiga: Scanning partition list\n");
block = rdb->partition_list;
PRINTF("part_print_amiga: partition list at 0x%x\n", block);
printf("Summary: DiskBlockSize: %d\n"
" Cylinders : %d\n"
" Sectors/Track: %d\n"
" Heads : %d\n\n",
rdb->block_bytes, rdb->cylinders, rdb->sectors,
rdb->heads);
printf(" First Num. \n"
"Nr. Part. Name Block Block Type Boot Priority\n");
while (block != 0xFFFFFFFF)
{
ulong res;
PRINTF("Trying to load block #0x%X\n", block);
res = blk_dread(dev_desc, block, 1, (ulong *)block_buffer);
if (res == 1)
{
p = (struct partition_block *)block_buffer;
if (p->id == AMIGA_ID_PART)
{
PRINTF("PART block suspect at 0x%x, checking checksum\n",block);
if (sum_block((struct block_header *)p) == 0)
{
printf("%-4d ", i); i++;
print_part_info(p);
block = p->next;
}
} else block = 0xFFFFFFFF;
} else block = 0xFFFFFFFF;
}
boot = get_bootcode(dev_desc);
if (boot)
{
printf("Disk is bootable\n");
}
}
U_BOOT_PART_TYPE(amiga) = {
.name = "AMIGA",
.part_type = PART_TYPE_AMIGA,
.max_entries = AMIGA_ENTRY_NUMBERS,
.get_info = part_get_info_amiga,
.print = part_print_amiga,
.test = part_test_amiga,
};
#endif
@@ -0,0 +1,140 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* (C) Copyright 2000
* Hans-Joerg Frieden, Hyperion Entertainment
* Hans-JoergF@hyperion-entertainment.com
*/
#ifndef _DISK_PART_AMIGA_H
#define _DISK_PART_AMIGA_H
#include <common.h>
#if CONFIG_IS_ENABLED(ISO_PARTITION)
/* Make the buffers bigger if ISO partition support is enabled -- CD-ROMS
have 2048 byte blocks */
#define DEFAULT_SECTOR_SIZE 2048
#else
#define DEFAULT_SECTOR_SIZE 512
#endif
#define AMIGA_BLOCK_LIMIT 16
/*
* Amiga disks have a very open structure. The head for the partition table information
* is stored somewhere within the first 16 blocks on disk, and is called the
* "RigidDiskBlock".
*/
struct rigid_disk_block
{
u32 id;
u32 summed_longs;
s32 chk_sum;
u32 host_id;
u32 block_bytes;
u32 flags;
u32 bad_block_list;
u32 partition_list;
u32 file_sys_header_list;
u32 drive_init;
u32 bootcode_block;
u32 reserved_1[5];
/* Physical drive geometry */
u32 cylinders;
u32 sectors;
u32 heads;
u32 interleave;
u32 park;
u32 reserved_2[3];
u32 write_pre_comp;
u32 reduced_write;
u32 step_rate;
u32 reserved_3[5];
/* logical drive geometry */
u32 rdb_blocks_lo;
u32 rdb_blocks_hi;
u32 lo_cylinder;
u32 hi_cylinder;
u32 cyl_blocks;
u32 auto_park_seconds;
u32 high_rdsk_block;
u32 reserved_4;
char disk_vendor[8];
char disk_product[16];
char disk_revision[4];
char controller_vendor[8];
char controller_product[16];
char controller_revision[4];
u32 reserved_5[10];
};
/*
* Each partition on this drive is defined by such a block
*/
struct partition_block
{
u32 id;
u32 summed_longs;
s32 chk_sum;
u32 host_id;
u32 next;
u32 flags;
u32 reserved_1[2];
u32 dev_flags;
char drive_name[32];
u32 reserved_2[15];
u32 environment[17];
u32 reserved_3[15];
};
struct bootcode_block
{
u32 id;
u32 summed_longs;
s32 chk_sum;
u32 host_id;
u32 next;
u32 load_data[123];
};
#define AMIGA_ID_RDISK 0x5244534B
#define AMIGA_ID_PART 0x50415254
#define AMIGA_ID_BOOT 0x424f4f54
/*
* The environment array in the partition block
* describes the partition
*/
struct amiga_part_geometry
{
u32 table_size;
u32 size_blocks;
u32 unused1;
u32 surfaces;
u32 sector_per_block;
u32 block_per_track;
u32 reserved;
u32 prealloc;
u32 interleave;
u32 low_cyl;
u32 high_cyl;
u32 num_buffers;
u32 buf_mem_type;
u32 max_transfer;
u32 mask;
s32 boot_priority;
u32 dos_type;
u32 baud;
u32 control;
u32 boot_blocks;
};
#endif /* _DISK_PART_AMIGA_H_ */
@@ -0,0 +1,348 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* (C) Copyright 2001
* Raymond Lo, lo@routefree.com
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*/
/*
* Support for harddisk partitions.
*
* To be compatible with LinuxPPC and Apple we use the standard Apple
* SCSI disk partitioning scheme. For more information see:
* http://developer.apple.com/techpubs/mac/Devices/Devices-126.html#MARKER-14-92
*/
#include <common.h>
#include <command.h>
#include <ide.h>
#include <memalign.h>
#include "part_dos.h"
#ifdef CONFIG_HAVE_BLOCK_DEVICE
#define DOS_PART_DEFAULT_SECTOR 512
/* should this be configurable? It looks like it's not very common at all
* to use large numbers of partitions */
#define MAX_EXT_PARTS 256
/* Convert char[4] in little endian format to the host format integer
*/
static inline unsigned int le32_to_int(unsigned char *le32)
{
return ((le32[3] << 24) +
(le32[2] << 16) +
(le32[1] << 8) +
le32[0]
);
}
static inline int is_extended(int part_type)
{
return (part_type == 0x5 ||
part_type == 0xf ||
part_type == 0x85);
}
static inline int is_bootable(dos_partition_t *p)
{
return (p->sys_ind == 0xef) || (p->boot_ind == 0x80);
}
static void print_one_part(dos_partition_t *p, lbaint_t ext_part_sector,
int part_num, unsigned int disksig)
{
lbaint_t lba_start = ext_part_sector + le32_to_int (p->start4);
lbaint_t lba_size = le32_to_int (p->size4);
printf("%3d\t%-10" LBAFlength "u\t%-10" LBAFlength
"u\t%08x-%02x\t%02x%s%s\n",
part_num, lba_start, lba_size, disksig, part_num, p->sys_ind,
(is_extended(p->sys_ind) ? " Extd" : ""),
(is_bootable(p) ? " Boot" : ""));
}
static int test_block_type(unsigned char *buffer)
{
int slot;
struct dos_partition *p;
int part_count = 0;
if((buffer[DOS_PART_MAGIC_OFFSET + 0] != 0x55) ||
(buffer[DOS_PART_MAGIC_OFFSET + 1] != 0xaa) ) {
return (-1);
} /* no DOS Signature at all */
p = (struct dos_partition *)&buffer[DOS_PART_TBL_OFFSET];
/* Check that the boot indicators are valid and count the partitions. */
for (slot = 0; slot < 4; ++slot, ++p) {
if (p->boot_ind != 0 && p->boot_ind != 0x80)
break;
if (p->sys_ind)
++part_count;
}
/*
* If the partition table is invalid or empty,
* check if this is a DOS PBR
*/
if (slot != 4 || !part_count) {
if (!strncmp((char *)&buffer[DOS_PBR_FSTYPE_OFFSET],
"FAT", 3) ||
!strncmp((char *)&buffer[DOS_PBR32_FSTYPE_OFFSET],
"FAT32", 5))
return DOS_PBR; /* This is a DOS PBR and not an MBR */
}
if (slot == 4)
return DOS_MBR; /* This is an DOS MBR */
/* This is neither a DOS MBR nor a DOS PBR */
return -1;
}
static int part_test_dos(struct blk_desc *dev_desc)
{
#ifndef CONFIG_SPL_BUILD
ALLOC_CACHE_ALIGN_BUFFER(legacy_mbr, mbr,
DIV_ROUND_UP(dev_desc->blksz, sizeof(legacy_mbr)));
if (blk_dread(dev_desc, 0, 1, (ulong *)mbr) != 1)
return -1;
if (test_block_type((unsigned char *)mbr) != DOS_MBR)
return -1;
if (dev_desc->sig_type == SIG_TYPE_NONE &&
mbr->unique_mbr_signature != 0) {
dev_desc->sig_type = SIG_TYPE_MBR;
dev_desc->mbr_sig = mbr->unique_mbr_signature;
}
#else
ALLOC_CACHE_ALIGN_BUFFER(unsigned char, buffer, dev_desc->blksz);
if (blk_dread(dev_desc, 0, 1, (ulong *)buffer) != 1)
return -1;
if (test_block_type(buffer) != DOS_MBR)
return -1;
#endif
return 0;
}
/* Print a partition that is relative to its Extended partition table
*/
static void print_partition_extended(struct blk_desc *dev_desc,
lbaint_t ext_part_sector,
lbaint_t relative,
int part_num, unsigned int disksig)
{
ALLOC_CACHE_ALIGN_BUFFER(unsigned char, buffer, dev_desc->blksz);
dos_partition_t *pt;
int i;
/* set a maximum recursion level */
if (part_num > MAX_EXT_PARTS)
{
printf("** Nested DOS partitions detected, stopping **\n");
return;
}
if (blk_dread(dev_desc, ext_part_sector, 1, (ulong *)buffer) != 1) {
printf ("** Can't read partition table on %d:" LBAFU " **\n",
dev_desc->devnum, ext_part_sector);
return;
}
i=test_block_type(buffer);
if (i != DOS_MBR) {
printf ("bad MBR sector signature 0x%02x%02x\n",
buffer[DOS_PART_MAGIC_OFFSET],
buffer[DOS_PART_MAGIC_OFFSET + 1]);
return;
}
if (!ext_part_sector)
disksig = le32_to_int(&buffer[DOS_PART_DISKSIG_OFFSET]);
/* Print all primary/logical partitions */
pt = (dos_partition_t *) (buffer + DOS_PART_TBL_OFFSET);
for (i = 0; i < 4; i++, pt++) {
/*
* fdisk does not show the extended partitions that
* are not in the MBR
*/
if ((pt->sys_ind != 0) &&
(ext_part_sector == 0 || !is_extended (pt->sys_ind)) ) {
print_one_part(pt, ext_part_sector, part_num, disksig);
}
/* Reverse engr the fdisk part# assignment rule! */
if ((ext_part_sector == 0) ||
(pt->sys_ind != 0 && !is_extended (pt->sys_ind)) ) {
part_num++;
}
}
/* Follows the extended partitions */
pt = (dos_partition_t *) (buffer + DOS_PART_TBL_OFFSET);
for (i = 0; i < 4; i++, pt++) {
if (is_extended (pt->sys_ind)) {
lbaint_t lba_start
= le32_to_int (pt->start4) + relative;
print_partition_extended(dev_desc, lba_start,
ext_part_sector == 0 ? lba_start : relative,
part_num, disksig);
}
}
return;
}
/* Print a partition that is relative to its Extended partition table
*/
static int part_get_info_extended(struct blk_desc *dev_desc,
lbaint_t ext_part_sector, lbaint_t relative,
int part_num, int which_part,
disk_partition_t *info, unsigned int disksig)
{
ALLOC_CACHE_ALIGN_BUFFER(unsigned char, buffer, dev_desc->blksz);
dos_partition_t *pt;
int i;
int dos_type;
/* set a maximum recursion level */
if (part_num > MAX_EXT_PARTS)
{
printf("** Nested DOS partitions detected, stopping **\n");
return -1;
}
if (blk_dread(dev_desc, ext_part_sector, 1, (ulong *)buffer) != 1) {
printf ("** Can't read partition table on %d:" LBAFU " **\n",
dev_desc->devnum, ext_part_sector);
return -1;
}
if (buffer[DOS_PART_MAGIC_OFFSET] != 0x55 ||
buffer[DOS_PART_MAGIC_OFFSET + 1] != 0xaa) {
printf ("bad MBR sector signature 0x%02x%02x\n",
buffer[DOS_PART_MAGIC_OFFSET],
buffer[DOS_PART_MAGIC_OFFSET + 1]);
return -1;
}
#if CONFIG_IS_ENABLED(PARTITION_UUIDS)
if (!ext_part_sector)
disksig = le32_to_int(&buffer[DOS_PART_DISKSIG_OFFSET]);
#endif
/* Print all primary/logical partitions */
pt = (dos_partition_t *) (buffer + DOS_PART_TBL_OFFSET);
for (i = 0; i < 4; i++, pt++) {
/*
* fdisk does not show the extended partitions that
* are not in the MBR
*/
if (((pt->boot_ind & ~0x80) == 0) &&
(pt->sys_ind != 0) &&
(part_num == which_part) &&
(ext_part_sector == 0 || is_extended(pt->sys_ind) == 0)) {
info->blksz = DOS_PART_DEFAULT_SECTOR;
info->start = (lbaint_t)(ext_part_sector +
le32_to_int(pt->start4));
info->size = (lbaint_t)le32_to_int(pt->size4);
part_set_generic_name(dev_desc, part_num,
(char *)info->name);
/* sprintf(info->type, "%d, pt->sys_ind); */
strcpy((char *)info->type, "U-Boot");
info->bootable = is_bootable(pt);
#if CONFIG_IS_ENABLED(PARTITION_UUIDS)
sprintf(info->uuid, "%08x-%02x", disksig, part_num);
#endif
info->sys_ind = pt->sys_ind;
return 0;
}
/* Reverse engr the fdisk part# assignment rule! */
if ((ext_part_sector == 0) ||
(pt->sys_ind != 0 && !is_extended (pt->sys_ind)) ) {
part_num++;
}
}
/* Follows the extended partitions */
pt = (dos_partition_t *) (buffer + DOS_PART_TBL_OFFSET);
for (i = 0; i < 4; i++, pt++) {
if (is_extended (pt->sys_ind)) {
lbaint_t lba_start
= le32_to_int (pt->start4) + relative;
return part_get_info_extended(dev_desc, lba_start,
ext_part_sector == 0 ? lba_start : relative,
part_num, which_part, info, disksig);
}
}
/* Check for DOS PBR if no partition is found */
dos_type = test_block_type(buffer);
if (dos_type == DOS_PBR) {
info->start = 0;
info->size = dev_desc->lba;
info->blksz = DOS_PART_DEFAULT_SECTOR;
info->bootable = 0;
strcpy((char *)info->type, "U-Boot");
#if CONFIG_IS_ENABLED(PARTITION_UUIDS)
info->uuid[0] = 0;
#endif
return 0;
}
return -1;
}
void part_print_dos(struct blk_desc *dev_desc)
{
printf("Part\tStart Sector\tNum Sectors\tUUID\t\tType\n");
print_partition_extended(dev_desc, 0, 0, 1, 0);
}
int part_get_info_dos(struct blk_desc *dev_desc, int part,
disk_partition_t *info)
{
return part_get_info_extended(dev_desc, 0, 0, 1, part, info, 0);
}
int is_valid_dos_buf(void *buf)
{
return test_block_type(buf) == DOS_MBR ? 0 : -1;
}
int write_mbr_partition(struct blk_desc *dev_desc, void *buf)
{
if (is_valid_dos_buf(buf))
return -1;
/* write MBR */
if (blk_dwrite(dev_desc, 0, 1, buf) != 1) {
printf("%s: failed writing '%s' (1 blks at 0x0)\n",
__func__, "MBR");
return 1;
}
return 0;
}
U_BOOT_PART_TYPE(dos) = {
.name = "DOS",
.part_type = PART_TYPE_DOS,
.max_entries = DOS_ENTRY_NUMBERS,
.get_info = part_get_info_ptr(part_get_info_dos),
.print = part_print_ptr(part_print_dos),
.test = part_test_dos,
};
#endif
@@ -0,0 +1,32 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* (C) Copyright 2000
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*/
#ifndef _DISK_PART_DOS_H
#define _DISK_PART_DOS_H
#define DOS_PART_DISKSIG_OFFSET 0x1b8
#define DOS_PART_TBL_OFFSET 0x1be
#define DOS_PART_MAGIC_OFFSET 0x1fe
#define DOS_PBR_FSTYPE_OFFSET 0x36
#define DOS_PBR32_FSTYPE_OFFSET 0x52
#define DOS_PBR_MEDIA_TYPE_OFFSET 0x15
#define DOS_MBR 0
#define DOS_PBR 1
typedef struct dos_partition {
unsigned char boot_ind; /* 0x80 - active */
unsigned char head; /* starting head */
unsigned char sector; /* starting sector */
unsigned char cyl; /* starting cylinder */
unsigned char sys_ind; /* What partition type */
unsigned char end_head; /* end head */
unsigned char end_sector; /* end sector */
unsigned char end_cyl; /* end cylinder */
unsigned char start4[4]; /* starting sector counting from 0 */
unsigned char size4[4]; /* nr of sectors in partition */
} dos_partition_t;
#endif /* _DISK_PART_DOS_H */
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,241 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* (C) Copyright 2001
* Denis Peter, MPL AG Switzerland, d.peter@mpl.ch.
*/
#include <common.h>
#include <command.h>
#include <asm/unaligned.h>
#include "part_iso.h"
#ifdef CONFIG_HAVE_BLOCK_DEVICE
/* #define ISO_PART_DEBUG */
#ifdef ISO_PART_DEBUG
#define PRINTF(fmt,args...) printf (fmt ,##args)
#else
#define PRINTF(fmt,args...)
#endif
/* enable this if CDs are written with the PowerPC Platform ID */
#undef CHECK_FOR_POWERPC_PLATTFORM
#define CD_SECTSIZE 2048
static unsigned char tmpbuf[CD_SECTSIZE] __aligned(ARCH_DMA_MINALIGN);
unsigned long iso_dread(struct blk_desc *block_dev, lbaint_t start,
lbaint_t blkcnt, void *buffer)
{
unsigned long ret;
if (block_dev->blksz == 512) {
/* Convert from 2048 to 512 sector size */
start *= 4;
blkcnt *= 4;
}
ret = blk_dread(block_dev, start, blkcnt, buffer);
if (block_dev->blksz == 512)
ret /= 4;
return ret;
}
/* only boot records will be listed as valid partitions */
int part_get_info_iso_verb(struct blk_desc *dev_desc, int part_num,
disk_partition_t *info, int verb)
{
int i,offset,entry_num;
unsigned short *chksumbuf;
unsigned short chksum;
unsigned long newblkaddr,blkaddr,lastsect,bootaddr;
iso_boot_rec_t *pbr = (iso_boot_rec_t *)tmpbuf; /* boot record */
iso_pri_rec_t *ppr = (iso_pri_rec_t *)tmpbuf; /* primary desc */
iso_val_entry_t *pve = (iso_val_entry_t *)tmpbuf;
iso_init_def_entry_t *pide;
if ((dev_desc->blksz != CD_SECTSIZE) && (dev_desc->blksz != 512))
return -1;
/* the first sector (sector 0x10) must be a primary volume desc */
blkaddr=PVD_OFFSET;
if (iso_dread(dev_desc, PVD_OFFSET, 1, (ulong *)tmpbuf) != 1)
return -1;
if(ppr->desctype!=0x01) {
if(verb)
printf ("** First descriptor is NOT a primary desc on %d:%d **\n",
dev_desc->devnum, part_num);
return (-1);
}
if(strncmp((char *)ppr->stand_ident,"CD001",5)!=0) {
if(verb)
printf ("** Wrong ISO Ident: %s on %d:%d **\n",
ppr->stand_ident, dev_desc->devnum, part_num);
return (-1);
}
lastsect = le32_to_cpu(ppr->firstsek_LEpathtab1_LE);
/* assuming same block size for all entries */
info->blksz = be16_to_cpu(ppr->secsize_BE);
PRINTF(" Lastsect:%08lx\n",lastsect);
for(i=blkaddr;i<lastsect;i++) {
PRINTF("Reading block %d\n", i);
if (iso_dread(dev_desc, i, 1, (ulong *)tmpbuf) != 1)
return -1;
if(ppr->desctype==0x00)
break; /* boot entry found */
if(ppr->desctype==0xff) {
if(verb)
printf ("** No valid boot catalog found on %d:%d **\n",
dev_desc->devnum, part_num);
return (-1);
}
}
/* boot entry found */
if(strncmp(pbr->ident_str,"EL TORITO SPECIFICATION",23)!=0) {
if(verb)
printf ("** Wrong El Torito ident: %s on %d:%d **\n",
pbr->ident_str, dev_desc->devnum, part_num);
return (-1);
}
bootaddr = get_unaligned_le32(pbr->pointer);
PRINTF(" Boot Entry at: %08lX\n",bootaddr);
if (iso_dread(dev_desc, bootaddr, 1, (ulong *)tmpbuf) != 1) {
if(verb)
printf ("** Can't read Boot Entry at %lX on %d:%d **\n",
bootaddr, dev_desc->devnum, part_num);
return (-1);
}
chksum=0;
chksumbuf = (unsigned short *)tmpbuf;
for(i=0;i<0x10;i++)
chksum += le16_to_cpu(chksumbuf[i]);
if(chksum!=0) {
if(verb)
printf("** Checksum Error in booting catalog validation entry on %d:%d **\n",
dev_desc->devnum, part_num);
return (-1);
}
if((pve->key[0]!=0x55)||(pve->key[1]!=0xAA)) {
if(verb)
printf ("** Key 0x55 0xAA error on %d:%d **\n",
dev_desc->devnum, part_num);
return(-1);
}
#ifdef CHECK_FOR_POWERPC_PLATTFORM
if(pve->platform!=0x01) {
if(verb)
printf ("** No PowerPC platform CD on %d:%d **\n",
dev_desc->devnum, part_num);
return(-1);
}
#endif
/* the validation entry seems to be ok, now search the "partition" */
entry_num=1;
offset=0x20;
strcpy((char *)info->type, "U-Boot");
part_set_generic_name(dev_desc, part_num, (char *)info->name);
/* the bootcatalog (including validation Entry) is limited to 2048Bytes
* (63 boot entries + validation entry) */
while(offset<2048) {
pide=(iso_init_def_entry_t *)&tmpbuf[offset];
if ((pide->boot_ind==0x88) ||
(pide->boot_ind==0x00)) { /* Header Id for default Sections Entries */
if(entry_num==part_num) { /* part found */
goto found;
}
entry_num++; /* count partitions Entries (boot and non bootables */
offset+=0x20;
continue;
}
if ((pide->boot_ind==0x90) || /* Section Header Entry */
(pide->boot_ind==0x91) || /* Section Header Entry (last) */
(pide->boot_ind==0x44)) { /* Extension Indicator */
offset+=0x20; /* skip unused entries */
}
else {
if(verb)
printf ("** Partition %d not found on device %d **\n",
part_num, dev_desc->devnum);
return(-1);
}
}
/* if we reach this point entire sector has been
* searched w/o succsess */
if(verb)
printf ("** Partition %d not found on device %d **\n",
part_num, dev_desc->devnum);
return(-1);
found:
if(pide->boot_ind!=0x88) {
if(verb)
printf("** Partition %d is not bootable on device %d **\n",
part_num, dev_desc->devnum);
return (-1);
}
switch(pide->boot_media) {
case 0x00: /* no emulation */
info->size = get_unaligned_le16(pide->sec_cnt)>>2;
break;
case 0x01: info->size=2400>>2; break; /* 1.2MByte Floppy */
case 0x02: info->size=2880>>2; break; /* 1.44MByte Floppy */
case 0x03: info->size=5760>>2; break; /* 2.88MByte Floppy */
case 0x04: info->size=2880>>2; break; /* dummy (HD Emulation) */
default: info->size=0; break;
}
newblkaddr = get_unaligned_le32(pide->rel_block_addr);
info->start=newblkaddr;
if (dev_desc->blksz == 512) {
info->size *= 4;
info->start *= 4;
info->blksz = 512;
}
PRINTF(" part %d found @ %lx size %lx\n",part_num,info->start,info->size);
return 0;
}
static int part_get_info_iso(struct blk_desc *dev_desc, int part_num,
disk_partition_t *info)
{
return part_get_info_iso_verb(dev_desc, part_num, info, 0);
}
static void part_print_iso(struct blk_desc *dev_desc)
{
disk_partition_t info;
int i;
if (part_get_info_iso_verb(dev_desc, 1, &info, 0) == -1) {
printf("** No boot partition found on device %d **\n",
dev_desc->devnum);
return;
}
printf("Part Start Sect x Size Type\n");
i=1;
do {
printf(" %2d " LBAFU " " LBAFU " %6ld %.32s\n",
i, info.start, info.size, info.blksz, info.type);
i++;
} while (part_get_info_iso_verb(dev_desc, i, &info, 0) != -1);
}
static int part_test_iso(struct blk_desc *dev_desc)
{
disk_partition_t info;
return part_get_info_iso_verb(dev_desc, 1, &info, 0);
}
U_BOOT_PART_TYPE(iso) = {
.name = "ISO",
.part_type = PART_TYPE_ISO,
.max_entries = ISO_ENTRY_NUMBERS,
.get_info = part_get_info_iso,
.print = part_print_iso,
.test = part_test_iso,
};
#endif
@@ -0,0 +1,143 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* (C) Copyright 2001
* Denis Peter, MPL AG Switzerland, d.peter@mpl.ch.
*/
#ifndef _PART_CD_H
#define _PART_CD_H
#define BRVD 0x11
#define PVD_OFFSET 0x10
typedef struct iso_boot_rec {
unsigned char desctype; /* type of Volume descriptor: 0 = boot record, 1 = primary, 2 = Supplement, 3 = volume part 0xff trminator */
unsigned char stand_ident[5]; /* "CD001" */
unsigned char vers; /* Version */
char ident_str[0x20]; /* Ident String "EL TORITO SPECIFICATION" */
unsigned char unused[0x20]; /* unused */
unsigned char pointer[4]; /* absolute pointer to Boot Catalog */
} iso_boot_rec_t;
typedef struct iso_pri_rec {
unsigned char desctype; /* type of Volume descriptor: 0 = boot record, 1 = primary, 2 = Supplement, 3 = volume part 0xff trminator */
unsigned char stand_ident[5]; /* "CD001" */
unsigned char vers; /* Version */
unsigned char unused;
char sysid[32]; /* system Identifier */
char volid[32]; /* volume Identifier */
unsigned char zeros1[8]; /* unused */
unsigned int volsiz_LE; /* volume size Little Endian */
unsigned int volsiz_BE; /* volume size Big Endian */
unsigned char zeros2[32]; /* unused */
unsigned short setsize_LE; /* volume set size LE */
unsigned short setsize_BE; /* volume set size BE */
unsigned short seqnum_LE; /* volume sequence number LE */
unsigned short seqnum_BE; /* volume sequence number BE */
unsigned short secsize_LE; /* sector size LE */
unsigned short secsize_BE; /* sector size BE */
unsigned int pathtablen_LE;/* Path Table size LE */
unsigned int pathtablen_BE;/* Path Table size BE */
unsigned int firstsek_LEpathtab1_LE; /* location of first occurrence of little endian type path table */
unsigned int firstsek_LEpathtab2_LE; /* location of optional occurrence of little endian type path table */
unsigned int firstsek_BEpathtab1_BE; /* location of first occurrence of big endian type path table */
unsigned int firstsek_BEpathtab2_BE; /* location of optional occurrence of big endian type path table */
unsigned char rootdir[34]; /* directory record for root dir */
char volsetid[128];/* Volume set identifier */
char pubid[128]; /* Publisher identifier */
char dataprepid[128]; /* data preparer identifier */
char appid[128]; /* application identifier */
char copyr[37]; /* copyright string */
char abstractfileid[37]; /* abstract file identifier */
char bibliofileid[37]; /* bibliographic file identifier */
unsigned char creationdate[17]; /* creation date */
unsigned char modify[17]; /* modification date */
unsigned char expire[17]; /* expiring date */
unsigned char effective[17];/* effective date */
unsigned char filestruc_ver; /* file structur version */
} iso_pri_rec_t;
typedef struct iso_sup_rec {
unsigned char desctype; /* type of Volume descriptor: 0 = boot record, 1 = primary, 2 = Supplement, 3 = volume part 0xff trminator */
unsigned char stand_ident[5]; /* "CD001" */
unsigned char vers; /* Version */
unsigned char volumeflags; /* if bit 0 = 0 => all escape sequences are according ISO 2375 */
char sysid[32]; /* system Identifier */
char volid[32]; /* volume Identifier */
unsigned char zeros1[8]; /* unused */
unsigned int volsiz_LE; /* volume size Little Endian */
unsigned int volsiz_BE; /* volume size Big Endian */
unsigned char escapeseq[32];/* Escape sequences */
unsigned short setsize_LE; /* volume set size LE */
unsigned short setsize_BE; /* volume set size BE */
unsigned short seqnum_LE; /* volume sequence number LE */
unsigned short seqnum_BE; /* volume sequence number BE */
unsigned short secsize_LE; /* sector size LE */
unsigned short secsize_BE; /* sector size BE */
unsigned int pathtablen_LE;/* Path Table size LE */
unsigned int pathtablen_BE;/* Path Table size BE */
unsigned int firstsek_LEpathtab1_LE; /* location of first occurrence of little endian type path table */
unsigned int firstsek_LEpathtab2_LE; /* location of optional occurrence of little endian type path table */
unsigned int firstsek_BEpathtab1_BE; /* location of first occurrence of big endian type path table */
unsigned int firstsek_BEpathtab2_BE; /* location of optional occurrence of big endian type path table */
unsigned char rootdir[34]; /* directory record for root dir */
char volsetid[128];/* Volume set identifier */
char pubid[128]; /* Publisher identifier */
char dataprepid[128]; /* data preparer identifier */
char appid[128]; /* application identifier */
char copyr[37]; /* copyright string */
char abstractfileid[37]; /* abstract file identifier */
char bibliofileid[37]; /* bibliographic file identifier */
unsigned char creationdate[17]; /* creation date */
unsigned char modify[17]; /* modification date */
unsigned char expire[17]; /* expiring date */
unsigned char effective[17];/* effective date */
unsigned char filestruc_ver; /* file structur version */
}iso_sup_rec_t;
typedef struct iso_part_rec {
unsigned char desctype; /* type of Volume descriptor: 0 = boot record, 1 = primary, 2 = Supplement, 3 = volume part 0xff trminator */
unsigned char stand_ident[5]; /* "CD001" */
unsigned char vers; /* Version */
unsigned char unused;
char sysid[32]; /* system Identifier */
char volid[32]; /* volume partition Identifier */
unsigned int partloc_LE; /* volume partition location LE */
unsigned int partloc_BE; /* volume partition location BE */
unsigned int partsiz_LE; /* volume partition size LE */
unsigned int partsiz_BE; /* volume partition size BE */
}iso_part_rec_t;
typedef struct iso_val_entry {
unsigned char header_id; /* Header ID must be 0x01 */
unsigned char platform; /* Platform: 0=x86, 1=PowerPC, 2=MAC */
unsigned char res[2]; /* reserved */
char manu_str[0x18]; /* Ident String of manufacturer/developer */
unsigned char chk_sum[2]; /* Check sum (all words must be zero) */
unsigned char key[2]; /* key[0]=55, key[1]=0xAA */
} iso_val_entry_t;
typedef struct iso_header_entry {
unsigned char header_id; /* Header ID must be 0x90 or 0x91 */
unsigned char platform; /* Platform: 0=x86, 1=PowerPC, 2=MAC */
unsigned char numentry[2]; /* number of entries */
char id_str[0x1C]; /* Ident String of sectionr */
} iso_header_entry_t;
typedef struct iso_init_def_entry {
unsigned char boot_ind; /* Boot indicator 0x88=bootable 0=not bootable */
unsigned char boot_media; /* boot Media Type: 0=no Emulation, 1=1.2MB floppy, 2=1.44MB floppy, 3=2.88MB floppy 4=hd (0x80) */
unsigned char ld_seg[2]; /* Load segment (flat model=addr/10) */
unsigned char systype; /* System Type copy of byte5 of part table */
unsigned char res; /* reserved */
unsigned char sec_cnt[2]; /* sector count in VIRTUAL Blocks (0x200) */
unsigned char rel_block_addr[4]; /* relative Block address */
} iso_init_def_entry_t;
void print_partition_cd(int dev);
#endif /* _PART_CD_H */
@@ -0,0 +1,248 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* (C) Copyright 2000
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*/
/*
* Support for harddisk partitions.
*
* To be compatible with LinuxPPC and Apple we use the standard Apple
* SCSI disk partitioning scheme. For more information see:
* http://developer.apple.com/techpubs/mac/Devices/Devices-126.html#MARKER-14-92
*/
#include <common.h>
#include <command.h>
#include <memalign.h>
#include <ide.h>
#include "part_mac.h"
#ifdef CONFIG_HAVE_BLOCK_DEVICE
/* stdlib.h causes some compatibility problems; should fixe these! -- wd */
#ifndef __ldiv_t_defined
typedef struct {
long int quot; /* Quotient */
long int rem; /* Remainder */
} ldiv_t;
extern ldiv_t ldiv (long int __numer, long int __denom);
# define __ldiv_t_defined 1
#endif
static int part_mac_read_ddb(struct blk_desc *dev_desc,
mac_driver_desc_t *ddb_p);
static int part_mac_read_pdb(struct blk_desc *dev_desc, int part,
mac_partition_t *pdb_p);
/*
* Test for a valid MAC partition
*/
static int part_test_mac(struct blk_desc *dev_desc)
{
ALLOC_CACHE_ALIGN_BUFFER(mac_driver_desc_t, ddesc, 1);
ALLOC_CACHE_ALIGN_BUFFER(mac_partition_t, mpart, 1);
ulong i, n;
if (part_mac_read_ddb (dev_desc, ddesc)) {
/*
* error reading Driver Descriptor Block,
* or no valid Signature
*/
return (-1);
}
n = 1; /* assuming at least one partition */
for (i=1; i<=n; ++i) {
if ((blk_dread(dev_desc, i, 1, (ulong *)mpart) != 1) ||
(mpart->signature != MAC_PARTITION_MAGIC) ) {
return (-1);
}
/* update partition count */
n = mpart->map_count;
}
return (0);
}
static void part_print_mac(struct blk_desc *dev_desc)
{
ulong i, n;
ALLOC_CACHE_ALIGN_BUFFER(mac_driver_desc_t, ddesc, 1);
ALLOC_CACHE_ALIGN_BUFFER(mac_partition_t, mpart, 1);
ldiv_t mb, gb;
if (part_mac_read_ddb (dev_desc, ddesc)) {
/*
* error reading Driver Descriptor Block,
* or no valid Signature
*/
return;
}
n = ddesc->blk_count;
mb = ldiv(n, ((1024 * 1024) / ddesc->blk_size)); /* MB */
/* round to 1 digit */
mb.rem *= 10 * ddesc->blk_size;
mb.rem += 512 * 1024;
mb.rem /= 1024 * 1024;
gb = ldiv(10 * mb.quot + mb.rem, 10240);
gb.rem += 512;
gb.rem /= 1024;
printf ("Block Size=%d, Number of Blocks=%d, "
"Total Capacity: %ld.%ld MB = %ld.%ld GB\n"
"DeviceType=0x%x, DeviceId=0x%x\n\n"
" #: type name"
" length base (size)\n",
ddesc->blk_size,
ddesc->blk_count,
mb.quot, mb.rem, gb.quot, gb.rem,
ddesc->dev_type, ddesc->dev_id
);
n = 1; /* assuming at least one partition */
for (i=1; i<=n; ++i) {
ulong bytes;
char c;
printf ("%4ld: ", i);
if (blk_dread(dev_desc, i, 1, (ulong *)mpart) != 1) {
printf ("** Can't read Partition Map on %d:%ld **\n",
dev_desc->devnum, i);
return;
}
if (mpart->signature != MAC_PARTITION_MAGIC) {
printf("** Bad Signature on %d:%ld - expected 0x%04x, got 0x%04x\n",
dev_desc->devnum, i, MAC_PARTITION_MAGIC,
mpart->signature);
return;
}
/* update partition count */
n = mpart->map_count;
c = 'k';
bytes = mpart->block_count;
bytes /= (1024 / ddesc->blk_size); /* kB; assumes blk_size == 512 */
if (bytes >= 1024) {
bytes >>= 10;
c = 'M';
}
if (bytes >= 1024) {
bytes >>= 10;
c = 'G';
}
printf ("%20.32s %-18.32s %10u @ %-10u (%3ld%c)\n",
mpart->type,
mpart->name,
mpart->block_count,
mpart->start_block,
bytes, c
);
}
return;
}
/*
* Read Device Descriptor Block
*/
static int part_mac_read_ddb(struct blk_desc *dev_desc,
mac_driver_desc_t *ddb_p)
{
if (blk_dread(dev_desc, 0, 1, (ulong *)ddb_p) != 1) {
debug("** Can't read Driver Descriptor Block **\n");
return (-1);
}
if (ddb_p->signature != MAC_DRIVER_MAGIC) {
return (-1);
}
return (0);
}
/*
* Read Partition Descriptor Block
*/
static int part_mac_read_pdb(struct blk_desc *dev_desc, int part,
mac_partition_t *pdb_p)
{
int n = 1;
for (;;) {
/*
* We must always read the descritpor block for
* partition 1 first since this is the only way to
* know how many partitions we have.
*/
if (blk_dread(dev_desc, n, 1, (ulong *)pdb_p) != 1) {
printf ("** Can't read Partition Map on %d:%d **\n",
dev_desc->devnum, n);
return (-1);
}
if (pdb_p->signature != MAC_PARTITION_MAGIC) {
printf("** Bad Signature on %d:%d: expected 0x%04x, got 0x%04x\n",
dev_desc->devnum, n, MAC_PARTITION_MAGIC,
pdb_p->signature);
return (-1);
}
if (n == part)
return (0);
if ((part < 1) || (part > pdb_p->map_count)) {
printf ("** Invalid partition %d:%d [%d:1...%d:%d only]\n",
dev_desc->devnum, part,
dev_desc->devnum,
dev_desc->devnum, pdb_p->map_count);
return (-1);
}
/* update partition count */
n = part;
}
/* NOTREACHED */
}
static int part_get_info_mac(struct blk_desc *dev_desc, int part,
disk_partition_t *info)
{
ALLOC_CACHE_ALIGN_BUFFER(mac_driver_desc_t, ddesc, 1);
ALLOC_CACHE_ALIGN_BUFFER(mac_partition_t, mpart, 1);
if (part_mac_read_ddb (dev_desc, ddesc)) {
return (-1);
}
info->blksz = ddesc->blk_size;
if (part_mac_read_pdb (dev_desc, part, mpart)) {
return (-1);
}
info->start = mpart->start_block;
info->size = mpart->block_count;
memcpy (info->type, mpart->type, sizeof(info->type));
memcpy (info->name, mpart->name, sizeof(info->name));
return (0);
}
U_BOOT_PART_TYPE(mac) = {
.name = "MAC",
.part_type = PART_TYPE_MAC,
.max_entries = MAC_ENTRY_NUMBERS,
.get_info = part_get_info_mac,
.print = part_print_mac,
.test = part_test_mac,
};
#endif
@@ -0,0 +1,82 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* (C) Copyright 2000
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*/
/*
* See also Linux sources, fs/partitions/mac.h
*
* This file describes structures and values related to the standard
* Apple SCSI disk partitioning scheme. For more information see:
* http://developer.apple.com/techpubs/mac/Devices/Devices-126.html#MARKER-14-92
*/
#ifndef _DISK_PART_MAC_H
#define _DISK_PART_MAC_H
#define MAC_DRIVER_MAGIC 0x4552
/*
* Driver Descriptor Structure, in block 0.
* This block is (and shall remain) 512 bytes long.
* Note that there is an alignment problem for the driver descriptor map!
*/
typedef struct mac_driver_desc {
__u16 signature; /* expected to be MAC_DRIVER_MAGIC */
__u16 blk_size; /* block size of device */
__u32 blk_count; /* number of blocks on device */
__u16 dev_type; /* device type */
__u16 dev_id; /* device id */
__u32 data; /* reserved */
__u16 drvr_cnt; /* number of driver descriptor entries */
__u16 drvr_map[247]; /* driver descriptor map */
} mac_driver_desc_t;
/*
* Device Driver Entry
* (Cannot be included in mac_driver_desc because of alignment problems)
*/
typedef struct mac_driver_entry {
__u32 block; /* block number of starting block */
__u16 size; /* size of driver, in 512 byte blocks */
__u16 type; /* OS Type */
} mac_driver_entry_t;
#define MAC_PARTITION_MAGIC 0x504d
/* type field value for A/UX or other Unix partitions */
#define APPLE_AUX_TYPE "Apple_UNIX_SVR2"
/*
* Each Partition Map entry (in blocks 1 ... N) has this format:
*/
typedef struct mac_partition {
__u16 signature; /* expected to be MAC_PARTITION_MAGIC */
__u16 sig_pad; /* reserved */
__u32 map_count; /* # blocks in partition map */
__u32 start_block; /* abs. starting block # of partition */
__u32 block_count; /* number of blocks in partition */
uchar name[32]; /* partition name */
uchar type[32]; /* string type description */
__u32 data_start; /* rel block # of first data block */
__u32 data_count; /* number of data blocks */
__u32 status; /* partition status bits */
__u32 boot_start; /* first block of boot code */
__u32 boot_size; /* size of boot code, in bytes */
__u32 boot_load; /* boot code load address */
__u32 boot_load2; /* reserved */
__u32 boot_entry; /* boot code entry point */
__u32 boot_entry2; /* reserved */
__u32 boot_cksum; /* boot code checksum */
uchar processor[16]; /* Type of Processor */
__u16 part_pad[188]; /* reserved */
#if CONFIG_IS_ENABLED(ISO_PARTITION)
uchar iso_dummy[2048];/* Reservere enough room for an ISO partition block to fit */
#endif
} mac_partition_t;
#define MAC_STATUS_BOOTABLE 8 /* partition is bootable */
#endif /* _DISK_PART_MAC_H */