diff options
| author | Michal Idziorek <m.i@gmx.at> | 2014-10-22 01:50:07 +0200 |
|---|---|---|
| committer | Michal Idziorek <m.i@gmx.at> | 2014-10-22 01:50:07 +0200 |
| commit | 27a5147baf83f07e0f9cc53c56356a5d2152a5ee (patch) | |
| tree | 9338c87c0805ee5e2c8a9c50eb2198ba5f40a550 /fs | |
| parent | 67ec3995b4fd2c65c3f741d2fc16aa6983b5baa3 (diff) | |
started simple ext2 driver (read-only)
Diffstat (limited to 'fs')
| -rw-r--r-- | fs/Makefile | 9 | ||||
| -rw-r--r-- | fs/ext2.c | 186 |
2 files changed, 195 insertions, 0 deletions
diff --git a/fs/Makefile b/fs/Makefile new file mode 100644 index 0000000..c88dda4 --- /dev/null +++ b/fs/Makefile @@ -0,0 +1,9 @@ +run: a.out + ./a.out < ext2.img +a.out: ext2.c + gcc ext2.c -std=c11 +filesys: + dd if=/dev/zero of=ext2.img bs=512 count=10000 + sudo mkfs.ext2 -O ^large_file ext2.img + + diff --git a/fs/ext2.c b/fs/ext2.c new file mode 100644 index 0000000..f96d4f0 --- /dev/null +++ b/fs/ext2.c @@ -0,0 +1,186 @@ +// ext2 minidriver +// based on osdev wiki article: http://wiki.osdev.org/Ext2 + +#include <stdint.h> +#include <stdio.h> + +typedef struct ext2_superblock_struct +{ + uint32_t inodes_count; + uint32_t blocks_count; + uint32_t blocks_reserved_count; + uint32_t inodes_unalloc_count; + uint32_t blocks_unalloc_count; + uint32_t superblock_number; + uint32_t block_size; + uint32_t fragment_size; + uint32_t blocks_per_group; + uint32_t fragments_per_group; + uint32_t inodes_per_group; + uint8_t skip[12]; // maybe we will look at these fields later... + uint16_t ext2_sig; // 0xef5 + uint16_t fs_state; + uint16_t error_handle; + uint16_t version_minor; + uint8_t skip2[8]; // maybe we will look at these fields later... + uint32_t os_id; + uint32_t version_major; + uint16_t uid_reserved; + uint16_t gid_reserved; +}ext2_superblock; + +typedef struct ext2_superblock_ext_struct +{ + uint32_t first_inode; + uint16_t size_inode; + uint16_t blockgroup; + + uint32_t features_opt; + uint32_t features_req; + uint32_t features_write; + + uint32_t blkid[4]; + char vol_name[16]; + char last_path[64]; + uint32_t compression; + uint8_t prealloc_files; + uint8_t prealloc_dirs; + uint8_t unused[2]; + uint32_t journalid[4]; + uint32_t journal_inode; + uint32_t journal_device; + uint32_t orpan_head; + +}ext2_superblock_ext; + +typedef struct ext2_blockgroup_desc_struct +{ + uint32_t addr_block_bitmap; + uint32_t addr_inode_bitmap;; + uint32_t addr_inode_table; + uint16_t unalloc_blocks_count; + uint16_t unalloc_inodes_count; + uint16_t dir_count; + uint8_t unused[14]; +}ext2_blockgroup_desc; + +typedef struct ext2_dir_struct +{ + uint32_t inode; + uint16_t size; + uint8_t name_length_low; + uint8_t name_length_high; + // name follows + char name[10]; // TODO: load dynamiccaly N chars! +}ext2_dir; + +typedef struct ext2_inode_struct +{ + uint16_t permissions; + uint16_t user_id; + uint32_t size_low; + uint32_t skip[4]; + uint16_t group_id; + uint16_t hardlink_count; + uint32_t disk_sectors; + uint32_t flags; + uint32_t os_specific; + uint32_t direct_pointer[12]; + uint32_t indirect1; + uint32_t indirect2; + uint32_t indirect3; + uint32_t gen_num; + uint32_t later1; // will be implemented later by the fooldriver + uint32_t later2; + uint32_t frag; + uint32_t os_spec2[3]; +}ext2_inode; + + +int main() +{ + ext2_superblock super; + ext2_superblock_ext super_ext; + + + printf("ext2 fools driver\n"); + printf("reading superblock...\n\n"); + + fseek(stdin,1024,SEEK_SET); + fread(&super,sizeof(super),1,stdin); + + printf("block size: %i\n",1024<<super.block_size); + printf("block count: %i\n",super.blocks_count); + printf("inode count: %i\n\n",super.inodes_count); + + printf("blocks/group: %i\n",super.blocks_per_group); + printf("inodes/group: %i\n\n",super.inodes_per_group); + + printf("signature: 0x%x\n",super.ext2_sig); + printf("fs state: %i\n",super.fs_state); + printf("version: %i.%i\n\n",super.version_major,super.version_minor); + + if(super.version_major>=1) + { + printf("getting extended fields...\n\n"); + fread(&super_ext,sizeof(super_ext),1,stdin); + + printf("first (non reserved) inode: %i\n",super_ext.first_inode); + printf("inode size: %i\n\n",super_ext.size_inode); + + printf("opt_features: %i\n",super_ext.features_opt); + printf("req_features: %i\n",super_ext.features_req); + printf("write_features: %i\n\n",super_ext.features_write); + + printf("volume name: %s\n",super_ext.vol_name); + printf("mount path: %s\n\n",super_ext.last_path); + + } + + ext2_blockgroup_desc desc; + printf("getting block group descriptors...\n\n"); + //TODO: only correct for 1024bytes/block. read more than one!!! + int block_size=1024; + int descriptor_start_block=2; + fseek(stdin,block_size*descriptor_start_block,SEEK_SET); + fread(&desc,sizeof(desc),1,stdin); + printf("block usage bitmap: 0x%x\n",desc.addr_block_bitmap); + printf("inode usage bitmap: 0x%x\n",desc.addr_inode_bitmap); + printf("inode table: 0x%x\n\n",desc.addr_inode_table); + printf("unalloc blocks: %i\n",desc.unalloc_blocks_count); + printf("unalloc inodes: %i\n",desc.unalloc_inodes_count); + printf("directories: %i\n\n",desc.dir_count); + + //TODO: check for version >1 + int inode_size=128; + ext2_inode inode; + printf("reading inode 2 (root dir)...\n\n"); + fseek(stdin,block_size*desc.addr_inode_table,SEEK_SET); + fread(&inode,sizeof(inode),1,stdin); + + fread(&inode,sizeof(inode),1,stdin); + + printf("---------- root ---------\n"); + printf("uid/gid: %i/%i\n",inode.user_id,inode.group_id); + printf("hardlinks: %i\n",inode.hardlink_count); + printf("direct block pointer 0: %i\n\n",inode.direct_pointer[0]); + + // read dir + ext2_dir dir; + fseek(stdin,block_size*inode.direct_pointer[0],SEEK_SET); + fread(&dir,sizeof(dir),1,stdin); + printf("inode: %i\n",dir.inode); + printf("total size: %i\n",dir.size); + printf("name: %s\n\n",dir.name); + + + puts(""); + puts(""); + + + + +} + + + |
