From 39d7bd7707d9fac76617940c1d3b4e9afba9e7b8 Mon Sep 17 00:00:00 2001 From: linzhenxing Date: Thu, 5 May 2022 16:30:11 +0800 Subject: [PATCH 1/5] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E7=A3=81=E7=9B=98?= =?UTF-8?q?=E5=88=86=E5=8C=BA=E6=A0=BC=E5=BC=8F=20gpt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- components/drivers/include/drivers/gpt.h | 121 ++++ .../drivers/include/drivers/mmcsd_card.h | 1 + .../drivers/include/drivers/mmcsd_core.h | 3 + components/drivers/sdio/SConscript | 1 + components/drivers/sdio/block_dev.c | 219 +++++-- components/drivers/sdio/gpt.c | 558 ++++++++++++++++++ components/drivers/sdio/mmc.c | 5 +- components/drivers/sdio/sd.c | 3 +- 8 files changed, 847 insertions(+), 64 deletions(-) create mode 100644 components/drivers/include/drivers/gpt.h create mode 100644 components/drivers/sdio/gpt.c diff --git a/components/drivers/include/drivers/gpt.h b/components/drivers/include/drivers/gpt.h new file mode 100644 index 0000000000..9956405575 --- /dev/null +++ b/components/drivers/include/drivers/gpt.h @@ -0,0 +1,121 @@ +#ifndef __GPT_H +#define __GPT_H +#include +#include +typedef struct +{ + uint8_t b[16]; +} guid_t; + +#define MSDOS_MBR_SIGNATURE 0xaa55 +#define EFI_PMBR_OSTYPE_EFI 0xEF +#define EFI_PMBR_OSTYPE_EFI_GPT 0xEE + +#define GPT_MBR_PROTECTIVE 1 +#define GPT_MBR_HYBRID 2 + +#define GPT_HEADER_SIGNATURE 0x5452415020494645ULL +#define GPT_HEADER_REVISION_V1 0x00010000 +#define GPT_PRIMARY_PARTITION_TABLE_LBA 1 + +typedef guid_t gpt_guid_t __attribute__ ((aligned (4))); +#define EFI_GUID(a, b, c, d...) (gpt_guid_t){ { \ + (a) & 0xff, ((a) >> 8) & 0xff, ((a) >> 16) & 0xff, ((a) >> 24) & 0xff, \ + (b) & 0xff, ((b) >> 8) & 0xff, \ + (c) & 0xff, ((c) >> 8) & 0xff, d } } + +#define NULL_GUID \ + EFI_GUID(0x00000000, 0x0000, 0x0000,\ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00) +#define PARTITION_SYSTEM_GUID \ + EFI_GUID( 0xC12A7328, 0xF81F, 0x11d2, \ + 0xBA, 0x4B, 0x00, 0xA0, 0xC9, 0x3E, 0xC9, 0x3B) +#define LEGACY_MBR_PARTITION_GUID \ + EFI_GUID( 0x024DEE41, 0x33E7, 0x11d3, \ + 0x9D, 0x69, 0x00, 0x08, 0xC7, 0x81, 0xF3, 0x9F) +#define PARTITION_MSFT_RESERVED_GUID \ + EFI_GUID( 0xE3C9E316, 0x0B5C, 0x4DB8, \ + 0x81, 0x7D, 0xF9, 0x2D, 0xF0, 0x02, 0x15, 0xAE) +#define PARTITION_BASIC_DATA_GUID \ + EFI_GUID( 0xEBD0A0A2, 0xB9E5, 0x4433, \ + 0x87, 0xC0, 0x68, 0xB6, 0xB7, 0x26, 0x99, 0xC7) +#define PARTITION_LINUX_RAID_GUID \ + EFI_GUID( 0xa19d880f, 0x05fc, 0x4d3b, \ + 0xa0, 0x06, 0x74, 0x3f, 0x0f, 0x84, 0x91, 0x1e) +#define PARTITION_LINUX_SWAP_GUID \ + EFI_GUID( 0x0657fd6d, 0xa4ab, 0x43c4, \ + 0x84, 0xe5, 0x09, 0x33, 0xc8, 0x4b, 0x4f, 0x4f) +#define PARTITION_LINUX_LVM_GUID \ + EFI_GUID( 0xe6d6d379, 0xf507, 0x44c2, \ + 0xa2, 0x3c, 0x23, 0x8f, 0x2a, 0x3d, 0xf9, 0x28) +#pragma pack(push, 1) +typedef struct _gpt_header +{ + uint64_t signature; + uint32_t revision; + uint32_t header_size; + uint32_t header_crc32; + uint32_t reserved1; + uint64_t my_lba; + uint64_t alternate_lba; + uint64_t first_usable_lba; + uint64_t last_usable_lba; + gpt_guid_t disk_guid; + uint64_t partition_entry_lba; + uint32_t num_partition_entries; + uint32_t sizeof_partition_entry; + uint32_t partition_entry_array_crc32; + + /* The rest of the logical block is reserved by UEFI and must be zero. + * EFI standard handles this by: + * + * uint8_t reserved2[ BlockSize - 92 ]; + */ +} gpt_header; + +typedef struct _gpt_entry_attributes +{ + uint64_t required_to_function:1; + uint64_t reserved:47; + uint64_t type_guid_specific:16; +} gpt_entry_attributes; + +typedef struct _gpt_entry +{ + gpt_guid_t partition_type_guid; + gpt_guid_t unique_partition_guid; + uint64_t starting_lba; + uint64_t ending_lba; + gpt_entry_attributes attributes; + uint16_t partition_name[72/sizeof(uint16_t)]; +} gpt_entry; + +typedef struct _gpt_mbr_record +{ + uint8_t boot_indicator; /* unused by EFI, set to 0x80 for bootable */ + uint8_t start_head; /* unused by EFI, pt start in CHS */ + uint8_t start_sector; /* unused by EFI, pt start in CHS */ + uint8_t start_track; + uint8_t os_type; /* EFI and legacy non-EFI OS types */ + uint8_t end_head; /* unused by EFI, pt end in CHS */ + uint8_t end_sector; /* unused by EFI, pt end in CHS */ + uint8_t end_track; /* unused by EFI, pt end in CHS */ + uint32_t starting_lba; /* used by EFI - start addr of the on disk pt */ + uint32_t size_in_lba; /* used by EFI - size of pt in LBA */ +} gpt_mbr_record; + + +typedef struct _legacy_mbr +{ + uint8_t boot_code[440]; + uint32_t unique_mbr_signature; + uint16_t unknown; + gpt_mbr_record partition_record[4]; + uint16_t signature; +} legacy_mbr; +#pragma pack(pop) + +int check_gpt(struct rt_mmcsd_card *card); +int get_partition_param(struct rt_mmcsd_card *card, struct dfs_partition *part, uint32_t pindex); +void gpt_free(); +#endif /*__GPT_H*/ diff --git a/components/drivers/include/drivers/mmcsd_card.h b/components/drivers/include/drivers/mmcsd_card.h index 3ee5a20465..ea2de15ca5 100644 --- a/components/drivers/include/drivers/mmcsd_card.h +++ b/components/drivers/include/drivers/mmcsd_card.h @@ -141,6 +141,7 @@ struct rt_mmcsd_card { rt_uint32_t max_data_rate; /* max data transfer rate */ rt_uint32_t card_capacity; /* card capacity, unit:KB */ rt_uint32_t card_blksize; /* card block size */ + rt_uint32_t card_sec_cnt; /* card sector count*/ rt_uint32_t erase_size; /* erase size in sectors */ rt_uint16_t card_type; #define CARD_TYPE_MMC 0 /* MMC card */ diff --git a/components/drivers/include/drivers/mmcsd_core.h b/components/drivers/include/drivers/mmcsd_core.h index 05a5af6d79..e78469007a 100644 --- a/components/drivers/include/drivers/mmcsd_core.h +++ b/components/drivers/include/drivers/mmcsd_core.h @@ -15,6 +15,8 @@ #include #include #include +#include +#include #ifdef __cplusplus extern "C" { @@ -235,6 +237,7 @@ void mmcsd_free_host(struct rt_mmcsd_host *host); int rt_mmcsd_core_init(void); int rt_mmcsd_blk_init(void); +rt_int32_t read_lba(struct rt_mmcsd_card *card, size_t lba, uint8_t *buffer, size_t count); rt_int32_t rt_mmcsd_blk_probe(struct rt_mmcsd_card *card); void rt_mmcsd_blk_remove(struct rt_mmcsd_card *card); diff --git a/components/drivers/sdio/SConscript b/components/drivers/sdio/SConscript index 95dcfa2578..d5b6eb1cb9 100644 --- a/components/drivers/sdio/SConscript +++ b/components/drivers/sdio/SConscript @@ -7,6 +7,7 @@ block_dev.c mmcsd_core.c sd.c sdio.c +gpt.c mmc.c """) diff --git a/components/drivers/sdio/block_dev.c b/components/drivers/sdio/block_dev.c index 1e12735cba..ee4ec0e442 100644 --- a/components/drivers/sdio/block_dev.c +++ b/components/drivers/sdio/block_dev.c @@ -12,6 +12,7 @@ #include #include +#include #define DBG_TAG "SDIO" #ifdef RT_SDIO_DEBUG @@ -339,6 +340,19 @@ static rt_int32_t mmcsd_set_blksize(struct rt_mmcsd_card *card) return 0; } +rt_int32_t read_lba(struct rt_mmcsd_card *card, size_t lba, uint8_t *buffer, size_t count) +{ + rt_uint8_t status = 0; + + status = mmcsd_set_blksize(card); + if(status) + { + return status; + } + mmcsd_delay_ms(1); + status = rt_mmcsd_req_blk(card, lba, buffer, count, 0); + return status; +} #ifdef RT_USING_DEVICE_OPS const static struct rt_device_ops mmcsd_blk_ops = @@ -360,25 +374,34 @@ rt_int32_t rt_mmcsd_blk_probe(struct rt_mmcsd_card *card) char dname[10]; char sname[16]; struct mmcsd_blk_device *blk_dev = RT_NULL; + int gpt_chk = 0; - err = mmcsd_set_blksize(card); - if(err) + LOG_D("probe mmcsd block device!"); + gpt_chk = check_gpt(card); + if (gpt_chk == 1) { - return err; + status = RT_EOK; } - - LOG_D("probe mmcsd block device!"); - - /* get the first sector to read partition table */ - sector = (rt_uint8_t *)rt_malloc(SECTOR_SIZE); - if (sector == RT_NULL) + else { - LOG_E("allocate partition sector buffer failed!"); + err = mmcsd_set_blksize(card); + if(err) + { + return err; + } + mmcsd_delay_ms(1); + /* get the first sector to read partition table */ + sector = (rt_uint8_t *)rt_malloc(SECTOR_SIZE); + if (sector == RT_NULL) + { + LOG_E("allocate partition sector buffer failed!"); return -RT_ENOMEM; } - status = rt_mmcsd_req_blk(card, 0, sector, 1, 0); + status = rt_mmcsd_req_blk(card, 0, sector, 1, 0); + } + if (status == RT_EOK) { blk_dev = rt_calloc(1, sizeof(struct mmcsd_blk_device)); @@ -420,68 +443,135 @@ rt_int32_t rt_mmcsd_blk_probe(struct rt_mmcsd_card *card) rt_device_register(&(blk_dev->dev), card->host->name, RT_DEVICE_FLAG_RDWR); rt_list_insert_after(&blk_devices, &blk_dev->list); - - for (i = 0; i < RT_MMCSD_MAX_PARTITION; i++) + if (gpt_chk == 1) { - blk_dev = rt_calloc(1, sizeof(struct mmcsd_blk_device)); - if (!blk_dev) + for (i = 0; i < 128; i++) { - LOG_E("mmcsd:malloc memory failed!"); - break; - } + blk_dev = rt_calloc(1, sizeof(struct mmcsd_blk_device)); + if (!blk_dev) + { + LOG_E("mmcsd:malloc memory failed!"); + break; + } + blk_dev->max_req_size = BLK_MIN((card->host->max_dma_segs * + card->host->max_seg_size) >> 9, + (card->host->max_blk_count * + card->host->max_blk_size) >> 9); + + /* get the first partition */ + status = get_partition_param(card, &blk_dev->part, i); + if (status == RT_EOK) + { + rt_snprintf(dname, sizeof(dname)-1, "%s%d", card->host->name,i); + rt_snprintf(sname, sizeof(sname)-1, "sem_%s%d", card->host->name,i+1); + blk_dev->part.lock = rt_sem_create(sname, 1, RT_IPC_FLAG_FIFO); + + /* register mmcsd device */ + blk_dev->dev.type = RT_Device_Class_Block; +#ifdef RT_USING_DEVICE_OPS + blk_dev->dev.ops = &mmcsd_blk_ops; +#else + blk_dev->dev.init = rt_mmcsd_init; + blk_dev->dev.open = rt_mmcsd_open; + blk_dev->dev.close = rt_mmcsd_close; + blk_dev->dev.read = rt_mmcsd_read; + blk_dev->dev.write = rt_mmcsd_write; + blk_dev->dev.control = rt_mmcsd_control; +#endif + blk_dev->card = card; - blk_dev->max_req_size = BLK_MIN((card->host->max_dma_segs * - card->host->max_seg_size) >> 9, - (card->host->max_blk_count * - card->host->max_blk_size) >> 9); + blk_dev->geometry.bytes_per_sector = 1<<9; + blk_dev->geometry.block_size = card->card_blksize; + blk_dev->geometry.sector_count = blk_dev->part.size; - /* get the first partition */ - status = dfs_filesystem_get_partition(&blk_dev->part, sector, i); - if (status == RT_EOK) - { - rt_snprintf(dname, sizeof(dname)-1, "%s%d", card->host->name,i); - rt_snprintf(sname, sizeof(sname)-1, "sem_%s%d", card->host->name,i+1); - blk_dev->part.lock = rt_sem_create(sname, 1, RT_IPC_FLAG_FIFO); + blk_dev->dev.user_data = blk_dev; - /* register mmcsd device */ - blk_dev->dev.type = RT_Device_Class_Block; + rt_device_register(&(blk_dev->dev), dname, + RT_DEVICE_FLAG_RDWR); + rt_list_insert_after(&blk_devices, &blk_dev->list); + } + else + { + rt_free(blk_dev); + blk_dev = RT_NULL; + break; + } + +#ifdef RT_USING_DFS_MNTTABLE + if (blk_dev) + { + LOG_I("try to mount file system!"); + /* try to mount file system on this block device */ + dfs_mount_device(&(blk_dev->dev)); + } +#endif + } + + } + else + { + for (i = 0; i < RT_MMCSD_MAX_PARTITION; i++) + { + blk_dev = rt_calloc(1, sizeof(struct mmcsd_blk_device)); + if (!blk_dev) + { + LOG_E("mmcsd:malloc memory failed!"); + break; + } + blk_dev->max_req_size = BLK_MIN((card->host->max_dma_segs * + card->host->max_seg_size) >> 9, + (card->host->max_blk_count * + card->host->max_blk_size) >> 9); + + /* get the first partition */ + status = dfs_filesystem_get_partition(&blk_dev->part, sector, i); + if (status == RT_EOK) + { + rt_snprintf(dname, sizeof(dname)-1, "%s%d", card->host->name,i); + rt_snprintf(sname, sizeof(sname)-1, "sem_%s%d", card->host->name,i+1); + blk_dev->part.lock = rt_sem_create(sname, 1, RT_IPC_FLAG_FIFO); + + /* register mmcsd device */ + blk_dev->dev.type = RT_Device_Class_Block; #ifdef RT_USING_DEVICE_OPS - blk_dev->dev.ops = &mmcsd_blk_ops; + blk_dev->dev.ops = &mmcsd_blk_ops; #else - blk_dev->dev.init = rt_mmcsd_init; - blk_dev->dev.open = rt_mmcsd_open; - blk_dev->dev.close = rt_mmcsd_close; - blk_dev->dev.read = rt_mmcsd_read; - blk_dev->dev.write = rt_mmcsd_write; - blk_dev->dev.control = rt_mmcsd_control; + blk_dev->dev.init = rt_mmcsd_init; + blk_dev->dev.open = rt_mmcsd_open; + blk_dev->dev.close = rt_mmcsd_close; + blk_dev->dev.read = rt_mmcsd_read; + blk_dev->dev.write = rt_mmcsd_write; + blk_dev->dev.control = rt_mmcsd_control; #endif - blk_dev->card = card; + blk_dev->card = card; - blk_dev->geometry.bytes_per_sector = 1<<9; - blk_dev->geometry.block_size = card->card_blksize; - blk_dev->geometry.sector_count = blk_dev->part.size; + blk_dev->geometry.bytes_per_sector = 1<<9; + blk_dev->geometry.block_size = card->card_blksize; + blk_dev->geometry.sector_count = blk_dev->part.size; - blk_dev->dev.user_data = blk_dev; + blk_dev->dev.user_data = blk_dev; - rt_device_register(&(blk_dev->dev), dname, - RT_DEVICE_FLAG_RDWR); - rt_list_insert_after(&blk_devices, &blk_dev->list); - } - else - { - rt_free(blk_dev); - blk_dev = RT_NULL; - break; - } + rt_device_register(&(blk_dev->dev), dname, + RT_DEVICE_FLAG_RDWR); + rt_list_insert_after(&blk_devices, &blk_dev->list); + } + else + { + rt_free(blk_dev); + blk_dev = RT_NULL; + break; + } #ifdef RT_USING_DFS_MNTTABLE - if (blk_dev) - { - LOG_I("try to mount file system!"); - /* try to mount file system on this block device */ - dfs_mount_device(&(blk_dev->dev)); - } + if (blk_dev) + { + LOG_I("try to mount file system!"); + /* try to mount file system on this block device */ + dfs_mount_device(&(blk_dev->dev)); + } #endif + } + } } else @@ -490,8 +580,15 @@ rt_int32_t rt_mmcsd_blk_probe(struct rt_mmcsd_card *card) err = -RT_ERROR; } - /* release sector buffer */ - rt_free(sector); + if (gpt_chk == 1) + { + gpt_free(); + } + else + { + /* release sector buffer */ + rt_free(sector); + } return err; } diff --git a/components/drivers/sdio/gpt.c b/components/drivers/sdio/gpt.c new file mode 100644 index 0000000000..c575986caa --- /dev/null +++ b/components/drivers/sdio/gpt.c @@ -0,0 +1,558 @@ +#include +#include +#include +#include + +#define DBG_TAG "GPT" +#ifdef RT_SDIO_DEBUG +#define DBG_LVL DBG_LOG +#else +#define DBG_LVL DBG_INFO +#endif /* RT_SDIO_DEBUG */ +#include + +#define min(a, b) a < b ? a : b +static int force_gpt = 0; + +static inline int efi_guidcmp (gpt_guid_t left, gpt_guid_t right) +{ + return rt_memcmp(&left, &right, sizeof (gpt_guid_t)); +} + +static uint32_t last_lba(struct rt_mmcsd_card *card) +{ + RT_ASSERT(card != RT_NULL); + return (card->card_sec_cnt) - 1; +} + +static inline int pmbr_part_valid(gpt_mbr_record *part) +{ + if (part->os_type != EFI_PMBR_OSTYPE_EFI_GPT) + { + goto invalid; + } + + /* set to 0x00000001 (i.e., the LBA of the GPT Partition Header) */ + if ((uint32_t)(part->starting_lba) != GPT_PRIMARY_PARTITION_TABLE_LBA) + { + goto invalid; + } + + return GPT_MBR_PROTECTIVE; +invalid: + return 0; +} +/* +* +* return ret +* ret = 0, invalid mbr +* ret = 1, protect mbr +* ret = 2, hybrid mbr +*/ +int is_pmbr_valid(legacy_mbr *mbr, uint64_t total_sectors) +{ + uint32_t sz = 0; + int i, part = 0, ret = 0; /* invalid by default */ + + if (!mbr || (uint16_t)(mbr->signature) != MSDOS_MBR_SIGNATURE) + { + goto done; + } + + for (i = 0; i < 4; i++) + { + ret = pmbr_part_valid(&mbr->partition_record[i]); + if (ret == GPT_MBR_PROTECTIVE) + { + part = i; + /* + * Ok, we at least know that there's a protective MBR, + * now check if there are other partition types for + * hybrid MBR. + */ + goto check_hybrid; + } + } + + if (ret != GPT_MBR_PROTECTIVE) + { + goto done; + } + +check_hybrid: + for (i = 0; i < 4; i++) + { + if ((mbr->partition_record[i].os_type != + EFI_PMBR_OSTYPE_EFI_GPT) && + (mbr->partition_record[i].os_type != 0x00)) + { + ret = GPT_MBR_HYBRID; + } + + } + + /* + * Protective MBRs take up the lesser of the whole disk + * or 2 TiB (32bit LBA), ignoring the rest of the disk. + * Some partitioning programs, nonetheless, choose to set + * the size to the maximum 32-bit limitation, disregarding + * the disk size. + * + * Hybrid MBRs do not necessarily comply with this. + * + * Consider a bad value here to be a warning to support dd'ing + * an image from a smaller disk to a larger disk. + */ + if (ret == GPT_MBR_PROTECTIVE) + { + sz = (uint32_t)(mbr->partition_record[part].size_in_lba); + if (sz != (uint32_t) total_sectors - 1 && sz != 0xFFFFFFFF) + { + LOG_I("GPT: mbr size in lba (%u) different than whole disk (%u).\n", + sz, min(total_sectors - 1, 0xFFFFFFFF)); + } + } + +done: + return ret; + +} + +static gpt_entry *alloc_read_gpt_entries(struct rt_mmcsd_card *card, gpt_header *gpt) +{ + size_t count; + gpt_entry *pte; + + if (!gpt) + { + return RT_NULL; + } + + count = (size_t)(gpt->num_partition_entries) * (gpt->sizeof_partition_entry); + if (!count) + { + return RT_NULL; + } + + pte = rt_malloc(count); + if (!pte) + return RT_NULL; + + if (read_lba(card, (size_t)(gpt->partition_entry_lba),(uint8_t *)pte, count/512) != RT_EOK) + { + rt_free(pte); + return RT_NULL; + } + return pte; + +} + +static gpt_header *alloc_read_gpt_header(struct rt_mmcsd_card *card, size_t lba) +{ + gpt_header *gpt; + void *buf; + + buf = rt_malloc(512); + if (!buf) + { + return RT_NULL; + } + + if (read_lba(card, lba, (uint8_t *)buf, 1) != RT_EOK) + { + rt_free(buf); + return RT_NULL; + } + gpt = (gpt_header *)buf; + + return gpt; +} + +static int is_gpt_valid(struct rt_mmcsd_card *card, size_t lba, gpt_header **gpt, gpt_entry **ptes) +{ + size_t lastlba; + + if (!ptes) + { + return 0; + } + + if (!(*gpt = alloc_read_gpt_header(card, lba))) + { + return 0; + } + + /* Check the GUID Partition Table signature */ + if ((uint64_t)((*gpt)->signature) != GPT_HEADER_SIGNATURE) + { + printf("GUID Partition Table Header signature is wrong:" + "%ld != %ld\n",(uint64_t)((*gpt)->signature),(uint64_t)GPT_HEADER_SIGNATURE); + goto fail; + } + + /* Check the GUID Partition Table header size is too small */ + if ((uint32_t)((*gpt)->header_size) < sizeof(gpt_header)) + { + printf("GUID Partition Table Header size is too small: %u < %zu\n", + (uint32_t)((*gpt)->header_size),sizeof(gpt_header)); + goto fail; + } + + /* Check that the my_lba entry points to the LBA that contains + * the GUID Partition Table */ + if ((uint64_t)((*gpt)->my_lba) != lba) + { + printf("GPT my_lba incorrect: %ld != %ld\n", + (uint64_t)((*gpt)->my_lba), + (uint64_t)lba); + goto fail; + } + + /* Check the first_usable_lba and last_usable_lba are + * within the disk. + */ + lastlba = last_lba(card); + if ((uint64_t)((*gpt)->first_usable_lba) > lastlba) + { + printf("GPT: first_usable_lba incorrect: %ld > %ld\n", + ((uint64_t)((*gpt)->first_usable_lba)), + (size_t)lastlba); + goto fail; + } + + if ((uint64_t)((*gpt)->last_usable_lba) > lastlba) + { + printf("GPT: last_usable_lba incorrect: %ld > %ld\n", + (uint64_t)((*gpt)->last_usable_lba), + (size_t)lastlba); + goto fail; + } + + if ((uint64_t)((*gpt)->last_usable_lba) < (uint64_t)((*gpt)->first_usable_lba)) + { + printf("GPT: last_usable_lba incorrect: %ld > %ld\n", + (uint64_t)((*gpt)->last_usable_lba), + (uint64_t)((*gpt)->first_usable_lba)); + goto fail; + } + /* Check that sizeof_partition_entry has the correct value */ + if ((uint32_t)((*gpt)->sizeof_partition_entry) != sizeof(gpt_entry)) { + printf("GUID Partition Entry Size check failed.\n"); + goto fail; + } + + if (!(*ptes = alloc_read_gpt_entries(card, *gpt))) + { + goto fail; + } + + /* We're done, all's well */ + return 1; + + fail: + rt_free(*gpt); + *gpt = RT_NULL; + return 0; +} + +/** + * is_pte_valid() - tests one PTE for validity + * @pte:pte to check + * @lastlba: last lba of the disk + * + * Description: returns 1 if valid, 0 on error. + */ +static inline int is_pte_valid(const gpt_entry *pte, const size_t lastlba) +{ + if ((!efi_guidcmp(pte->partition_type_guid, NULL_GUID)) || + (uint64_t)(pte->starting_lba) > lastlba || + (uint64_t)(pte->ending_lba) > lastlba) + { + return 0; + } + + return 1; +} + +/** + * compare_gpts() - Search disk for valid GPT headers and PTEs + * @pgpt: primary GPT header + * @agpt: alternate GPT header + * @lastlba: last LBA number + * + * Description: Returns nothing. Sanity checks pgpt and agpt fields + * and prints warnings on discrepancies. + * + */ +static void compare_gpts(gpt_header *pgpt, gpt_header *agpt, size_t lastlba) +{ + int error_found = 0; + if (!pgpt || !agpt) + { + return; + } + + if ((uint64_t)(pgpt->my_lba) != (uint64_t)(agpt->alternate_lba)) + { + LOG_I("GPT:Primary header LBA != Alt. header alternate_lba\n"); + LOG_I("GPT:%lld != %lld\n", + (uint64_t)(pgpt->my_lba), + (uint64_t)(agpt->alternate_lba)); + error_found++; + } + + if ((uint64_t)(pgpt->alternate_lba) != (uint64_t)(agpt->my_lba)) + { + LOG_I("GPT:Primary header alternate_lba != Alt. header my_lba\n"); + LOG_I("GPT:%lld != %lld\n", + (uint64_t)(pgpt->alternate_lba), + (uint64_t)(agpt->my_lba)); + error_found++; + } + + if ((uint64_t)(pgpt->first_usable_lba) != (uint64_t)(agpt->first_usable_lba)) + { + LOG_I("GPT:first_usable_lbas don't match.\n"); + LOG_I("GPT:%lld != %lld\n", + (uint64_t)(pgpt->first_usable_lba), + (uint64_t)(agpt->first_usable_lba)); + error_found++; + } + + if ((uint64_t)(pgpt->last_usable_lba) != (uint64_t)(agpt->last_usable_lba)) + { + LOG_I("GPT:last_usable_lbas don't match.\n"); + LOG_I("GPT:%lld != %lld\n", + (uint64_t)(pgpt->last_usable_lba), + (uint64_t)(agpt->last_usable_lba)); + error_found++; + } + + if (efi_guidcmp(pgpt->disk_guid, agpt->disk_guid)) + { + LOG_I("GPT:disk_guids don't match.\n"); + error_found++; + } + + if ((pgpt->num_partition_entries) != (agpt->num_partition_entries)) + { + LOG_I("GPT:num_partition_entries don't match: " + "0x%x != 0x%x\n", + (pgpt->num_partition_entries), + (agpt->num_partition_entries)); + error_found++; + } + + if ((pgpt->sizeof_partition_entry) != (agpt->sizeof_partition_entry)) + { + LOG_I("GPT:sizeof_partition_entry values don't match: " + "0x%x != 0x%x\n", + (pgpt->sizeof_partition_entry), + (agpt->sizeof_partition_entry)); + error_found++; + } + + if ((pgpt->partition_entry_array_crc32) != (agpt->partition_entry_array_crc32)) + { + LOG_I("GPT:partition_entry_array_crc32 values don't match: " + "0x%x != 0x%x\n", + (pgpt->partition_entry_array_crc32), + (agpt->partition_entry_array_crc32)); + error_found++; + } + + if ((pgpt->alternate_lba) != lastlba) + { + LOG_I("GPT:Primary header thinks Alt. header is not at the end of the disk.\n"); + LOG_I("GPT:%lld != %lld\n", + (uint64_t)(pgpt->alternate_lba), + (size_t)lastlba); + error_found++; + } + + if ((agpt->my_lba) != lastlba) + { + LOG_I("GPT:Alternate GPT header not at the end of the disk.\n"); + LOG_I("GPT:%lld != %lld\n", + (uint64_t)(agpt->my_lba), + (size_t)lastlba); + error_found++; + } + + if (error_found) + { + LOG_I("GPT: Use GNU Parted to correct GPT errors.\n"); + } + return; +} + +/** + * find_valid_gpt() - Search disk for valid GPT headers and PTEs + * @state: disk parsed partitions + * @gpt: GPT header ptr, filled on return. + * @ptes: PTEs ptr, filled on return. + * + * Description: Returns 1 if valid, 0 on error. + * If valid, returns pointers to newly allocated GPT header and PTEs. + * Validity depends on PMBR being valid (or being overridden by the + * 'gpt' kernel command line option) and finding either the Primary + * GPT header and PTEs valid, or the Alternate GPT header and PTEs + * valid. If the Primary GPT header is not valid, the Alternate GPT header + * is not checked unless the 'gpt' kernel command line option is passed. + * This protects against devices which misreport their size, and forces + * the user to decide to use the Alternate GPT. + */ +static int find_valid_gpt(struct rt_mmcsd_card *card, gpt_header **gpt, + gpt_entry **ptes) +{ + int good_pgpt = 0, good_agpt = 0, good_pmbr = 0; + gpt_header *pgpt = RT_NULL, *agpt = RT_NULL; + gpt_entry *pptes = RT_NULL, *aptes = RT_NULL; + legacy_mbr *legacymbr; + size_t total_sectors = last_lba(card) + 1; + size_t lastlba; + int status = 0; + + if (!ptes) + { + return 0; + } + + lastlba = last_lba(card); + LOG_D("total_sectors:%d, lastlba:%d\n", total_sectors, lastlba); + if (!force_gpt) + { + /* This will be added to the EFI Spec. per Intel after v1.02. */ + legacymbr = rt_malloc(512); + if (!legacymbr) + { + goto fail; + } + + status = read_lba(card, 0, (uint8_t *)legacymbr, 1); + if (status) + { + LOG_I("status:%d\n", status); + goto fail; + } + + good_pmbr = is_pmbr_valid(legacymbr, total_sectors); + rt_free(legacymbr); + + if (!good_pmbr) + { + goto fail; + } + + LOG_D("Device has a %s MBR\n", + good_pmbr == GPT_MBR_PROTECTIVE ? + "protective" : "hybrid"); + } + + good_pgpt = is_gpt_valid(card, GPT_PRIMARY_PARTITION_TABLE_LBA, + &pgpt, &pptes); + if (good_pgpt) + { + good_agpt = is_gpt_valid(card, (pgpt->alternate_lba), &agpt, &aptes); + if (!good_agpt && force_gpt) + { + good_agpt = is_gpt_valid(card, lastlba, &agpt, &aptes); + } + + /* The obviously unsuccessful case */ + if (!good_pgpt && !good_agpt) + { + goto fail; + } + + compare_gpts(pgpt, agpt, lastlba); + // legacymbr = rt_malloc(512); + // if (!legacymbr) + // { + // goto fail; + // } + + // status = read_lba(card, 0, (uint8_t *)legacymbr, 1); + // if (status) + // { + // LOG_I("status:%d\n", status); + // goto fail; + // } + // rt_free(legacymbr); + + /* The good cases */ + if (good_pgpt) + { + *gpt = pgpt; + *ptes = pptes; + rt_free(agpt); + rt_free(aptes); + if (!good_agpt) + { + LOG_D("Alternate GPT is invalid, using primary GPT.\n"); + } + return 1; + } + else if (good_agpt) + { + *gpt = agpt; + *ptes = aptes; + rt_free(pgpt); + rt_free(pptes); + LOG_D("Primary GPT is invalid, using alternate GPT.\n"); + return 1; + } + } + + fail: + rt_free(pgpt); + rt_free(agpt); + rt_free(pptes); + rt_free(aptes); + *gpt = RT_NULL; + *ptes = RT_NULL; + return 0; +} +static gpt_header *_gpt; +static gpt_entry *_ptes; +int check_gpt(struct rt_mmcsd_card *card) +{ + if (!find_valid_gpt(card, &_gpt, &_ptes) || !_gpt || !_ptes) + { + rt_free(_gpt); + rt_free(_ptes); + return 0; + } + return 1; +} + +int get_partition_param(struct rt_mmcsd_card *card, struct dfs_partition *part, uint32_t pindex) +{ + if (!is_pte_valid(&_ptes[pindex], last_lba(card))) + { + return -1; + } + part->offset = (off_t)(_ptes[pindex].starting_lba); + part->size = (_ptes[pindex].ending_lba) - (_ptes[pindex].starting_lba) + 1ULL; + + rt_kprintf("found part[%d], begin(sector): %d, end(sector):%d size: ", + pindex, _ptes[pindex].starting_lba, _ptes[pindex].ending_lba); + if ((part->size >> 11) == 0) + rt_kprintf("%d%s", part->size >> 1, "KB\n"); /* KB */ + else + { + unsigned int part_size; + part_size = part->size >> 11; /* MB */ + if ((part_size >> 10) == 0) + rt_kprintf("%d.%d%s", part_size, (part->size >> 1) & 0x3FF, "MB\n"); + else + rt_kprintf("%d.%d%s", part_size >> 10, part_size & 0x3FF, "GB\n"); + } + return 0; +} + +void gpt_free() +{ + rt_free(_ptes); + rt_free(_gpt); +} diff --git a/components/drivers/sdio/mmc.c b/components/drivers/sdio/mmc.c index e3e09d8bcc..ff946d93d0 100644 --- a/components/drivers/sdio/mmc.c +++ b/components/drivers/sdio/mmc.c @@ -193,10 +193,11 @@ static int mmc_parse_ext_csd(struct rt_mmcsd_card *card, rt_uint8_t *ext_csd) card->hs_max_data_rate = 52000000; card_capacity = *((rt_uint32_t *)&ext_csd[EXT_CSD_SEC_CNT]); + card->card_sec_cnt = card_capacity; card_capacity *= card->card_blksize; card_capacity >>= 10; /* unit:KB */ card->card_capacity = card_capacity; - LOG_I("emmc card capacity %d KB.", card->card_capacity); + LOG_I("emmc card capacity %d KB, card sec count:%d.", card->card_capacity, card->card_sec_cnt); return 0; } @@ -322,7 +323,7 @@ static int mmc_select_bus_width(struct rt_mmcsd_card *card, rt_uint8_t *ext_csd) * set by drivers. */ - if (!(((host->flags & MMCSD_BUSWIDTH_8) && + if (!(((host->flags & MMCSD_BUSWIDTH_8) && ext_csd_bits[idx] == EXT_CSD_BUS_WIDTH_8) || ((host->flags & MMCSD_BUSWIDTH_4) && ext_csd_bits[idx] == EXT_CSD_BUS_WIDTH_4) || diff --git a/components/drivers/sdio/sd.c b/components/drivers/sdio/sd.c index f7e4e46720..0e6a14db83 100644 --- a/components/drivers/sdio/sd.c +++ b/components/drivers/sdio/sd.c @@ -117,8 +117,9 @@ static rt_int32_t mmcsd_parse_csd(struct rt_mmcsd_card *card) csd->wr_blk_partial = GET_BITS(resp, 21, 1); csd->csd_crc = GET_BITS(resp, 1, 7); - card->card_blksize = 512; + card->card_blksize = 512; card->card_capacity = (csd->c_size + 1) * 512; /* unit:KB */ + card->card_sec_cnt = card->card_capacity * 2; card->tacc_clks = 0; card->tacc_ns = 0; card->max_data_rate = tran_unit[csd->tran_speed&0x07] * tran_value[(csd->tran_speed&0x78)>>3]; -- Gitee From 8440ef6b8008c80231a8138e3ff46bd3118a4da3 Mon Sep 17 00:00:00 2001 From: linzhenxing Date: Thu, 5 May 2022 23:37:38 +0800 Subject: [PATCH 2/5] =?UTF-8?q?=E6=B7=BB=E5=8A=A0license?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- components/drivers/include/drivers/gpt.h | 9 +++++++++ components/drivers/sdio/gpt.c | 9 +++++++++ 2 files changed, 18 insertions(+) diff --git a/components/drivers/include/drivers/gpt.h b/components/drivers/include/drivers/gpt.h index 9956405575..4195997eba 100644 --- a/components/drivers/include/drivers/gpt.h +++ b/components/drivers/include/drivers/gpt.h @@ -1,3 +1,12 @@ +/* + * Copyright (c) 2006-2021, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2022-05-05 linzhenxing first version + */ #ifndef __GPT_H #define __GPT_H #include diff --git a/components/drivers/sdio/gpt.c b/components/drivers/sdio/gpt.c index c575986caa..6ac2baf57f 100644 --- a/components/drivers/sdio/gpt.c +++ b/components/drivers/sdio/gpt.c @@ -1,3 +1,12 @@ +/* + * Copyright (c) 2006-2021, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2022-05-05 linzhenxing first version + */ #include #include #include -- Gitee From aa7684ff6691811f4f9f1c5a7e091129e7f97139 Mon Sep 17 00:00:00 2001 From: linzhenxing Date: Fri, 6 May 2022 09:41:26 +0800 Subject: [PATCH 3/5] =?UTF-8?q?=E5=88=A0=E9=99=A4=E6=B2=A1=E7=94=A8?= =?UTF-8?q?=E7=9A=84=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- components/drivers/sdio/gpt.c | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/components/drivers/sdio/gpt.c b/components/drivers/sdio/gpt.c index 6ac2baf57f..e3651b977a 100644 --- a/components/drivers/sdio/gpt.c +++ b/components/drivers/sdio/gpt.c @@ -475,19 +475,6 @@ static int find_valid_gpt(struct rt_mmcsd_card *card, gpt_header **gpt, } compare_gpts(pgpt, agpt, lastlba); - // legacymbr = rt_malloc(512); - // if (!legacymbr) - // { - // goto fail; - // } - - // status = read_lba(card, 0, (uint8_t *)legacymbr, 1); - // if (status) - // { - // LOG_I("status:%d\n", status); - // goto fail; - // } - // rt_free(legacymbr); /* The good cases */ if (good_pgpt) -- Gitee From a2339cdd361a998a2d15df3869f60a6128c82663 Mon Sep 17 00:00:00 2001 From: linzhenxing-bit Date: Fri, 6 May 2022 17:38:07 +0800 Subject: [PATCH 4/5] code format --- .gitignore | 4 +- components/drivers/include/drivers/gpt.h | 14 +- components/drivers/sdio/block_dev.c | 356 ++++++++++++----------- components/drivers/sdio/gpt.c | 72 +++-- 4 files changed, 232 insertions(+), 214 deletions(-) diff --git a/.gitignore b/.gitignore index 59b9974e8a..632dc40022 100644 --- a/.gitignore +++ b/.gitignore @@ -34,4 +34,6 @@ ncscope.* #ctag files tags -.vscode/ \ No newline at end of file +.vscode/ + +bsp/ \ No newline at end of file diff --git a/components/drivers/include/drivers/gpt.h b/components/drivers/include/drivers/gpt.h index 4195997eba..c1bdcb732a 100644 --- a/components/drivers/include/drivers/gpt.h +++ b/components/drivers/include/drivers/gpt.h @@ -9,11 +9,13 @@ */ #ifndef __GPT_H #define __GPT_H + +#include #include -#include + typedef struct { - uint8_t b[16]; + uint8_t b[16]; /* GUID 16 bytes*/ } guid_t; #define MSDOS_MBR_SIGNATURE 0xaa55 @@ -65,8 +67,8 @@ typedef struct _gpt_header uint32_t header_size; uint32_t header_crc32; uint32_t reserved1; - uint64_t my_lba; - uint64_t alternate_lba; + uint64_t start_lba; /*GPT head start sector*/ + uint64_t alternate_lba; /*GPT head alternate sector*/ uint64_t first_usable_lba; uint64_t last_usable_lba; gpt_guid_t disk_guid; @@ -125,6 +127,6 @@ typedef struct _legacy_mbr #pragma pack(pop) int check_gpt(struct rt_mmcsd_card *card); -int get_partition_param(struct rt_mmcsd_card *card, struct dfs_partition *part, uint32_t pindex); -void gpt_free(); +int gpt_get_partition_param(struct rt_mmcsd_card *card, struct dfs_partition *part, uint32_t pindex); +void gpt_free(void); #endif /*__GPT_H*/ diff --git a/components/drivers/sdio/block_dev.c b/components/drivers/sdio/block_dev.c index ee4ec0e442..1c60ec0084 100644 --- a/components/drivers/sdio/block_dev.c +++ b/components/drivers/sdio/block_dev.c @@ -39,6 +39,7 @@ struct mmcsd_blk_device #ifndef RT_MMCSD_MAX_PARTITION #define RT_MMCSD_MAX_PARTITION 16 #endif +#define RT_GPT_PARTITION_MAX 128 rt_int32_t mmcsd_num_wr_blocks(struct rt_mmcsd_card *card) { @@ -366,230 +367,235 @@ const static struct rt_device_ops mmcsd_blk_ops = }; #endif -rt_int32_t rt_mmcsd_blk_probe(struct rt_mmcsd_card *card) +rt_int32_t gpt_device_probe(struct rt_mmcsd_card *card) { - rt_int32_t err = 0; + rt_int32_t err = RT_EOK; rt_uint8_t i, status; - rt_uint8_t *sector; char dname[10]; char sname[16]; struct mmcsd_blk_device *blk_dev = RT_NULL; - int gpt_chk = 0; - LOG_D("probe mmcsd block device!"); - gpt_chk = check_gpt(card); - if (gpt_chk == 1) + blk_dev = rt_calloc(1, sizeof(struct mmcsd_blk_device)); + if (!blk_dev) { - status = RT_EOK; + LOG_E("mmcsd:malloc memory failed!"); + return -1; } - else - { - err = mmcsd_set_blksize(card); - if(err) - { - return err; - } - mmcsd_delay_ms(1); - /* get the first sector to read partition table */ - sector = (rt_uint8_t *)rt_malloc(SECTOR_SIZE); - if (sector == RT_NULL) - { - LOG_E("allocate partition sector buffer failed!"); - return -RT_ENOMEM; - } + blk_dev->max_req_size = BLK_MIN((card->host->max_dma_segs * + card->host->max_seg_size) >> 9, + (card->host->max_blk_count * + card->host->max_blk_size) >> 9); + blk_dev->part.offset = 0; + blk_dev->part.size = 0; + rt_snprintf(sname, sizeof(sname)-1, "sem_%s%d", card->host->name,0); + blk_dev->part.lock = rt_sem_create(sname, 1, RT_IPC_FLAG_FIFO); + /* register mmcsd device */ + blk_dev->dev.type = RT_Device_Class_Block; +#ifdef RT_USING_DEVICE_OPS + blk_dev->dev.ops = &mmcsd_blk_ops; +#else + blk_dev->dev.init = rt_mmcsd_init; + blk_dev->dev.open = rt_mmcsd_open; + blk_dev->dev.close = rt_mmcsd_close; + blk_dev->dev.read = rt_mmcsd_read; + blk_dev->dev.write = rt_mmcsd_write; + blk_dev->dev.control = rt_mmcsd_control; +#endif + blk_dev->card = card; - status = rt_mmcsd_req_blk(card, 0, sector, 1, 0); - } + blk_dev->geometry.bytes_per_sector = 1<<9; + blk_dev->geometry.block_size = card->card_blksize; + blk_dev->geometry.sector_count = + card->card_capacity * (1024 / 512); - if (status == RT_EOK) + blk_dev->dev.user_data = blk_dev; + + rt_device_register(&(blk_dev->dev), card->host->name, + RT_DEVICE_FLAG_RDWR); + rt_list_insert_after(&blk_devices, &blk_dev->list); + + for (i = 0; i < RT_GPT_PARTITION_MAX; i++) { blk_dev = rt_calloc(1, sizeof(struct mmcsd_blk_device)); if (!blk_dev) { LOG_E("mmcsd:malloc memory failed!"); - return -1; + break; } - blk_dev->max_req_size = BLK_MIN((card->host->max_dma_segs * - card->host->max_seg_size) >> 9, + card->host->max_seg_size) >> 9, (card->host->max_blk_count * - card->host->max_blk_size) >> 9); - blk_dev->part.offset = 0; - blk_dev->part.size = 0; - rt_snprintf(sname, sizeof(sname)-1, "sem_%s%d", card->host->name,0); - blk_dev->part.lock = rt_sem_create(sname, 1, RT_IPC_FLAG_FIFO); - /* register mmcsd device */ - blk_dev->dev.type = RT_Device_Class_Block; -#ifdef RT_USING_DEVICE_OPS - blk_dev->dev.ops = &mmcsd_blk_ops; -#else - blk_dev->dev.init = rt_mmcsd_init; - blk_dev->dev.open = rt_mmcsd_open; - blk_dev->dev.close = rt_mmcsd_close; - blk_dev->dev.read = rt_mmcsd_read; - blk_dev->dev.write = rt_mmcsd_write; - blk_dev->dev.control = rt_mmcsd_control; -#endif - blk_dev->card = card; - - blk_dev->geometry.bytes_per_sector = 1<<9; - blk_dev->geometry.block_size = card->card_blksize; - blk_dev->geometry.sector_count = - card->card_capacity * (1024 / 512); + card->host->max_blk_size) >> 9); - blk_dev->dev.user_data = blk_dev; - - rt_device_register(&(blk_dev->dev), card->host->name, - RT_DEVICE_FLAG_RDWR); - rt_list_insert_after(&blk_devices, &blk_dev->list); - if (gpt_chk == 1) + /* get the first partition */ + status = gpt_get_partition_param(card, &blk_dev->part, i); + if (status == RT_EOK) { - for (i = 0; i < 128; i++) - { - blk_dev = rt_calloc(1, sizeof(struct mmcsd_blk_device)); - if (!blk_dev) - { - LOG_E("mmcsd:malloc memory failed!"); - break; - } - blk_dev->max_req_size = BLK_MIN((card->host->max_dma_segs * - card->host->max_seg_size) >> 9, - (card->host->max_blk_count * - card->host->max_blk_size) >> 9); - - /* get the first partition */ - status = get_partition_param(card, &blk_dev->part, i); - if (status == RT_EOK) - { - rt_snprintf(dname, sizeof(dname)-1, "%s%d", card->host->name,i); - rt_snprintf(sname, sizeof(sname)-1, "sem_%s%d", card->host->name,i+1); - blk_dev->part.lock = rt_sem_create(sname, 1, RT_IPC_FLAG_FIFO); - - /* register mmcsd device */ - blk_dev->dev.type = RT_Device_Class_Block; + rt_snprintf(dname, sizeof(dname)-1, "%s%d", card->host->name,i); + rt_snprintf(sname, sizeof(sname)-1, "sem_%s%d", card->host->name,i+1); + blk_dev->part.lock = rt_sem_create(sname, 1, RT_IPC_FLAG_FIFO); + + /* register mmcsd device */ + blk_dev->dev.type = RT_Device_Class_Block; #ifdef RT_USING_DEVICE_OPS - blk_dev->dev.ops = &mmcsd_blk_ops; + blk_dev->dev.ops = &mmcsd_blk_ops; #else - blk_dev->dev.init = rt_mmcsd_init; - blk_dev->dev.open = rt_mmcsd_open; - blk_dev->dev.close = rt_mmcsd_close; - blk_dev->dev.read = rt_mmcsd_read; - blk_dev->dev.write = rt_mmcsd_write; - blk_dev->dev.control = rt_mmcsd_control; + blk_dev->dev.init = rt_mmcsd_init; + blk_dev->dev.open = rt_mmcsd_open; + blk_dev->dev.close = rt_mmcsd_close; + blk_dev->dev.read = rt_mmcsd_read; + blk_dev->dev.write = rt_mmcsd_write; + blk_dev->dev.control = rt_mmcsd_control; #endif - blk_dev->card = card; + blk_dev->card = card; - blk_dev->geometry.bytes_per_sector = 1<<9; - blk_dev->geometry.block_size = card->card_blksize; - blk_dev->geometry.sector_count = blk_dev->part.size; + blk_dev->geometry.bytes_per_sector = 1<<9; + blk_dev->geometry.block_size = card->card_blksize; + blk_dev->geometry.sector_count = blk_dev->part.size; - blk_dev->dev.user_data = blk_dev; - - rt_device_register(&(blk_dev->dev), dname, - RT_DEVICE_FLAG_RDWR); - rt_list_insert_after(&blk_devices, &blk_dev->list); - } - else - { - rt_free(blk_dev); - blk_dev = RT_NULL; - break; - } - -#ifdef RT_USING_DFS_MNTTABLE - if (blk_dev) - { - LOG_I("try to mount file system!"); - /* try to mount file system on this block device */ - dfs_mount_device(&(blk_dev->dev)); - } -#endif - } + blk_dev->dev.user_data = blk_dev; + rt_device_register(&(blk_dev->dev), dname, + RT_DEVICE_FLAG_RDWR); + rt_list_insert_after(&blk_devices, &blk_dev->list); } else { - for (i = 0; i < RT_MMCSD_MAX_PARTITION; i++) - { - blk_dev = rt_calloc(1, sizeof(struct mmcsd_blk_device)); - if (!blk_dev) - { - LOG_E("mmcsd:malloc memory failed!"); - break; - } - blk_dev->max_req_size = BLK_MIN((card->host->max_dma_segs * - card->host->max_seg_size) >> 9, - (card->host->max_blk_count * - card->host->max_blk_size) >> 9); - - /* get the first partition */ - status = dfs_filesystem_get_partition(&blk_dev->part, sector, i); - if (status == RT_EOK) - { - rt_snprintf(dname, sizeof(dname)-1, "%s%d", card->host->name,i); - rt_snprintf(sname, sizeof(sname)-1, "sem_%s%d", card->host->name,i+1); - blk_dev->part.lock = rt_sem_create(sname, 1, RT_IPC_FLAG_FIFO); - - /* register mmcsd device */ - blk_dev->dev.type = RT_Device_Class_Block; -#ifdef RT_USING_DEVICE_OPS - blk_dev->dev.ops = &mmcsd_blk_ops; -#else - blk_dev->dev.init = rt_mmcsd_init; - blk_dev->dev.open = rt_mmcsd_open; - blk_dev->dev.close = rt_mmcsd_close; - blk_dev->dev.read = rt_mmcsd_read; - blk_dev->dev.write = rt_mmcsd_write; - blk_dev->dev.control = rt_mmcsd_control; + rt_free(blk_dev); + blk_dev = RT_NULL; + break; + } + +#ifdef RT_USING_DFS_MNTTABLE + if (blk_dev) + { + LOG_I("try to mount file system!"); + /* try to mount file system on this block device */ + dfs_mount_device(&(blk_dev->dev)); + } #endif - blk_dev->card = card; + } + gpt_free(); - blk_dev->geometry.bytes_per_sector = 1<<9; - blk_dev->geometry.block_size = card->card_blksize; - blk_dev->geometry.sector_count = blk_dev->part.size; + return err; +} - blk_dev->dev.user_data = blk_dev; +rt_int32_t mbr_device_probe(struct rt_mmcsd_card *card) +{ + rt_int32_t err = 0; + rt_uint8_t i, status; + rt_uint8_t *sector; + char dname[10]; + char sname[16]; + struct mmcsd_blk_device *blk_dev = RT_NULL; - rt_device_register(&(blk_dev->dev), dname, - RT_DEVICE_FLAG_RDWR); - rt_list_insert_after(&blk_devices, &blk_dev->list); - } - else - { - rt_free(blk_dev); - blk_dev = RT_NULL; - break; - } + err = mmcsd_set_blksize(card); + if(err) + { + return err; + } + mmcsd_delay_ms(1); + /* get the first sector to read partition table */ + sector = (rt_uint8_t *)rt_malloc(SECTOR_SIZE); + if (sector == RT_NULL) + { + LOG_E("allocate partition sector buffer failed!"); -#ifdef RT_USING_DFS_MNTTABLE - if (blk_dev) - { - LOG_I("try to mount file system!"); - /* try to mount file system on this block device */ - dfs_mount_device(&(blk_dev->dev)); - } -#endif + return -RT_ENOMEM; + } + + status = rt_mmcsd_req_blk(card, 0, sector, 1, 0); + if (status == RT_EOK) + { + for (i = 0; i < RT_MMCSD_MAX_PARTITION; i++) + { + blk_dev = rt_calloc(1, sizeof(struct mmcsd_blk_device)); + if (!blk_dev) + { + LOG_E("mmcsd:malloc memory failed!"); + break; + } + blk_dev->max_req_size = BLK_MIN((card->host->max_dma_segs * + card->host->max_seg_size) >> 9, + (card->host->max_blk_count * + card->host->max_blk_size) >> 9); + + /* get the first partition */ + status = dfs_filesystem_get_partition(&blk_dev->part, sector, i); + if (status == RT_EOK) + { + rt_snprintf(dname, sizeof(dname)-1, "%s%d", card->host->name,i); + rt_snprintf(sname, sizeof(sname)-1, "sem_%s%d", card->host->name,i+1); + blk_dev->part.lock = rt_sem_create(sname, 1, RT_IPC_FLAG_FIFO); + + /* register mmcsd device */ + blk_dev->dev.type = RT_Device_Class_Block; + #ifdef RT_USING_DEVICE_OPS + blk_dev->dev.ops = &mmcsd_blk_ops; + #else + blk_dev->dev.init = rt_mmcsd_init; + blk_dev->dev.open = rt_mmcsd_open; + blk_dev->dev.close = rt_mmcsd_close; + blk_dev->dev.read = rt_mmcsd_read; + blk_dev->dev.write = rt_mmcsd_write; + blk_dev->dev.control = rt_mmcsd_control; + #endif + blk_dev->card = card; + + blk_dev->geometry.bytes_per_sector = 1<<9; + blk_dev->geometry.block_size = card->card_blksize; + blk_dev->geometry.sector_count = blk_dev->part.size; + + blk_dev->dev.user_data = blk_dev; + + rt_device_register(&(blk_dev->dev), dname, + RT_DEVICE_FLAG_RDWR); + rt_list_insert_after(&blk_devices, &blk_dev->list); + } + else + { + rt_free(blk_dev); + blk_dev = RT_NULL; + break; } + #ifdef RT_USING_DFS_MNTTABLE + if (blk_dev) + { + LOG_I("try to mount file system!"); + /* try to mount file system on this block device */ + dfs_mount_device(&(blk_dev->dev)); + } + #endif } } else { LOG_E("read mmcsd first sector failed"); - err = -RT_ERROR; + err = -RT_ERROR; } - if (gpt_chk == 1) + /* release sector buffer */ + rt_free(sector); + + return err; + +} + +rt_int32_t rt_mmcsd_blk_probe(struct rt_mmcsd_card *card) +{ + uint32_t err = 0; + + LOG_D("probe mmcsd block device!"); + if (check_gpt(card) != 0) { - gpt_free(); + err = gpt_device_probe(card); } else { - /* release sector buffer */ - rt_free(sector); + err = mbr_device_probe(card); } - return err; } diff --git a/components/drivers/sdio/gpt.c b/components/drivers/sdio/gpt.c index e3651b977a..9d1c11e150 100644 --- a/components/drivers/sdio/gpt.c +++ b/components/drivers/sdio/gpt.c @@ -22,6 +22,10 @@ #define min(a, b) a < b ? a : b static int force_gpt = 0; +static gpt_header *_gpt; +static gpt_entry *_ptes; +#define GPT_TYPE 1 +#define MBR_TYPE 0 static inline int efi_guidcmp (gpt_guid_t left, gpt_guid_t right) { @@ -51,6 +55,7 @@ static inline int pmbr_part_valid(gpt_mbr_record *part) invalid: return 0; } + /* * * return ret @@ -194,7 +199,7 @@ static int is_gpt_valid(struct rt_mmcsd_card *card, size_t lba, gpt_header **gpt /* Check the GUID Partition Table signature */ if ((uint64_t)((*gpt)->signature) != GPT_HEADER_SIGNATURE) { - printf("GUID Partition Table Header signature is wrong:" + LOG_E("GUID Partition Table Header signature is wrong:" "%ld != %ld\n",(uint64_t)((*gpt)->signature),(uint64_t)GPT_HEADER_SIGNATURE); goto fail; } @@ -202,17 +207,17 @@ static int is_gpt_valid(struct rt_mmcsd_card *card, size_t lba, gpt_header **gpt /* Check the GUID Partition Table header size is too small */ if ((uint32_t)((*gpt)->header_size) < sizeof(gpt_header)) { - printf("GUID Partition Table Header size is too small: %u < %zu\n", + LOG_E("GUID Partition Table Header size is too small: %u < %zu\n", (uint32_t)((*gpt)->header_size),sizeof(gpt_header)); goto fail; } - /* Check that the my_lba entry points to the LBA that contains + /* Check that the start_lba entry points to the LBA that contains * the GUID Partition Table */ - if ((uint64_t)((*gpt)->my_lba) != lba) + if ((uint64_t)((*gpt)->start_lba) != lba) { - printf("GPT my_lba incorrect: %ld != %ld\n", - (uint64_t)((*gpt)->my_lba), + LOG_E("GPT start_lba incorrect: %ld != %ld\n", + (uint64_t)((*gpt)->start_lba), (uint64_t)lba); goto fail; } @@ -223,7 +228,7 @@ static int is_gpt_valid(struct rt_mmcsd_card *card, size_t lba, gpt_header **gpt lastlba = last_lba(card); if ((uint64_t)((*gpt)->first_usable_lba) > lastlba) { - printf("GPT: first_usable_lba incorrect: %ld > %ld\n", + LOG_E("GPT: first_usable_lba incorrect: %ld > %ld\n", ((uint64_t)((*gpt)->first_usable_lba)), (size_t)lastlba); goto fail; @@ -231,7 +236,7 @@ static int is_gpt_valid(struct rt_mmcsd_card *card, size_t lba, gpt_header **gpt if ((uint64_t)((*gpt)->last_usable_lba) > lastlba) { - printf("GPT: last_usable_lba incorrect: %ld > %ld\n", + LOG_E("GPT: last_usable_lba incorrect: %ld > %ld\n", (uint64_t)((*gpt)->last_usable_lba), (size_t)lastlba); goto fail; @@ -239,14 +244,14 @@ static int is_gpt_valid(struct rt_mmcsd_card *card, size_t lba, gpt_header **gpt if ((uint64_t)((*gpt)->last_usable_lba) < (uint64_t)((*gpt)->first_usable_lba)) { - printf("GPT: last_usable_lba incorrect: %ld > %ld\n", + LOG_E("GPT: last_usable_lba incorrect: %ld > %ld\n", (uint64_t)((*gpt)->last_usable_lba), (uint64_t)((*gpt)->first_usable_lba)); goto fail; } /* Check that sizeof_partition_entry has the correct value */ if ((uint32_t)((*gpt)->sizeof_partition_entry) != sizeof(gpt_entry)) { - printf("GUID Partition Entry Size check failed.\n"); + LOG_E("GUID Partition Entry Size check failed.\n"); goto fail; } @@ -266,8 +271,8 @@ static int is_gpt_valid(struct rt_mmcsd_card *card, size_t lba, gpt_header **gpt /** * is_pte_valid() - tests one PTE for validity - * @pte:pte to check - * @lastlba: last lba of the disk + * pte:pte to check + * lastlba: last lba of the disk * * Description: returns 1 if valid, 0 on error. */ @@ -285,9 +290,9 @@ static inline int is_pte_valid(const gpt_entry *pte, const size_t lastlba) /** * compare_gpts() - Search disk for valid GPT headers and PTEs - * @pgpt: primary GPT header - * @agpt: alternate GPT header - * @lastlba: last LBA number + * pgpt: primary GPT header + * agpt: alternate GPT header + * lastlba: last LBA number * * Description: Returns nothing. Sanity checks pgpt and agpt fields * and prints warnings on discrepancies. @@ -301,21 +306,21 @@ static void compare_gpts(gpt_header *pgpt, gpt_header *agpt, size_t lastlba) return; } - if ((uint64_t)(pgpt->my_lba) != (uint64_t)(agpt->alternate_lba)) + if ((uint64_t)(pgpt->start_lba) != (uint64_t)(agpt->alternate_lba)) { LOG_I("GPT:Primary header LBA != Alt. header alternate_lba\n"); LOG_I("GPT:%lld != %lld\n", - (uint64_t)(pgpt->my_lba), + (uint64_t)(pgpt->start_lba), (uint64_t)(agpt->alternate_lba)); error_found++; } - if ((uint64_t)(pgpt->alternate_lba) != (uint64_t)(agpt->my_lba)) + if ((uint64_t)(pgpt->alternate_lba) != (uint64_t)(agpt->start_lba)) { - LOG_I("GPT:Primary header alternate_lba != Alt. header my_lba\n"); + LOG_I("GPT:Primary header alternate_lba != Alt. header start_lba\n"); LOG_I("GPT:%lld != %lld\n", (uint64_t)(pgpt->alternate_lba), - (uint64_t)(agpt->my_lba)); + (uint64_t)(agpt->start_lba)); error_found++; } @@ -379,11 +384,11 @@ static void compare_gpts(gpt_header *pgpt, gpt_header *agpt, size_t lastlba) error_found++; } - if ((agpt->my_lba) != lastlba) + if ((agpt->start_lba) != lastlba) { LOG_I("GPT:Alternate GPT header not at the end of the disk.\n"); LOG_I("GPT:%lld != %lld\n", - (uint64_t)(agpt->my_lba), + (uint64_t)(agpt->start_lba), (size_t)lastlba); error_found++; } @@ -397,9 +402,9 @@ static void compare_gpts(gpt_header *pgpt, gpt_header *agpt, size_t lastlba) /** * find_valid_gpt() - Search disk for valid GPT headers and PTEs - * @state: disk parsed partitions - * @gpt: GPT header ptr, filled on return. - * @ptes: PTEs ptr, filled on return. + * state: disk parsed partitions + * gpt: GPT header ptr, filled on return. + * ptes: PTEs ptr, filled on return. * * Description: Returns 1 if valid, 0 on error. * If valid, returns pointers to newly allocated GPT header and PTEs. @@ -509,32 +514,35 @@ static int find_valid_gpt(struct rt_mmcsd_card *card, gpt_header **gpt, *ptes = RT_NULL; return 0; } -static gpt_header *_gpt; -static gpt_entry *_ptes; + int check_gpt(struct rt_mmcsd_card *card) { if (!find_valid_gpt(card, &_gpt, &_ptes) || !_gpt || !_ptes) { rt_free(_gpt); rt_free(_ptes); - return 0; + return MBR_TYPE; } - return 1; + return GPT_TYPE; } -int get_partition_param(struct rt_mmcsd_card *card, struct dfs_partition *part, uint32_t pindex) +int gpt_get_partition_param(struct rt_mmcsd_card *card, struct dfs_partition *part, uint32_t pindex) { if (!is_pte_valid(&_ptes[pindex], last_lba(card))) { return -1; } + part->offset = (off_t)(_ptes[pindex].starting_lba); part->size = (_ptes[pindex].ending_lba) - (_ptes[pindex].starting_lba) + 1ULL; rt_kprintf("found part[%d], begin(sector): %d, end(sector):%d size: ", pindex, _ptes[pindex].starting_lba, _ptes[pindex].ending_lba); + if ((part->size >> 11) == 0) - rt_kprintf("%d%s", part->size >> 1, "KB\n"); /* KB */ + { + rt_kprintf("%d%s", part->size >> 1, "KB\n"); /* KB */ + } else { unsigned int part_size; @@ -547,7 +555,7 @@ int get_partition_param(struct rt_mmcsd_card *card, struct dfs_partition *part, return 0; } -void gpt_free() +void gpt_free(void) { rt_free(_ptes); rt_free(_gpt); -- Gitee From 7b85c29c6e99ba3b18da3f49f6e3320d6ce36b8f Mon Sep 17 00:00:00 2001 From: linzhenxing-bit Date: Fri, 6 May 2022 17:42:14 +0800 Subject: [PATCH 5/5] code format --- .gitignore | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index 632dc40022..59b9974e8a 100644 --- a/.gitignore +++ b/.gitignore @@ -34,6 +34,4 @@ ncscope.* #ctag files tags -.vscode/ - -bsp/ \ No newline at end of file +.vscode/ \ No newline at end of file -- Gitee