From 4b7594db1e779154a723b543c522153778341873 Mon Sep 17 00:00:00 2001 From: linzhenxing Date: Fri, 21 Jan 2022 18:24:56 +0800 Subject: [PATCH 1/6] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E7=A3=81=E7=9B=98?= =?UTF-8?q?=E5=88=86=E5=8C=BA=E7=B1=BB=E5=9E=8Bgpt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- components/drivers/Kconfig | 3 + 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 | 221 +++++-- components/drivers/sdio/gpt.c | 547 ++++++++++++++++++ 7 files changed, 835 insertions(+), 62 deletions(-) create mode 100644 components/drivers/include/drivers/gpt.h create mode 100644 components/drivers/sdio/gpt.c diff --git a/components/drivers/Kconfig b/components/drivers/Kconfig index 8e6a17eef5..802f71270e 100755 --- a/components/drivers/Kconfig +++ b/components/drivers/Kconfig @@ -279,6 +279,9 @@ config RT_USING_SPI bool "Using RW009/007 SPI Wi-Fi wireless interface" select RT_USING_LWIP default n + config RT_SPI_DEBUG + bool "Enable SPI debug log output" + default n endif config RT_USING_WDT 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..0ca53d06e4 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 c7be39209f..5e45a7b523 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)); @@ -409,7 +432,6 @@ rt_int32_t rt_mmcsd_blk_probe(struct rt_mmcsd_card *card) 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 = @@ -420,68 +442,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 +579,16 @@ 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..d73671bc49 --- /dev/null +++ b/components/drivers/sdio/gpt.c @@ -0,0 +1,547 @@ +#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; + + gpt = rt_malloc(sizeof(gpt_header)); + if (!gpt) + { + return RT_NULL; + } + + if (read_lba(card, lba, (uint8_t *)gpt, 1) != RT_EOK) + { + rt_free(gpt); + return RT_NULL; + } + + return gpt; +} + +static int is_gpt_valid(struct rt_mmcsd_card *card, size_t lba, gpt_header **gpt, gpt_entry **ptes) +{ + //uint32_t crc, origcrc; + size_t lastlba, pt_size; + 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) + { + LOG_I("GUID Partition Table Header signature is wrong:" + "%lld != %lld\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)) + { + LOG_I("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) + { + LOG_I("GPT my_lba incorrect: %lld != %lld\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) + { + LOG_I("GPT: first_usable_lba incorrect: %lld > %lld\n", + ((uint64_t)((*gpt)->first_usable_lba)), + (size_t)lastlba); + goto fail; + } + + if ((uint64_t)((*gpt)->last_usable_lba) > lastlba) + { + LOG_I("GPT: last_usable_lba incorrect: %lld > %lld\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)) + { + LOG_I("GPT: last_usable_lba incorrect: %lld > %lld\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)) { + LOG_I("GUID Partition Entry Size check failed.\n"); + goto fail; + } + + /* Sanity check partition table size */ + pt_size = (uint64_t)((*gpt)->num_partition_entries) * ((*gpt)->sizeof_partition_entry); + + 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); + + /* 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: %d, size: ", + pindex, part->offset * 512); + 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); +} -- Gitee From 1da9812905656b51615dcc8bef623802a893c688 Mon Sep 17 00:00:00 2001 From: linzhenxing Date: Fri, 21 Jan 2022 18:35:16 +0800 Subject: [PATCH 2/6] format code --- components/drivers/include/drivers/mmcsd_card.h | 2 +- components/drivers/sdio/block_dev.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/components/drivers/include/drivers/mmcsd_card.h b/components/drivers/include/drivers/mmcsd_card.h index 0ca53d06e4..02980e01e4 100644 --- a/components/drivers/include/drivers/mmcsd_card.h +++ b/components/drivers/include/drivers/mmcsd_card.h @@ -141,7 +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 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/sdio/block_dev.c b/components/drivers/sdio/block_dev.c index 5e45a7b523..91f2dfeb18 100644 --- a/components/drivers/sdio/block_dev.c +++ b/components/drivers/sdio/block_dev.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2021, RT-Thread Development Team + * Copyright (c) 2006-2022, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * -- Gitee From bf13d5a123d92b4fdf81b83aa4be15740d9102ae Mon Sep 17 00:00:00 2001 From: linzhenxing Date: Mon, 14 Feb 2022 17:06:01 +0800 Subject: [PATCH 3/6] =?UTF-8?q?=E4=BF=AE=E6=94=B9mmc=E5=88=9D=E5=A7=8B?= =?UTF-8?q?=E5=8C=96bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- components/drivers/include/drivers/mmcsd_card.h | 2 +- components/drivers/sdio/mmc.c | 14 +++++++++----- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/components/drivers/include/drivers/mmcsd_card.h b/components/drivers/include/drivers/mmcsd_card.h index 02980e01e4..ea2de15ca5 100644 --- a/components/drivers/include/drivers/mmcsd_card.h +++ b/components/drivers/include/drivers/mmcsd_card.h @@ -141,7 +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 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/sdio/mmc.c b/components/drivers/sdio/mmc.c index 0a41eee594..04cbd76c8d 100644 --- a/components/drivers/sdio/mmc.c +++ b/components/drivers/sdio/mmc.c @@ -193,6 +193,7 @@ 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; @@ -321,12 +322,15 @@ static int mmc_select_bus_width(struct rt_mmcsd_card *card, rt_uint8_t *ext_csd) * bail out early if corresponding bus capable wasn't * 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 || - ext_csd_bits[idx] == EXT_CSD_BUS_WIDTH_8))) - continue; + ((host->flags & MMCSD_BUSWIDTH_4) && + ext_csd_bits[idx] == EXT_CSD_BUS_WIDTH_4) || + !(ext_csd_bits[idx] == EXT_CSD_BUS_WIDTH_8))) + { + continue; + } err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BUS_WIDTH, -- Gitee From b00ba5489d44361ac111dcdb2eece7008d761296 Mon Sep 17 00:00:00 2001 From: linzhenxing Date: Mon, 14 Feb 2022 17:06:40 +0800 Subject: [PATCH 4/6] =?UTF-8?q?=E4=BF=AE=E6=94=B9gpt=20malloc=20=E7=A9=BA?= =?UTF-8?q?=E9=97=B4=E8=BF=87=E5=B0=8F=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- components/drivers/sdio/gpt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/drivers/sdio/gpt.c b/components/drivers/sdio/gpt.c index d73671bc49..6d0c2636f5 100644 --- a/components/drivers/sdio/gpt.c +++ b/components/drivers/sdio/gpt.c @@ -151,7 +151,7 @@ static gpt_header *alloc_read_gpt_header(struct rt_mmcsd_card *card, size_t lba) { gpt_header *gpt; - gpt = rt_malloc(sizeof(gpt_header)); + gpt = rt_malloc(512); if (!gpt) { return RT_NULL; -- Gitee From de8968c8ed7e2174650f3151c5a43bd62c598e16 Mon Sep 17 00:00:00 2001 From: linzhenxing Date: Mon, 14 Feb 2022 17:07:15 +0800 Subject: [PATCH 5/6] =?UTF-8?q?=E4=BF=AE=E6=94=B9tty=E5=9C=A8=E5=A4=9A?= =?UTF-8?q?=E6=A0=B8=E4=B8=8B=E8=B7=91=E6=8C=82=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- components/drivers/tty/n_tty.c | 1 + components/drivers/tty/pty.c | 3 +-- components/drivers/tty/tty.c | 2 ++ 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/components/drivers/tty/n_tty.c b/components/drivers/tty/n_tty.c index f44f0cdf8f..d7515fd70f 100644 --- a/components/drivers/tty/n_tty.c +++ b/components/drivers/tty/n_tty.c @@ -1846,6 +1846,7 @@ static int n_tty_read(struct dfs_fd *fd, void *buf, size_t count) c = job_control(tty); if (c < 0) { + rt_hw_interrupt_enable(level); return c; } diff --git a/components/drivers/tty/pty.c b/components/drivers/tty/pty.c index 2c147b21c2..7233c17566 100644 --- a/components/drivers/tty/pty.c +++ b/components/drivers/tty/pty.c @@ -308,8 +308,7 @@ static int ptmx_register(void) level = rt_hw_interrupt_disable(); RT_ASSERT(ptm_drv->init_flag == TTY_INIT_FLAG_NONE); - - level = rt_hw_interrupt_disable(); + device = &(ptm_drv->parent); device->type = RT_Device_Class_Char; diff --git a/components/drivers/tty/tty.c b/components/drivers/tty/tty.c index b88a4b700f..6ba733f778 100644 --- a/components/drivers/tty/tty.c +++ b/components/drivers/tty/tty.c @@ -79,11 +79,13 @@ int __tty_check_change(struct tty_struct *tty, int sig) level = rt_hw_interrupt_disable(); if (current == RT_NULL) { + rt_hw_interrupt_enable(level); return 0; } if (current->tty != tty) { + rt_hw_interrupt_enable(level); return 0; } -- Gitee From b30bdc67eef83a800c4970e6c48a6bf4ebff6f00 Mon Sep 17 00:00:00 2001 From: linzhenxing Date: Tue, 15 Feb 2022 09:21:49 +0800 Subject: [PATCH 6/6] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dwarning?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- components/drivers/tty/n_tty.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/components/drivers/tty/n_tty.c b/components/drivers/tty/n_tty.c index d7515fd70f..38bfd90060 100644 --- a/components/drivers/tty/n_tty.c +++ b/components/drivers/tty/n_tty.c @@ -791,7 +791,8 @@ static size_t __process_echoes(struct tty_struct *tty) size_t tail = 0; unsigned char c = 0; char ch = 0; - + unsigned char num_chars = 0, num_bs = 0; + tail = ldata->echo_tail; while (ldata->echo_commit != tail) { @@ -809,8 +810,6 @@ static size_t __process_echoes(struct tty_struct *tty) switch (op) { - unsigned char num_chars = 0, num_bs = 0; - case ECHO_OP_ERASE_TAB: num_chars = echo_buf(ldata, tail + 2); -- Gitee