diff --git a/fs_generator.c b/fs_generator.c new file mode 100644 index 0000000..243479e --- /dev/null +++ b/fs_generator.c @@ -0,0 +1,55 @@ +/* This program comes from James Molloy tutorial + * on how to create an UNIX clone You can find the original code at: + * http://www.jamesmolloy.co.uk/tutorial_html/8.-The%20VFS%20and%20the%20initrd.html */ + +#include +#include +#include + +struct initrd_header { + unsigned char magic; // Magic number for consistency + char name[64]; + unsigned int offset; // Offset of the file start + unsigned int length; +}; + +int main(int argc, char **argv) { + int heads = (argc - 1) / 2; + struct initrd_header headers[64]; + printf("Size of header(in bytes): %ld\n", sizeof(struct initrd_header)); + unsigned int off = sizeof(struct initrd_header) * 64 + sizeof(int); + for(int i = 0; i < heads; i++) { + printf("Writing file %s->%s at 0x%d\n", argv[i*2+1], argv[i*2+2], off); + strcpy(headers[i].name, argv[i*2+2]); + headers[i].offset = off; + FILE *stream = fopen(argv[i*2+1], "r"); + if(stream == 0) { + puts("Error, file not found!"); + return 1; + } + fseek(stream, 0, SEEK_END); + headers[i].length = ftell(stream); + off += headers[i].length; + fclose(stream); + headers[i].magic = 0xBF; + } + + FILE *wstream = fopen("./initrd.img", "w"); + unsigned char *data = (unsigned char*)malloc(off); + fwrite(&heads, sizeof(int), 1, wstream); + fwrite(&heads, sizeof(struct initrd_header), 64, wstream); + + for(int i = 0; i < heads; i++) { + FILE *stream = fopen(argv[i*2+1], "r"); + unsigned char *buf = (unsigned char*)malloc(headers[i].length); + fread(buf, 1, headers[i].length, stream); + fread(buf, 1, headers[i].length, wstream); + fclose(stream); + free(buf); + } + + fclose(wstream); + free(data); + + return 0; +} \ No newline at end of file diff --git a/iceOS.iso b/iceOS.iso new file mode 100644 index 0000000..83f14b8 Binary files /dev/null and b/iceOS.iso differ diff --git a/isodir/boot/grub/grub.cfg b/isodir/boot/grub/grub.cfg new file mode 100644 index 0000000..38bd850 --- /dev/null +++ b/isodir/boot/grub/grub.cfg @@ -0,0 +1,7 @@ +set timeout = 0 +set default = 0 + +menuentry "iceOS" { + multiboot2 /boot/iceOS.bin + boot +} \ No newline at end of file diff --git a/isodir/boot/iceOS.bin b/isodir/boot/iceOS.bin new file mode 100755 index 0000000..60fa387 Binary files /dev/null and b/isodir/boot/iceOS.bin differ diff --git a/kernel/drivers/fs.c b/kernel/drivers/fs.c new file mode 100644 index 0000000..622d857 --- /dev/null +++ b/kernel/drivers/fs.c @@ -0,0 +1,51 @@ +#include "fs.h" + +fs_node_t *fs_root = 0; // Initialize the root of the filesystem + +uint32_t read_fs(fs_node_t *node, uint32_t offset, uint32_t size, uint8_t *buffer) { + // Check if inode got a read callback from the kernel + if(node->read != 0) + return node->read(node, offset, size, buffer); + else + return 0; +} + +uint32_t write_fs(fs_node_t *node, uint32_t offset, uint32_t size, uint8_t *buffer) { + // Check if inode got a write callback from the kernel + if(node->write != 0) + return node->write(node, offset, size, buffer); + else + return 0; +} + +void open_fs(fs_node_t *node, uint8_t read, uint8_t write) { + // Check if inode got a open callback from the kernel + if(node->open != 0) + return node->open(node); + else + return 0; +} + +void close_fs(fs_node_t *node) { + // Check if inode got a close callback from the kernel + if(node->close =! 0) + return node->close(node); + else + return 0; +} + +struct dirent *readdir_fs(fs_node_t *node, uint32_t index) { + // Read dir content(only if file descriptor is FS_DIRECTORY) + if((node->flags&0x7) == FS_DIRECTORY && node->readdir != 0) + return node->readdir(node, index); + else + return 0; +} + +fs_node_t *finddir_fs(fs_node_t *node, char *name) { + // Check if an inode is a directory + if((node->flags&0x7) == FS_DIRECTORY && node->finddir != 0) + return node->finddir(node, name); + else + return 0; +} \ No newline at end of file diff --git a/kernel/drivers/fs.h b/kernel/drivers/fs.h new file mode 100644 index 0000000..03e5b11 --- /dev/null +++ b/kernel/drivers/fs.h @@ -0,0 +1,84 @@ +/************************************** + * iceOS Kernel * + * Developed by Marco 'icebit' Cetica * + * (c) 2019 * + * Released under GPLv3 * + * https://github.com/ice-bit/iceOS * + ***************************************/ +#ifndef FS_H +#define FS_H + +#include +/* This Virtual File System(VFS) is a simplified version of + * standard UNIX VFS where all files comes organized in a graph + * of nodes. Keeping in mind the concept of "everything is a file" we can + * store a file, a directory, a serial device or anything else just by adding + * a new node to the data structure. + * And this is a list of common operations: + * - Open: Initialize a new node as a file descriptor + * - Close: CLose a node + * - Read: return the content of a node + * - Write: set content to node + * - Readdir: Return directory content + * - Finddir: Given a specific name find the corresponding child node.*/ + +// Define some standard node types +#define FS_FILE 0x01 +#define FS_DIRECTORY 0x02 +#define FS_CHARDEVICE 0x03 +#define FS_BLOCKDEVICE 0x04 +#define FS_PIPE 0x05 +#define FS_SYMLINK 0x06 +#define FS_MOUNTPOINT 0x08 + +struct fs_node; + +/* Define some callbacks to be called when read/write/open/close + * operations are called */ +typedef uint32_t (*read_type_t)(struct fs_node*, uint32_t, uint32_t, uint8_t*); +typedef uint32_t (*write_type_t)(struct fs_node*, uint32_t, uint32_t, uint8_t*); +typedef void (*open_type_t)(struct fs_node*); +typedef void (*close_type_t)(struct fs_node*); +typedef struct dirent*(*readdir_type_t)(struct fs_node*, uint32_t); +typedef struct fs_node*(*finddir_type_t)(struct fs_node*, char *name); + +// This define the structure of a node +typedef struct fs_node { + uint8_t name[128]; // File name + uint32_t mask; // Permission mask + uint32_t uid; // Owning user + uint32_t gid; // Owning group + uint32_t flags; // Node type + uint32_t inode; // used by file systems to identify files + uint32_t length; // Length of the file, in bytes. + uint32_t impl; + // Callback section + read_type_t read; + write_type_t write; + open_type_t open; + close_type_t close; + readdir_type_t readdir; + finddir_type_t finddir; + struct fs_node *ptr; // Used by mountpoints and symlinks +} fs_node_t; + +struct dirent { + uint8_t name[120]; // File name + uint32_t ino; // POSIX standard requires inode number; +}; + +// Filesystem root +extern fs_node_t *fs_root; + +/* Write/Read/Open/Close operations + * NOTE: those functions are NOT like the Callback + * functions; the first one deals with inodes while + * the second one deals with file descriptors. */ +uint32_t read_fs(fs_node_t *node, uint32_t offset, uint32_t size, uint8_t *buffer); +uint32_t write_fs(fs_node_t *node, uint32_t offset, uint32_t size, uint8_t *buffer); +void open_fs(fs_node_t *node, uint8_t read, uint8_t write); +void close_fs(fs_node_t *node); +struct dirent *readdir_fs(fs_node_t *node, uint32_t index); +fs_node_t *finddir_fs(fs_node_t *node, char *name); + +#endif \ No newline at end of file diff --git a/kernel/drivers/gdt.h b/kernel/drivers/gdt.h index ed0185e..9d6a8b5 100644 --- a/kernel/drivers/gdt.h +++ b/kernel/drivers/gdt.h @@ -136,5 +136,4 @@ typedef struct gdt_ptr gdt_ptr_t; /* GDT Kernel API */ void gdt_setup(); - #endif