Чтение содержимого каталога в FAT32

Я пытаюсь написать драйвер файловой системы FAT32 на чистом металле на RPI 3B. Я могу читать сектора FAT и сектора корневого каталога с помощью драйвера emmc.

У меня есть сомнения относительно того, как следовать связанному списку записей FAT, когда указатель следующей записи (следующий номер кластера) не помещается в текущий сектор FAT? Должен ли я читать сектор FAT каждый раз, когда я получаю новый номер кластера?

В настоящее время я понимаю следующее: Получить первый номер кластера (номер_кластера) каталога/файла. Прочитать сектор FAT, который содержит запись first_cluster_number. Скажем, я читаю сектор FAT как

uint8_t fat_sector[512] = { 0 };
uint32_t this_fat_sector_num, this_fat_entry_offset;
this_fat_sector_num =  unusedSectors + reservedSectorCount + ((cluster_number * 4)/ bytesPerSector);
this_fat_entry_offset =  (cluster_number * 4)/ bytesPerSector;
read_fat_sector(this_fat_sector_num, & fat_sector[0]);
// Calculate next cluster in chain
uint32_t next_cluster_number = ((uint32_t * fat_sector[this_fat_entry_offset])) & 0x0fffffff;
// Calculate next cluster in chain 1 more time, is below code correct ?
 uint32_t next_next_cluster_number = ((uint32_t * fat_sector[next_cluster_number])) & 0x0fffffff;

Что происходит, когда следующий номер кластера отсутствует в уже прочитанном буфере fat_sector (512 байт)? Если номер кластера = индексу следующей записи в fat_sector, нужно ли умножать его на 4, учитывая, что толстые 32 записи охватывают 4 байта. Если кто-то может дать некоторую ясность, это будет полезно. Заранее спасибо.


person zero    schedule 05.05.2019    source источник


Ответы (2)


Реализовать кэш (в ОЗУ) FAT. Допустим, в кеше достаточно оперативной памяти для 20 секторов и он пуст.

Затем напишите функцию «getFATentry», которая проверяет, находится ли сектор в кеше, и находит в кеше правильную запись, если она есть; или (при необходимости) вытесняет что-то из кеша, чтобы освободить место, выбирает нужный сектор с диска в кеш, затем находит нужную запись в кеше.

Как только это будет сделано, вы можете next_cluster = getFATentry(previous_cluster); не беспокоиться о кеше или каком-либо дисковом вводе-выводе (но вам захочется что-то сделать, когда FAT будет изменен, например, принять политику «сквозной записи» или «обратной записи»).

Примечание. Регулируя размер «кэша FAT», вы можете повысить производительность или уменьшить потребление оперативной памяти. Было бы неплохо позволить кешу динамически увеличиваться/сокращаться (например, увеличиваться до размера всего FAT, если больше ничего не нужно ОЗУ, но уменьшаться до минимума, если вся ОЗУ нужна для чего-то другого).

person Brendan    schedule 14.05.2019

Я нашел решение.

Сначала прочитайте начальный толстый сектор для данного номера кластера.

Узнайте thisFatEntryOffset и прочитайте следующую толстую запись.

Новая толстая запись будет новым номером кластера. Узнайте thisFatNumber и thisFatEntryOffset для нового номера кластера.

Если новый толстый сектор != старый толстый сектор, то прочитать новый толстый сектор и прочитать запись, используя thisFatEntryOffset.

person zero    schedule 14.05.2019