fat.hpp 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. #pragma once
  2. #include <kernel/mem.h>
  3. #include <kernel/vfs.hpp>
  4. #include <types/size.h>
  5. #include <types/stdint.h>
  6. namespace fs::fat {
  7. using cluster_t = uint32_t;
  8. // for FAT32
  9. struct PACKED old_boot_sector {
  10. uint8_t jmp_instruction[3];
  11. char oem_name[8];
  12. // usually 512
  13. uint16_t bytes_per_sector;
  14. uint8_t sectors_per_cluster;
  15. // 32 for FAT32
  16. uint16_t reserved_sectors;
  17. // usually 2
  18. uint8_t fat_copies;
  19. // 0 for FAT32
  20. uint16_t root_directory_entries;
  21. // valid before FAT32
  22. uint16_t _sectors_cnt;
  23. // 0xf8 for hard disk
  24. uint8_t type;
  25. // valid before FAT32
  26. uint16_t _sectors_per_fat;
  27. // 12
  28. uint16_t sectors_per_track;
  29. // 2
  30. uint16_t heads;
  31. // 0
  32. uint16_t hidden_sectors;
  33. };
  34. // for FAT32
  35. struct PACKED ext_boot_sector {
  36. struct old_boot_sector old;
  37. // 0
  38. uint16_t hidden_sector_ext;
  39. uint32_t sectors_cnt;
  40. uint32_t sectors_per_fat;
  41. uint16_t mirror_flags;
  42. uint16_t fs_version;
  43. // 2
  44. cluster_t root_directory;
  45. // 1
  46. uint16_t fs_info_sector;
  47. // usually at 6, 0x0000 or 0xffff if none
  48. uint16_t backup_boot_sector;
  49. uint8_t _reserved[12];
  50. // for int $0x13
  51. uint8_t drive_number;
  52. uint8_t _reserved_for_current_head;
  53. // 0x29
  54. uint8_t ext_signature;
  55. uint32_t serial_number;
  56. char label[11];
  57. char fs_type[8];
  58. uint8_t _reserved_blank[420];
  59. // 0x55, 0xaa
  60. uint16_t magic;
  61. };
  62. struct PACKED fs_info_sector {
  63. // 0x41615252
  64. uint32_t signature_one;
  65. uint8_t _reserved[480];
  66. // 0x61417272
  67. uint32_t signature_two;
  68. // may be incorrect
  69. uint32_t free_clusters;
  70. // hint only
  71. uint32_t next_free_cluster;
  72. uint8_t _reserved_two[12];
  73. // 0xaa550000
  74. uint32_t sector_signature;
  75. };
  76. struct PACKED directory_entry {
  77. char filename[8];
  78. char extension[3];
  79. struct PACKED {
  80. uint8_t ro : 1;
  81. uint8_t hidden : 1;
  82. uint8_t system : 1;
  83. uint8_t volume_label : 1;
  84. uint8_t subdir : 1;
  85. uint8_t archive : 1;
  86. uint8_t _reserved : 2;
  87. } attributes;
  88. uint8_t _reserved;
  89. uint8_t c_time_date[5];
  90. uint16_t access_date;
  91. uint16_t cluster_hi;
  92. uint8_t m_time_date[4];
  93. uint16_t cluster_lo;
  94. uint32_t size;
  95. };
  96. class fat32 : public virtual fs::vfs {
  97. private:
  98. constexpr static uint32_t SECTOR_SIZE = 512;
  99. constexpr static cluster_t EOC = 0xffffff8;
  100. private:
  101. uint32_t sector_cnt;
  102. uint32_t sectors_per_fat;
  103. uint32_t serial_number;
  104. uint32_t free_clusters;
  105. uint32_t next_free_cluster_hint;
  106. cluster_t root_dir;
  107. cluster_t data_region_offset;
  108. inode* device;
  109. uint16_t reserved_sectors;
  110. uint8_t fat_copies;
  111. uint8_t sectors_per_cluster;
  112. char label[12];
  113. cluster_t* fat;
  114. // buf MUST be larger than 512 bytes
  115. inline void read_sector(void* buf, uint32_t sector_no);
  116. // buf MUST be larger than 4096 bytes
  117. inline void read_cluster(void* buf, cluster_t no);
  118. static inline cluster_t cl(const inode* ind)
  119. {
  120. return reinterpret_cast<cluster_t>(ind->impl);
  121. }
  122. static inline cluster_t _rearrange(directory_entry* d)
  123. {
  124. return (((cluster_t)d->cluster_hi) << 16) + d->cluster_lo;
  125. }
  126. static inline size_t _write_buf_n(char* buf, size_t buf_size, const char* src, size_t n)
  127. {
  128. if (n <= buf_size) {
  129. memcpy(buf, src, n);
  130. return n;
  131. } else {
  132. memcpy(buf, src, buf_size);
  133. return buf_size;
  134. }
  135. }
  136. protected:
  137. virtual int load_dentry(dentry* ent) override;
  138. public:
  139. fat32(const fat32&) = delete;
  140. explicit fat32(inode* _device);
  141. ~fat32();
  142. virtual size_t inode_read(inode* file, char* buf, size_t buf_size, size_t offset, size_t n) override;
  143. virtual int inode_stat(dentry* ent, stat* st) override;
  144. };
  145. }; // namespace fs::fat