[victoriafalls] Add an Ext2Driver class which probes the superblock.
This commit is contained in:
parent
0274339cc9
commit
a49d13f1d1
|
@ -1,4 +1,5 @@
|
||||||
add_executable(victoriafalls
|
add_executable(victoriafalls
|
||||||
|
fs/ext2/ext2_driver.cpp
|
||||||
victoriafalls.cpp)
|
victoriafalls.cpp)
|
||||||
|
|
||||||
target_include_directories(victoriafalls
|
target_include_directories(victoriafalls
|
||||||
|
|
|
@ -0,0 +1,62 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
struct Superblock {
|
||||||
|
uint32_t inodes_count;
|
||||||
|
uint32_t blocks_count;
|
||||||
|
uint32_t reserved_blocks_count;
|
||||||
|
uint32_t free_blocks_count;
|
||||||
|
uint32_t free_inodes_count;
|
||||||
|
uint32_t first_data_blok;
|
||||||
|
uint32_t log_block_size;
|
||||||
|
uint32_t log_frag_size;
|
||||||
|
uint32_t blocks_per_group;
|
||||||
|
uint32_t frags_per_group;
|
||||||
|
uint32_t inodes_per_group;
|
||||||
|
uint32_t mtime;
|
||||||
|
uint32_t wtime;
|
||||||
|
uint16_t mnt_count;
|
||||||
|
uint16_t max_mnt_count;
|
||||||
|
uint16_t magic;
|
||||||
|
uint16_t state;
|
||||||
|
uint16_t errors;
|
||||||
|
uint16_t minor_rev_level;
|
||||||
|
uint32_t lastcheck;
|
||||||
|
uint32_t checkinterval;
|
||||||
|
uint32_t creator_os;
|
||||||
|
uint32_t rev_level;
|
||||||
|
uint16_t def_resuid;
|
||||||
|
uint16_t def_resgid;
|
||||||
|
} __attribute__((__packed__));
|
||||||
|
|
||||||
|
struct BlockGroupDescriptor {
|
||||||
|
uint32_t block_bitmap;
|
||||||
|
uint32_t inode_bitmap;
|
||||||
|
uint32_t inode_table;
|
||||||
|
uint16_t free_blocks_count;
|
||||||
|
uint16_t free_inodes_count;
|
||||||
|
uint16_t used_dirs_count;
|
||||||
|
uint8_t reserved[14];
|
||||||
|
} __attribute__((__packed__));
|
||||||
|
|
||||||
|
struct Inode {
|
||||||
|
uint16_t mode;
|
||||||
|
uint16_t uid;
|
||||||
|
uint32_t size;
|
||||||
|
uint32_t atime;
|
||||||
|
uint32_t ctime;
|
||||||
|
uint32_t mtime;
|
||||||
|
uint32_t dtime;
|
||||||
|
uint16_t gid;
|
||||||
|
uint16_t links_count;
|
||||||
|
uint32_t blocks;
|
||||||
|
uint32_t flags;
|
||||||
|
uint32_t osd1;
|
||||||
|
uint32_t block[15];
|
||||||
|
uint32_t generation;
|
||||||
|
uint32_t file_acl;
|
||||||
|
uint32_t dir_acl;
|
||||||
|
uint32_t faddr;
|
||||||
|
uint32_t osd2[3];
|
||||||
|
} __attribute__((__packed__));
|
|
@ -0,0 +1,50 @@
|
||||||
|
#include "fs/ext2/ext2_driver.h"
|
||||||
|
|
||||||
|
#include <mammoth/debug.h>
|
||||||
|
|
||||||
|
glcr::ErrorCode Ext2Driver::ProbePartition() {
|
||||||
|
// Read 1024 bytes from 1024 offset.
|
||||||
|
// FIXME: Don't assume 512 byte sectors somehow.
|
||||||
|
ASSIGN_OR_RETURN(MappedMemoryRegion superblock, denali_.ReadSectors(2, 2));
|
||||||
|
superblock_ = reinterpret_cast<Superblock*>(superblock.vaddr());
|
||||||
|
|
||||||
|
if (superblock_->magic != 0xEF53) {
|
||||||
|
dbgln("Invalid EXT2 magic code: %x");
|
||||||
|
return glcr::INVALID_ARGUMENT;
|
||||||
|
}
|
||||||
|
dbgln("Block size: 0x%x", 1024 << superblock_->log_block_size);
|
||||||
|
|
||||||
|
dbgln("Blocks: 0x%x (0x%x per group)", superblock_->blocks_count,
|
||||||
|
superblock_->blocks_per_group);
|
||||||
|
dbgln("Inodes: 0x%x (0x%x per group)", superblock_->inodes_count,
|
||||||
|
superblock_->inodes_per_group);
|
||||||
|
|
||||||
|
dbgln("Mounts: 0x%x out of 0x%x", superblock_->mnt_count,
|
||||||
|
superblock_->max_mnt_count);
|
||||||
|
dbgln("State: %x", superblock_->state);
|
||||||
|
|
||||||
|
dbgln("Created by: %x", superblock_->creator_os);
|
||||||
|
|
||||||
|
uint64_t num_block_groups =
|
||||||
|
superblock_->blocks_count / superblock_->blocks_per_group;
|
||||||
|
dbgln("\nReading %u blocks groups", num_block_groups);
|
||||||
|
uint64_t bgdt_bytes = sizeof(BlockGroupDescriptor) * num_block_groups;
|
||||||
|
uint64_t bgdt_block = (superblock_->log_block_size == 0) ? 2 : 1;
|
||||||
|
ASSIGN_OR_RETURN(MappedMemoryRegion bgdt,
|
||||||
|
ReadBlocks(bgdt_block, BytesToBlockCount(bgdt_bytes)));
|
||||||
|
|
||||||
|
BlockGroupDescriptor* bgds =
|
||||||
|
reinterpret_cast<BlockGroupDescriptor*>(bgdt.vaddr());
|
||||||
|
|
||||||
|
for (uint64_t i = 0; i < num_block_groups; i++) {
|
||||||
|
dbgln("BGD %x", i);
|
||||||
|
dbgln("Block Bitmap: %x", bgds[i].block_bitmap);
|
||||||
|
dbgln("Inode Bitmap: %x", bgds[i].inode_bitmap);
|
||||||
|
dbgln("Inode Table: %x", bgds[i].inode_table);
|
||||||
|
dbgln("Free blocks: %x", bgds[i].free_blocks_count);
|
||||||
|
dbgln("Free inodes: %x", bgds[i].free_inodes_count);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t root_inode = 2;
|
||||||
|
return glcr::OK;
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <denali/denali_client.h>
|
||||||
|
#include <glacier/memory/move.h>
|
||||||
|
|
||||||
|
#include "fs/ext2/ext2.h"
|
||||||
|
|
||||||
|
class Ext2Driver {
|
||||||
|
public:
|
||||||
|
Ext2Driver(ScopedDenaliClient&& denali) : denali_(glcr::Move(denali)) {}
|
||||||
|
|
||||||
|
glcr::ErrorCode ProbePartition();
|
||||||
|
|
||||||
|
glcr::ErrorOr<MappedMemoryRegion> ReadBlocks(uint64_t block_num,
|
||||||
|
uint64_t num_blocks) {
|
||||||
|
return denali_.ReadSectors(SectorsPerBlock() * block_num,
|
||||||
|
SectorsPerBlock() * num_blocks);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t SectorsPerBlock() { return 1 << (superblock_->log_block_size + 1); }
|
||||||
|
uint64_t BlockToLba(uint64_t block) { return block * SectorsPerBlock(); }
|
||||||
|
uint64_t BytesToBlockCount(uint64_t bytes) {
|
||||||
|
return (bytes - 1) / (1024 << superblock_->log_block_size) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
ScopedDenaliClient denali_;
|
||||||
|
Superblock* superblock_;
|
||||||
|
};
|
|
@ -2,13 +2,7 @@
|
||||||
#include <mammoth/init.h>
|
#include <mammoth/init.h>
|
||||||
#include <yellowstone_stub.h>
|
#include <yellowstone_stub.h>
|
||||||
|
|
||||||
struct Superblock {
|
#include "fs/ext2/ext2_driver.h"
|
||||||
uint32_t inode_count;
|
|
||||||
uint32_t blocks_count;
|
|
||||||
uint32_t reserved_blocks_count;
|
|
||||||
uint32_t free_blocks_count;
|
|
||||||
uint32_t free_inodes_count;
|
|
||||||
};
|
|
||||||
|
|
||||||
uint64_t main(uint64_t init_cap) {
|
uint64_t main(uint64_t init_cap) {
|
||||||
ParseInitPort(init_cap);
|
ParseInitPort(init_cap);
|
||||||
|
@ -17,12 +11,9 @@ uint64_t main(uint64_t init_cap) {
|
||||||
|
|
||||||
YellowstoneStub yellowstone(gInitEndpointCap);
|
YellowstoneStub yellowstone(gInitEndpointCap);
|
||||||
ASSIGN_OR_RETURN(ScopedDenaliClient denali, yellowstone.GetDenali());
|
ASSIGN_OR_RETURN(ScopedDenaliClient denali, yellowstone.GetDenali());
|
||||||
|
Ext2Driver ext2(glcr::Move(denali));
|
||||||
|
|
||||||
ASSIGN_OR_RETURN(MappedMemoryRegion region, denali.ReadSectors(2, 2));
|
check(ext2.ProbePartition());
|
||||||
Superblock* super = reinterpret_cast<Superblock*>(region.vaddr());
|
|
||||||
|
|
||||||
dbgln("Inodes: %x / %x", super->free_inodes_count, super->inode_count);
|
|
||||||
dbgln("Blocks: %x / %x", super->free_blocks_count, super->blocks_count);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue