mirror of
https://github.com/Leonmmcoset/cleonos.git
synced 2026-04-24 11:14:01 +00:00
硬盘支持(FAT32)
This commit is contained in:
@@ -93,6 +93,8 @@ set(ISO_ROOT "${BUILD_ROOT}/iso_root")
|
|||||||
set(RAMDISK_ROOT "${BUILD_ROOT}/ramdisk_root")
|
set(RAMDISK_ROOT "${BUILD_ROOT}/ramdisk_root")
|
||||||
set(KERNEL_ELF "${BUILD_ROOT}/clks_kernel.elf")
|
set(KERNEL_ELF "${BUILD_ROOT}/clks_kernel.elf")
|
||||||
set(RAMDISK_IMAGE "${BUILD_ROOT}/cleonos_ramdisk.tar")
|
set(RAMDISK_IMAGE "${BUILD_ROOT}/cleonos_ramdisk.tar")
|
||||||
|
set(DISK_IMAGE "${BUILD_ROOT}/cleonos_disk.img")
|
||||||
|
set(CLEONOS_DISK_IMAGE_MB "64" CACHE STRING "Default runtime disk image size in MB")
|
||||||
set(ISO_IMAGE "${CMAKE_SOURCE_DIR}/build/CLeonOS-x86_64.iso")
|
set(ISO_IMAGE "${CMAKE_SOURCE_DIR}/build/CLeonOS-x86_64.iso")
|
||||||
set(KERNEL_SYMBOLS_FILE "${BUILD_ROOT}/kernel.sym")
|
set(KERNEL_SYMBOLS_FILE "${BUILD_ROOT}/kernel.sym")
|
||||||
|
|
||||||
@@ -457,6 +459,15 @@ add_custom_command(
|
|||||||
-P "${CL_LOG_EMIT_SCRIPT}"
|
-P "${CL_LOG_EMIT_SCRIPT}"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
add_custom_target(disk-image
|
||||||
|
COMMAND ${CMAKE_COMMAND}
|
||||||
|
"-DDISK_IMAGE=${DISK_IMAGE}"
|
||||||
|
"-DDISK_MB=${CLEONOS_DISK_IMAGE_MB}"
|
||||||
|
-P "${CMAKE_SOURCE_DIR}/cmake/ensure_disk_image.cmake"
|
||||||
|
BYPRODUCTS "${DISK_IMAGE}"
|
||||||
|
VERBATIM
|
||||||
|
)
|
||||||
|
|
||||||
add_custom_command(
|
add_custom_command(
|
||||||
OUTPUT "${ISO_IMAGE}"
|
OUTPUT "${ISO_IMAGE}"
|
||||||
COMMAND ${CMAKE_COMMAND} -E rm -rf "${ISO_ROOT}"
|
COMMAND ${CMAKE_COMMAND} -E rm -rf "${ISO_ROOT}"
|
||||||
@@ -511,8 +522,8 @@ add_custom_target(run
|
|||||||
"-DLOG_LEVEL=STEP"
|
"-DLOG_LEVEL=STEP"
|
||||||
"-DLOG_TEXT=launching qemu run"
|
"-DLOG_TEXT=launching qemu run"
|
||||||
-P "${CL_LOG_EMIT_SCRIPT}"
|
-P "${CL_LOG_EMIT_SCRIPT}"
|
||||||
COMMAND ${QEMU_X86_64} -M q35 -m 1024M -cdrom "${ISO_IMAGE}" -serial stdio
|
COMMAND ${QEMU_X86_64} -M pc -m 1024M -boot order=d -cdrom "${ISO_IMAGE}" -drive "file=${DISK_IMAGE},format=raw,if=ide,index=0,media=disk" -serial stdio
|
||||||
DEPENDS iso
|
DEPENDS iso disk-image
|
||||||
USES_TERMINAL
|
USES_TERMINAL
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -522,8 +533,8 @@ add_custom_target(debug
|
|||||||
"-DLOG_LEVEL=STEP"
|
"-DLOG_LEVEL=STEP"
|
||||||
"-DLOG_TEXT=launching qemu debug (-s -S)"
|
"-DLOG_TEXT=launching qemu debug (-s -S)"
|
||||||
-P "${CL_LOG_EMIT_SCRIPT}"
|
-P "${CL_LOG_EMIT_SCRIPT}"
|
||||||
COMMAND ${QEMU_X86_64} -M q35 -m 1024M -cdrom "${ISO_IMAGE}" -serial stdio -s -S
|
COMMAND ${QEMU_X86_64} -M pc -m 1024M -boot order=d -cdrom "${ISO_IMAGE}" -drive "file=${DISK_IMAGE},format=raw,if=ide,index=0,media=disk" -serial stdio -s -S
|
||||||
DEPENDS iso
|
DEPENDS iso disk-image
|
||||||
USES_TERMINAL
|
USES_TERMINAL
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -586,5 +597,6 @@ add_custom_target(cleonos-help
|
|||||||
COMMAND ${CMAKE_COMMAND} -E echo " cmake --build build-cmake --target iso"
|
COMMAND ${CMAKE_COMMAND} -E echo " cmake --build build-cmake --target iso"
|
||||||
COMMAND ${CMAKE_COMMAND} -E echo " cmake --build build-cmake --target run"
|
COMMAND ${CMAKE_COMMAND} -E echo " cmake --build build-cmake --target run"
|
||||||
COMMAND ${CMAKE_COMMAND} -E echo " cmake --build build-cmake --target debug"
|
COMMAND ${CMAKE_COMMAND} -E echo " cmake --build build-cmake --target debug"
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E echo " cmake --build build-cmake --target disk-image"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
12
Makefile
12
Makefile
@@ -18,6 +18,7 @@ READELF_FOR_TARGET ?=
|
|||||||
PYTHON ?= python3
|
PYTHON ?= python3
|
||||||
MENUCONFIG_ARGS ?=
|
MENUCONFIG_ARGS ?=
|
||||||
MENUCONFIG_PRESET ?=
|
MENUCONFIG_PRESET ?=
|
||||||
|
DISK_IMAGE_MB ?=
|
||||||
|
|
||||||
ifeq ($(strip $(CMAKE_GENERATOR)),)
|
ifeq ($(strip $(CMAKE_GENERATOR)),)
|
||||||
GEN_ARG :=
|
GEN_ARG :=
|
||||||
@@ -52,8 +53,11 @@ endif
|
|||||||
ifneq ($(strip $(READELF_FOR_TARGET)),)
|
ifneq ($(strip $(READELF_FOR_TARGET)),)
|
||||||
CMAKE_PASSTHROUGH_ARGS += -DREADELF_FOR_TARGET=$(READELF_FOR_TARGET)
|
CMAKE_PASSTHROUGH_ARGS += -DREADELF_FOR_TARGET=$(READELF_FOR_TARGET)
|
||||||
endif
|
endif
|
||||||
|
ifneq ($(strip $(DISK_IMAGE_MB)),)
|
||||||
|
CMAKE_PASSTHROUGH_ARGS += -DCLEONOS_DISK_IMAGE_MB=$(DISK_IMAGE_MB)
|
||||||
|
endif
|
||||||
|
|
||||||
.PHONY: all configure reconfigure menuconfig menuconfig-gui setup setup-tools setup-limine kernel userapps ramdisk-root ramdisk iso run debug clean clean-all help
|
.PHONY: all configure reconfigure menuconfig menuconfig-gui setup setup-tools setup-limine kernel userapps ramdisk-root ramdisk disk-image iso run debug clean clean-all help
|
||||||
|
|
||||||
all: iso
|
all: iso
|
||||||
|
|
||||||
@@ -107,6 +111,9 @@ ramdisk-root: configure
|
|||||||
ramdisk: configure
|
ramdisk: configure
|
||||||
> @$(CMAKE) --build $(CMAKE_BUILD_DIR) --target ramdisk
|
> @$(CMAKE) --build $(CMAKE_BUILD_DIR) --target ramdisk
|
||||||
|
|
||||||
|
disk-image: configure
|
||||||
|
> @$(CMAKE) --build $(CMAKE_BUILD_DIR) --target disk-image
|
||||||
|
|
||||||
iso: configure
|
iso: configure
|
||||||
> @$(CMAKE) --build $(CMAKE_BUILD_DIR) --target iso
|
> @$(CMAKE) --build $(CMAKE_BUILD_DIR) --target iso
|
||||||
|
|
||||||
@@ -137,6 +144,7 @@ help:
|
|||||||
> @echo " make menuconfig-gui"
|
> @echo " make menuconfig-gui"
|
||||||
> @echo " make setup"
|
> @echo " make setup"
|
||||||
> @echo " make userapps"
|
> @echo " make userapps"
|
||||||
|
> @echo " make disk-image"
|
||||||
> @echo " make iso"
|
> @echo " make iso"
|
||||||
> @echo " make run"
|
> @echo " make run"
|
||||||
> @echo " make debug"
|
> @echo " make debug"
|
||||||
@@ -147,6 +155,8 @@ help:
|
|||||||
> @echo " make configure CMAKE_EXTRA_ARGS='-DLIMINE_SKIP_CONFIGURE=1 -DOBJCOPY_FOR_TARGET=objcopy'"
|
> @echo " make configure CMAKE_EXTRA_ARGS='-DLIMINE_SKIP_CONFIGURE=1 -DOBJCOPY_FOR_TARGET=objcopy'"
|
||||||
> @echo "Direct passthrough is also supported:"
|
> @echo "Direct passthrough is also supported:"
|
||||||
> @echo " make run LIMINE_SKIP_CONFIGURE=1"
|
> @echo " make run LIMINE_SKIP_CONFIGURE=1"
|
||||||
|
> @echo "Disk image size example:"
|
||||||
|
> @echo " make run DISK_IMAGE_MB=128"
|
||||||
> @echo "Preset examples:"
|
> @echo "Preset examples:"
|
||||||
> @echo " make menuconfig MENUCONFIG_PRESET=full"
|
> @echo " make menuconfig MENUCONFIG_PRESET=full"
|
||||||
> @echo " make menuconfig MENUCONFIG_PRESET=minimal"
|
> @echo " make menuconfig MENUCONFIG_PRESET=minimal"
|
||||||
|
|||||||
12
README.md
12
README.md
@@ -8,6 +8,7 @@ Experimental x86_64 operating system project with a C kernel, Rust-assisted runt
|
|||||||
|
|
||||||
- x86_64 kernel booted by Limine
|
- x86_64 kernel booted by Limine
|
||||||
- RAM-disk VFS layout (`/system`, `/shell`, `/temp`, `/driver`)
|
- RAM-disk VFS layout (`/system`, `/shell`, `/temp`, `/driver`)
|
||||||
|
- Virtual disk backend with FAT32 format + mount support (default mount path: `/temp/disk`)
|
||||||
- Virtual TTY subsystem (multi TTY, ANSI handling, cursor, PSF font support)
|
- Virtual TTY subsystem (multi TTY, ANSI handling, cursor, PSF font support)
|
||||||
- Keyboard and mouse input stack, plus desktop mode on TTY2
|
- Keyboard and mouse input stack, plus desktop mode on TTY2
|
||||||
- User-space ELF app model with syscall ABI (`int 0x80`)
|
- User-space ELF app model with syscall ABI (`int 0x80`)
|
||||||
@@ -60,6 +61,12 @@ git submodule update --init --recursive
|
|||||||
make run
|
make run
|
||||||
```
|
```
|
||||||
|
|
||||||
|
`make run` now auto-prepares `build/x86_64/cleonos_disk.img` (if missing) and attaches it as a QEMU emulated physical disk (`-drive ... if=ide`).
|
||||||
|
This disk is **not** packed into the ISO and is **not** loaded through Limine modules.
|
||||||
|
Kernel currently uses an in-memory disk cache window (default up to 8MB) for metadata/file operations.
|
||||||
|
You can override disk size (MB), for example: `make run DISK_IMAGE_MB=128`.
|
||||||
|
Inside CLeonOS, use `diskinfo` to confirm the disk is visible.
|
||||||
|
|
||||||
If you already have Limine artifacts and want to skip configure:
|
If you already have Limine artifacts and want to skip configure:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
@@ -72,6 +79,7 @@ make run LIMINE_SKIP_CONFIGURE=1
|
|||||||
- `make kernel` - build kernel ELF
|
- `make kernel` - build kernel ELF
|
||||||
- `make userapps` - build user-space ELF apps
|
- `make userapps` - build user-space ELF apps
|
||||||
- `make ramdisk` - package runtime ramdisk
|
- `make ramdisk` - package runtime ramdisk
|
||||||
|
- `make disk-image` - create/resize runtime disk image (`build/x86_64/cleonos_disk.img`)
|
||||||
- `make iso` - build bootable ISO
|
- `make iso` - build bootable ISO
|
||||||
- `make run` - launch QEMU
|
- `make run` - launch QEMU
|
||||||
- `make debug` - launch QEMU with `-s -S` for GDB
|
- `make debug` - launch QEMU with `-s -S` for GDB
|
||||||
@@ -102,6 +110,10 @@ cat /shell/init.cmd
|
|||||||
grep -n exec /shell/init.cmd
|
grep -n exec /shell/init.cmd
|
||||||
cat /shell/init.cmd | grep -n exec
|
cat /shell/init.cmd | grep -n exec
|
||||||
ls /shell > /temp/shell_list.txt
|
ls /shell > /temp/shell_list.txt
|
||||||
|
diskinfo
|
||||||
|
mkfsfat32 CLEONOS
|
||||||
|
mount /temp/disk
|
||||||
|
write /temp/disk/hello.txt hello-disk
|
||||||
```
|
```
|
||||||
|
|
||||||
## Documentation
|
## Documentation
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
- 基于 Limine 启动的 x86_64 内核
|
- 基于 Limine 启动的 x86_64 内核
|
||||||
- RAM-disk VFS 目录布局(`/system`、`/shell`、`/temp`、`/driver`)
|
- RAM-disk VFS 目录布局(`/system`、`/shell`、`/temp`、`/driver`)
|
||||||
|
- 虚拟磁盘后端,支持 FAT32 格式化与挂载(默认挂载点:`/temp/disk`)
|
||||||
- 虚拟 TTY 子系统(多 TTY、ANSI、光标、PSF 字体)
|
- 虚拟 TTY 子系统(多 TTY、ANSI、光标、PSF 字体)
|
||||||
- 键盘/鼠标输入栈,TTY2 提供桌面模式
|
- 键盘/鼠标输入栈,TTY2 提供桌面模式
|
||||||
- 用户态 ELF 应用模型,syscall ABI 使用 `int 0x80`
|
- 用户态 ELF 应用模型,syscall ABI 使用 `int 0x80`
|
||||||
@@ -60,6 +61,12 @@ git submodule update --init --recursive
|
|||||||
make run
|
make run
|
||||||
```
|
```
|
||||||
|
|
||||||
|
`make run` 现在会自动准备 `build/x86_64/cleonos_disk.img`(不存在时自动创建),并以 QEMU 模拟物理硬盘方式挂载(`-drive ... if=ide`)。
|
||||||
|
该磁盘**不会**打包进 ISO,也**不会**通过 Limine `module_path` 注入。
|
||||||
|
内核当前通过内存缓存窗口处理磁盘元数据/文件(默认最多约 8MB)。
|
||||||
|
你也可以覆盖磁盘大小(MB),例如:`make run DISK_IMAGE_MB=128`。
|
||||||
|
进入系统后可先执行 `diskinfo` 确认磁盘已识别。
|
||||||
|
|
||||||
如果你已经准备好 Limine 产物,可跳过 configure:
|
如果你已经准备好 Limine 产物,可跳过 configure:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
@@ -72,6 +79,7 @@ make run LIMINE_SKIP_CONFIGURE=1
|
|||||||
- `make kernel` - 构建内核 ELF
|
- `make kernel` - 构建内核 ELF
|
||||||
- `make userapps` - 构建用户态 ELF 应用
|
- `make userapps` - 构建用户态 ELF 应用
|
||||||
- `make ramdisk` - 打包运行时 ramdisk
|
- `make ramdisk` - 打包运行时 ramdisk
|
||||||
|
- `make disk-image` - 创建/调整运行时磁盘镜像(`build/x86_64/cleonos_disk.img`)
|
||||||
- `make iso` - 生成可启动 ISO
|
- `make iso` - 生成可启动 ISO
|
||||||
- `make run` - 启动 QEMU
|
- `make run` - 启动 QEMU
|
||||||
- `make debug` - 以 `-s -S` 启动 QEMU 供 GDB 附加
|
- `make debug` - 以 `-s -S` 启动 QEMU 供 GDB 附加
|
||||||
@@ -102,6 +110,10 @@ cat /shell/init.cmd
|
|||||||
grep -n exec /shell/init.cmd
|
grep -n exec /shell/init.cmd
|
||||||
cat /shell/init.cmd | grep -n exec
|
cat /shell/init.cmd | grep -n exec
|
||||||
ls /shell > /temp/shell_list.txt
|
ls /shell > /temp/shell_list.txt
|
||||||
|
diskinfo
|
||||||
|
mkfsfat32 CLEONOS
|
||||||
|
mount /temp/disk
|
||||||
|
write /temp/disk/hello.txt hello-disk
|
||||||
```
|
```
|
||||||
|
|
||||||
## 文档
|
## 文档
|
||||||
|
|||||||
@@ -130,6 +130,7 @@ set(USER_SHELL_COMMAND_APPS
|
|||||||
help args ls cat grep head tail wc cut uniq sort pwd cd exec pid spawn wait sleep yield
|
help args ls cat grep head tail wc cut uniq sort pwd cd exec pid spawn wait sleep yield
|
||||||
bg fg jobs kill ps top
|
bg fg jobs kill ps top
|
||||||
procstat sysstat
|
procstat sysstat
|
||||||
|
diskinfo mkfsfat32 mount
|
||||||
shutdown restart exit clear ansi ansitest wavplay fastfetch memstat fsstat taskstat userstat
|
shutdown restart exit clear ansi ansitest wavplay fastfetch memstat fsstat taskstat userstat
|
||||||
shstat stats tty dmesg kbdstat mkdir touch write append cp mv rm kdbg bmpview qrcode
|
shstat stats tty dmesg kbdstat mkdir touch write append cp mv rm kdbg bmpview qrcode
|
||||||
)
|
)
|
||||||
|
|||||||
87
cleonos/c/apps/diskinfo_main.c
Normal file
87
cleonos/c/apps/diskinfo_main.c
Normal file
@@ -0,0 +1,87 @@
|
|||||||
|
#include "cmd_runtime.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
static void clio_writeln(const char *text) {
|
||||||
|
(void)fputs(text, 1);
|
||||||
|
(void)putchar('\n');
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ush_cmd_diskinfo(void) {
|
||||||
|
u64 present = cleonos_sys_disk_present();
|
||||||
|
u64 size_bytes = 0ULL;
|
||||||
|
u64 sectors = 0ULL;
|
||||||
|
u64 formatted = 0ULL;
|
||||||
|
u64 mounted = 0ULL;
|
||||||
|
char mount_path[USH_PATH_MAX];
|
||||||
|
|
||||||
|
if (present == 0ULL) {
|
||||||
|
clio_writeln("disk: not present");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_bytes = cleonos_sys_disk_size_bytes();
|
||||||
|
sectors = cleonos_sys_disk_sector_count();
|
||||||
|
formatted = cleonos_sys_disk_formatted();
|
||||||
|
mounted = cleonos_sys_disk_mounted();
|
||||||
|
mount_path[0] = '\0';
|
||||||
|
|
||||||
|
if (mounted != 0ULL) {
|
||||||
|
(void)cleonos_sys_disk_mount_path(mount_path, (u64)sizeof(mount_path));
|
||||||
|
}
|
||||||
|
|
||||||
|
(void)printf("disk.present: %llu\n", (unsigned long long)present);
|
||||||
|
(void)printf("disk.size_bytes: %llu\n", (unsigned long long)size_bytes);
|
||||||
|
(void)printf("disk.sectors: %llu\n", (unsigned long long)sectors);
|
||||||
|
(void)printf("disk.formatted_fat32: %llu\n", (unsigned long long)formatted);
|
||||||
|
(void)printf("disk.mounted: %llu\n", (unsigned long long)mounted);
|
||||||
|
|
||||||
|
if (mounted != 0ULL && mount_path[0] != '\0') {
|
||||||
|
(void)printf("disk.mount_path: %s\n", mount_path);
|
||||||
|
} else {
|
||||||
|
clio_writeln("disk.mount_path: (none)");
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int cleonos_app_main(void) {
|
||||||
|
ush_cmd_ctx ctx;
|
||||||
|
ush_cmd_ret ret;
|
||||||
|
ush_state sh;
|
||||||
|
char initial_cwd[USH_PATH_MAX];
|
||||||
|
int has_context = 0;
|
||||||
|
int success = 0;
|
||||||
|
|
||||||
|
ush_zero(&ctx, (u64)sizeof(ctx));
|
||||||
|
ush_zero(&ret, (u64)sizeof(ret));
|
||||||
|
ush_init_state(&sh);
|
||||||
|
ush_copy(initial_cwd, (u64)sizeof(initial_cwd), sh.cwd);
|
||||||
|
|
||||||
|
if (ush_command_ctx_read(&ctx) != 0) {
|
||||||
|
if (ctx.cmd[0] != '\0' && ush_streq(ctx.cmd, "diskinfo") != 0) {
|
||||||
|
has_context = 1;
|
||||||
|
if (ctx.cwd[0] == '/') {
|
||||||
|
ush_copy(sh.cwd, (u64)sizeof(sh.cwd), ctx.cwd);
|
||||||
|
ush_copy(initial_cwd, (u64)sizeof(initial_cwd), sh.cwd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
success = ush_cmd_diskinfo();
|
||||||
|
|
||||||
|
if (has_context != 0) {
|
||||||
|
if (ush_streq(sh.cwd, initial_cwd) == 0) {
|
||||||
|
ret.flags |= USH_CMD_RET_FLAG_CWD;
|
||||||
|
ush_copy(ret.cwd, (u64)sizeof(ret.cwd), sh.cwd);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sh.exit_requested != 0) {
|
||||||
|
ret.flags |= USH_CMD_RET_FLAG_EXIT;
|
||||||
|
ret.exit_code = sh.exit_code;
|
||||||
|
}
|
||||||
|
|
||||||
|
(void)ush_command_ret_write(&ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (success != 0) ? 0 : 1;
|
||||||
|
}
|
||||||
@@ -29,6 +29,9 @@ static int ush_cmd_help(void) {
|
|||||||
ush_writeln(" cp <src> <dst> (dst /temp only)");
|
ush_writeln(" cp <src> <dst> (dst /temp only)");
|
||||||
ush_writeln(" mv <src> <dst> (/temp only)");
|
ush_writeln(" mv <src> <dst> (/temp only)");
|
||||||
ush_writeln(" rm <path> (/temp only)");
|
ush_writeln(" rm <path> (/temp only)");
|
||||||
|
ush_writeln(" diskinfo");
|
||||||
|
ush_writeln(" mkfsfat32 [label]");
|
||||||
|
ush_writeln(" mount [path] (default suggested: /temp/disk)");
|
||||||
ush_writeln(" pid");
|
ush_writeln(" pid");
|
||||||
ush_writeln(" spawn <path|name> [args...] / bg <path|name> [args...]");
|
ush_writeln(" spawn <path|name> [args...] / bg <path|name> [args...]");
|
||||||
ush_writeln(" wait <pid> / fg [pid]");
|
ush_writeln(" wait <pid> / fg [pid]");
|
||||||
|
|||||||
106
cleonos/c/apps/mkfsfat32_main.c
Normal file
106
cleonos/c/apps/mkfsfat32_main.c
Normal file
@@ -0,0 +1,106 @@
|
|||||||
|
#include "cmd_runtime.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
static int ush_arg_parse_label(const char *arg, char *out_label, u64 out_label_size) {
|
||||||
|
char first[USH_ARG_MAX];
|
||||||
|
const char *rest = (const char *)0;
|
||||||
|
|
||||||
|
if (out_label == (char *)0 || out_label_size == 0ULL) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
out_label[0] = '\0';
|
||||||
|
|
||||||
|
if (arg == (const char *)0 || arg[0] == '\0') {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ush_split_first_and_rest(arg, first, (u64)sizeof(first), &rest) == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (rest != (const char *)0 && *rest != '\0' && ush_is_space(*rest) != 0) {
|
||||||
|
rest++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rest != (const char *)0 && *rest != '\0') {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ush_copy(out_label, out_label_size, first);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ush_cmd_mkfsfat32(const char *arg) {
|
||||||
|
char label[16];
|
||||||
|
u64 ok;
|
||||||
|
|
||||||
|
if (cleonos_sys_disk_present() == 0ULL) {
|
||||||
|
(void)fputs("mkfsfat32: disk not present\n", 1);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ush_arg_parse_label(arg, label, (u64)sizeof(label)) == 0) {
|
||||||
|
(void)fputs("mkfsfat32: usage mkfsfat32 [label]\n", 1);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ok = cleonos_sys_disk_format_fat32((label[0] != '\0') ? label : (const char *)0);
|
||||||
|
if (ok == 0ULL) {
|
||||||
|
(void)fputs("mkfsfat32: format failed\n", 1);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (label[0] != '\0') {
|
||||||
|
(void)printf("mkfsfat32: formatted (label=%s)\n", label);
|
||||||
|
} else {
|
||||||
|
(void)fputs("mkfsfat32: formatted\n", 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
(void)fputs("mkfsfat32: now run 'mount /temp/disk' (or another mount path)\n", 1);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int cleonos_app_main(void) {
|
||||||
|
ush_cmd_ctx ctx;
|
||||||
|
ush_cmd_ret ret;
|
||||||
|
ush_state sh;
|
||||||
|
char initial_cwd[USH_PATH_MAX];
|
||||||
|
int has_context = 0;
|
||||||
|
int success = 0;
|
||||||
|
const char *arg = "";
|
||||||
|
|
||||||
|
ush_zero(&ctx, (u64)sizeof(ctx));
|
||||||
|
ush_zero(&ret, (u64)sizeof(ret));
|
||||||
|
ush_init_state(&sh);
|
||||||
|
ush_copy(initial_cwd, (u64)sizeof(initial_cwd), sh.cwd);
|
||||||
|
|
||||||
|
if (ush_command_ctx_read(&ctx) != 0) {
|
||||||
|
if (ctx.cmd[0] != '\0' && ush_streq(ctx.cmd, "mkfsfat32") != 0) {
|
||||||
|
has_context = 1;
|
||||||
|
arg = ctx.arg;
|
||||||
|
if (ctx.cwd[0] == '/') {
|
||||||
|
ush_copy(sh.cwd, (u64)sizeof(sh.cwd), ctx.cwd);
|
||||||
|
ush_copy(initial_cwd, (u64)sizeof(initial_cwd), sh.cwd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
success = ush_cmd_mkfsfat32(arg);
|
||||||
|
|
||||||
|
if (has_context != 0) {
|
||||||
|
if (ush_streq(sh.cwd, initial_cwd) == 0) {
|
||||||
|
ret.flags |= USH_CMD_RET_FLAG_CWD;
|
||||||
|
ush_copy(ret.cwd, (u64)sizeof(ret.cwd), sh.cwd);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sh.exit_requested != 0) {
|
||||||
|
ret.flags |= USH_CMD_RET_FLAG_EXIT;
|
||||||
|
ret.exit_code = sh.exit_code;
|
||||||
|
}
|
||||||
|
|
||||||
|
(void)ush_command_ret_write(&ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (success != 0) ? 0 : 1;
|
||||||
|
}
|
||||||
134
cleonos/c/apps/mount_main.c
Normal file
134
cleonos/c/apps/mount_main.c
Normal file
@@ -0,0 +1,134 @@
|
|||||||
|
#include "cmd_runtime.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
static int ush_mount_parse_path_arg(const char *arg, char *out_path, u64 out_path_size) {
|
||||||
|
char first[USH_ARG_MAX];
|
||||||
|
const char *rest = (const char *)0;
|
||||||
|
|
||||||
|
if (out_path == (char *)0 || out_path_size == 0ULL) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
out_path[0] = '\0';
|
||||||
|
|
||||||
|
if (arg == (const char *)0 || arg[0] == '\0') {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ush_split_first_and_rest(arg, first, (u64)sizeof(first), &rest) == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (rest != (const char *)0 && *rest != '\0' && ush_is_space(*rest) != 0) {
|
||||||
|
rest++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rest != (const char *)0 && *rest != '\0') {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ush_copy(out_path, out_path_size, first);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ush_cmd_mount(ush_state *sh, const char *arg) {
|
||||||
|
char mount_arg[USH_PATH_MAX];
|
||||||
|
char mount_path[USH_PATH_MAX];
|
||||||
|
char current_path[USH_PATH_MAX];
|
||||||
|
u64 mounted;
|
||||||
|
|
||||||
|
if (sh == (ush_state *)0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cleonos_sys_disk_present() == 0ULL) {
|
||||||
|
(void)fputs("mount: disk not present\n", 1);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ush_mount_parse_path_arg(arg, mount_arg, (u64)sizeof(mount_arg)) == 0) {
|
||||||
|
(void)fputs("mount: usage mount [path]\n", 1);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
mounted = cleonos_sys_disk_mounted();
|
||||||
|
if (mount_arg[0] == '\0') {
|
||||||
|
if (mounted == 0ULL) {
|
||||||
|
(void)fputs("mount: no mounted disk path\n", 1);
|
||||||
|
(void)fputs("mount: usage mount /temp/disk\n", 1);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
current_path[0] = '\0';
|
||||||
|
(void)cleonos_sys_disk_mount_path(current_path, (u64)sizeof(current_path));
|
||||||
|
if (current_path[0] == '\0') {
|
||||||
|
(void)fputs("disk0 on (unknown) type fat32\n", 1);
|
||||||
|
} else {
|
||||||
|
(void)printf("disk0 on %s type fat32\n", current_path);
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cleonos_sys_disk_formatted() == 0ULL) {
|
||||||
|
(void)fputs("mount: disk is not FAT32 formatted\n", 1);
|
||||||
|
(void)fputs("mount: run mkfsfat32 first\n", 1);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ush_resolve_path(sh, mount_arg, mount_path, (u64)sizeof(mount_path)) == 0) {
|
||||||
|
(void)fputs("mount: invalid path\n", 1);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cleonos_sys_disk_mount(mount_path) == 0ULL) {
|
||||||
|
(void)fputs("mount: mount failed\n", 1);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
(void)printf("disk0 mounted on %s\n", mount_path);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int cleonos_app_main(void) {
|
||||||
|
ush_cmd_ctx ctx;
|
||||||
|
ush_cmd_ret ret;
|
||||||
|
ush_state sh;
|
||||||
|
char initial_cwd[USH_PATH_MAX];
|
||||||
|
int has_context = 0;
|
||||||
|
int success = 0;
|
||||||
|
const char *arg = "";
|
||||||
|
|
||||||
|
ush_zero(&ctx, (u64)sizeof(ctx));
|
||||||
|
ush_zero(&ret, (u64)sizeof(ret));
|
||||||
|
ush_init_state(&sh);
|
||||||
|
ush_copy(initial_cwd, (u64)sizeof(initial_cwd), sh.cwd);
|
||||||
|
|
||||||
|
if (ush_command_ctx_read(&ctx) != 0) {
|
||||||
|
if (ctx.cmd[0] != '\0' && ush_streq(ctx.cmd, "mount") != 0) {
|
||||||
|
has_context = 1;
|
||||||
|
arg = ctx.arg;
|
||||||
|
if (ctx.cwd[0] == '/') {
|
||||||
|
ush_copy(sh.cwd, (u64)sizeof(sh.cwd), ctx.cwd);
|
||||||
|
ush_copy(initial_cwd, (u64)sizeof(initial_cwd), sh.cwd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
success = ush_cmd_mount(&sh, arg);
|
||||||
|
|
||||||
|
if (has_context != 0) {
|
||||||
|
if (ush_streq(sh.cwd, initial_cwd) == 0) {
|
||||||
|
ret.flags |= USH_CMD_RET_FLAG_CWD;
|
||||||
|
ush_copy(ret.cwd, (u64)sizeof(ret.cwd), sh.cwd);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sh.exit_requested != 0) {
|
||||||
|
ret.flags |= USH_CMD_RET_FLAG_EXIT;
|
||||||
|
ret.exit_code = sh.exit_code;
|
||||||
|
}
|
||||||
|
|
||||||
|
(void)ush_command_ret_write(&ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (success != 0) ? 0 : 1;
|
||||||
|
}
|
||||||
@@ -145,6 +145,14 @@ typedef struct cleonos_fb_blit_req {
|
|||||||
#define CLEONOS_SYSCALL_FB_BLIT 82ULL
|
#define CLEONOS_SYSCALL_FB_BLIT 82ULL
|
||||||
#define CLEONOS_SYSCALL_FB_CLEAR 83ULL
|
#define CLEONOS_SYSCALL_FB_CLEAR 83ULL
|
||||||
#define CLEONOS_SYSCALL_KERNEL_VERSION 84ULL
|
#define CLEONOS_SYSCALL_KERNEL_VERSION 84ULL
|
||||||
|
#define CLEONOS_SYSCALL_DISK_PRESENT 85ULL
|
||||||
|
#define CLEONOS_SYSCALL_DISK_SIZE_BYTES 86ULL
|
||||||
|
#define CLEONOS_SYSCALL_DISK_SECTOR_COUNT 87ULL
|
||||||
|
#define CLEONOS_SYSCALL_DISK_FORMATTED 88ULL
|
||||||
|
#define CLEONOS_SYSCALL_DISK_FORMAT_FAT32 89ULL
|
||||||
|
#define CLEONOS_SYSCALL_DISK_MOUNT 90ULL
|
||||||
|
#define CLEONOS_SYSCALL_DISK_MOUNTED 91ULL
|
||||||
|
#define CLEONOS_SYSCALL_DISK_MOUNT_PATH 92ULL
|
||||||
|
|
||||||
u64 cleonos_syscall(u64 id, u64 arg0, u64 arg1, u64 arg2);
|
u64 cleonos_syscall(u64 id, u64 arg0, u64 arg1, u64 arg2);
|
||||||
u64 cleonos_sys_log_write(const char *message, u64 length);
|
u64 cleonos_sys_log_write(const char *message, u64 length);
|
||||||
@@ -232,5 +240,13 @@ u64 cleonos_sys_fb_info(cleonos_fb_info *out_info);
|
|||||||
u64 cleonos_sys_fb_blit(const cleonos_fb_blit_req *req);
|
u64 cleonos_sys_fb_blit(const cleonos_fb_blit_req *req);
|
||||||
u64 cleonos_sys_fb_clear(u64 rgb);
|
u64 cleonos_sys_fb_clear(u64 rgb);
|
||||||
u64 cleonos_sys_kernel_version(char *out_version, u64 out_size);
|
u64 cleonos_sys_kernel_version(char *out_version, u64 out_size);
|
||||||
|
u64 cleonos_sys_disk_present(void);
|
||||||
|
u64 cleonos_sys_disk_size_bytes(void);
|
||||||
|
u64 cleonos_sys_disk_sector_count(void);
|
||||||
|
u64 cleonos_sys_disk_formatted(void);
|
||||||
|
u64 cleonos_sys_disk_format_fat32(const char *label);
|
||||||
|
u64 cleonos_sys_disk_mount(const char *mount_path);
|
||||||
|
u64 cleonos_sys_disk_mounted(void);
|
||||||
|
u64 cleonos_sys_disk_mount_path(char *out_path, u64 out_size);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -371,3 +371,35 @@ u64 cleonos_sys_fb_clear(u64 rgb) {
|
|||||||
u64 cleonos_sys_kernel_version(char *out_version, u64 out_size) {
|
u64 cleonos_sys_kernel_version(char *out_version, u64 out_size) {
|
||||||
return cleonos_syscall(CLEONOS_SYSCALL_KERNEL_VERSION, (u64)out_version, out_size, 0ULL);
|
return cleonos_syscall(CLEONOS_SYSCALL_KERNEL_VERSION, (u64)out_version, out_size, 0ULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u64 cleonos_sys_disk_present(void) {
|
||||||
|
return cleonos_syscall(CLEONOS_SYSCALL_DISK_PRESENT, 0ULL, 0ULL, 0ULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
u64 cleonos_sys_disk_size_bytes(void) {
|
||||||
|
return cleonos_syscall(CLEONOS_SYSCALL_DISK_SIZE_BYTES, 0ULL, 0ULL, 0ULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
u64 cleonos_sys_disk_sector_count(void) {
|
||||||
|
return cleonos_syscall(CLEONOS_SYSCALL_DISK_SECTOR_COUNT, 0ULL, 0ULL, 0ULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
u64 cleonos_sys_disk_formatted(void) {
|
||||||
|
return cleonos_syscall(CLEONOS_SYSCALL_DISK_FORMATTED, 0ULL, 0ULL, 0ULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
u64 cleonos_sys_disk_format_fat32(const char *label) {
|
||||||
|
return cleonos_syscall(CLEONOS_SYSCALL_DISK_FORMAT_FAT32, (u64)label, 0ULL, 0ULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
u64 cleonos_sys_disk_mount(const char *mount_path) {
|
||||||
|
return cleonos_syscall(CLEONOS_SYSCALL_DISK_MOUNT, (u64)mount_path, 0ULL, 0ULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
u64 cleonos_sys_disk_mounted(void) {
|
||||||
|
return cleonos_syscall(CLEONOS_SYSCALL_DISK_MOUNTED, 0ULL, 0ULL, 0ULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
u64 cleonos_sys_disk_mount_path(char *out_path, u64 out_size) {
|
||||||
|
return cleonos_syscall(CLEONOS_SYSCALL_DISK_MOUNT_PATH, (u64)out_path, out_size, 0ULL);
|
||||||
|
}
|
||||||
|
|||||||
38
clks/include/clks/disk.h
Normal file
38
clks/include/clks/disk.h
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
#ifndef CLKS_DISK_H
|
||||||
|
#define CLKS_DISK_H
|
||||||
|
|
||||||
|
#include <clks/types.h>
|
||||||
|
|
||||||
|
#define CLKS_DISK_SECTOR_SIZE 512ULL
|
||||||
|
#define CLKS_DISK_PATH_MAX 192U
|
||||||
|
#define CLKS_DISK_NODE_FILE 1ULL
|
||||||
|
#define CLKS_DISK_NODE_DIR 2ULL
|
||||||
|
|
||||||
|
void clks_disk_init(void);
|
||||||
|
|
||||||
|
clks_bool clks_disk_present(void);
|
||||||
|
u64 clks_disk_size_bytes(void);
|
||||||
|
u64 clks_disk_sector_count(void);
|
||||||
|
|
||||||
|
clks_bool clks_disk_read_sector(u64 lba, void *out_sector);
|
||||||
|
clks_bool clks_disk_write_sector(u64 lba, const void *sector_data);
|
||||||
|
|
||||||
|
clks_bool clks_disk_is_formatted_fat32(void);
|
||||||
|
clks_bool clks_disk_format_fat32(const char *label);
|
||||||
|
|
||||||
|
clks_bool clks_disk_mount(const char *mount_path);
|
||||||
|
clks_bool clks_disk_is_mounted(void);
|
||||||
|
const char *clks_disk_mount_path(void);
|
||||||
|
clks_bool clks_disk_path_in_mount(const char *path);
|
||||||
|
|
||||||
|
clks_bool clks_disk_stat(const char *path, u64 *out_type, u64 *out_size);
|
||||||
|
const void *clks_disk_read_all(const char *path, u64 *out_size);
|
||||||
|
u64 clks_disk_count_children(const char *dir_path);
|
||||||
|
clks_bool clks_disk_get_child_name(const char *dir_path, u64 index, char *out_name, usize out_name_size);
|
||||||
|
clks_bool clks_disk_mkdir(const char *path);
|
||||||
|
clks_bool clks_disk_write_all(const char *path, const void *data, u64 size);
|
||||||
|
clks_bool clks_disk_append(const char *path, const void *data, u64 size);
|
||||||
|
clks_bool clks_disk_remove(const char *path);
|
||||||
|
u64 clks_disk_node_count(void);
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -88,6 +88,14 @@
|
|||||||
#define CLKS_SYSCALL_FB_BLIT 82ULL
|
#define CLKS_SYSCALL_FB_BLIT 82ULL
|
||||||
#define CLKS_SYSCALL_FB_CLEAR 83ULL
|
#define CLKS_SYSCALL_FB_CLEAR 83ULL
|
||||||
#define CLKS_SYSCALL_KERNEL_VERSION 84ULL
|
#define CLKS_SYSCALL_KERNEL_VERSION 84ULL
|
||||||
|
#define CLKS_SYSCALL_DISK_PRESENT 85ULL
|
||||||
|
#define CLKS_SYSCALL_DISK_SIZE_BYTES 86ULL
|
||||||
|
#define CLKS_SYSCALL_DISK_SECTOR_COUNT 87ULL
|
||||||
|
#define CLKS_SYSCALL_DISK_FORMATTED 88ULL
|
||||||
|
#define CLKS_SYSCALL_DISK_FORMAT_FAT32 89ULL
|
||||||
|
#define CLKS_SYSCALL_DISK_MOUNT 90ULL
|
||||||
|
#define CLKS_SYSCALL_DISK_MOUNTED 91ULL
|
||||||
|
#define CLKS_SYSCALL_DISK_MOUNT_PATH 92ULL
|
||||||
|
|
||||||
void clks_syscall_init(void);
|
void clks_syscall_init(void);
|
||||||
u64 clks_syscall_dispatch(void *frame_ptr);
|
u64 clks_syscall_dispatch(void *frame_ptr);
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
#include <clks/cpu.h>
|
#include <clks/cpu.h>
|
||||||
#include <clks/audio.h>
|
#include <clks/audio.h>
|
||||||
|
#include <clks/disk.h>
|
||||||
#include <clks/exec.h>
|
#include <clks/exec.h>
|
||||||
#include <clks/framebuffer.h>
|
#include <clks/framebuffer.h>
|
||||||
#include <clks/fs.h>
|
#include <clks/fs.h>
|
||||||
@@ -36,7 +37,7 @@
|
|||||||
#define CLKS_SYSCALL_KDBG_STACK_WINDOW_BYTES (128ULL * 1024ULL)
|
#define CLKS_SYSCALL_KDBG_STACK_WINDOW_BYTES (128ULL * 1024ULL)
|
||||||
#define CLKS_SYSCALL_KERNEL_SYMBOL_FILE "/system/kernel.sym"
|
#define CLKS_SYSCALL_KERNEL_SYMBOL_FILE "/system/kernel.sym"
|
||||||
#define CLKS_SYSCALL_KERNEL_ADDR_BASE 0xFFFF800000000000ULL
|
#define CLKS_SYSCALL_KERNEL_ADDR_BASE 0xFFFF800000000000ULL
|
||||||
#define CLKS_SYSCALL_STATS_MAX_ID CLKS_SYSCALL_KERNEL_VERSION
|
#define CLKS_SYSCALL_STATS_MAX_ID CLKS_SYSCALL_DISK_MOUNT_PATH
|
||||||
#define CLKS_SYSCALL_STATS_RING_SIZE 256U
|
#define CLKS_SYSCALL_STATS_RING_SIZE 256U
|
||||||
#define CLKS_SYSCALL_USC_MAX_ALLOWED_APPS 64U
|
#define CLKS_SYSCALL_USC_MAX_ALLOWED_APPS 64U
|
||||||
|
|
||||||
@@ -479,6 +480,56 @@ static u64 clks_syscall_kernel_version(u64 arg0, u64 arg1) {
|
|||||||
return clks_syscall_copy_text_to_user(arg0, arg1, CLKS_VERSION_STRING, len);
|
return clks_syscall_copy_text_to_user(arg0, arg1, CLKS_VERSION_STRING, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static u64 clks_syscall_disk_present(void) {
|
||||||
|
return (clks_disk_present() == CLKS_TRUE) ? 1ULL : 0ULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static u64 clks_syscall_disk_size_bytes(void) {
|
||||||
|
return clks_disk_size_bytes();
|
||||||
|
}
|
||||||
|
|
||||||
|
static u64 clks_syscall_disk_sector_count(void) {
|
||||||
|
return clks_disk_sector_count();
|
||||||
|
}
|
||||||
|
|
||||||
|
static u64 clks_syscall_disk_formatted(void) {
|
||||||
|
return (clks_disk_is_formatted_fat32() == CLKS_TRUE) ? 1ULL : 0ULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static u64 clks_syscall_disk_format_fat32(u64 arg0) {
|
||||||
|
char label[16];
|
||||||
|
|
||||||
|
if (clks_syscall_copy_user_optional_string(arg0, label, sizeof(label)) == CLKS_FALSE) {
|
||||||
|
return 0ULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (clks_disk_format_fat32((label[0] != '\0') ? label : CLKS_NULL) == CLKS_TRUE) ? 1ULL : 0ULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static u64 clks_syscall_disk_mount(u64 arg0) {
|
||||||
|
char path[CLKS_SYSCALL_PATH_MAX];
|
||||||
|
|
||||||
|
if (clks_syscall_copy_user_string(arg0, path, sizeof(path)) == CLKS_FALSE) {
|
||||||
|
return 0ULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (clks_disk_mount(path) == CLKS_TRUE) ? 1ULL : 0ULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static u64 clks_syscall_disk_mounted(void) {
|
||||||
|
return (clks_disk_is_mounted() == CLKS_TRUE) ? 1ULL : 0ULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static u64 clks_syscall_disk_mount_path(u64 arg0, u64 arg1) {
|
||||||
|
const char *mount_path = clks_disk_mount_path();
|
||||||
|
|
||||||
|
if (mount_path == CLKS_NULL || mount_path[0] == '\0') {
|
||||||
|
return 0ULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return clks_syscall_copy_text_to_user(arg0, arg1, mount_path, clks_strlen(mount_path));
|
||||||
|
}
|
||||||
|
|
||||||
static u64 clks_syscall_fd_open(u64 arg0, u64 arg1, u64 arg2) {
|
static u64 clks_syscall_fd_open(u64 arg0, u64 arg1, u64 arg2) {
|
||||||
char path[CLKS_SYSCALL_PATH_MAX];
|
char path[CLKS_SYSCALL_PATH_MAX];
|
||||||
|
|
||||||
@@ -1994,6 +2045,22 @@ static const char *clks_syscall_usc_syscall_name(u64 id) {
|
|||||||
return "SHUTDOWN";
|
return "SHUTDOWN";
|
||||||
case CLKS_SYSCALL_RESTART:
|
case CLKS_SYSCALL_RESTART:
|
||||||
return "RESTART";
|
return "RESTART";
|
||||||
|
case CLKS_SYSCALL_DISK_PRESENT:
|
||||||
|
return "DISK_PRESENT";
|
||||||
|
case CLKS_SYSCALL_DISK_SIZE_BYTES:
|
||||||
|
return "DISK_SIZE_BYTES";
|
||||||
|
case CLKS_SYSCALL_DISK_SECTOR_COUNT:
|
||||||
|
return "DISK_SECTOR_COUNT";
|
||||||
|
case CLKS_SYSCALL_DISK_FORMATTED:
|
||||||
|
return "DISK_FORMATTED";
|
||||||
|
case CLKS_SYSCALL_DISK_FORMAT_FAT32:
|
||||||
|
return "DISK_FORMAT_FAT32";
|
||||||
|
case CLKS_SYSCALL_DISK_MOUNT:
|
||||||
|
return "DISK_MOUNT";
|
||||||
|
case CLKS_SYSCALL_DISK_MOUNTED:
|
||||||
|
return "DISK_MOUNTED";
|
||||||
|
case CLKS_SYSCALL_DISK_MOUNT_PATH:
|
||||||
|
return "DISK_MOUNT_PATH";
|
||||||
default:
|
default:
|
||||||
return "UNKNOWN";
|
return "UNKNOWN";
|
||||||
}
|
}
|
||||||
@@ -2025,6 +2092,8 @@ static clks_bool clks_syscall_usc_is_dangerous(u64 id) {
|
|||||||
return (CLKS_CFG_USC_SC_SHUTDOWN != 0) ? CLKS_TRUE : CLKS_FALSE;
|
return (CLKS_CFG_USC_SC_SHUTDOWN != 0) ? CLKS_TRUE : CLKS_FALSE;
|
||||||
case CLKS_SYSCALL_RESTART:
|
case CLKS_SYSCALL_RESTART:
|
||||||
return (CLKS_CFG_USC_SC_RESTART != 0) ? CLKS_TRUE : CLKS_FALSE;
|
return (CLKS_CFG_USC_SC_RESTART != 0) ? CLKS_TRUE : CLKS_FALSE;
|
||||||
|
case CLKS_SYSCALL_DISK_FORMAT_FAT32:
|
||||||
|
return CLKS_TRUE;
|
||||||
default:
|
default:
|
||||||
return CLKS_FALSE;
|
return CLKS_FALSE;
|
||||||
}
|
}
|
||||||
@@ -2528,6 +2597,22 @@ u64 clks_syscall_dispatch(void *frame_ptr) {
|
|||||||
return clks_syscall_fb_clear(frame->rbx);
|
return clks_syscall_fb_clear(frame->rbx);
|
||||||
case CLKS_SYSCALL_KERNEL_VERSION:
|
case CLKS_SYSCALL_KERNEL_VERSION:
|
||||||
return clks_syscall_kernel_version(frame->rbx, frame->rcx);
|
return clks_syscall_kernel_version(frame->rbx, frame->rcx);
|
||||||
|
case CLKS_SYSCALL_DISK_PRESENT:
|
||||||
|
return clks_syscall_disk_present();
|
||||||
|
case CLKS_SYSCALL_DISK_SIZE_BYTES:
|
||||||
|
return clks_syscall_disk_size_bytes();
|
||||||
|
case CLKS_SYSCALL_DISK_SECTOR_COUNT:
|
||||||
|
return clks_syscall_disk_sector_count();
|
||||||
|
case CLKS_SYSCALL_DISK_FORMATTED:
|
||||||
|
return clks_syscall_disk_formatted();
|
||||||
|
case CLKS_SYSCALL_DISK_FORMAT_FAT32:
|
||||||
|
return clks_syscall_disk_format_fat32(frame->rbx);
|
||||||
|
case CLKS_SYSCALL_DISK_MOUNT:
|
||||||
|
return clks_syscall_disk_mount(frame->rbx);
|
||||||
|
case CLKS_SYSCALL_DISK_MOUNTED:
|
||||||
|
return clks_syscall_disk_mounted();
|
||||||
|
case CLKS_SYSCALL_DISK_MOUNT_PATH:
|
||||||
|
return clks_syscall_disk_mount_path(frame->rbx, frame->rcx);
|
||||||
default:
|
default:
|
||||||
return (u64)-1;
|
return (u64)-1;
|
||||||
}
|
}
|
||||||
|
|||||||
1853
clks/kernel/storage/disk.c
Normal file
1853
clks/kernel/storage/disk.c
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,4 +1,5 @@
|
|||||||
#include <clks/boot.h>
|
#include <clks/boot.h>
|
||||||
|
#include <clks/disk.h>
|
||||||
#include <clks/fs.h>
|
#include <clks/fs.h>
|
||||||
#include <clks/heap.h>
|
#include <clks/heap.h>
|
||||||
#include <clks/log.h>
|
#include <clks/log.h>
|
||||||
@@ -515,6 +516,14 @@ void clks_fs_init(void) {
|
|||||||
clks_log_hex(CLKS_LOG_INFO, "FS", "NODE_COUNT", (u64)clks_fs_nodes_used);
|
clks_log_hex(CLKS_LOG_INFO, "FS", "NODE_COUNT", (u64)clks_fs_nodes_used);
|
||||||
clks_log_hex(CLKS_LOG_INFO, "FS", "FILE_COUNT", stats.file_count);
|
clks_log_hex(CLKS_LOG_INFO, "FS", "FILE_COUNT", stats.file_count);
|
||||||
|
|
||||||
|
clks_disk_init();
|
||||||
|
if (clks_disk_present() == CLKS_TRUE) {
|
||||||
|
clks_log_hex(CLKS_LOG_INFO, "FS", "DISK_BYTES", clks_disk_size_bytes());
|
||||||
|
clks_log_hex(CLKS_LOG_INFO, "FS", "DISK_FAT32", (clks_disk_is_formatted_fat32() == CLKS_TRUE) ? 1ULL : 0ULL);
|
||||||
|
} else {
|
||||||
|
clks_log(CLKS_LOG_WARN, "FS", "DISK BACKEND NOT PRESENT");
|
||||||
|
}
|
||||||
|
|
||||||
if (clks_fs_require_directory("/system") == CLKS_FALSE) {
|
if (clks_fs_require_directory("/system") == CLKS_FALSE) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -545,11 +554,23 @@ clks_bool clks_fs_is_ready(void) {
|
|||||||
|
|
||||||
clks_bool clks_fs_stat(const char *path, struct clks_fs_node_info *out_info) {
|
clks_bool clks_fs_stat(const char *path, struct clks_fs_node_info *out_info) {
|
||||||
i32 node_index;
|
i32 node_index;
|
||||||
|
u64 disk_type = 0ULL;
|
||||||
|
u64 disk_size = 0ULL;
|
||||||
|
|
||||||
if (clks_fs_ready == CLKS_FALSE || out_info == CLKS_NULL) {
|
if (clks_fs_ready == CLKS_FALSE || out_info == CLKS_NULL) {
|
||||||
return CLKS_FALSE;
|
return CLKS_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (clks_disk_path_in_mount(path) == CLKS_TRUE) {
|
||||||
|
if (clks_disk_stat(path, &disk_type, &disk_size) == CLKS_FALSE) {
|
||||||
|
return CLKS_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
out_info->type = (disk_type == CLKS_DISK_NODE_DIR) ? CLKS_FS_NODE_DIR : CLKS_FS_NODE_FILE;
|
||||||
|
out_info->size = disk_size;
|
||||||
|
return CLKS_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
node_index = clks_fs_find_node_by_external(path);
|
node_index = clks_fs_find_node_by_external(path);
|
||||||
|
|
||||||
if (node_index < 0) {
|
if (node_index < 0) {
|
||||||
@@ -563,11 +584,17 @@ clks_bool clks_fs_stat(const char *path, struct clks_fs_node_info *out_info) {
|
|||||||
|
|
||||||
const void *clks_fs_read_all(const char *path, u64 *out_size) {
|
const void *clks_fs_read_all(const char *path, u64 *out_size) {
|
||||||
i32 node_index;
|
i32 node_index;
|
||||||
|
const void *disk_data;
|
||||||
|
|
||||||
if (clks_fs_ready == CLKS_FALSE) {
|
if (clks_fs_ready == CLKS_FALSE) {
|
||||||
return CLKS_NULL;
|
return CLKS_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (clks_disk_path_in_mount(path) == CLKS_TRUE) {
|
||||||
|
disk_data = clks_disk_read_all(path, out_size);
|
||||||
|
return disk_data;
|
||||||
|
}
|
||||||
|
|
||||||
node_index = clks_fs_find_node_by_external(path);
|
node_index = clks_fs_find_node_by_external(path);
|
||||||
|
|
||||||
if (node_index < 0) {
|
if (node_index < 0) {
|
||||||
@@ -598,6 +625,10 @@ u64 clks_fs_count_children(const char *dir_path) {
|
|||||||
return 0ULL;
|
return 0ULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (clks_disk_path_in_mount(dir_path) == CLKS_TRUE) {
|
||||||
|
return clks_disk_count_children(dir_path);
|
||||||
|
}
|
||||||
|
|
||||||
dir_index = clks_fs_find_node_by_external(dir_path);
|
dir_index = clks_fs_find_node_by_external(dir_path);
|
||||||
|
|
||||||
if (dir_index < 0) {
|
if (dir_index < 0) {
|
||||||
@@ -634,6 +665,10 @@ clks_bool clks_fs_get_child_name(const char *dir_path, u64 index, char *out_name
|
|||||||
return CLKS_FALSE;
|
return CLKS_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (clks_disk_path_in_mount(dir_path) == CLKS_TRUE) {
|
||||||
|
return clks_disk_get_child_name(dir_path, index, out_name, out_name_size);
|
||||||
|
}
|
||||||
|
|
||||||
dir_index = clks_fs_find_node_by_external(dir_path);
|
dir_index = clks_fs_find_node_by_external(dir_path);
|
||||||
|
|
||||||
if (dir_index < 0 || clks_fs_nodes[(u16)dir_index].type != CLKS_FS_NODE_DIR) {
|
if (dir_index < 0 || clks_fs_nodes[(u16)dir_index].type != CLKS_FS_NODE_DIR) {
|
||||||
@@ -683,6 +718,10 @@ clks_bool clks_fs_mkdir(const char *path) {
|
|||||||
return CLKS_FALSE;
|
return CLKS_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (clks_disk_path_in_mount(path) == CLKS_TRUE) {
|
||||||
|
return clks_disk_mkdir(path);
|
||||||
|
}
|
||||||
|
|
||||||
if (clks_fs_normalize_external_path(path, internal, sizeof(internal)) == CLKS_FALSE) {
|
if (clks_fs_normalize_external_path(path, internal, sizeof(internal)) == CLKS_FALSE) {
|
||||||
return CLKS_FALSE;
|
return CLKS_FALSE;
|
||||||
}
|
}
|
||||||
@@ -720,6 +759,10 @@ clks_bool clks_fs_write_all(const char *path, const void *data, u64 size) {
|
|||||||
return CLKS_FALSE;
|
return CLKS_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (clks_disk_path_in_mount(path) == CLKS_TRUE) {
|
||||||
|
return clks_disk_write_all(path, data, size);
|
||||||
|
}
|
||||||
|
|
||||||
if (clks_fs_normalize_external_path(path, internal, sizeof(internal)) == CLKS_FALSE) {
|
if (clks_fs_normalize_external_path(path, internal, sizeof(internal)) == CLKS_FALSE) {
|
||||||
return CLKS_FALSE;
|
return CLKS_FALSE;
|
||||||
}
|
}
|
||||||
@@ -785,6 +828,10 @@ clks_bool clks_fs_append(const char *path, const void *data, u64 size) {
|
|||||||
return CLKS_FALSE;
|
return CLKS_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (clks_disk_path_in_mount(path) == CLKS_TRUE) {
|
||||||
|
return clks_disk_append(path, data, size);
|
||||||
|
}
|
||||||
|
|
||||||
if (size > 0ULL && data == CLKS_NULL) {
|
if (size > 0ULL && data == CLKS_NULL) {
|
||||||
return CLKS_FALSE;
|
return CLKS_FALSE;
|
||||||
}
|
}
|
||||||
@@ -851,6 +898,10 @@ clks_bool clks_fs_remove(const char *path) {
|
|||||||
return CLKS_FALSE;
|
return CLKS_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (clks_disk_path_in_mount(path) == CLKS_TRUE) {
|
||||||
|
return clks_disk_remove(path);
|
||||||
|
}
|
||||||
|
|
||||||
if (clks_fs_normalize_external_path(path, internal, sizeof(internal)) == CLKS_FALSE) {
|
if (clks_fs_normalize_external_path(path, internal, sizeof(internal)) == CLKS_FALSE) {
|
||||||
return CLKS_FALSE;
|
return CLKS_FALSE;
|
||||||
}
|
}
|
||||||
@@ -908,5 +959,9 @@ u64 clks_fs_node_count(void) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (clks_disk_is_mounted() == CLKS_TRUE) {
|
||||||
|
used += clks_disk_node_count();
|
||||||
|
}
|
||||||
|
|
||||||
return used;
|
return used;
|
||||||
}
|
}
|
||||||
|
|||||||
72
cmake/ensure_disk_image.cmake
Normal file
72
cmake/ensure_disk_image.cmake
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
if(NOT DEFINED DISK_IMAGE OR "${DISK_IMAGE}" STREQUAL "")
|
||||||
|
message(FATAL_ERROR "ensure_disk_image: DISK_IMAGE is required")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(NOT DEFINED DISK_MB OR "${DISK_MB}" STREQUAL "")
|
||||||
|
set(DISK_MB 64)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
math(EXPR _disk_mb_int "${DISK_MB} + 0")
|
||||||
|
if(_disk_mb_int LESS 4)
|
||||||
|
set(_disk_mb_int 4)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
math(EXPR _disk_bytes "${_disk_mb_int} * 1024 * 1024")
|
||||||
|
get_filename_component(_disk_dir "${DISK_IMAGE}" DIRECTORY)
|
||||||
|
if(NOT EXISTS "${_disk_dir}")
|
||||||
|
file(MAKE_DIRECTORY "${_disk_dir}")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(_need_create TRUE)
|
||||||
|
if(EXISTS "${DISK_IMAGE}")
|
||||||
|
file(SIZE "${DISK_IMAGE}" _disk_size_now)
|
||||||
|
if(_disk_size_now GREATER_EQUAL _disk_bytes)
|
||||||
|
set(_need_create FALSE)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(_need_create)
|
||||||
|
find_program(_python_exec NAMES python3 python py)
|
||||||
|
if(_python_exec)
|
||||||
|
execute_process(
|
||||||
|
COMMAND "${_python_exec}" "-c" "import os,sys; p=sys.argv[1]; sz=int(sys.argv[2]); d=os.path.dirname(p); d and os.makedirs(d, exist_ok=True); f=open(p,'ab'); f.truncate(sz); f.close()"
|
||||||
|
"${DISK_IMAGE}" "${_disk_bytes}"
|
||||||
|
RESULT_VARIABLE _python_result
|
||||||
|
OUTPUT_QUIET
|
||||||
|
ERROR_QUIET
|
||||||
|
)
|
||||||
|
if(_python_result EQUAL 0)
|
||||||
|
set(_need_create FALSE)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(_need_create)
|
||||||
|
find_program(_dd_exec NAMES dd)
|
||||||
|
if(_dd_exec)
|
||||||
|
execute_process(
|
||||||
|
COMMAND "${_dd_exec}" "if=/dev/zero" "of=${DISK_IMAGE}" "bs=1M" "count=${_disk_mb_int}"
|
||||||
|
RESULT_VARIABLE _dd_result
|
||||||
|
OUTPUT_QUIET
|
||||||
|
ERROR_QUIET
|
||||||
|
)
|
||||||
|
if(_dd_result EQUAL 0)
|
||||||
|
set(_need_create FALSE)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(_need_create)
|
||||||
|
message(FATAL_ERROR "ensure_disk_image: failed to create disk image '${DISK_IMAGE}' (${_disk_mb_int}MB)")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(NOT EXISTS "${DISK_IMAGE}")
|
||||||
|
message(FATAL_ERROR "ensure_disk_image: disk image missing after create '${DISK_IMAGE}'")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
file(SIZE "${DISK_IMAGE}" _disk_size_final)
|
||||||
|
if(_disk_size_final LESS _disk_bytes)
|
||||||
|
message(FATAL_ERROR "ensure_disk_image: disk image too small (${_disk_size_final} bytes), expected >= ${_disk_bytes}")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
message(STATUS "ensure_disk_image: ready '${DISK_IMAGE}' (${_disk_size_final} bytes)")
|
||||||
@@ -73,7 +73,7 @@ u64 cleonos_syscall(u64 id, u64 arg0, u64 arg1, u64 arg2);
|
|||||||
|
|
||||||
文件系统写入类 syscall 的权限限制:
|
文件系统写入类 syscall 的权限限制:
|
||||||
|
|
||||||
- `FS_MKDIR` / `FS_WRITE` / `FS_APPEND` / `FS_REMOVE` 仅允许 `/temp` 树下路径。
|
- `FS_MKDIR` / `FS_WRITE` / `FS_APPEND` / `FS_REMOVE` 仅允许 `/temp` 树下路径,或已挂载磁盘路径树下(默认挂载点通常为 `/temp/disk`)。
|
||||||
|
|
||||||
`/proc` 虚拟目录(由 syscall 层动态导出):
|
`/proc` 虚拟目录(由 syscall 层动态导出):
|
||||||
|
|
||||||
@@ -83,7 +83,7 @@ u64 cleonos_syscall(u64 id, u64 arg0, u64 arg1, u64 arg2);
|
|||||||
- `/proc/<pid>`:指定 PID 快照文本
|
- `/proc/<pid>`:指定 PID 快照文本
|
||||||
- `/proc` 为只读;写入类 syscall 不支持。
|
- `/proc` 为只读;写入类 syscall 不支持。
|
||||||
|
|
||||||
## 4. Syscall 列表(0~84)
|
## 4. Syscall 列表(0~92)
|
||||||
|
|
||||||
### 0 `CLEONOS_SYSCALL_LOG_WRITE`
|
### 0 `CLEONOS_SYSCALL_LOG_WRITE`
|
||||||
|
|
||||||
@@ -667,6 +667,54 @@ u64 cleonos_syscall(u64 id, u64 arg0, u64 arg1, u64 arg2);
|
|||||||
- 返回:实际写入字节数(不含终止符),失败返回 `0`
|
- 返回:实际写入字节数(不含终止符),失败返回 `0`
|
||||||
- 说明:返回 CLKS 内核版本字符串(当前默认 `1.0.0-alpha`),内核会保证输出以 `\0` 结尾。
|
- 说明:返回 CLKS 内核版本字符串(当前默认 `1.0.0-alpha`),内核会保证输出以 `\0` 结尾。
|
||||||
|
|
||||||
|
### 85 `CLEONOS_SYSCALL_DISK_PRESENT`
|
||||||
|
|
||||||
|
- 参数:无
|
||||||
|
- 返回:`1` 表示存在可用磁盘后端,`0` 表示不存在。
|
||||||
|
- 说明:在 QEMU 运行时,磁盘后端来自模拟物理硬盘(`-drive`),不是 ISO/Limine module。
|
||||||
|
|
||||||
|
### 86 `CLEONOS_SYSCALL_DISK_SIZE_BYTES`
|
||||||
|
|
||||||
|
- 参数:无
|
||||||
|
- 返回:磁盘容量(字节);无磁盘时返回 `0`。
|
||||||
|
|
||||||
|
### 87 `CLEONOS_SYSCALL_DISK_SECTOR_COUNT`
|
||||||
|
|
||||||
|
- 参数:无
|
||||||
|
- 返回:扇区总数(按 512 字节扇区);无磁盘时返回 `0`。
|
||||||
|
|
||||||
|
### 88 `CLEONOS_SYSCALL_DISK_FORMATTED`
|
||||||
|
|
||||||
|
- 参数:无
|
||||||
|
- 返回:`1` 表示当前磁盘已识别为 FAT32,`0` 表示未格式化/不识别。
|
||||||
|
|
||||||
|
### 89 `CLEONOS_SYSCALL_DISK_FORMAT_FAT32`
|
||||||
|
|
||||||
|
- 参数:
|
||||||
|
- `arg0`: `const char *label`(可为 `0` 或空字符串)
|
||||||
|
- 返回:成功 `1`,失败 `0`
|
||||||
|
- 说明:将当前磁盘格式化为 FAT32;此操作会清空已有磁盘数据。该 syscall 在 USC 策略中默认视为高风险操作。
|
||||||
|
|
||||||
|
### 90 `CLEONOS_SYSCALL_DISK_MOUNT`
|
||||||
|
|
||||||
|
- 参数:
|
||||||
|
- `arg0`: `const char *mount_path`(绝对路径)
|
||||||
|
- 返回:成功 `1`,失败 `0`
|
||||||
|
- 说明:将 FAT32 磁盘挂载到指定路径(不能是 `/`)。挂载成功后,`FS_*` 接口可通过该路径访问磁盘内容。
|
||||||
|
|
||||||
|
### 91 `CLEONOS_SYSCALL_DISK_MOUNTED`
|
||||||
|
|
||||||
|
- 参数:无
|
||||||
|
- 返回:`1` 表示已挂载,`0` 表示未挂载。
|
||||||
|
|
||||||
|
### 92 `CLEONOS_SYSCALL_DISK_MOUNT_PATH`
|
||||||
|
|
||||||
|
- 参数:
|
||||||
|
- `arg0`: `char *out_path`
|
||||||
|
- `arg1`: `u64 out_size`
|
||||||
|
- 返回:实际写入字节数(不含终止符),失败返回 `0`
|
||||||
|
- 说明:查询当前挂载点路径;返回值为写入长度,且内核保证 `\0` 终止。
|
||||||
|
|
||||||
## 5. 用户态封装函数
|
## 5. 用户态封装函数
|
||||||
|
|
||||||
用户态封装位于:
|
用户态封装位于:
|
||||||
@@ -696,17 +744,19 @@ u64 cleonos_syscall(u64 id, u64 arg0, u64 arg1, u64 arg2);
|
|||||||
- `cleonos_sys_exec_pathv_io()`
|
- `cleonos_sys_exec_pathv_io()`
|
||||||
- `cleonos_sys_fb_info()` / `cleonos_sys_fb_blit()` / `cleonos_sys_fb_clear()`
|
- `cleonos_sys_fb_info()` / `cleonos_sys_fb_blit()` / `cleonos_sys_fb_clear()`
|
||||||
- `cleonos_sys_kernel_version()`
|
- `cleonos_sys_kernel_version()`
|
||||||
|
- `cleonos_sys_disk_present()` / `cleonos_sys_disk_size_bytes()` / `cleonos_sys_disk_sector_count()`
|
||||||
|
- `cleonos_sys_disk_formatted()` / `cleonos_sys_disk_format_fat32()` / `cleonos_sys_disk_mount()` / `cleonos_sys_disk_mounted()` / `cleonos_sys_disk_mount_path()`
|
||||||
|
|
||||||
## 6. 开发注意事项
|
## 6. 开发注意事项
|
||||||
|
|
||||||
- 传入的字符串/缓冲指针目前按“同地址空间可直接访问”模型处理,后续若引入严格用户态地址隔离,需要补充用户内存校验。
|
- 传入的字符串/缓冲指针目前按“同地址空间可直接访问”模型处理,后续若引入严格用户态地址隔离,需要补充用户内存校验。
|
||||||
- `FS_READ` 不保证文本终止符;读取文本请预留 1 字节并手动 `buf[n] = '\0'`。
|
- `FS_READ` 不保证文本终止符;读取文本请预留 1 字节并手动 `buf[n] = '\0'`。
|
||||||
- `FS_WRITE`/`FS_APPEND` 仅允许 `/temp`;大数据写入由内核自动分块处理。
|
- `FS_WRITE`/`FS_APPEND` 仅允许 `/temp` 或已挂载磁盘路径;大数据写入由内核自动分块处理。
|
||||||
- `/proc` 由 syscall 层虚拟导出,不占用 RAMDISK 节点,也不能通过写入类 syscall 修改。
|
- `/proc` 由 syscall 层虚拟导出,不占用 RAMDISK 节点,也不能通过写入类 syscall 修改。
|
||||||
|
|
||||||
## 7. Wine 兼容说明
|
## 7. Wine 兼容说明
|
||||||
|
|
||||||
- `wine/cleonos_wine_lib/runner.py` 当前已覆盖到 `0..84`(含 `DL_*`、`FB_*`、`KERNEL_VERSION`)。
|
- `wine/cleonos_wine_lib/runner.py` 当前已覆盖到 `0..92`(含 `DL_*`、`FB_*`、`KERNEL_VERSION`、`DISK_*`)。
|
||||||
- `DL_*`(`77..79`)在 Wine 中为“可运行兼容”实现:
|
- `DL_*`(`77..79`)在 Wine 中为“可运行兼容”实现:
|
||||||
- `DL_OPEN`:加载 guest ELF 到当前 Unicorn 地址空间,返回稳定 `handle`,并做引用计数。
|
- `DL_OPEN`:加载 guest ELF 到当前 Unicorn 地址空间,返回稳定 `handle`,并做引用计数。
|
||||||
- `DL_SYM`:解析 ELF `SYMTAB/DYNSYM` 并返回 guest 可调用地址。
|
- `DL_SYM`:解析 ELF `SYMTAB/DYNSYM` 并返回 guest 可调用地址。
|
||||||
@@ -718,6 +768,10 @@ u64 cleonos_syscall(u64 id, u64 arg0, u64 arg1, u64 arg2);
|
|||||||
- 配合 Wine 参数 `--fb-window` 可将 framebuffer 实时显示到主机窗口(pygame 后端);未启用时保持内存缓冲模式。
|
- 配合 Wine 参数 `--fb-window` 可将 framebuffer 实时显示到主机窗口(pygame 后端);未启用时保持内存缓冲模式。
|
||||||
- `FB_CLEAR` 支持清屏颜色写入。
|
- `FB_CLEAR` 支持清屏颜色写入。
|
||||||
- `KERNEL_VERSION`(`84`)在 Wine 中返回内核版本字符串(当前默认 `1.0.0-alpha`)。
|
- `KERNEL_VERSION`(`84`)在 Wine 中返回内核版本字符串(当前默认 `1.0.0-alpha`)。
|
||||||
|
- `DISK_*`(`85..92`)在 Wine 中已实现:
|
||||||
|
- 提供虚拟磁盘容量信息与 FAT32 格式化状态查询。
|
||||||
|
- `DISK_FORMAT_FAT32` 会初始化/重置 Wine rootfs 下的虚拟磁盘目录。
|
||||||
|
- `DISK_MOUNT`/`DISK_MOUNT_PATH` 支持挂载点管理,并与 `FS_MKDIR/WRITE/APPEND/REMOVE` 的路径规则联动。
|
||||||
- Wine 在运行时崩溃场景下会生成与内核一致格式的“信号编码退出状态”,可通过 `WAITPID` 读取。
|
- Wine 在运行时崩溃场景下会生成与内核一致格式的“信号编码退出状态”,可通过 `WAITPID` 读取。
|
||||||
- Wine 当前音频 syscall 为占位实现:`AUDIO_AVAILABLE=0`,`AUDIO_PLAY_TONE=0`,`AUDIO_STOP=1`。
|
- Wine 当前音频 syscall 为占位实现:`AUDIO_AVAILABLE=0`,`AUDIO_PLAY_TONE=0`,`AUDIO_STOP=1`。
|
||||||
- Wine 版本号策略固定为 `85.0.0-wine`(`85` = 当前实现 syscall 数量,后续保持不变)。
|
- Wine 版本号策略固定为 `85.0.0-wine`(历史兼容号;不会随 syscall 扩展继续增长)。
|
||||||
|
|||||||
@@ -38,10 +38,10 @@ python wine/cleonos_wine.py build/x86_64/ramdisk_root/shell/shell.elf --rootfs b
|
|||||||
## 支持
|
## 支持
|
||||||
|
|
||||||
- ELF64 (x86_64) PT_LOAD 段装载
|
- ELF64 (x86_64) PT_LOAD 段装载
|
||||||
- CLeonOS `int 0x80` syscall 0..84(含 `FD_*`、`DL_*`、`FB_*`、`PROC_*`、`STATS_*`、`EXEC_PATHV_IO`、`KERNEL_VERSION`)
|
- CLeonOS `int 0x80` syscall 0..92(含 `FD_*`、`DL_*`、`FB_*`、`PROC_*`、`STATS_*`、`EXEC_PATHV_IO`、`KERNEL_VERSION`、`DISK_*`)
|
||||||
- TTY 输出与键盘输入队列
|
- TTY 输出与键盘输入队列
|
||||||
- rootfs 文件/目录访问(`FS_*`)
|
- rootfs 文件/目录访问(`FS_*`)
|
||||||
- `/temp` 写入限制(`FS_MKDIR/WRITE/APPEND/REMOVE`)
|
- `/temp` 与已挂载磁盘路径写入限制(`FS_MKDIR/WRITE/APPEND/REMOVE`)
|
||||||
- `EXEC_PATH/EXEC_PATHV` 执行 ELF(带深度限制)
|
- `EXEC_PATH/EXEC_PATHV` 执行 ELF(带深度限制)
|
||||||
- `EXEC_PATHV_IO`(支持 stdio fd 继承/重定向)
|
- `EXEC_PATHV_IO`(支持 stdio fd 继承/重定向)
|
||||||
- `SPAWN_PATH/SPAWN_PATHV/WAITPID/EXIT/SLEEP_TICKS/YIELD`
|
- `SPAWN_PATH/SPAWN_PATHV/WAITPID/EXIT/SLEEP_TICKS/YIELD`
|
||||||
@@ -52,12 +52,14 @@ python wine/cleonos_wine.py build/x86_64/ramdisk_root/shell/shell.elf --rootfs b
|
|||||||
- 动态库兼容加载(`DL_OPEN/DL_CLOSE/DL_SYM`,基于 ELF 符号解析)
|
- 动态库兼容加载(`DL_OPEN/DL_CLOSE/DL_SYM`,基于 ELF 符号解析)
|
||||||
- framebuffer 兼容(`FB_INFO/FB_BLIT/FB_CLEAR`,支持内存缓冲与窗口显示)
|
- framebuffer 兼容(`FB_INFO/FB_BLIT/FB_CLEAR`,支持内存缓冲与窗口显示)
|
||||||
- 内核版本查询(`KERNEL_VERSION`)
|
- 内核版本查询(`KERNEL_VERSION`)
|
||||||
|
- 磁盘接口兼容(`DISK_PRESENT/SIZE_BYTES/SECTOR_COUNT/FORMATTED/FORMAT_FAT32/MOUNT/MOUNTED/MOUNT_PATH`)
|
||||||
|
- Wine 虚拟磁盘目录默认位于 `<rootfs>/__clks_disk0__`(格式化标记文件 `.fat32`)
|
||||||
- 异常退出状态编码与故障元信息(`PROC_LAST_SIGNAL/PROC_FAULT_*`)
|
- 异常退出状态编码与故障元信息(`PROC_LAST_SIGNAL/PROC_FAULT_*`)
|
||||||
|
|
||||||
## 版本策略
|
## 版本策略
|
||||||
|
|
||||||
- CLeonOS-Wine 版本号固定为:`85.0.0-wine`
|
- CLeonOS-Wine 版本号固定为:`85.0.0-wine`
|
||||||
- 该值来源于“当前实现 syscall 数量 = 85(0..84)”,按项目约定后续不再变更
|
- 该值按项目策略固定,不再随新增 syscall 变更(即使当前实现范围已扩展到 `0..92`)
|
||||||
|
|
||||||
## 参数
|
## 参数
|
||||||
|
|
||||||
@@ -71,6 +73,7 @@ python wine/cleonos_wine.py build/x86_64/ramdisk_root/shell/shell.elf --rootfs b
|
|||||||
- `--` 之后内容:作为 guest argv 透传(推荐)
|
- `--` 之后内容:作为 guest argv 透传(推荐)
|
||||||
- `--max-exec-depth N`:设置 exec 嵌套深度上限
|
- `--max-exec-depth N`:设置 exec 嵌套深度上限
|
||||||
- `--verbose`:打印更多日志
|
- `--verbose`:打印更多日志
|
||||||
|
- 环境变量 `CLEONOS_WINE_DISK_SIZE_MB`:设置 Wine 虚拟磁盘容量(MB,默认 `64`)
|
||||||
|
|
||||||
## `execv/spawnv` 参数格式
|
## `execv/spawnv` 参数格式
|
||||||
|
|
||||||
|
|||||||
@@ -99,6 +99,14 @@ SYS_FB_INFO = 81
|
|||||||
SYS_FB_BLIT = 82
|
SYS_FB_BLIT = 82
|
||||||
SYS_FB_CLEAR = 83
|
SYS_FB_CLEAR = 83
|
||||||
SYS_KERNEL_VERSION = 84
|
SYS_KERNEL_VERSION = 84
|
||||||
|
SYS_DISK_PRESENT = 85
|
||||||
|
SYS_DISK_SIZE_BYTES = 86
|
||||||
|
SYS_DISK_SECTOR_COUNT = 87
|
||||||
|
SYS_DISK_FORMATTED = 88
|
||||||
|
SYS_DISK_FORMAT_FAT32 = 89
|
||||||
|
SYS_DISK_MOUNT = 90
|
||||||
|
SYS_DISK_MOUNTED = 91
|
||||||
|
SYS_DISK_MOUNT_PATH = 92
|
||||||
|
|
||||||
# proc states (from cleonos/c/include/cleonos_syscall.h)
|
# proc states (from cleonos/c/include/cleonos_syscall.h)
|
||||||
PROC_STATE_UNUSED = 0
|
PROC_STATE_UNUSED = 0
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
import shutil
|
||||||
import struct
|
import struct
|
||||||
import sys
|
import sys
|
||||||
import time
|
import time
|
||||||
@@ -62,6 +63,14 @@ from .constants import (
|
|||||||
SYS_FS_STAT_SIZE,
|
SYS_FS_STAT_SIZE,
|
||||||
SYS_FS_STAT_TYPE,
|
SYS_FS_STAT_TYPE,
|
||||||
SYS_FS_WRITE,
|
SYS_FS_WRITE,
|
||||||
|
SYS_DISK_FORMATTED,
|
||||||
|
SYS_DISK_FORMAT_FAT32,
|
||||||
|
SYS_DISK_MOUNT,
|
||||||
|
SYS_DISK_MOUNTED,
|
||||||
|
SYS_DISK_MOUNT_PATH,
|
||||||
|
SYS_DISK_PRESENT,
|
||||||
|
SYS_DISK_SECTOR_COUNT,
|
||||||
|
SYS_DISK_SIZE_BYTES,
|
||||||
SYS_GETPID,
|
SYS_GETPID,
|
||||||
SYS_KERNEL_VERSION,
|
SYS_KERNEL_VERSION,
|
||||||
SYS_KBD_BUFFERED,
|
SYS_KBD_BUFFERED,
|
||||||
@@ -272,6 +281,23 @@ class CLeonOSWineNative:
|
|||||||
self._fb_dirty = False
|
self._fb_dirty = False
|
||||||
self._fb_presented_once = False
|
self._fb_presented_once = False
|
||||||
|
|
||||||
|
self._disk_present = True
|
||||||
|
self._disk_size_bytes = self._bounded_env_int("CLEONOS_WINE_DISK_SIZE_MB", 64, 8, 4096) * 1024 * 1024
|
||||||
|
self._disk_mount_path = "/temp/disk"
|
||||||
|
self._disk_root = (self.rootfs / "__clks_disk0__").resolve()
|
||||||
|
self._disk_marker = self._disk_root / ".fat32"
|
||||||
|
self._disk_formatted = False
|
||||||
|
self._disk_mounted = False
|
||||||
|
try:
|
||||||
|
self._disk_root.mkdir(parents=True, exist_ok=True)
|
||||||
|
if self._disk_marker.exists():
|
||||||
|
self._disk_formatted = True
|
||||||
|
self._disk_mounted = True
|
||||||
|
except Exception:
|
||||||
|
self._disk_present = False
|
||||||
|
self._disk_formatted = False
|
||||||
|
self._disk_mounted = False
|
||||||
|
|
||||||
default_path = self._normalize_guest_path(self.guest_path_hint or f"/{self.elf_path.name}")
|
default_path = self._normalize_guest_path(self.guest_path_hint or f"/{self.elf_path.name}")
|
||||||
self.argv_items, self.env_items = self._prepare_exec_items(default_path, self.argv_items, self.env_items)
|
self.argv_items, self.env_items = self._prepare_exec_items(default_path, self.argv_items, self.env_items)
|
||||||
self._init_default_fds()
|
self._init_default_fds()
|
||||||
@@ -717,6 +743,25 @@ class CLeonOSWineNative:
|
|||||||
return self._fb_clear(arg0)
|
return self._fb_clear(arg0)
|
||||||
if sid == SYS_KERNEL_VERSION:
|
if sid == SYS_KERNEL_VERSION:
|
||||||
return self._kernel_version(uc, arg0, arg1)
|
return self._kernel_version(uc, arg0, arg1)
|
||||||
|
if sid == SYS_DISK_PRESENT:
|
||||||
|
return 1 if self._disk_present else 0
|
||||||
|
if sid == SYS_DISK_SIZE_BYTES:
|
||||||
|
return int(u64(self._disk_size_bytes if self._disk_present else 0))
|
||||||
|
if sid == SYS_DISK_SECTOR_COUNT:
|
||||||
|
if not self._disk_present:
|
||||||
|
return 0
|
||||||
|
return int(u64(self._disk_size_bytes // 512))
|
||||||
|
if sid == SYS_DISK_FORMATTED:
|
||||||
|
return 1 if (self._disk_present and self._disk_formatted) else 0
|
||||||
|
if sid == SYS_DISK_FORMAT_FAT32:
|
||||||
|
label = self._read_guest_cstring(uc, arg0, 16) if arg0 != 0 else ""
|
||||||
|
return self._disk_format_fat32(label)
|
||||||
|
if sid == SYS_DISK_MOUNT:
|
||||||
|
return self._disk_mount(uc, arg0)
|
||||||
|
if sid == SYS_DISK_MOUNTED:
|
||||||
|
return 1 if self._disk_mounted else 0
|
||||||
|
if sid == SYS_DISK_MOUNT_PATH:
|
||||||
|
return self._disk_mount_path_query(uc, arg0, arg1)
|
||||||
|
|
||||||
return u64_neg1()
|
return u64_neg1()
|
||||||
|
|
||||||
@@ -1008,9 +1053,90 @@ class CLeonOSWineNative:
|
|||||||
def _guest_path_is_under_temp(path: str) -> bool:
|
def _guest_path_is_under_temp(path: str) -> bool:
|
||||||
return path == "/temp" or path.startswith("/temp/")
|
return path == "/temp" or path.startswith("/temp/")
|
||||||
|
|
||||||
|
def _disk_path_is_under_mount(self, path: str) -> bool:
|
||||||
|
if not self._disk_mounted:
|
||||||
|
return False
|
||||||
|
normalized = self._normalize_guest_path(path)
|
||||||
|
mount = self._normalize_guest_path(self._disk_mount_path)
|
||||||
|
return normalized == mount or normalized.startswith(mount + "/")
|
||||||
|
|
||||||
|
def _disk_guest_to_host(self, guest_path: str, *, must_exist: bool) -> Optional[Path]:
|
||||||
|
normalized = self._normalize_guest_path(guest_path)
|
||||||
|
mount = self._normalize_guest_path(self._disk_mount_path)
|
||||||
|
|
||||||
|
if not self._disk_present or not self._disk_formatted or not self._disk_mounted:
|
||||||
|
return None
|
||||||
|
|
||||||
|
if normalized == mount:
|
||||||
|
host = self._disk_root
|
||||||
|
elif normalized.startswith(mount + "/"):
|
||||||
|
rel = normalized[len(mount) + 1 :]
|
||||||
|
parts = [part for part in rel.split("/") if part]
|
||||||
|
host = self._disk_root.joinpath(*parts) if parts else self._disk_root
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
|
if must_exist and not host.exists():
|
||||||
|
return None
|
||||||
|
return host
|
||||||
|
|
||||||
|
def _disk_format_fat32(self, label: str) -> int:
|
||||||
|
_ = label
|
||||||
|
if not self._disk_present:
|
||||||
|
return 0
|
||||||
|
|
||||||
|
try:
|
||||||
|
self._disk_root.mkdir(parents=True, exist_ok=True)
|
||||||
|
for child in list(self._disk_root.iterdir()):
|
||||||
|
if child.name == self._disk_marker.name:
|
||||||
|
continue
|
||||||
|
if child.is_dir():
|
||||||
|
shutil.rmtree(child)
|
||||||
|
else:
|
||||||
|
child.unlink()
|
||||||
|
self._disk_marker.write_text("FAT32\n", encoding="utf-8")
|
||||||
|
self._disk_formatted = True
|
||||||
|
return 1
|
||||||
|
except Exception:
|
||||||
|
return 0
|
||||||
|
|
||||||
|
def _disk_mount(self, uc: Uc, mount_ptr: int) -> int:
|
||||||
|
mount_path = self._normalize_guest_path(self._read_guest_cstring(uc, mount_ptr, EXEC_PATH_MAX))
|
||||||
|
|
||||||
|
if not self._disk_present or not self._disk_formatted:
|
||||||
|
return 0
|
||||||
|
|
||||||
|
if mount_path == "/":
|
||||||
|
return 0
|
||||||
|
|
||||||
|
self._disk_mount_path = mount_path
|
||||||
|
self._disk_mounted = True
|
||||||
|
return 1
|
||||||
|
|
||||||
|
def _disk_mount_path_query(self, uc: Uc, out_ptr: int, out_size: int) -> int:
|
||||||
|
if out_ptr == 0 or out_size == 0:
|
||||||
|
return 0
|
||||||
|
|
||||||
|
if not self._disk_mounted:
|
||||||
|
return 0
|
||||||
|
|
||||||
|
payload = self._normalize_guest_path(self._disk_mount_path).encode("utf-8", errors="replace")
|
||||||
|
max_copy = int(out_size) - 1
|
||||||
|
if max_copy < 0:
|
||||||
|
return 0
|
||||||
|
if len(payload) > max_copy:
|
||||||
|
payload = payload[:max_copy]
|
||||||
|
return len(payload) if self._write_guest_bytes(uc, out_ptr, payload + b"\x00") else 0
|
||||||
|
|
||||||
def _fs_mkdir(self, uc: Uc, path_ptr: int) -> int:
|
def _fs_mkdir(self, uc: Uc, path_ptr: int) -> int:
|
||||||
path = self._normalize_guest_path(self._read_guest_cstring(uc, path_ptr))
|
path = self._normalize_guest_path(self._read_guest_cstring(uc, path_ptr))
|
||||||
if not self._guest_path_is_under_temp(path):
|
is_temp_path = self._guest_path_is_under_temp(path)
|
||||||
|
is_disk_path = self._disk_path_is_under_mount(path)
|
||||||
|
|
||||||
|
if not is_temp_path and not is_disk_path:
|
||||||
|
return 0
|
||||||
|
|
||||||
|
if is_disk_path and not self._disk_formatted:
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
host_path = self._guest_to_host(path, must_exist=False)
|
host_path = self._guest_to_host(path, must_exist=False)
|
||||||
@@ -1028,8 +1154,17 @@ class CLeonOSWineNative:
|
|||||||
|
|
||||||
def _fs_write_common(self, uc: Uc, path_ptr: int, data_ptr: int, size: int, append_mode: bool) -> int:
|
def _fs_write_common(self, uc: Uc, path_ptr: int, data_ptr: int, size: int, append_mode: bool) -> int:
|
||||||
path = self._normalize_guest_path(self._read_guest_cstring(uc, path_ptr))
|
path = self._normalize_guest_path(self._read_guest_cstring(uc, path_ptr))
|
||||||
|
is_temp_path = self._guest_path_is_under_temp(path)
|
||||||
|
is_disk_path = self._disk_path_is_under_mount(path)
|
||||||
|
disk_mount = self._normalize_guest_path(self._disk_mount_path)
|
||||||
|
|
||||||
if not self._guest_path_is_under_temp(path) or path == "/temp":
|
if not is_temp_path and not is_disk_path:
|
||||||
|
return 0
|
||||||
|
|
||||||
|
if is_disk_path and not self._disk_formatted:
|
||||||
|
return 0
|
||||||
|
|
||||||
|
if path == "/temp" or (is_disk_path and path == disk_mount):
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
if size < 0 or size > self.state.fs_write_max:
|
if size < 0 or size > self.state.fs_write_max:
|
||||||
@@ -1068,8 +1203,17 @@ class CLeonOSWineNative:
|
|||||||
|
|
||||||
def _fs_remove(self, uc: Uc, path_ptr: int) -> int:
|
def _fs_remove(self, uc: Uc, path_ptr: int) -> int:
|
||||||
path = self._normalize_guest_path(self._read_guest_cstring(uc, path_ptr))
|
path = self._normalize_guest_path(self._read_guest_cstring(uc, path_ptr))
|
||||||
|
is_temp_path = self._guest_path_is_under_temp(path)
|
||||||
|
is_disk_path = self._disk_path_is_under_mount(path)
|
||||||
|
disk_mount = self._normalize_guest_path(self._disk_mount_path)
|
||||||
|
|
||||||
if not self._guest_path_is_under_temp(path) or path == "/temp":
|
if not is_temp_path and not is_disk_path:
|
||||||
|
return 0
|
||||||
|
|
||||||
|
if is_disk_path and not self._disk_formatted:
|
||||||
|
return 0
|
||||||
|
|
||||||
|
if path == "/temp" or (is_disk_path and path == disk_mount):
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
host_path = self._guest_to_host(path, must_exist=True)
|
host_path = self._guest_to_host(path, must_exist=True)
|
||||||
@@ -2178,6 +2322,11 @@ class CLeonOSWineNative:
|
|||||||
|
|
||||||
def _guest_to_host(self, guest_path: str, *, must_exist: bool) -> Optional[Path]:
|
def _guest_to_host(self, guest_path: str, *, must_exist: bool) -> Optional[Path]:
|
||||||
norm = self._normalize_guest_path(guest_path)
|
norm = self._normalize_guest_path(guest_path)
|
||||||
|
disk_host = self._disk_guest_to_host(norm, must_exist=must_exist)
|
||||||
|
|
||||||
|
if disk_host is not None:
|
||||||
|
return disk_host
|
||||||
|
|
||||||
if norm == "/":
|
if norm == "/":
|
||||||
return self.rootfs if (not must_exist or self.rootfs.exists()) else None
|
return self.rootfs if (not must_exist or self.rootfs.exists()) else None
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user