xaizek / tos (License: GPLv3 only) (since 2018-12-07)
This is an alternative version of sources presented as part of Write Your Own OS video tutorial by Viktor Engelmann.
Commit 4f3df597ebe34811da23608d977b012fbdc09659

Better code in fs/fat unit
Author: xaizek
Author date (UTC): 2018-04-11 18:53
Committer name: xaizek
Committer date (UTC): 2018-04-12 13:51
Parent(s): aac0bc95f658418811bdff5af80e598176ff8405
Signing key: 99DC5E4DB05F6BE2
Tree: 0569af358baacea64bd3a6503b7320b5664dad98
File Lines added Lines deleted
src/fs/fat.cpp 39 23
File src/fs/fat.cpp changed (mode: 100644) (index 5a95607..6b993de)
5 5
6 6 using namespace fs; using namespace fs;
7 7
8 static void printFileContents(const DirectoryEntryFat32 &ent,
9 drv::ATA &hd, const BiosParameterBlock32 &bpb,
10 std::uint32_t fatStart, std::uint32_t dataStart);
11
8 12 void void
9 13 fs::readBiosBlock(drv::ATA &hd, std::uint32_t partitionOffset) fs::readBiosBlock(drv::ATA &hd, std::uint32_t partitionOffset)
10 14 { {
 
... ... fs::readBiosBlock(drv::ATA &hd, std::uint32_t partitionOffset)
41 45 } }
42 46 kprint(foo); kprint(foo);
43 47
44 if ((dirent[i].attributes & 0x10) == 0x10) { // directory
45 continue;
48 // Skip directories.
49 if (!(dirent[i].attributes & 0x10)) {
50 printFileContents(dirent[i], hd, bpb, fatStart, dataStart);
46 51 } }
52 }
53 }
47 54
48 std::uint32_t firstFileCluster = ((std::uint32_t)dirent[i].firstClusterHi) << 16
49 | ((std::uint32_t)dirent[i].firstClusterLow);
55 static void
56 printFileContents(const DirectoryEntryFat32 &ent, drv::ATA &hd,
57 const BiosParameterBlock32 &bpb, std::uint32_t fatStart,
58 std::uint32_t dataStart)
59 {
60 std::uint32_t firstCluster = ent.firstClusterHi;
61 firstCluster = (firstCluster << 16) | ent.firstClusterLow;
50 62
51 std::int32_t SIZE = dirent[i].size;
52 std::int32_t nextFileCluster = firstFileCluster;
53 std::uint8_t buffer[513];
54 std::uint8_t fatbuffer[513];
63 std::int32_t size = ent.size;
64 std::int32_t currentCluster = firstCluster;
65 std::uint8_t buffer[513];
55 66
56 while (SIZE > 0) {
57 std::uint32_t fileSector = dataStart + bpb.sectorsPerCluster * (nextFileCluster-2);
58 int sectorOffset = 0;
67 while (size > 0) {
68 std::uint32_t sector = dataStart
69 + bpb.sectorsPerCluster*(currentCluster - 2);
70 int sectorOffset = 0;
59 71
60 for (; SIZE > 0; SIZE -= 512) {
61 hd.read28(fileSector+sectorOffset, buffer, 512);
72 for (; size > 0; size -= 512) {
73 hd.read28(sector + sectorOffset, buffer, 512);
62 74
63 buffer[SIZE > 512 ? 512 : SIZE] = '\0';
64 kprint(reinterpret_cast<const char *>(buffer));
75 buffer[size > 512 ? 512 : size] = '\0';
76 kprint(reinterpret_cast<const char *>(buffer));
65 77
66 if (++sectorOffset > bpb.sectorsPerCluster) {
67 break;
68 }
78 if (++sectorOffset > bpb.sectorsPerCluster) {
79 break;
69 80 } }
70
71 std::uint32_t fatSectorForCurrentCluster = nextFileCluster / (512/sizeof(std::uint32_t));
72 hd.read28(fatStart+fatSectorForCurrentCluster, fatbuffer, 512);
73 std::uint32_t fatOffsetInSectorForCurrentCluster = nextFileCluster % (512/sizeof(std::uint32_t));
74 nextFileCluster = ((std::uint32_t*)&fatbuffer)[fatOffsetInSectorForCurrentCluster] & 0x0FFFFFFF;
75 81 } }
82
83 std::uint8_t fat[513];
84 std::uint32_t fatSector = currentCluster/(512/sizeof(std::uint32_t));
85 hd.read28(fatStart + fatSector, fat, 512);
86 std::uint32_t fatOffset = currentCluster%(512/sizeof(std::uint32_t));
87
88 currentCluster = fat[fatOffset + 3] & 0x0f;
89 currentCluster = (currentCluster << 8) | fat[fatOffset + 2];
90 currentCluster = (currentCluster << 8) | fat[fatOffset + 1];
91 currentCluster = (currentCluster << 8) | fat[fatOffset + 0];
76 92 } }
77 93 } }
Hints

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