summaryrefslogtreecommitdiff
path: root/fs/ext2.c
diff options
context:
space:
mode:
authorMichal Idziorek <m.i@gmx.at>2014-10-22 01:50:07 +0200
committerMichal Idziorek <m.i@gmx.at>2014-10-22 01:50:07 +0200
commit27a5147baf83f07e0f9cc53c56356a5d2152a5ee (patch)
tree9338c87c0805ee5e2c8a9c50eb2198ba5f40a550 /fs/ext2.c
parent67ec3995b4fd2c65c3f741d2fc16aa6983b5baa3 (diff)
started simple ext2 driver (read-only)
Diffstat (limited to 'fs/ext2.c')
-rw-r--r--fs/ext2.c186
1 files changed, 186 insertions, 0 deletions
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("");
+
+
+
+
+}
+
+
+