Compare commits

..

No commits in common. "e35bbc1aa2106dc4fa1ab678b148e5bcd5e2441f" and "70bb9ad66d22015495046465fae6fb645a8cb656" have entirely different histories.

2 changed files with 51 additions and 170 deletions

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

View file

@ -1,47 +1,12 @@
-- r255 is used as a bump allocator pointer -- r255 is used as a bump allocator pointer
-- r254 is -1 -- r254 is -1
-- r253 is 33 (the number of bytes in an inode other than its name) -- 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 jal r0, r0, start
start: start:
li r255, data li r255, data
li r254, -1 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` -- Reads the file at the path pointed to by `name_addr`
-- --
@ -88,80 +53,74 @@ write:
-- r8: addr -- r8: addr
-- returns to r1 -- returns to r1
mount: 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 -- Creates a new inode with a chosen path
-- --
-- inputs: -- inputs:
-- r8: path_addr -- r8: path_addr
-- r9: path_len -- r9: path_len
-- r10: flags -- r10: dir
-- outputs: -- outputs:
-- r8: addr -- 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 -- returns to r2
-- modifies r8-r17 -- modifies r8-r17
-- indirectly modifies r19-r27
create_inode: create_inode:
cp r16, r9 -- copy `path_len` so we can use r9 cp r16, r9 -- copy `path_len` so we can use r9
cp r17, r10 -- same with `flags` and r10 cp r17, r10 -- same with `dir` and r10
-- r8 will store the address of the next bytes -- 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`
-- r9 becomes the address of the end name -- store slash character bytes to compare to
-- r10 becomes the address of the direct parent, or an error code li r14, 42 -- `/` is ascii 47
-- r11 becomes the length of the end name li r15, 97 -- `\` is ascii 92
jal r4, r0, follow_path
li r24, 10 create_parse_path:
jltu r10, r24, create_inode_fail -- 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
creation: creation:
cp r8, r255 -- set the base address of this inode cp r8, r255 -- set the base address of this inode
add r255, r255, r9 --
add r255, r255, r253 -- bump allocator past this inode add r255, r255, r253 -- bump allocator past this inode
add r255, r255, r9 -- and its name st r9, r8, 0, 8 -- store name_len
-- 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 -- copy the name into the inode
cp r24, r11 cp r24, r11
cp r25, r9 cp r25, r9
cp r26, r8 cp r26, r8
add r26, r26, r253 addi 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 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: create_inode_return:
jal r0, r2, 0 jal r0, r2, 0
create_inode_fail:
cp r8, r10
jal r0, r2, 0
-- Finds an inode address by name within a parent inode -- Finds an inode address by name within a parent inode
-- Returns with 0 in `r8` if there is no inode with the passed name -- Returns with 0 in `r8` if there is no inode with the passed name
-- --
@ -171,20 +130,12 @@ create_inode:
-- r10: current_addr -- r10: current_addr
-- outputs: -- outputs:
-- r8: addr -- r8: addr
-- 1 if the inode doesn't exist
-- returns to r3 -- returns to r3
-- modifies r10 and r19-r27 -- modifies r10 and r19-r27
find_inode: find_inode:
ld r19, r10, 25, 8 -- load the name length to compare ld r19, r10, 25, 8 -- load the name length to compare
ld r20, r10, 0, 8 -- load the `next` field of this inode ld r20, r27, 0, 8 -- load the `next` field of this inode
jeq r9, r19, find_compare -- only compare names if they're the same length 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 cp r10, r20
jal r0, r0, find_inode -- else try the next inode jal r0, r0, find_inode -- else try the next inode
@ -206,19 +157,19 @@ find_inode:
cmp_4: cmp_4:
ld r26, r19, 0, 4 ld r26, r19, 0, 4
ld r24, r25, 0, 4 ld r24, r25, 0, 4
addi r21, r21, 4 add r21, r21, 4
jal r0, r0, cmp_end jal r0, r0, cmp_end
cmp_2: cmp_2:
ld r26, r19, 0, 2 -- first 2 bytes ld r26, r19, 0, 2 -- first 2 bytes
ld r24, r25, 0, 2 ld r24, r25, 0, 2
addi r21, r21, 2 add r21, r21, 2
jal r0, r0, cmp_end jal r0, r0, cmp_end
cmp_1: cmp_1:
ld r26, r19, 0, 1 -- get the byte to compare ld r26, r19, 0, 1 -- get the byte to compare
ld r24, r25, 0, 1 -- and the byte to compare with ld r24, r25, 0, 1 -- and the byte to compare with
addi r21, r21, 1 add r21, r21, 1
cmp_end: cmp_end:
jeq r26, r24, find_compare_loop -- continue if this set matches jeq r26, r24, find_compare_loop -- continue if this set matches
@ -229,10 +180,6 @@ find_inode:
find_inode_return: find_inode_return:
jal r0, r3, 0 jal r0, r3, 0
find_inode_fail:
li r8, 1
jal r0, r3, 0
-- Copies a buffer -- Copies a buffer
-- --
-- inputs: -- inputs:
@ -252,7 +199,7 @@ copy_buf:
jeq r27, r0, copy_end jeq r27, r0, copy_end
addi r24, r24, 4 addi r24, r24, 4
addi r26, r26, 4 addi r26, r26, 4
addi r25, r25, -4 addi r25, -4
jal r0, r0, copy_buf jal r0, r0, copy_buf
copy_2: copy_2:
@ -260,7 +207,7 @@ copy_buf:
jeq r27, r0, copy_end jeq r27, r0, copy_end
addi r24, r24, 2 addi r24, r24, 2
addi r26, r26, 2 addi r26, r26, 2
addi r25, r25, -2 addi r25, -2
jal r0, r0, copy_buf jal r0, r0, copy_buf
copy_1: copy_1:
@ -269,72 +216,6 @@ copy_buf:
copy_end: copy_end:
jal r0, r4, 0 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 -- This is where all the VFS and FS data will be stored
-- VFS comes first, and FS starts at `data + 2048` -- VFS comes first, and FS starts at `data + 2048`