diff --git a/README.md b/README.md index bd12fcc..b33ca62 100644 --- a/README.md +++ b/README.md @@ -6,9 +6,15 @@ // reads the whole file pub fn read(file: FileHandle) -> Vec +// reads up to 4096 bytes of the file +pub fn read_block(file: FileHandle) -> Vec + // overwrites the contents of the file pub fn write(file: FileHandle, data: Vec) +// writes 4096 bytes to the file +pub fn write_block(file: FileHandle, data: Vec) + // opens a file for reading and writing pub fn open(path: Path) @@ -48,7 +54,7 @@ All filesystems must expose at least these functions in order to work with the V ## Structure -### Mount Point Lookup Entry +### Mount Point ``` path_len: u64 @@ -57,17 +63,30 @@ entries: u64 addr: u64 ``` +There is one of these for each mount point, stored sequentially within the root directory it belongs to. The list ends when it finds a `path_len` of 0 -There is one of these for each mount point, stored sequentially. The list ends when it finds a path_len of 0 - -### Sub Part +### Inode ``` name_len: u64 name: [u8; ] -dir: u8 -size: u64 +next: u64 +flags: u8 +entries: u64 addr: u64 ``` -There can be many of these in a mount point, and they can be nested within eachother. dir is 1 if the part is a directory, or 0 if it's a file. size specifies the number of sub parts within a directory, or the number of bytes within a file \ No newline at end of file +There can be many of these in a mount point, and they can be nested within eachother. If this is the last entry in the parent, `next` will refer to this inode, otherwise it will be the address of the next inode under the parent. `entries` specifies the number of inodes within a directory + +#### Flags +| 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | +|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:| +| NA | NA | NA | NA | NA | NA | dir | mnt | + +`dir` is set if the inode is a directory, or unset if it's a file. +`mnt` is set if the inode is a mount point + +#### create_inode + +1. traverse the path until we reach the last element or a nonexistent directory +2. if any path elements are mount points, request the filesystem belonging to it to create the item and if it succeeds create the inode \ No newline at end of file diff --git a/src/vfs.hbasm b/src/vfs.hbasm index b12b993..f798341 100644 --- a/src/vfs.hbasm +++ b/src/vfs.hbasm @@ -1,14 +1,113 @@ -jmp r0, write +-- r64 is used as a bump allocator pointer +jal r0, r0, start +start: + li r64, fsdata + +-- Reads the file at the path pointed to by `name_addr` +-- +-- inputs: +-- r8: name_addr +-- r9: name_len +-- outputs: +-- r8: data_addr +-- r9: data_len +-- returns to r32 +read: + muli r16, r8, 8 + ld r8, r16, fsdata, 8 + jal r0, r32, 0 + +-- Writes `data_len` bytes from `data_addr` to the file at the path pointed to by `name_addr` +-- This creates the file if it doesn't exist +-- +-- inputs: +-- r8: name_addr +-- r9: name_len +-- r10: data_addr +-- r11: data_len +-- returns to r32 write: - li r8, 64 - -- ctrl-a ctrl-c ctrl-v - brc r9, r8, 1 - brc r10, r8, 2 - brc r12, r8, 4 - brc r16, r8, 8 - brc r24, r8, 16 - li r8, 32 + muli r16, r8, 8 + st r10, r16, fsdata, 8 + jal r0, r32, 0 -fsdata: \ No newline at end of file +-- Creates a mount point with the path located at `path_addr` +-- +-- Structure: +-- path_len: u64 +-- path: [u8; ] +-- entries: u64 +-- fs: u64 +-- addr: u64 +-- +-- inputs: +-- r8: path_addr +-- r9: path_len +-- r10: size +-- outputs: +-- r8: addr +-- returns to r32 +mount: + +-- Creates a new inode with a chosen path +-- +-- inputs: +-- r8: path_addr +-- r9: path_len +-- r10: dir +-- outputs: +-- r8: addr +-- returns to r34 +create_inode: + -- back up path arguments + -- we need to use r8 and r9 as arguments for `find_inode` + brc r8, r16, 3 + -- r8 will store the address of the next character + li r9, 0 -- this will be store the length of the current part + li r10, data -- this will be used to refer to the current parent inode, so we'll start it at the root + cp r11, r8 -- this will store the base of the current part + li r12, 0 -- this will store the total length of the parsed path for comparing to `path_len` + + -- store slash characters to compare to + li r48, 42 + li r49, 97 + + jal r0, r0, create_parse_path + + create_parse_path: + -- we have the start address, now we need the length of the part + -- this can be found by adding 1 and jumping to `parse_path` if the next character is not a / or \ + -- `/` is 47, and `\` is 92 + -- the next character goes in r24 + ld r24, r8, 0, 8 + -- try to enter the inode if a slash was found + jeq r24, r48, create_enter_inode + jeq r24, r49, create_enter_inode + -- increment the character pointer and check the next one + addi r8, r8, 1 + jal r0, r0, create_parse_path + + create_enter_inode: + -- move the base of the part into r8 + cp r8, r11 + jal r36, r0, find_inode + + +-- Finds an inode address by name within a parent inode +-- Returns with 0 in `r8` if there is no inode with the chosen name +-- +-- inputs: +-- r8: name_addr +-- r9: name_len +-- r10: parent_addr +-- outputs: +-- r8: addr +-- returns to r36 +find_inode: + + +// This is where all the VFS and FS data will be stored +// VFS comes first, and FS starts at `data + 2048` +data: \ No newline at end of file