BMFS: Difference between revisions

From OSDev.wiki
Jump to navigation Jump to search
[unchecked revision][unchecked revision]
Content added Content deleted
(BMFS)
 
(Added link to documentation and how to open a directory.)
Line 44: Line 44:
You can also install it to /usr/local, to avoid having to do that.
You can also install it to /usr/local, to avoid having to do that.


=== Using the Library ===
=== Initializing the File System ===


Once the project is built, and your build system has the information to use the library, you can start writing code.
Once the project is built, and your build system has the information to use the library, you can start writing code.
Line 95: Line 95:
}
}
}
}

=== Opening a File ===


With the disk and the file system initialized, you can open the file.
With the disk and the file system initialized, you can open the file.


int open_file(const char *path) {
int show_file(const char *path) {
/* Initialize disk here. */
/* Initialize disk here. */
Line 118: Line 120:
}
}
bmfs_file_set_mode(&file, BMFS_MODE_RW);
bmfs_file_set_mode(&file, BMFS_MODE_READ);
char buf[512];
/* Read from or write to the file here. */
while (bmfs_file_eof(&file)) {
bmfs_uint64 read_count = 0;
err = bmfs_file_read(&file, buf, 512, &read_count);
if (err != 0)
break;
my_print_function(buf, read_count);
}
}
}

=== Opening a Directory ===

Opening a directory is similar to opening a file.

You'll have to initialize the file system the same as you did for the file.

int list_dir(const char *path) {
/* Initialize the file system here. */
struct BMFSDir dir;
bmfs_dir_init(&dir);
int err = bmfs_open_dir(&bmfs, &dir, path);
if (err == ENOTDIR) {
kprintf("Entry '%s' is not a directory.\n", path);
return -1;
} else if (err == ENOENT) {
kprintf("Directory '%s' does not exist.\n", path);
return -1;
} else if (err != 0) {
kprintf("Failed to open directory '%s'.\n", path);
return -1;
}
for (;;) {
const struct BMFSEntry *entry = bmfs_dir_next(&dir);
if (entry == BMFS_NULL)
break;
kprintf("Entry: %s\n", entry->Name);
}
}

=== Going Further ===

The library can do even more than that and new features are added continuously.

Visit the Doxygen generated documentation [https://returninfinity.github.io/bmfs-doc/modules.html] for more information.

Revision as of 00:11, 5 April 2018

BMFS

BMFS is a simple file system in active development that supports regular files and directories.

A Little History

BMFS was a file system initially designed by Ian Seyler for the BareMetal-OS project. Since then, it has been put into a separate project and the development continued there.

In it's initial design, it only supported a root directory with a maximum of 64 files. The idea was to have a simple file system that supported just enough of a file system for a database program to use.

The development continued and the design changed a bit, and now it supports sub-directories, file permissions, user and group IDs, and more.

It also comes with a user space program to construct file systems and examine their contents, and a FUSE binding to use BMFS on Linux systems.

The project is now being constantly improved, and one of its design goals is to be used in any other operating system.

Building BMFS

While using the instructions from the project is the most reliable way to build the project, this should also help build the project.

Starting by cloning the project using git, and entering the directory.

   git clone https://github.com/ReturnInfinity/BMFS
   cd BMFS

Then use GNU Make to build the project, specifying that you are cross compiling using the CONFIG variable.

   make CONFIG=cross

The cross compiler here defaults to x86_64-none-elf-gcc. If you would like to use a different target, use the CROSS_COMPILE variable like this:

   make CONFIG=cross CROSS_COMPILE=aarch64-none-elf-

Once the project is built, you can install it in a location of your choosing by using the PREFIX variable, and the install target.

   make CONFIG=cross install PREFIX=/home/taylor/.local

Now, you have the library libbmfs.a installed at /home/taylor/.local/lib and the headers installed at /home/taylor/include

That means you'll have to pass those paths to GCC, by doing something like this:

   gcc -I /home/taylor/.local/include -L /home/taylor/.local/lib

You can also install it to /usr/local, to avoid having to do that.

Initializing the File System

Once the project is built, and your build system has the information to use the library, you can start writing code.

The header bmfs/bmfs.h is there for convenience to include all the headers used in the project.

Start by including that header in your code.

   #include <bmfs/bmfs.h>
   
   void open_file(const char *path) {
       /* Do stuff here */
   }

Once that's done, you'll need to tell BMFS how to read the disk that contains the file system.

You can do that using the BMFSDisk structure.

   int my_disk_read(void *disk_data, void *buf, bmfs_uint64 len, bmfs_uint64 *read_len);
   
   int my_disk_seek(void *disk_data, bmfs_uint64_t pos, int whence);
   
   void open_file(const char *path) {
   
       struct BMFSDisk disk;
   
       bmfs_disk_init(&disk);
       disk.seek = my_disk_seek;
       disk.read = my_disk_read;
   }
   
   /* Implement my_disk_read and my_disk_seek */

Now that the disk is initialized, you can initialize the file system structure and read the file system contents.

   int open_file(const char *path) {
   
       /* Initialize disk here */
   
       struct BMFS bmfs;
   
       bmfs_init(&bmfs);
   
       bmfs_set_disk(&bmfs, &disk);
   
       int err = bmfs_import(&bmfs);
       if (err != 0) {
           kprintf("Failed to import BMFS file system.\n");
           return -1;
       }
   }

Opening a File

With the disk and the file system initialized, you can open the file.

   int show_file(const char *path) {
   
       /* Initialize disk here. */
   
       /* Initialize file system header. */
   
       struct BMFSFile file;
   
       bmfs_file_init(&file);
   
       err = bmfs_open_file(&bmfs, &file, path);
       if (err == BMFS_ENOENT) {
           kprintf("Entry '%s' does not exist.\n", path);
       } else if (err == BMFS_EISDIR) {
           kprintf("Entry '%s' is a directory.\n", path);
       } else if (err != 0) {
           kprintf("Failed to open '%s'.\n", path);
           return -1;
       }
   
       bmfs_file_set_mode(&file, BMFS_MODE_READ);
   
       char buf[512];
   
       while (bmfs_file_eof(&file)) {
   
           bmfs_uint64 read_count = 0;
   
           err = bmfs_file_read(&file, buf, 512, &read_count);
           if (err != 0)
               break;
   
           my_print_function(buf, read_count);
       }
   }

Opening a Directory

Opening a directory is similar to opening a file.

You'll have to initialize the file system the same as you did for the file.

   int list_dir(const char *path) {
   
       /* Initialize the file system here. */
   
       struct BMFSDir dir;
   
       bmfs_dir_init(&dir);
   
       int err = bmfs_open_dir(&bmfs, &dir, path);
       if (err == ENOTDIR) {
           kprintf("Entry '%s' is not a directory.\n", path);
           return -1;
       } else if (err == ENOENT) {
           kprintf("Directory '%s' does not exist.\n", path);
           return -1;
       } else if (err != 0) {
           kprintf("Failed to open directory '%s'.\n", path);
           return -1;
       }
       
       for (;;) {
           const struct BMFSEntry *entry = bmfs_dir_next(&dir);
           if (entry == BMFS_NULL)
               break;
           
           kprintf("Entry: %s\n", entry->Name);
       }
   }

Going Further

The library can do even more than that and new features are added continuously.

Visit the Doxygen generated documentation [1] for more information.