ext2 can't find superblock

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
deltakatzu
Posts: 1
Joined: Tue Feb 04, 2020 8:17 pm

ext2 can't find superblock

Post by deltakatzu »

Hello there. I'm trying to implement the ext2 file system in my OS as my first FS.
However I can't locate the superblock. I search for it in LBA 2 (as the wiki & documentation states) but for some reason I can't find it and read the signature. Also I tried with the partition lba start (2048) / sector size (512) (which gives 4 in total) formula, but nothing. Any help?

Code: Select all

#include <vulpes/drivers/ata.h>
#include <vulpes/kernel.h>
#include <vulpes/tty.h>
#include <vulpes/panic.h>
#include <stdint.h>

struct ext2_superblock
{
    uint32_t inode_no;
    uint32_t block_no;
    uint32_t su_reserved_blocks;
    uint32_t unalloc_blocks_no;
    uint32_t unalloc_inodes_no;
    uint32_t block_no_sblock;
    uint32_t block_size;
    uint32_t fragment_size;
    uint32_t block_no_blockg;
    uint32_t fragment_no_blockg;
    uint32_t inodes_no_blockg;
    uint32_t last_mount_time;
    uint32_t last_written_time;
    uint16_t cons_mount_times; /* no. since last consistency check */
    uint16_t cons_mount_times_allowed; /* no. of mounts allowed before consistency check */
    uint16_t signature; /* 0xEF53 */
    uint16_t fs_state;
    uint16_t wtd_error; /* What to do when an error is detected */
    uint16_t version_minor;
    uint32_t cons_last_posix;
    uint32_t cons_finv_posix;
    uint32_t os_id;
    uint32_t version_major;
    uint16_t su_blocks_uid;
    uint16_t su_blocks_gid;
}__attribute__((packed));

struct ext2_block_group_descriptor
{
    uint32_t blk_addr_blk_bitmap;
    uint32_t blk_addr_inode_bitmap;
    uint32_t st_blk_addr_inode_table;
    uint16_t unalloc_blk_group_no;
    uint16_t unalloc_inode_group_no;
    uint16_t dir_group_no;
}__attribute__((packed));

struct os_specific_value2
{
    uint8_t fragment_number;
    uint8_t fragment_size;
    uint16_t res;
    uint16_t user_id_hi;
    uint16_t group_id_hi;
    uint32_t res1;
}__attribute__((packed));

struct ext2_inode_data
{
    uint16_t type_perm;
    uint16_t user_id;
    uint32_t size_low;
    uint32_t last_access;
    uint32_t creation_time;
    uint32_t last_modification;
    uint32_t delete_time;
    uint16_t group_id;
    uint16_t hard_link_count;
    uint32_t disk_sectors_count;
    uint32_t flags;
    uint32_t os_specific;
    uint32_t direct_block_pointer0;
    uint32_t direct_block_pointer1;
    uint32_t direct_block_pointer2;
    uint32_t direct_block_pointer3;
    uint32_t direct_block_pointer4;
    uint32_t direct_block_pointer5;
    uint32_t direct_block_pointer6;
    uint32_t direct_block_pointer7;
    uint32_t direct_block_pointer8;
    uint32_t direct_block_pointer9;
    uint32_t direct_block_pointer10;
    uint32_t direct_block_pointer11;
    uint32_t single_indirect_blk_ptr;
    uint32_t double_indirect_blk_ptr;
    uint32_t triple_indirect_blk_ptr;
    uint32_t generation_number;
    uint32_t extended_attr_block;
    uint32_t size_hi;
    uint32_t block_addr_fragment;
    struct os_specific_value2 os_specific2;
}__attribute__((packed));

enum fs_state
{
    fs_clean = 1,
    fs_dirty = 2,
};

enum fs_error_handling
{
    fs_err_ignore = 1,
    fs_err_mro = 2,
    fs_err_kp = 3,
};

enum fs_os
{
    fs_linux,
    fs_hurd,
    fs_masix,
    fs_freebsd,
    fs_otherbsd,
    fs_vulpes = 195,
};

enum fs_optional_features
{
    dir_prealloc = 0x0001,
    afss_inodes = 0x0002,
    has_journal = 0x0004,
    inodes_ext_attr = 0x0008,
    fs_self_resize = 0x0010,
    dir_can_hashin = 0x0020,
};

enum fs_required_features
{
    using_compress = 0x0001,
    dir_type_field = 0x0002,
    fs_journal_rep = 0x0004,
    fs_uses_journal_dev = 0x0008,
};

enum fs_read_features
{
    sparse_sblocks = 0x0001, /* (and gdts) */
    fs_uses_64file = 0x0002,
    dir_bintree = 0x0004,
};

#define EXT2_MAGIC 0xEF53

/* lba_start is the start of the partition */
void init_ext2(uint32_t lba_start)
{
    struct ext2_superblock ext2s;
    uint16_t buffer[1024 / 2];

    hd_read(2, sizeof(struct ext2_superblock), buffer);
    memcpy(&ext2s, buffer, sizeof(struct ext2_superblock));

    if (ext2s.signature != EXT2_MAGIC) {
        kprintf("Invalid ext2 signature %x (should be 0xEF53)\n", ext2s.signature);
        return;
    }

    kprintf("ext2 signature: %x, inodes: %i, os: %i\n", ext2s.signature, ext2s.inode_no, ext2s.os_id);
}

Octocontrabass
Member
Member
Posts: 5578
Joined: Mon Mar 25, 2013 7:01 pm

Re: ext2 can't find superblock

Post by Octocontrabass »

deltakatzu wrote:Also I tried with the partition lba start (2048) / sector size (512) (which gives 4 in total) formula, but nothing.
The superblock starts at LBA 2 relative to the start of the partition. So, if the partition starts at LBA 2048, then the superblock starts at LBA 2050.

Typically, filesystem drivers are given access to a "partition" device instead of the entire hard disk. That way, the driver can only read and write sectors within its partition, and doesn't need to worry about things like where the partition is located relative to the start of the disk (although this information can be useful as a performance hint). Of course, it's up to you to decide if your OS should do things like this.
User avatar
iansjack
Member
Member
Posts: 4703
Joined: Sat Mar 31, 2012 3:07 am
Location: Chichester, UK

Re: ext2 can't find superblock

Post by iansjack »

You might find it useful to inspect your disk with a hex editor to ensure that you understand its structure.
Post Reply