Compare commits
2 commits
70bb9ad66d
...
e35bbc1aa2
Author | SHA1 | Date | |
---|---|---|---|
e35bbc1aa2 | |||
79054a0c3f |
|
@ -1 +1 @@
|
|||
Subproject commit 75995422262a192f2c87713d239856e98c799f41
|
||||
Subproject commit 6a444bd29ea6d474ec98edbc11b27030825b86e2
|
215
src/vfs.hbasm
215
src/vfs.hbasm
|
@ -1,12 +1,47 @@
|
|||
-- r255 is used as a bump allocator pointer
|
||||
-- r254 is -1
|
||||
-- r253 is 33 (the number of bytes in an inode other than its name)
|
||||
-- r252 is the root inode address
|
||||
-- r251 is `/` (47)
|
||||
-- r250 is `\` (92)
|
||||
|
||||
jal r0, r0, start
|
||||
|
||||
start:
|
||||
li r255, data
|
||||
li r254, -1
|
||||
li r253, 33
|
||||
li r251, 47
|
||||
li r250, 92
|
||||
|
||||
jal r1, r0, create_root
|
||||
|
||||
-- allocate space for the path ("/e")
|
||||
cp r8, r255
|
||||
addi r255, r255, 2
|
||||
li r9, 101
|
||||
-- store the path
|
||||
st r251, r8, 0, 1
|
||||
st r9, r8, 1, 1
|
||||
|
||||
li r9, 2
|
||||
li r10, 0
|
||||
cp r32, r8 -- copy r8 to use the path again later
|
||||
|
||||
jal r2, r0, create_inode
|
||||
|
||||
cp r33, r8 -- copy r8 to compare against
|
||||
|
||||
-- find `e` in /
|
||||
cp r8, r32
|
||||
addi r8, r8, 1
|
||||
li r9, 1
|
||||
ld r10, r252, 17, 8
|
||||
jal r3, r0, find_inode
|
||||
cp r34, r8
|
||||
|
||||
-- at this point r33 is the address we created /e at, and r34 is the address we found it at
|
||||
ecall
|
||||
|
||||
-- Reads the file at the path pointed to by `name_addr`
|
||||
--
|
||||
|
@ -53,74 +88,80 @@ write:
|
|||
-- r8: addr
|
||||
-- returns to r1
|
||||
mount:
|
||||
jal r0, r1, 0 -- do nothing for now
|
||||
|
||||
-- Creates the root inode `/`
|
||||
-- This should be run at the start of execution, before any other inodes are made
|
||||
--
|
||||
-- returns to r1
|
||||
-- sets 252 to root inode's address
|
||||
create_root:
|
||||
cp r252, r255
|
||||
add r255, r255, r253 -- bump allocator past this inode
|
||||
st r0, r252, 0, 8 -- `next`
|
||||
li r8, 2
|
||||
st r8, r252, 8, 1 -- put 2 in `flags`
|
||||
st r0, r252, 9, 8 -- 0 `size` for now
|
||||
st r0, r252, 17, 8 -- 0 `addr` too
|
||||
st r0, r252, 25, 8 -- 0 `name_len`
|
||||
jal r0, r1, 0
|
||||
|
||||
-- Creates a new inode with a chosen path
|
||||
--
|
||||
-- inputs:
|
||||
-- r8: path_addr
|
||||
-- r9: path_len
|
||||
-- r10: dir
|
||||
-- r10: flags
|
||||
-- outputs:
|
||||
-- r8: addr
|
||||
-- 1 if the path doesn't begin with a slash
|
||||
-- 2 if a parent doesn't exist
|
||||
-- 3 if a parent is a file
|
||||
-- returns to r2
|
||||
-- modifies r8-r17
|
||||
-- indirectly modifies r19-r27
|
||||
create_inode:
|
||||
cp r16, r9 -- copy `path_len` so we can use r9
|
||||
cp r17, r10 -- same with `dir` and r10
|
||||
-- r8 will store the address of the next byte
|
||||
li r9, 0 -- r9 will store the parsed 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`
|
||||
cp r17, r10 -- same with `flags` and r10
|
||||
-- r8 will store the address of the next bytes
|
||||
|
||||
-- store slash character bytes to compare to
|
||||
li r14, 42 -- `/` is ascii 47
|
||||
li r15, 97 -- `\` is ascii 92
|
||||
|
||||
create_parse_path:
|
||||
-- we have the start address, now we need the length of the part
|
||||
-- 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
|
||||
jeq r12, r16, creation -- create the inode if this is the last part
|
||||
jal r0, r0, create_parse_path
|
||||
|
||||
create_enter_inode:
|
||||
cp r8, r11 -- for `find_inode` argument
|
||||
jal r3, r0, find_inode -- this will put the inode address in r8, or 0 if not found
|
||||
jeq r8, r0, create_inode_return -- return if the inode wasn't found
|
||||
cp r10, r8
|
||||
add r11, r11, r9 -- skip to the next path part
|
||||
addi r11, r10, 1 -- also skip the slash
|
||||
cp r8, r11
|
||||
add r12, r12, r9 -- increase the parsed length
|
||||
addi r12, r12, 1
|
||||
li r9, 0
|
||||
jal r0, r0, create_parse_path
|
||||
-- r9 becomes the address of the end name
|
||||
-- r10 becomes the address of the direct parent, or an error code
|
||||
-- r11 becomes the length of the end name
|
||||
jal r4, r0, follow_path
|
||||
li r24, 10
|
||||
jltu r10, r24, create_inode_fail
|
||||
|
||||
creation:
|
||||
cp r8, r255 -- set the base address of this inode
|
||||
add r255, r255, r9 --
|
||||
add r255, r255, r253 -- bump allocator past this inode
|
||||
st r9, r8, 0, 8 -- store name_len
|
||||
add r255, r255, r9 -- and its name
|
||||
-- get the first entry under the parent inode
|
||||
addi r24, r10, 17 -- r24 is now at the `addr` field of the parent
|
||||
st r24, r8, 0, 8 -- make this inode's `next` field point to the previous first child
|
||||
st r8, r10, 17, 8 -- point the parent's `addr` to this inode
|
||||
st r17, r8, 8, 1 -- store `flags`
|
||||
st r0, r8, 9, 8 -- store 0 for `size` until something gets added
|
||||
st r0, r8, 17, 8 -- same for `addr`
|
||||
st r9, r8, 25, 8 -- store `name_len`
|
||||
-- copy the name into the inode
|
||||
cp r24, r11
|
||||
cp r25, r9
|
||||
cp r26, r8
|
||||
addi r26, r253
|
||||
add r26, r26, r253
|
||||
-- increase the parent's size
|
||||
ld r24, r10, 9, 1
|
||||
addi r24, r24, 1
|
||||
st r24, r10, 9, 1
|
||||
jal r4, r0, copy_buf
|
||||
-- get the first entry under the parent inode
|
||||
addi r25, r25, -- now r25 is at the `addr` field of the parent
|
||||
|
||||
|
||||
create_inode_return:
|
||||
jal r0, r2, 0
|
||||
|
||||
create_inode_fail:
|
||||
cp r8, r10
|
||||
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 passed name
|
||||
--
|
||||
|
@ -130,12 +171,20 @@ create_inode:
|
|||
-- r10: current_addr
|
||||
-- outputs:
|
||||
-- r8: addr
|
||||
-- 1 if the inode doesn't exist
|
||||
-- returns to r3
|
||||
-- modifies r10 and r19-r27
|
||||
find_inode:
|
||||
ld r19, r10, 25, 8 -- load the name length to compare
|
||||
ld r20, r27, 0, 8 -- load the `next` field of this inode
|
||||
ld r20, r10, 0, 8 -- load the `next` field of this inode
|
||||
jeq r9, r19, find_compare -- only compare names if they're the same length
|
||||
|
||||
ld r64, r10, 0, 8
|
||||
ld r65, r10, 8, 1
|
||||
ld r66, r10, 9, 24
|
||||
ecall
|
||||
|
||||
jeq r10, r20, find_inode_fail -- fail if this is the last one
|
||||
cp r10, r20
|
||||
jal r0, r0, find_inode -- else try the next inode
|
||||
|
||||
|
@ -157,19 +206,19 @@ find_inode:
|
|||
cmp_4:
|
||||
ld r26, r19, 0, 4
|
||||
ld r24, r25, 0, 4
|
||||
add r21, r21, 4
|
||||
addi r21, r21, 4
|
||||
jal r0, r0, cmp_end
|
||||
|
||||
cmp_2:
|
||||
ld r26, r19, 0, 2 -- first 2 bytes
|
||||
ld r24, r25, 0, 2
|
||||
add r21, r21, 2
|
||||
addi r21, r21, 2
|
||||
jal r0, r0, cmp_end
|
||||
|
||||
cmp_1:
|
||||
ld r26, r19, 0, 1 -- get the byte to compare
|
||||
ld r24, r25, 0, 1 -- and the byte to compare with
|
||||
add r21, r21, 1
|
||||
addi r21, r21, 1
|
||||
|
||||
cmp_end:
|
||||
jeq r26, r24, find_compare_loop -- continue if this set matches
|
||||
|
@ -180,6 +229,10 @@ find_inode:
|
|||
find_inode_return:
|
||||
jal r0, r3, 0
|
||||
|
||||
find_inode_fail:
|
||||
li r8, 1
|
||||
jal r0, r3, 0
|
||||
|
||||
-- Copies a buffer
|
||||
--
|
||||
-- inputs:
|
||||
|
@ -199,7 +252,7 @@ copy_buf:
|
|||
jeq r27, r0, copy_end
|
||||
addi r24, r24, 4
|
||||
addi r26, r26, 4
|
||||
addi r25, -4
|
||||
addi r25, r25, -4
|
||||
jal r0, r0, copy_buf
|
||||
|
||||
copy_2:
|
||||
|
@ -207,7 +260,7 @@ copy_buf:
|
|||
jeq r27, r0, copy_end
|
||||
addi r24, r24, 2
|
||||
addi r26, r26, 2
|
||||
addi r25, -2
|
||||
addi r25, r25, -2
|
||||
jal r0, r0, copy_buf
|
||||
|
||||
copy_1:
|
||||
|
@ -216,6 +269,72 @@ copy_buf:
|
|||
copy_end:
|
||||
jal r0, r4, 0
|
||||
|
||||
-- Parses a path, returning the address of the direct parent
|
||||
--
|
||||
-- inputs:
|
||||
-- r8: path_addr
|
||||
-- r16: path_len
|
||||
-- outputs:
|
||||
-- r9: name_len
|
||||
-- r10: parent_addr
|
||||
-- 1 if the direct parent wasn't found
|
||||
-- 2 if a parent is a file
|
||||
-- r11: name_addr
|
||||
-- returns to r4
|
||||
-- modifies r12-r13
|
||||
follow_path:
|
||||
li r9, 0 -- r9 will store the parsed length of the current part
|
||||
cp r10, r252 -- 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`
|
||||
|
||||
-- skip leading slash if it exists
|
||||
ld r13, r8, 0, 1
|
||||
jeq r13, r14, skip_leading
|
||||
jeq r13, r15, skip_leading
|
||||
li r8, 1 -- return with a 1 in r8
|
||||
jal r0, r0, parse_return
|
||||
|
||||
skip_leading:
|
||||
addi r8, r8, 1
|
||||
addi r9, r9, 1
|
||||
|
||||
parse_loop:
|
||||
-- we have the start address, now we need the length of the part
|
||||
-- the next byte goes in r13
|
||||
ld r13, r8, 0, 1
|
||||
-- try to enter the inode if a slash was found
|
||||
jeq r13, r251, enter_inode
|
||||
jeq r13, r250, enter_inode
|
||||
-- increment the byte pointer and check the next one
|
||||
addi r8, r8, 1
|
||||
addi r9, r9, 1
|
||||
jeq r12, r16, parse_return -- return inode if this is the last part
|
||||
jal r0, r0, parse_loop
|
||||
|
||||
enter_inode:
|
||||
cp r8, r11 -- for `find_inode` argument
|
||||
jal r3, r0, find_inode -- this will put the inode address in r8, or 0 if not found
|
||||
jeq r8, r0, parse_fail -- fail if the inode wasn't found
|
||||
cp r10, r8
|
||||
add r11, r11, r9 -- skip to the next path part
|
||||
addi r11, r11, 1 -- also skip the slash
|
||||
cp r8, r11
|
||||
add r12, r12, r9 -- increase the parsed length
|
||||
addi r12, r12, 1 -- including the slash
|
||||
li r9, 0
|
||||
jal r0, r0, parse_loop
|
||||
|
||||
parse_return:
|
||||
jal r0, r4, 0
|
||||
|
||||
parse_fail:
|
||||
li r10, 1
|
||||
jal r0, r4, 0
|
||||
|
||||
parse_parent_file:
|
||||
li r10, 2
|
||||
jal r0, r4, 0
|
||||
|
||||
-- This is where all the VFS and FS data will be stored
|
||||
-- VFS comes first, and FS starts at `data + 2048`
|
||||
|
|
Loading…
Reference in a new issue