aboutsummaryrefslogtreecommitdiff
path: root/src/kernel/fs/marfs/read_whole_file.c
diff options
context:
space:
mode:
authorMarvin Borner2019-11-20 22:17:48 +0100
committerMarvin Borner2019-11-20 22:28:30 +0100
commit0ba991750314310a5e53b0d8135aef5b1352b261 (patch)
treeacae7106a24b85116cd7119bd239c3d9299f2ba8 /src/kernel/fs/marfs/read_whole_file.c
parent6ca5f1bcec7f0716bad5e1cdd38d41be137fe7e5 (diff)
Began two-stage hdd bootloader and os installer
Diffstat (limited to 'src/kernel/fs/marfs/read_whole_file.c')
-rw-r--r--src/kernel/fs/marfs/read_whole_file.c65
1 files changed, 65 insertions, 0 deletions
diff --git a/src/kernel/fs/marfs/read_whole_file.c b/src/kernel/fs/marfs/read_whole_file.c
new file mode 100644
index 0000000..86aae5f
--- /dev/null
+++ b/src/kernel/fs/marfs/read_whole_file.c
@@ -0,0 +1,65 @@
+#include <stdint.h>
+#include <kernel/fs/ata_pio.h>
+#include <kernel/lib/alloc.h>
+#include "marfs.h"
+
+static uint8_t last_maxlevel = 0;
+
+uint32_t marfs_get_recursive(uint8_t level, uint32_t i, uint32_t recLBA) {
+ if (level > last_maxlevel) last_maxlevel = level;
+ uint32_t *contents = (uint32_t *) ATA_read28(iface, recLBA);
+ uint32_t idx = i - 10;
+ if (last_maxlevel > 1) idx -= 1 << 7;
+ if (last_maxlevel > 2) idx -= 1 << (7 * 2);
+ if (last_maxlevel > 3) idx -= 1 << (7 * 3);
+ idx >>= 7 * (level - 1);
+
+ uint32_t next_recLBA = contents[idx];
+ kfree(contents);
+
+ uint32_t toRet;
+ if (level > 1) toRet = marfs_get_recursive(level - 1, i, next_recLBA);
+ else toRet = next_recLBA;
+ last_maxlevel = 0;
+ return toRet;
+}
+
+uint32_t marfs_get_block(struct marfs_INODE *inode, uint32_t i) {
+ if (i > 9 + (128 * 128 * 128)) {
+ return marfs_get_recursive(4, i, inode->ext_4);
+ } else if (i > 9 + (128 * 128)) {
+ return marfs_get_recursive(3, i, inode->ext_3);
+ } else if (i > 9 + 128) {
+ return marfs_get_recursive(2, i, inode->ext_2);
+ } else if (i > 9) {
+ return marfs_get_recursive(1, i, inode->ext_1);
+ } else {
+ return inode->DBPs[i];
+ }
+}
+
+void marfs_read_whole_file(uint32_t LBAinode, uint8_t *buffer) {
+ struct marfs_INODE *inode = (struct marfs_INODE *) ATA_read28(iface, LBAinode);
+
+ uint32_t size_in_blocks = inode->n_blocks;
+ for (uint32_t i = 0; i < size_in_blocks; i++) {
+ uint32_t this_block = marfs_get_block(inode, i);
+ uint8_t *this_block_contents = ATA_read28(iface, this_block);
+ uint16_t upper_bound = (i != size_in_blocks - 1) ? 512 : (inode->size % 512);
+ for (uint16_t j = 0; j < upper_bound; j++) buffer[(i * 512) + j] = this_block_contents[j];
+ kfree(this_block_contents);
+ }
+
+ kfree(inode);
+}
+
+// TODO: Beautify
+uint8_t *marfs_allocate_and_read_whole_file(uint32_t LBAinode) {
+ struct marfs_INODE *inode = (struct marfs_INODE *) ATA_read28(iface, LBAinode);
+ uint64_t size = inode->size;
+ kfree(inode);
+
+ uint8_t *buffer = kmalloc(size);
+ marfs_read_whole_file(LBAinode, buffer);
+ return buffer;
+}