dfs.c 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. /*
  2. * Copyright (c) 2006-2023, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2011-07-25 weety first version
  9. * 2023-02-25 GuEe-GUI make blk interface
  10. */
  11. #include "efi.h"
  12. #define DBG_TAG "blk.part.dfs"
  13. #define DBG_LVL DBG_INFO
  14. #include <rtdbg.h>
  15. rt_err_t dfs_partition(struct rt_blk_disk *disk)
  16. {
  17. rt_ssize_t res;
  18. struct dfs_partition part;
  19. rt_uint8_t *sector = rt_malloc(rt_blk_disk_get_logical_block_size(disk));
  20. if (!sector)
  21. {
  22. return -RT_ENOMEM;
  23. }
  24. res = disk->ops->read(disk, 0, sector, 1);
  25. if (res < 0)
  26. {
  27. rt_free(sector);
  28. return res;
  29. }
  30. /* check MBR signature at offset 0x1FE-0x1FF */
  31. if (sector[0x1FE] != 0x55 || sector[0x1FF] != 0xAA)
  32. {
  33. rt_free(sector);
  34. return -RT_ERROR;
  35. }
  36. /* get disk total capacity */
  37. rt_ssize_t disk_capacity = rt_blk_disk_get_capacity(disk);
  38. if (disk_capacity <= 0)
  39. {
  40. rt_free(sector);
  41. return disk_capacity < 0 ? disk_capacity : -RT_ERROR;
  42. }
  43. for (rt_size_t i = 0; i < disk->max_partitions; ++i)
  44. {
  45. res = dfs_filesystem_get_partition(&part, sector, i);
  46. if (res)
  47. {
  48. break;
  49. }
  50. /* check if partition start and size are within disk capacity */
  51. off_t part_start = part.offset;
  52. size_t part_size = part.size;
  53. off_t part_end = part_start + (off_t)part_size;
  54. if (part_start >= (off_t)disk_capacity)
  55. {
  56. LOG_W("Partition %d: start sector %ld >= disk capacity %ld, skipped",
  57. i, part_start, disk_capacity);
  58. continue;
  59. }
  60. if (part_size == 0 || part_end > (off_t)disk_capacity)
  61. {
  62. LOG_W("Partition %d: size %lu or end sector %ld > disk capacity %ld, skipped",
  63. i, part_size, part_end, disk_capacity);
  64. continue;
  65. }
  66. if (blk_put_partition(disk, "dfs", part.offset, part.size, i) == -RT_ENOMEM)
  67. {
  68. break;
  69. }
  70. }
  71. rt_free(sector);
  72. return RT_EOK;
  73. }