Skip to content

Commit

Permalink
feat: add ext fs support
Browse files Browse the repository at this point in the history
update docs
  • Loading branch information
Godones committed Feb 7, 2024
1 parent c22c7a4 commit bc78739
Show file tree
Hide file tree
Showing 15 changed files with 7,545 additions and 6,958 deletions.
330 changes: 321 additions & 9 deletions Cargo.lock

Large diffs are not rendered by default.

74 changes: 46 additions & 28 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
TRACE_EXE := trace_exe
TRACE_EXE := trace_exe
EXTMKFS := lwext4-mkfs
TARGET := riscv64gc-unknown-none-elf
OUTPUT := target/$(TARGET)/release
KERNEL_FILE := $(OUTPUT)/kernel
Expand All @@ -10,6 +11,7 @@ BOOTLOADER := ./boot/rustsbi-qemu.bin
BOOTLOADER := default
KERNEL_BIN := $(KERNEL_FILE).bin
IMG := tools/sdcard.img
FSMOUNT := ./diskfs
SMP ?= 1
GUI ?=n
NET ?=y
Expand All @@ -21,10 +23,11 @@ UNMATCHED ?=n
FEATURES :=
QEMU_ARGS :=
MEMORY_SIZE := 1024M
img ?=fat32
SLAB ?=n
TALLOC ?=y
BUDDY ?=n
FS ?=fat


comma:= ,
empty:=
Expand Down Expand Up @@ -56,6 +59,13 @@ else ifeq ($(BUDDY),y)
FEATURES += buddy
endif

ifeq ($(FS),fat)
FEATURES += fat
else ifeq ($(FS),ext)
FEATURES += ext
endif


ifeq ($(NET),y)
QEMU_ARGS += -device virtio-net-device,netdev=net0 \
-netdev user,id=net0,hostfwd=tcp::5555-:5555,hostfwd=udp::5555-:5555
Expand Down Expand Up @@ -91,19 +101,16 @@ build:install compile
compile:
cargo build --release -p kernel --target $(TARGET) --features $(FEATURES)
(nm -n ${KERNEL_FILE} | $(TRACE_EXE) > subsystems/unwinder/src/kernel_symbol.S)
@#call trace_info
cargo build --release -p kernel --target $(TARGET) --features $(FEATURES)
@#$(OBJCOPY) $(KERNEL_FILE) --strip-all -O binary $(KERNEL_BIN)
cp $(KERNEL_FILE) ./kernel-qemu

trace_info:
@(nm -n ${KERNEL_FILE} | $(TRACE_EXE) > kernel/src/trace/kernel_symbol.S)

user:
@cd apps && make all
@make all -C apps

sdcard:fat32 testelf user
@sudo umount /fat
sdcard:$(FS) mount testelf user
@sudo umount $(FSMOUNT)
@rm -rf $(FSMOUNT)

run:sdcard install compile
@echo qemu booot $(SMP)
Expand Down Expand Up @@ -149,7 +156,7 @@ f_test:

testelf:
@if [ -d "tests/testbin-second-stage" ]; then \
sudo cp tests/testbin-second-stage/* /fat -r; \
sudo cp tests/testbin-second-stage/* $(FSMOUNT) -r; \
fi

dtb:
Expand All @@ -161,26 +168,35 @@ jh7110:
@dtc -I dtb -o dts -o jh7110.dts ./tools/jh7110-visionfive-v2.dtb


SecondFile:
#创建64MB大小空白文件
@dd if=/dev/zero of=$(IMG1) bs=1M count=64

ZeroFile:
#创建空白文件
@dd if=/dev/zero of=$(IMG) bs=1M count=64

fat32:
@-touch $(IMG)
@dd if=/dev/zero of=$(IMG) bs=1M count=72
fat:
@if [ -f $(IMG) ]; then \
echo "file exist"; \
else \
echo "file not exist"; \
@touch $(IMG); \
@dd if=/dev/zero of=$(IMG) bs=1M count=72; \
fi
@mkfs.fat -F 32 $(IMG)
@if mountpoint -q /fat; then \
sudo umount /fat; \

ext:
@if [ -f $(IMG) ]; then \
echo "file exist"; \
else \
echo "file not exist"; \
touch $(IMG); \
@dd if=/dev/zero of=$(IMG) bs=1M count=2048; \
fi
@sudo mount $(IMG) /fat
@sudo cp tools/f1.txt /fat
@sudo mkdir /fat/folder
@sudo cp tools/f1.txt /fat/folder
@echo fat32 has been created
@mkfs.ext4 $(IMG)

mount:
@mkdir $(FSMOUNT)
@if mountpoint -q $(FSMOUNT); then \
sudo umount $(FSMOUNT); \
fi
@sudo mount $(IMG) $(FSMOUNT)
@sudo cp tools/f1.txt $(FSMOUNT)
@sudo mkdir $(FSMOUNT)/folder
@sudo cp tools/f1.txt $(FSMOUNT)/folder


img-hex:
Expand Down Expand Up @@ -213,6 +229,8 @@ clean:
@cargo clean
@-rm kernel-qemu
@-rm alien-*
@-sudo umount $(FSMOUNT)
@-rm -rf $(FSMOUNT)


check:
Expand Down
6 changes: 3 additions & 3 deletions apps/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ mode := release
target := ../target/riscv64gc-unknown-none-elf/$(mode)/
APPS_NAME := $(shell ls -d */ | cut -d '/' -f 1)
GUI ?=n

