Compare commits

...

2 commits

Author SHA1 Message Date
Egggggg e35bbc1aa2 hamburglar was here 2023-07-13 21:31:22 -04:00
Egggggg 79054a0c3f Updata 2023-07-13 21:21:39 -04:00
2 changed files with 170 additions and 51 deletions

@ -1 +1 @@
Subproject commit 75995422262a192f2c87713d239856e98c799f41
Subproject commit 6a444bd29ea6d474ec98edbc11b27030825b86e2

View file

@ -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, r253 -- bump allocator past this inode
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
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
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
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`