426 lines
17 KiB
C
426 lines
17 KiB
C
/*
|
|
* Copyright (c) 2008-2012 Apple Inc. All rights reserved.
|
|
*
|
|
* This document is the property of Apple Inc.
|
|
* It is considered confidential and proprietary.
|
|
*
|
|
* This document may not be reproduced or transmitted in any form,
|
|
* in whole or in part, without the express written permission of
|
|
* Apple Inc.
|
|
*/
|
|
|
|
/* ========================================================================== */
|
|
|
|
/*!
|
|
@header nand_part
|
|
|
|
@abstract definition of device-resident persistent partition table
|
|
|
|
@copyright Apple Inc.
|
|
|
|
@updated 2012-02-21
|
|
*/
|
|
|
|
/* ========================================================================== */
|
|
|
|
#ifndef _NAND_PART_H
|
|
#define _NAND_PART_H
|
|
|
|
#include <sys/types.h>
|
|
|
|
__BEGIN_DECLS
|
|
|
|
|
|
// =============================================================================
|
|
// feature introduction version history
|
|
|
|
#define kNandPartFeatureInitialVersionMajor ((uint32_t)0x00000000)
|
|
#define kNandPartFeatureFBBTCacheVersionMajor ((uint32_t)0x00000000)
|
|
#define kNandPartFeatureEffaceableVersionMajor ((uint32_t)0x00000000)
|
|
#define kNandPartFeatureIgnoreFBBTVersionMajor ((uint32_t)0x00000000)
|
|
#define kNandPartFeatureTrimDeviceVersionMajor ((uint32_t)0x00000000)
|
|
#define kNandPartFeatureFuneralDirgeVersionMajor ((uint32_t)0x00000000)
|
|
#define kNandPartFeatureCleanEntryFlagsVersionMajor ((uint32_t)0x00000000)
|
|
#define kNandPartFeaturePortableCoreVersionMajor ((uint32_t)0x00000000)
|
|
#define kNandPartFeaturePoolPartitionVersionMajor ((uint32_t)0x00000001)
|
|
|
|
#define kNandPartFeatureInitialVersionMinor ((uint32_t)0x00000001)
|
|
#define kNandPartFeatureFBBTCacheVersionMinor ((uint32_t)0x00000002)
|
|
#define kNandPartFeatureEffaceableVersionMinor ((uint32_t)0x00000003)
|
|
#define kNandPartFeatureIgnoreFBBTVersionMinor ((uint32_t)0x00000004)
|
|
#define kNandPartFeatureTrimDeviceVersionMinor ((uint32_t)0x00000005)
|
|
#define kNandPartFeatureFuneralDirgeVersionMinor ((uint32_t)0x00000006)
|
|
#define kNandPartFeatureCleanEntryFlagsVersionMinor ((uint32_t)0x00000007)
|
|
#define kNandPartFeaturePortableCoreVersionMinor ((uint32_t)0x00000008)
|
|
#define kNandPartFeaturePoolPartitionVersionMinor ((uint32_t)0x00000009)
|
|
|
|
|
|
// =============================================================================
|
|
// release version history - for historical reference only
|
|
|
|
#define kNandPartReleaseNorthstarVersionMajor kNandPartFeatureFBBTCacheVersionMajor
|
|
#define kNandPartReleaseNorthstarVersionMinor kNandPartFeatureFBBTCacheVersionMinor
|
|
|
|
#define kNandPartReleaseNorthstar2VersionMajor kNandPartFeatureFBBTCacheVersionMajor
|
|
#define kNandPartReleaseNorthstar2VersionMinor kNandPartFeatureFBBTCacheVersionMinor
|
|
|
|
#define kNandPartReleaseApexVersionMajor kNandPartFeatureIgnoreFBBTVersionMajor
|
|
#define kNandPartReleaseApexVersionMinor kNandPartFeatureIgnoreFBBTVersionMinor
|
|
|
|
#define kNandPartReleaseBakerVersionMajor kNandPartFeatureFuneralDirgeVersionMajor
|
|
#define kNandPartReleaseBakerVersionMinor kNandPartFeatureFuneralDirgeVersionMinor
|
|
|
|
#define kNandPartReleaseDurangoVersionMajor kNandPartFeatureFuneralDirgeVersionMajor
|
|
#define kNandPartReleaseDurangoVersionMinor kNandPartFeatureFuneralDirgeVersionMinor
|
|
|
|
#define kNandPartReleaseTellurideVersionMajor kNandPartFeatureFuneralDirgeVersionMajor
|
|
#define kNandPartReleaseTellurideVersionMinor kNandPartFeatureFuneralDirgeVersionMinor
|
|
|
|
#define kNandPartReleaseHoodooVersionMajor kNandPartFeatureFuneralDirgeVersionMajor
|
|
#define kNandPartReleaseHoodooVersionMinor kNandPartFeatureFuneralDirgeVersionMinor
|
|
|
|
#define kNandPartReleaseSundanceVersionMajor kNandPartFeaturePoolPartitionVersionMajor
|
|
#define kNandPartReleaseSundanceVersionMinor kNandPartFeaturePoolPartitionVersionMinor
|
|
|
|
|
|
// =============================================================================
|
|
// general constants
|
|
|
|
#define kNandPartSectorSize 512
|
|
#define kNandPartSectorsPerPage 3
|
|
#define kNandPartPageSize (kNandPartSectorSize * kNandPartSectorsPerPage)
|
|
#define kNandPartBankMax 16
|
|
|
|
|
|
// =============================================================================
|
|
// partition header
|
|
|
|
typedef struct _NandPartHeader {
|
|
|
|
uint32_t magic;
|
|
uint32_t should_be_zero;
|
|
uint32_t versionMajor;
|
|
uint32_t versionMinor;
|
|
uint32_t generation;
|
|
uint8_t reserved[12];
|
|
|
|
} __attribute__((__packed__)) NandPartHeader;
|
|
|
|
#define kNandPartHeaderMagic 'Grdn'
|
|
|
|
#define kNandPartHeaderVersionMajor kNandPartReleaseSundanceVersionMajor
|
|
#define kNandPartHeaderVersionMinor kNandPartReleaseSundanceVersionMinor
|
|
|
|
#define kNandPartHeaderMaxSize (kNandPartSectorSize / 16)
|
|
|
|
|
|
// =============================================================================
|
|
// partition factory BBT cache
|
|
|
|
typedef struct _NandPartFBBTCacheInfo {
|
|
|
|
uint32_t blockDepth;
|
|
uint32_t entryCount;
|
|
|
|
} __attribute__((__packed__)) NandPartFBBTCacheInfo;
|
|
|
|
#define kNandPartFBBTCacheMaxSize (kNandPartSectorSize - kNandPartHeaderMaxSize)
|
|
#define kNandPartFBBTCacheEntriesMaxSize (kNandPartFBBTCacheMaxSize - sizeof(NandPartFBBTCacheInfo))
|
|
|
|
typedef struct _NandPartFBBTCacheEntry {
|
|
|
|
uint32_t bankNum;
|
|
uint32_t blockAddr;
|
|
|
|
} __attribute__((__packed__)) NandPartFBBTCacheEntry;
|
|
|
|
#define kNandPartFBBTCacheEntryCount (kNandPartFBBTCacheEntriesMaxSize / sizeof(NandPartFBBTCacheEntry))
|
|
|
|
typedef struct _NandPartFBBTCache {
|
|
|
|
NandPartFBBTCacheInfo info;
|
|
NandPartFBBTCacheEntry entries[kNandPartFBBTCacheEntryCount];
|
|
|
|
} __attribute__((__packed__)) NandPartFBBTCache;
|
|
|
|
|
|
// =============================================================================
|
|
// partition device info
|
|
|
|
typedef struct _NandPartDevice {
|
|
|
|
uint32_t should_be_zero[2];
|
|
uint32_t should_be_one;
|
|
|
|
uint32_t numOfCS;
|
|
uint32_t blocksPerCS;
|
|
uint32_t pagesPerBlock;
|
|
uint32_t sectorsPerPage;
|
|
uint32_t spareBytesPerPage;
|
|
|
|
uint32_t flags;
|
|
|
|
} __attribute__((__packed__)) NandPartDevice;
|
|
|
|
#define kNandPartDeviceFlagNone ((uint32_t)0x00000000)
|
|
#define kNandPartDeviceFlagNeedsCemetery (((uint32_t)0x1) << 0)
|
|
#define kNandPartDeviceFlagExplicitEntries (((uint32_t)0x1) << 1)
|
|
#define kNandPartDeviceFlagAllowPool (((uint32_t)0x1) << 2)
|
|
|
|
|
|
// =============================================================================
|
|
// cemetery
|
|
//
|
|
// Where bad blocks go to die.
|
|
|
|
#define kNandPartCemeteryGate ((uint32_t) 0xDeadCafe)
|
|
#define kNandPartCemeteryCapacity 256
|
|
#define nandPartCemeteryPlotsSize(capacity) (((capacity) / 8) + (((capacity) % 8) ? 1 : 0))
|
|
#define kNandPartCemeteryPlotsSize nandPartCemeteryPlotsSize(kNandPartCemeteryCapacity)
|
|
|
|
typedef struct _NandPartCemetery {
|
|
|
|
uint32_t gate;
|
|
uint16_t capacity;
|
|
uint8_t flags;
|
|
uint8_t reserved[3];
|
|
uint8_t plots[kNandPartCemeteryPlotsSize];
|
|
uint8_t locks[2];
|
|
|
|
} __attribute__((__packed__)) NandPartCemetery;
|
|
|
|
#define kNandPartCemeteryFlagIgnoreLocks ((uint8_t)0x01)
|
|
|
|
|
|
// =============================================================================
|
|
// spare blocks
|
|
|
|
#define kNandPartSpareMaxCount 64
|
|
#define kNandPartSpareMagic 'spAr'
|
|
|
|
typedef struct _NandPartSpareLocation {
|
|
|
|
uint8_t block[3];
|
|
uint8_t ce;
|
|
|
|
} __attribute__((__packed__)) NandPartSpareLocation;
|
|
|
|
typedef struct _NandPartSpare {
|
|
|
|
uint32_t magic;
|
|
uint16_t count;
|
|
uint8_t flags;
|
|
uint8_t reserved[3];
|
|
NandPartSpareLocation locations[kNandPartSpareMaxCount];
|
|
uint8_t checks[2];
|
|
|
|
} __attribute__((__packed__)) NandPartSpare;
|
|
|
|
#define kNandPartSpareFlagIgnoreChecks ((uint8_t)0x01)
|
|
#define kNandPartSpareMinExtraCount 4
|
|
|
|
|
|
// =============================================================================
|
|
// block substitutions
|
|
|
|
#define kNandPartSubstMaxCount kNandPartSpareMaxCount
|
|
#define kNandPartSubstMagic 'subs'
|
|
|
|
typedef struct _NandPartSubst {
|
|
|
|
uint32_t magic;
|
|
uint16_t count;
|
|
uint8_t flags;
|
|
uint8_t reserved[3];
|
|
uint8_t maps[kNandPartSubstMaxCount];
|
|
uint8_t checks[2];
|
|
|
|
} __attribute__((__packed__)) NandPartSubst;
|
|
|
|
#define kNandPartSubstFlagIgnoreChecks ((uint8_t)0x01)
|
|
#define kNandPartSubstFlagCorrectedChecks ((uint8_t)0x02)
|
|
|
|
|
|
// =============================================================================
|
|
// unused
|
|
|
|
#define kNandPartUnusedSize (kNandPartSectorSize \
|
|
- sizeof(NandPartDevice) \
|
|
- sizeof(NandPartCemetery) \
|
|
- sizeof(NandPartSpare) \
|
|
- sizeof(NandPartSubst))
|
|
|
|
|
|
// =============================================================================
|
|
// partition content
|
|
|
|
#define kNandPartContentUndefined 0x00000000
|
|
#define kNandPartContentNone 'none'
|
|
#define kNandPartContentBootBlock 'boot'
|
|
#define kNandPartContentDiagData 'diag'
|
|
#define kNandPartContentSyscfg 'scfg'
|
|
#define kNandPartContentFirmware 'firm'
|
|
#define kNandPartContentNVRAM 'nvrm'
|
|
#define kNandPartContentFilesystem 'fsys'
|
|
#define kNandPartContentEffaceable 'plog'
|
|
#define kNandPartContentBadBlockTable 'fbbt'
|
|
#define kNandPartContentErased 0xFFFFFFFF
|
|
|
|
#define kNandPartContentNameUnformatted "Unformatted"
|
|
#define kNandPartContentNameUnallocated "Unallocated"
|
|
#define kNandPartContentNameUnrecognized "Unrecognized"
|
|
#define kNandPartContentNameBootBlock "Boot Block"
|
|
#define kNandPartContentNameDiagData "Diagnostic Data"
|
|
#define kNandPartContentNameSyscfg "System Config"
|
|
#define kNandPartContentNameNVRAM "NVRAM"
|
|
#define kNandPartContentNameFirmware "Firmware"
|
|
#define kNandPartContentNameFilesystem "Filesystem"
|
|
#define kNandPartContentNameEffaceable "Effaceable"
|
|
#define kNandPartContentNameBadBlockTable "Bad Block Table"
|
|
|
|
|
|
// =============================================================================
|
|
// partition entry
|
|
|
|
typedef struct _NandPartEntryInfo {
|
|
|
|
uint32_t content;
|
|
uint32_t reserved_0;
|
|
uint32_t reserved_1;
|
|
uint32_t flags;
|
|
|
|
} __attribute__((__packed__)) NandPartEntryInfo;
|
|
|
|
typedef struct _NandPartEntrySlice {
|
|
|
|
uint32_t content;
|
|
uint32_t offset;
|
|
uint32_t depth;
|
|
uint32_t flags;
|
|
|
|
} __attribute__((__packed__)) NandPartEntrySlice;
|
|
|
|
typedef struct _NandPartEntryPool {
|
|
|
|
uint32_t content;
|
|
uint32_t width;
|
|
uint32_t depth;
|
|
uint32_t flags;
|
|
|
|
} __attribute__((__packed__)) NandPartEntryPool;
|
|
|
|
typedef union _NandPartEntry {
|
|
|
|
struct {
|
|
|
|
uint32_t content;
|
|
uint32_t reserved_0;
|
|
uint32_t reserved_1;
|
|
uint32_t flags;
|
|
|
|
} __attribute__((__packed__));
|
|
|
|
NandPartEntryInfo info;
|
|
NandPartEntrySlice slice;
|
|
NandPartEntryPool pool;
|
|
|
|
} NandPartEntry;
|
|
|
|
#define kNandPartEntryMaxCount (kNandPartSectorSize / sizeof(NandPartEntry))
|
|
|
|
#define kNandPartEntryFlagsNone 0x00000000
|
|
|
|
#define kNandPartEntryFlagsTypeInfo 0x00000001
|
|
#define kNandPartEntryFlagsTypeSlice 0x00000002
|
|
#define kNandPartEntryFlagsTypePool 0x00000008
|
|
#define kNandPartEntryFlagsUnpartitioned 0x80000000
|
|
|
|
#define kNandPartEntryFlagsTypeMask (kNandPartEntryFlagsTypeInfo | \
|
|
kNandPartEntryFlagsTypeSlice | \
|
|
kNandPartEntryFlagsTypePool | \
|
|
kNandPartEntryFlagsUnpartitioned)
|
|
|
|
#define kNandPartEntryFlagsIsBulk 0x00000004
|
|
#define kNandPartEntryFlagsUsingSLCBlocks 0x00000100
|
|
#define kNandPartEntryFlagsUsingFullPages 0x00000200
|
|
#define kNandPartEntryFlagsIgnoreFBBT 0x40000000
|
|
|
|
#define kNandPartEntryFlagsMiscMask (kNandPartEntryFlagsIsBulk | \
|
|
kNandPartEntryFlagsUsingSLCBlocks | \
|
|
kNandPartEntryFlagsUsingFullPages | \
|
|
kNandPartEntryFlagsIgnoreFBBT)
|
|
|
|
#define kNandPartEntryFlagsMask (kNandPartEntryFlagsTypeMask | \
|
|
kNandPartEntryFlagsMiscMask)
|
|
|
|
|
|
// =============================================================================
|
|
// partition table
|
|
|
|
typedef struct _NandPartTable {
|
|
|
|
NandPartHeader header;
|
|
NandPartFBBTCache fbbtCache;
|
|
NandPartDevice device;
|
|
NandPartCemetery cemetery;
|
|
NandPartSpare spare;
|
|
NandPartSubst subst;
|
|
uint8_t unused[kNandPartUnusedSize];
|
|
NandPartEntry entries[kNandPartEntryMaxCount];
|
|
|
|
} __attribute__((__packed__)) NandPartTable;
|
|
|
|
#define kNandPartTableLayoutIsValid (sizeof(NandPartTable) == kNandPartPageSize)
|
|
#define kNandPartTableCopies 2
|
|
|
|
|
|
// =============================================================================
|
|
// partition table incremental differences
|
|
//
|
|
// incremental difference information about the current partition
|
|
// table state that is stored in metadata of other on-nand containers
|
|
// (e.g. nvram, effaceable) rather than in partition table itself
|
|
|
|
typedef struct _NandPartDiffHeader {
|
|
|
|
uint32_t magic;
|
|
uint16_t size;
|
|
uint16_t sequence;
|
|
uint32_t versionMajor;
|
|
uint32_t versionMinor;
|
|
uint32_t generation;
|
|
uint16_t flags;
|
|
uint8_t reserved[10];
|
|
|
|
} __attribute__((__packed__)) NandPartDiffHeader;
|
|
|
|
typedef struct _NandPartDiff {
|
|
|
|
NandPartDiffHeader header;
|
|
NandPartCemetery cemetery;
|
|
uint8_t checks[2];
|
|
|
|
} __attribute__((__packed__)) NandPartDiff;
|
|
|
|
#define kNandPartDiffMagic 'Diff'
|
|
#define kNandPartDiffFlagIgnoreChecks ((uint16_t)0x0001)
|
|
|
|
|
|
// =============================================================================
|
|
// boot loader
|
|
|
|
#define kNandPartLoaderPageCount 128
|
|
#define kNandPartLoaderMaxPages (kNandPartLoaderPageCount - kNandPartTableCopies - 1)
|
|
#define kNandPartLoaderMaxSize (kNandPartLoaderMaxPages * kNandPartPageSize)
|
|
|
|
|
|
// =============================================================================
|
|
// generally useful macros
|
|
|
|
#define isMaskSet(_msk, _val) ((_msk) == ((_msk) & (_val)))
|
|
|
|
|
|
__END_DECLS
|
|
|
|
#endif /* ! _NAND_PART_H */
|