FSMOUNT := ../diskfs

all:build
@echo "Moving apps to /fat32/bin"
@$(foreach dir, $(BUILD_CRATES), (sudo cp $(target)$(dir) /fat/$(dir););)
@echo "Moving apps to ../diskfs/bin"
@$(foreach dir, $(BUILD_CRATES), (sudo cp $(target)$(dir) $(FSMOUNT)/$(dir););)


build:
Expand Down
22 changes: 11 additions & 11 deletions apps/final_test/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,17 @@ fn run_test() {
"./copy-file-range-test-2\0",
"./copy-file-range-test-3\0",
"./copy-file-range-test-4\0",
"./lua_testcode.sh\0",
"./busybox_testcode.sh\0",
"./run-static.sh\0",
"./run-dynamic.sh\0",
"./libc-bench\0",
"./cyclictest_testcode.sh\0",
"./netperf_testcode.sh\0",
"./iperf_testcode.sh\0",
"./lmbench_testcode.sh\0",
"./iozone_testcode.sh\0",
"./unixbench_testcode.sh\0",
// "./lua_testcode.sh\0",
// "./busybox_testcode.sh\0",
// "./run-static.sh\0",
// "./run-dynamic.sh\0",
// "./libc-bench\0",
// "./cyclictest_testcode.sh\0",
// "./netperf_testcode.sh\0",
// "./iperf_testcode.sh\0",
// "./lmbench_testcode.sh\0",
// "./iozone_testcode.sh\0",
// "./unixbench_testcode.sh\0",
];
commands.into_iter().for_each(|app| {
let args = [app.as_ptr()];
Expand Down
67 changes: 67 additions & 0 deletions docs/ext.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# Ext文件系统支持

在之前的系统中,我们对磁盘文件系统只支持FAT32,为了使得文件系统具备更多的功能,这段时间我们移植了ext系列的文件。

## lwext4 ?

The main goal of the lwext4 project is to provide ext2/3/4 filesystem for microcontrollers. It may be an interesting alternative for traditional MCU filesystem libraries (mostly based on FAT32). Library has some cool and unique features in microcontrollers world:

- directory indexing - fast file find and list operations
- extents - fast big file truncate
- journaling transactions & recovery - power loss resistance

Lwext4 is an excellent choice for SD/MMC card, USB flash drive or any other wear leveled memory types. However it is not good for raw flash devices.

You can find more information from [lwext4](https://github.com/gkostka/lwext4).

## How to do it ?

lwext是一个C语言编写的库,为了在rust中使用它,我们需要生成C语言绑定。我们使用[bindgen](https://github.com/rust-lang/rust-bindgen)来完成这个工作。在此之前,需要让lwext4支持`no_std`环境和`riscv`平台,由于lwext4是为嵌入式环境实现,具有良好的可移植性,因此只需要参考已有的几个平台,并添加新平台的支持,这需要对makefile进行简单的修改以使用musl工具链并去除标准库的依赖。

[lwext4-c](https://github.com/os-module/lwext4-c) 是这部分的具体实现。

有了c实现的支持,我们只需要在rust中生成相关的头文件以及静态库。在做这部分之前,我们首先查看了一下`crates.io`中是否已有相关的实现,幸运的是,2年前已经有一个实现[lwext4](https://github.com/djdisodo/lwext4), 在简单阅读了其实现之后,我们打算参考其实现重新编写,因为其已经缺乏维护,并且不包含对`no_std`环境的支持。这个已有的实现给予我们很好的想法。

[lwext4](https://github.com/os-module/lwext4)中,为了更好的扩展性,我们添加了三个`crate`:

- lwext4-sys
- lwext4-rs
- lwext4-mkfs

lwext4-sys是生成绑定的库,其只是简单地导出生成的c绑定。

lwext4-rs使用lwext-sys,并使用更多的rust实现,尽可能地降低unsafe代码块出现。我们实现了`lwext4`中绝大部分功能。并提供了详细的例子和简单的测试,从而确保使用者可以更轻松地理解和使用。

lwext-mkfs只是对lwext-rs库中mkfs功能简单的封装,使用者可以使用其格式化磁盘,但更推荐直接使用`mkfs.ext`进行格式化。

## How to use ?

因为我们内核中已经引入了一个简单`VFS`,所以我们也参考之前的文件系统实现,对`lwext-rs`进行封装并实现`VFS`的接口。这部分的工作有了之前的参考而且本身对lwext4的封装也比较完善,因此实现起来较为轻松。

[lwext4-vfs](https://github.com/os-module/rvfs/tree/main/lwext4-vfs)提供了部分功能的实现,满足现在内核的需求。

后期我们仍需要对其`VFS`进行完善并加入更多功能。

实现`VFS`接口后,将其引入内核的做法和FAT32的类似。因为通常我们只挂载一块磁盘,因此我们使用`cfg`对磁盘文件系统的使用进行选择。

`MakeFile`中,我们添加了ext磁盘格式的支持。

在lwext4的c实现配置中,我们开启了debug输出,所以其会依赖`printf/fflush/stdout` 进行输出,除此之外,其还依赖几个函数:

1. `malloc` / `free` / `calloc` / `realloc`
2. `strcmp` / `strcpy` / `strncmp`
3. `qsort`

为了处理这几个函数依赖,我们手动提供这些实现,也可以使用一些已有的实现。[tinyrlibc](https://github.com/rust-embedded-community/tinyrlibc) 库提供了1和2的实现。为了实现`printf`,可以参考[prinf_compat](https://docs.rs/printf-compat/0.1.1/printf_compat/). [c-ward](https://github.com/sunfishcode/c-ward)提供了qsort的实现,可以直接从这里复制。 最后,我们需要实现的只是`fflush``stdout`。 通常,我们只需要将这两个实现为空函数即可。

```rust
#[no_mangle]
static stdout: usize = 0;

#[no_mangle]
extern "C" fn fflush(file: *mut c_void) -> c_int{
assert!(file.is_null());
0
}
```

1 change: 1 addition & 0 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ Welcome to the Alien OS blog, where Alien OS maintainers announce development an

## Posts from 2024

**2024/2** [ext文件系统支持](./ext.md)
**2024/1** [子系统划分](./subsystem.md)

## Posts from 2023
Expand Down
2 changes: 2 additions & 0 deletions kernel/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ vf2 = ["platform/vf2","interrupt/vf2", "devices/vf2"]
hifive = ["platform/hifive","interrupt/hifive"]
smp = ["platform/smp"]

fat = ["vfs/fat"]
ext = ["vfs/ext"]

slab = []
talloc = []
Expand Down
4 changes: 3 additions & 1 deletion kernel/src/fs/basic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ pub fn sys_read(fd: usize, buf: *mut u8, len: usize) -> AlienResult<isize> {
break;
}
}

info!("read: {:?}", count);
Ok(count as _)
}

Expand All @@ -230,6 +230,7 @@ pub fn sys_write(fd: usize, buf: *const u8, len: usize) -> AlienResult<isize> {
break;
}
}
info!("write: {:?}", count);
Ok(count as _)
}

Expand Down Expand Up @@ -332,6 +333,7 @@ pub fn sys_lseek(fd: usize, offset: isize, whence: usize) -> AlienResult<isize>
let file = process.get_file(fd).ok_or(LinuxErrno::EBADF)?;
let seek = SeekFrom::try_from((whence, offset as usize)).unwrap();
let r = file.seek(seek).map(|x| x as isize)?;
info!("seek: {:?}", r);
Ok(r)
}

Expand Down
8 changes: 1 addition & 7 deletions kernel/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ extern crate syscall_table;
#[macro_use]
extern crate platform;
extern crate alloc;

extern crate unwinder;
use alloc::boxed::Box;
pub use syscall_table::*;
mod fs;
Expand Down Expand Up @@ -65,9 +65,3 @@ fn main(hart_id: usize) {
println!("Begin run task...");
task::schedule::run_task();
}

#[panic_handler]
fn panic(info: &PanicInfo) -> ! {
println!("{}", info);
system_shutdown()
}
1 change: 1 addition & 0 deletions subsystems/devices/src/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ impl VfsInode for BLKDevice {
Ok(VfsFileStat {
st_rdev: self.device_id.id(),
st_size: self.device.size() as u64,
st_blksize: 512,
..Default::default()
})
}
Expand Down
Loading

0 comments on commit bc78739

Please sign in to comment.