[ext2] Read ext2 initial ramdisk image and print out a file's content
This commit is contained in:
parent
8caba9f095
commit
21260c345c
2
Makefile
2
Makefile
@ -18,7 +18,7 @@ run: bootdisk.img
|
||||
qemu -fda bootdisk.img
|
||||
|
||||
kernel: start.o link.ld main.o core
|
||||
${LD} -T link.ld -o kernel *.o core/*.o
|
||||
${LD} -T link.ld -o kernel *.o core/*.o core/fs/*.o
|
||||
|
||||
%.o: %.c
|
||||
${CC} ${CFLAGS} -I./include -c -o $@ $<
|
||||
|
@ -1,10 +1,13 @@
|
||||
include ../Makefile.inc
|
||||
.PHONY: all clean install core
|
||||
.PHONY: all clean install fs
|
||||
|
||||
all: system.o multiboot.o gdt.o idt.o irq.o isrs.o kbd.o kprintf.o timer.o vga.o mem.o panic.o alloc.o vfs.o
|
||||
all: system.o multiboot.o gdt.o idt.o irq.o isrs.o kbd.o kprintf.o timer.o vga.o mem.o panic.o alloc.o vfs.o fs
|
||||
|
||||
%.o: %.c
|
||||
${CC} ${CFLAGS} -I../include -c -o $@ $<
|
||||
|
||||
fs:
|
||||
cd fs; ${MAKE} ${MFLAGS}
|
||||
|
||||
clean:
|
||||
-rm -f *.o
|
||||
|
10
core/fs/Makefile
Normal file
10
core/fs/Makefile
Normal file
@ -0,0 +1,10 @@
|
||||
include ../../Makefile.inc
|
||||
.PHONY: all clean install
|
||||
|
||||
all: ext2_initrd.o
|
||||
|
||||
%.o: %.c
|
||||
${CC} ${CFLAGS} -I../../include -c -o $@ $<
|
||||
|
||||
clean:
|
||||
-rm -f *.o
|
4
core/fs/ext2_initrd.c
Normal file
4
core/fs/ext2_initrd.c
Normal file
@ -0,0 +1,4 @@
|
||||
#include <system.h>
|
||||
#include <ext2.h>
|
||||
|
||||
|
152
include/ext2.h
Normal file
152
include/ext2.h
Normal file
@ -0,0 +1,152 @@
|
||||
#ifndef EXT2_H
|
||||
#define EXT2_h
|
||||
|
||||
#include <system.h>
|
||||
#include <fs.h>
|
||||
|
||||
#define EXT2_SUPER_MAGIC 0xEF53
|
||||
|
||||
struct ext2_superblock {
|
||||
uint32_t inodes_count;
|
||||
uint32_t blocks_count;
|
||||
uint32_t r_blocks_count;
|
||||
uint32_t free_blocks_count;
|
||||
uint32_t free_inodes_count;
|
||||
uint32_t first_data_block;
|
||||
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;
|
||||
|
||||
/* EXT2_DYNAMIC_REV */
|
||||
uint32_t first_ino;
|
||||
uint16_t inode_size;
|
||||
uint16_t block_group_nr;
|
||||
uint32_t feature_compat;
|
||||
uint32_t feature_incompat;
|
||||
uint32_t feature_ro_compat;
|
||||
|
||||
uint8_t uuid[16];
|
||||
uint8_t volume_name[16];
|
||||
|
||||
uint8_t last_mounted[16];
|
||||
|
||||
uint32_t algo_bitmap;
|
||||
|
||||
/* Performance Hints */
|
||||
uint8_t prealloc_blocks;
|
||||
uint8_t prealloc_dir_blocks;
|
||||
uint16_t _padding;
|
||||
|
||||
/* Journaling Support */
|
||||
uint8_t journal_uuid[16];
|
||||
uint32_t journal_inum;
|
||||
uint32_t jounral_dev;
|
||||
uint32_t last_orphan;
|
||||
|
||||
/* Directory Indexing Support */
|
||||
uint32_t hash_seed[4];
|
||||
uint8_t def_hash_version;
|
||||
uint16_t _padding_a;
|
||||
uint8_t _padding_b;
|
||||
|
||||
/* Other Options */
|
||||
uint32_t default_mount_options;
|
||||
uint32_t first_meta_bg;
|
||||
uint8_t _unused[760];
|
||||
|
||||
} __attribute__((packed));
|
||||
|
||||
typedef struct ext2_superblock ext2_superblock_t;
|
||||
|
||||
struct ext2_bgdescriptor {
|
||||
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;
|
||||
uint16_t pad;
|
||||
uint8_t reserved[12];
|
||||
} __attribute__((packed));
|
||||
|
||||
typedef struct ext2_bgdescriptor ext2_bgdescriptor_t;
|
||||
|
||||
/* File Types */
|
||||
#define EXT2_S_IFSOCK 0xC000
|
||||
#define EXT2_S_IFLNK 0xA000
|
||||
#define EXT2_S_IFREG 0x8000
|
||||
#define EXT2_S_IFBLK 0x6000
|
||||
#define EXT2_S_IFDIR 0x4000
|
||||
#define EXT2_S_IFCHR 0x2000
|
||||
#define EXT2_S_IFIFO 0x1000
|
||||
|
||||
/* setuid, etc. */
|
||||
#define EXT2_S_ISUID 0x0800
|
||||
#define EXT2_S_ISGID 0x0400
|
||||
#define EXT2_S_ISVTX 0x0200
|
||||
|
||||
/* rights */
|
||||
#define EXT2_S_IRUSR 0x0100
|
||||
#define EXT2_S_IWUSR 0x0080
|
||||
#define EXT2_S_IXUSR 0x0040
|
||||
#define EXT2_S_IRGRP 0x0020
|
||||
#define EXT2_S_IWGRP 0x0010
|
||||
#define EXT2_S_IXGRP 0x0008
|
||||
#define EXT2_S_IROTH 0x0004
|
||||
#define EXT2_S_IWOTH 0x0002
|
||||
#define EXT2_S_IXOTH 0x0001
|
||||
|
||||
|
||||
struct ext2_inodetable {
|
||||
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;
|
||||
uint8_t osd2[12];
|
||||
} __attribute__((packed));
|
||||
|
||||
typedef struct ext2_inodetable ext2_inodetable_t;
|
||||
|
||||
struct ext2_dir {
|
||||
uint32_t inode;
|
||||
uint16_t rec_len;
|
||||
uint8_t name_len;
|
||||
uint8_t file_type;
|
||||
char name; /* Actually a set of characters, at most 255 bytes */
|
||||
} __attribute__((packed));
|
||||
|
||||
typedef struct ext2_dir ext2_dir_t;
|
||||
|
||||
#endif
|
@ -8,7 +8,9 @@
|
||||
typedef unsigned long uintptr_t;
|
||||
typedef long size_t;
|
||||
typedef unsigned int uint32_t;
|
||||
typedef unsigned short uint16_t;
|
||||
typedef unsigned char uint8_t;
|
||||
typedef unsigned long long uint64_t;
|
||||
|
||||
/* Unimportant Kernel Strings */
|
||||
#define KERNEL_UNAME "ToAruOS"
|
||||
|
78
main.c
78
main.c
@ -31,6 +31,7 @@
|
||||
|
||||
#include <system.h>
|
||||
#include <multiboot.h>
|
||||
#include <ext2.h>
|
||||
|
||||
/*
|
||||
* kernel entry point
|
||||
@ -88,18 +89,77 @@ main(struct multiboot *mboot_ptr) {
|
||||
/* Print multiboot information */
|
||||
dump_multiboot(mboot_ptr);
|
||||
|
||||
kprintf("Will begin dumping from second kB of module 1 in a second.\n");
|
||||
timer_wait(100);
|
||||
kprintf("Dumping.\n");
|
||||
uint32_t i;
|
||||
uint32_t module_start = *((uint32_t*)mboot_ptr->mods_addr);
|
||||
uint32_t module_end = *(uint32_t*)(mboot_ptr->mods_addr+4);
|
||||
for (i = module_start + 1024; i < module_end; ++i) {
|
||||
kprintf("%c ", *((char *)i));
|
||||
if (i % 35 == 0) { kprintf("\n"); }
|
||||
timer_wait(1);
|
||||
}
|
||||
|
||||
ext2_superblock_t * superblock = (ext2_superblock_t *)(module_start + 1024);
|
||||
kprintf("Magic is 0x%x\n", (int)superblock->magic);
|
||||
assert(superblock->magic == EXT2_SUPER_MAGIC);
|
||||
|
||||
kprintf("Partition has %d inodes and %d blocks.\n", superblock->inodes_count, superblock->blocks_count);
|
||||
kprintf("%d blocks reserved for root\n", superblock->r_blocks_count);
|
||||
kprintf("%d blocks free\n", superblock->free_blocks_count);
|
||||
kprintf("%d free inodes\n", superblock->free_inodes_count);
|
||||
kprintf("Blocks contain %d bytes\n", 1024 << superblock->log_block_size);
|
||||
kprintf("Fragments contain %d bytes\n", 1024 << superblock->log_frag_size);
|
||||
kprintf("I am at block id: %d (should be 1 if this is a 1KB block)\n", superblock->first_data_block);
|
||||
kprintf("There are %d blocks in a group\n", superblock->blocks_per_group);
|
||||
kprintf("There are %d fragments in a group\n", superblock->frags_per_group);
|
||||
kprintf("There are %d inodes in a group\n", superblock->inodes_per_group);
|
||||
kprintf("Last mount: 0x%x\n", superblock->mtime);
|
||||
kprintf("Last write: 0x%x\n", superblock->wtime);
|
||||
kprintf("Mounts since verification: %d\n", superblock->mnt_count);
|
||||
kprintf("Must be verified in %d mounts\n", superblock->max_mnt_count - superblock->mnt_count);
|
||||
kprintf("Inodes are %d bytes\n", (int)superblock->inode_size);
|
||||
|
||||
ext2_bgdescriptor_t * blockgroups = (ext2_bgdescriptor_t *)(module_start + 1024 + 1024);
|
||||
kprintf("First block group has %d free blocks, %d free inodes, %d used dirs\n",
|
||||
blockgroups->free_blocks_count,
|
||||
blockgroups->free_inodes_count,
|
||||
blockgroups->used_dirs_count);
|
||||
|
||||
ext2_inodetable_t * inodetable = (ext2_inodetable_t *)(module_start + (1024 << superblock->log_block_size) * blockgroups->inode_table);
|
||||
uint32_t i;
|
||||
for (i = 0; i < superblock->inodes_per_group; ++i) {
|
||||
ext2_inodetable_t * inode = (ext2_inodetable_t *)((int)inodetable + (int)superblock->inode_size * i);
|
||||
if (inode->block[0] == 0)
|
||||
continue;
|
||||
kprintf("Inode %d starts at block %d,%d and is %d bytes (%d blocks). ", i, inode->block[0], inode->block[1], inode->size, inode->blocks);
|
||||
if (inode->mode & EXT2_S_IFDIR) {
|
||||
kprintf("is a directory\n");
|
||||
kprintf("File listing:\n");
|
||||
uint32_t dir_offset;
|
||||
dir_offset = 0;
|
||||
while (dir_offset < inode->size) {
|
||||
ext2_dir_t * d_ent = (ext2_dir_t *)(module_start + (1024 << superblock->log_block_size) * inode->block[0] + dir_offset);
|
||||
unsigned char * name = malloc(sizeof(unsigned char) * (d_ent->name_len + 1));
|
||||
memcpy(name, &d_ent->name, d_ent->name_len);
|
||||
name[d_ent->name_len] = '\0';
|
||||
kprintf("[%d] %s [%d]\n", dir_offset, name, d_ent->inode);
|
||||
if (name[0] == 'h' &&
|
||||
name[1] == 'e' &&
|
||||
name[2] == 'l' &&
|
||||
name[3] == 'l' &&
|
||||
name[4] == 'o') {
|
||||
kprintf("Found a file to read.\n");
|
||||
ext2_inodetable_t * inode_f = (ext2_inodetable_t *)((int)inodetable + (int)superblock->inode_size * (d_ent->inode -1));
|
||||
kprintf("Going to print %d bytes from block %d\n", inode_f->size, inode_f->block[0]);
|
||||
unsigned char * file_pointer = (unsigned char *)(module_start + (1024 << superblock->log_block_size) * inode_f->block[0]);
|
||||
unsigned int file_offset;
|
||||
for (file_offset = 0; file_offset < inode_f->size; ++file_offset) {
|
||||
kprintf("%c", file_pointer[file_offset]);
|
||||
}
|
||||
}
|
||||
|
||||
free(name);
|
||||
dir_offset += d_ent->rec_len;
|
||||
if (d_ent->inode == 0)
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
kprintf("\n");
|
||||
};
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user