Compare commits

..

No commits in common. "045d7e5106ac03c5558e2b2b6e0e01d819361732" and "7d9d20b6519808adeb3f45c7573a098ec39b50e9" have entirely different histories.

2 changed files with 17 additions and 156 deletions

View file

@ -6,15 +6,9 @@
// reads the whole file
pub fn read(file: FileHandle) -> Vec<u8>
// reads up to 4096 bytes of the file
pub fn read_block(file: FileHandle) -> Vec<u8>
// overwrites the contents of the file
pub fn write(file: FileHandle, data: Vec<u8>)
// writes 4096 bytes to the file
pub fn write_block(file: FileHandle, data: Vec<u8>)
// opens a file for reading and writing
pub fn open(path: Path)
@ -54,7 +48,7 @@ All filesystems must expose at least these functions in order to work with the V
## Structure
### Mount Point
### Mount Point Lookup Entry
```
path_len: u64
@ -63,31 +57,17 @@ 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
### Inode
There is one of these for each mount point, stored sequentially. The list ends when it finds a path_len of 0
### Sub Part
```
name_len: u64
name: [u8; <name_len>]
next: u64
flags: u8
entries: u64
dir: u8
size: u64
addr: u64
```
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
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

View file

@ -1,133 +1,14 @@
-- r255 is used as a bump allocator pointer
jmp r0, write
jal r0, r0, start
start:
li r255, data
-- 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 r1
read:
muli r16, r8, 8
ld r8, r16, data, 8
jal r0, r1, 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 r1
write:
muli r16, r8, 8
st r10, r16, data, 8
jal r0, r1, 0
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
-- Creates a mount point with the path located at `path_addr`
--
-- Structure:
-- path_len: u64
-- path: [u8; <path_len>]
-- entries: u64
-- fs: u64
-- addr: u64
--
-- inputs:
-- r8: path_addr
-- r9: path_len
-- r10: size
-- outputs:
-- r8: addr
-- returns to r1
mount:
-- Creates a new inode with a chosen path
--
-- inputs:
-- r8: path_addr
-- r9: path_len
-- r10: dir
-- outputs:
-- r8: addr
-- returns to r2
-- also uses regs r11-r15
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 byte
li r9, 0 -- r9 will be store the length of the current part
li r10, data -- r10 will be used to refer to the current parent inode, so we'll start it at the root
cp r11, r8 -- r11 will store the base of the current part
li r12, 0 -- r12 will store the total length of the parsed path for comparing to `path_len`
-- store slash character bytes to compare to
-- `/` is 47, and `\` is 92
li r14, 42
li r15, 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 \
-- the next byte goes in r13
ld r13, r8, 0, 8
-- try to enter the inode if a slash was found
jeq r13, r14, create_enter_inode
jeq r13, r15, create_enter_inode
-- increment the byte pointer and check the next one
addi r8, r8, 1
addi r9, r9, 1
jal r0, r0, create_parse_path
create_enter_inode:
-- move the base of the part into r8
cp r8, r11
jal r3, r0, find_inode
jal r0, r2, 0
-- 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: current_addr
-- outputs:
-- r8: addr
-- returns to r3
-- also uses regs r16-r24
find_inode:
ld r20, r10, 0, 1 -- load the name length to compare
jeq r9, r20, find_compare -- compare names if they're the same length
add r10, r10, r20 -- skip the name
addi r10, r10, 33 -- the structure other than the name is 33 bytes
jal r0, r0, find_inode
find_compare:
addi r16, r10, 8 -- r16 will store the base index of the string we're comparing against
li r17, 0 -- r17 will store the index of the byte we're checking
find_compare_loop:
-- try to batch up to 16 bytes at once
sub r18, r9, r17 -- get the number of bytes left
cmpi r19, r18, 16 -- r19 will be -1 if there are less than 16 bytes remaining
-- This is where all the VFS and FS data will be stored
-- VFS comes first, and FS starts at `data + 2048`
data:
fsdata: