#include "fs/fat.hpp"
#include "drv/ATA.hpp"
#include "print.hpp"
using namespace fs;
FAT::FAT(drv::ATA &hd, std::uint32_t partitionOffset) : hd(hd)
{
std::uint8_t bpbData[512];
hd.read28(partitionOffset, bpbData);
BiosParameterBlock32 bpb(bpbData);
fatStart = partitionOffset + bpb.reservedSectors;
dataStart = fatStart + bpb.tableSize*bpb.fatCopies;
rootStart = dataStart + bpb.sectorsPerCluster*(bpb.rootCluster - 2);
sectorsPerCluster = bpb.sectorsPerCluster;
kprint("sectors per cluster: ", sectorsPerCluster, "\n");
}
void
FAT::printFiles()
{
std::uint8_t dirData[512];
hd.read28(rootStart, dirData);
std::uint8_t *dataPtr = dirData;
Fields<DirectoryEntryFat32, 16> dirent(dataPtr);
for (int i = 0; i < 16; ++i) {
DirectoryEntryFat32 &ent = dirent[i];
if (ent.name[0] == 0x00) {
break;
}
if ((ent.attributes & 0x0f) == 0x0f) {
continue;
}
char foo[] = " \n";
for (int j = 0; j < 8; ++j) {
foo[j] = ent.name[j];
}
kprint(foo);
// Skip directories.
if (!(ent.attributes & 0x10)) {
printFileContents(ent);
}
}
}
void
FAT::printFileContents(const DirectoryEntryFat32 &ent) const
{
std::uint32_t firstCluster = ent.firstClusterHi;
firstCluster = (firstCluster << 16) | ent.firstClusterLow;
std::int32_t size = ent.size;
std::int32_t currentCluster = firstCluster;
std::uint8_t buffer[513];
while (size > 0) {
std::uint32_t sector = dataStart
+ sectorsPerCluster*(currentCluster - 2);
std::uint32_t sectorOffset = 0;
while (size > 0) {
hd.read28(sector + sectorOffset, { buffer, 512 });
buffer[size > 512 ? 512 : size] = '\0';
kprint(reinterpret_cast<const char *>(buffer));
size -= 512;
if (++sectorOffset == sectorsPerCluster) {
break;
}
}
if (size <= 0) {
break;
}
std::uint8_t fat[512];
std::uint32_t fatSector = currentCluster/(512/sizeof(std::uint32_t));
hd.read28(fatStart + fatSector, fat);
std::uint32_t fatOffset = currentCluster%(512/sizeof(std::uint32_t))*4;
currentCluster = fat[fatOffset + 3] & 0x0f;
currentCluster = (currentCluster << 8) | fat[fatOffset + 2];
currentCluster = (currentCluster << 8) | fat[fatOffset + 1];
currentCluster = (currentCluster << 8) | fat[fatOffset + 0];
}
}
Before first commit, do not forget to setup your git environment:
git config --global user.name "your_name_here"
git config --global user.email "your@email_here"
Clone this repository using HTTP(S):
git clone https://code.reversed.top/user/xaizek/tos
Clone this repository using ssh (do not forget to upload a key first):
git clone ssh://rocketgit@code.reversed.top/user/xaizek/tos
You are allowed to anonymously push to this repository.
This means that your pushed commits will automatically be transformed into a
pull request:
... clone the repository ...
... make some changes and some commits ...
git push origin master