diff --git a/.gitignore b/.gitignore index bfc4af84..a2ff54b6 100644 --- a/.gitignore +++ b/.gitignore @@ -15,3 +15,5 @@ sysroot minimalsysroot tools/init/init tools/init/main.o +tools/mount/mount +tools/mount/main.o diff --git a/kernel-src/arch/x86-64/syscall.asm b/kernel-src/arch/x86-64/syscall.asm index bf952daa..b924a159 100644 --- a/kernel-src/arch/x86-64/syscall.asm +++ b/kernel-src/arch/x86-64/syscall.asm @@ -36,6 +36,7 @@ extern syscall_umask extern syscall_poll extern syscall_nanosleep extern syscall_ftruncate +extern syscall_mount syscalltab: dq syscall_print dq syscall_mmap @@ -74,7 +75,8 @@ dq syscall_umask dq syscall_poll dq syscall_nanosleep dq syscall_ftruncate -syscallcount equ 37 +dq syscall_mount +syscallcount equ 38 section .text global arch_syscall_entry ; on entry: diff --git a/kernel-src/arch/x86-64/syscalllog.c b/kernel-src/arch/x86-64/syscalllog.c index 98b2b4fc..f5a94671 100644 --- a/kernel-src/arch/x86-64/syscalllog.c +++ b/kernel-src/arch/x86-64/syscalllog.c @@ -4,7 +4,7 @@ #ifdef SYSCALL_LOGGING -#define SYSCALL_COUNT 35 +#define SYSCALL_COUNT 38 #define LOGSTR(x) arch_e9_puts(x) static char *name[] = { @@ -44,7 +44,8 @@ static char *name[] = { "umask", "poll", "nanosleep", - "ftruncate" + "ftruncate", + "mount" }; static char *args[] = { @@ -84,7 +85,8 @@ static char *args[] = { "mode %o", // umask "fds %p nfds %d timeout %d", // poll "time %p remaining %p", // nanosleep - "fd %d size %lu" // ftruncate + "fd %d size %lu", // ftruncate + "backing %s mountpoint %s fs %s flags %d data %p" // mount }; #endif diff --git a/kernel-src/sys/syscalls/mount.c b/kernel-src/sys/syscalls/mount.c new file mode 100644 index 00000000..30117313 --- /dev/null +++ b/kernel-src/sys/syscalls/mount.c @@ -0,0 +1,71 @@ +#include +#include +#include +#include +#include + +syscallret_t syscall_mount(context_t *context, const char *ubacking, const char *umountpoint, const char *ufs, unsigned long flags, void *data) { + syscallret_t ret = { + .ret = -1 + }; + __assert(flags == 0); + + if ((void *)ubacking > USERSPACE_END || (void *)umountpoint > USERSPACE_END || (void *)ufs > USERSPACE_END) { + ret.errno = EFAULT; + return ret; + } + + ret.errno = ENOMEM; + char *mountpoint = alloc(strlen(umountpoint) + 1); + if (mountpoint == NULL) { + return ret; + } + + char *fs = alloc(strlen(ufs) + 1); + if (fs == NULL) { + free(mountpoint); + return ret; + } + + char *backing = NULL; + if (ubacking) { + backing = alloc(strlen(ubacking) + 1); + if (backing == NULL) { + free(mountpoint); + free(fs); + return ret; + } + strcpy(backing, ubacking); + } + strcpy(fs, ufs); + strcpy(mountpoint, umountpoint); + + vnode_t *backingrefnode = NULL; + if (ubacking) + backingrefnode = *backing == '/' ? sched_getroot() : sched_getcwd(); + vnode_t *mountpointrefnode = *mountpoint == '/' ? sched_getroot() : sched_getcwd(); + vnode_t *backingnode = NULL; + + if (ubacking) { + ret.errno = vfs_lookup(&backingnode, backingrefnode, backing, NULL, 0); + if (ret.errno) + goto cleanup; + } + + ret.errno = vfs_mount(backingnode, mountpointrefnode, mountpoint, fs, data); + if (ubacking) { + VOP_RELEASE(backingnode); + } + + cleanup: + if (ubacking) { + VOP_RELEASE(backingrefnode); + free(backing); + } + + VOP_RELEASE(mountpointrefnode); + + free(mountpoint); + free(fs); + return ret; +} diff --git a/limine.cfg b/limine.cfg index d1ce2b07..13db5e89 100644 --- a/limine.cfg +++ b/limine.cfg @@ -3,9 +3,28 @@ TERM_MARGIN_GRADIENT=40 TERM_WALLPAPER=boot:///liminebg.bmp TERM_WALLPAPER_STYLE=stretched TIMEOUT=5 -:Astral + +:Astral +PROTOCOL=limine +KERNEL_PATH=boot:///astral +KERNEL_CMDLINE=root=nvme0n1 rootfs=ext2 +COMMENT="The Astral operating system" + +:Astral (initrd) PROTOCOL=limine KERNEL_PATH=boot:///astral MODULE_PATH=boot:///initrd -KERNEL_CMDLINE= +KERNEL_CMDLINE=initrd rootfs=tmpfs +COMMENT="The Astral operating system" + +:Astral (debugging) +PROTOCOL=limine +KERNEL_PATH=boot:///astral +KERNEL_CMDLINE=root=nvme0n1 rootfs=ext2 e9 syscall_log +COMMENT="The Astral operating system" + +:Astral (debugging, initrd) +KERNEL_PATH=boot:///astral +MODULE_PATH=boot:///initrd +KERNEL_CMDLINE=initrd rootfs=tmpfs e9 syscall_log COMMENT="The Astral operating system" diff --git a/patches/mlibc/jinx-working-patch.patch b/patches/mlibc/jinx-working-patch.patch index b218d56f..bf21dcdf 100644 --- a/patches/mlibc/jinx-working-patch.patch +++ b/patches/mlibc/jinx-working-patch.patch @@ -13,16 +13,18 @@ index bb5b6ef..bd2f740 100644 #define IPPROTO_HOPOPTS 0 #define IPPROTO_ICMP 1 diff --git mlibc-clean/meson.build mlibc-workdir/meson.build -index 2261926..03b6260 100644 +index 2261926..b5e6108 100644 --- mlibc-clean/meson.build +++ mlibc-workdir/meson.build -@@ -153,6 +153,10 @@ elif host_machine.system() == 'dripos' +@@ -153,6 +153,12 @@ elif host_machine.system() == 'dripos' rtdl_include_dirs += include_directories('sysdeps/dripos/include') libc_include_dirs += include_directories('sysdeps/dripos/include') subdir('sysdeps/dripos') +elif host_machine.system() == 'astral' + rtdl_include_dirs += include_directories('sysdeps/astral/include') + libc_include_dirs += include_directories('sysdeps/astral/include') ++ internal_conf.set10('MLIBC_MAP_DSO_SEGMENTS', true) ++ internal_conf.set10('MLIBC_MAP_FILE_WINDOWS', true) + subdir('sysdeps/astral') else error('No sysdeps defined for OS: ' + host_machine.system()) @@ -133,10 +135,10 @@ index 0000000..e5b087a + diff --git mlibc-workdir/sysdeps/astral/generic/generic.cpp mlibc-workdir/sysdeps/astral/generic/generic.cpp new file mode 100644 -index 0000000..f7b6375 +index 0000000..23128c0 --- /dev/null +++ mlibc-workdir/sysdeps/astral/generic/generic.cpp -@@ -0,0 +1,443 @@ +@@ -0,0 +1,448 @@ +#include +#include +#include @@ -216,6 +218,11 @@ index 0000000..f7b6375 + return 0; + } + ++ int sys_mount(const char *source, const char *target, const char *fstype, unsigned long flags, const void *data) { ++ long ret; ++ return syscall(SYSCALL_MOUNT, &ret, (uint64_t)source, (uint64_t)target, (uint64_t)fstype, flags, (uint64_t)data); ++ } ++ + int sys_ftruncate(int fd, size_t size) { + long ret; + return syscall(SYSCALL_FTRUNCATE, &ret, fd, size); @@ -599,10 +606,10 @@ index 0000000..990eca0 +#endif diff --git mlibc-workdir/sysdeps/astral/include/astral/syscall.h mlibc-workdir/sysdeps/astral/include/astral/syscall.h new file mode 100644 -index 0000000..76b4800 +index 0000000..2fda766 --- /dev/null +++ mlibc-workdir/sysdeps/astral/include/astral/syscall.h -@@ -0,0 +1,60 @@ +@@ -0,0 +1,61 @@ +#ifndef _SYSCALL_H_INCLUDE +#define _SYSCALL_H_INCLUDE + @@ -643,6 +650,7 @@ index 0000000..76b4800 +#define SYSCALL_POLL 34 +#define SYSCALL_NANOSLEEP 35 +#define SYSCALL_FTRUNCATE 36 ++#define SYSCALL_MOUNT 37 + +#include +#include diff --git a/recipes/mount b/recipes/mount new file mode 100644 index 00000000..34a5aadf --- /dev/null +++ b/recipes/mount @@ -0,0 +1,18 @@ +name=mount +revision=1 +from_source=mount +imagedeps="base-devel" +hostdeps="xbinutils xgcc" +deps="mlibc" + +configure() { + true +} + +build() { + make -C ${source_dir} -j ${parallelism} +} + +install() { + make -C ${source_dir} install PREFIX=${prefix} DESTDIR=${dest_dir} +} diff --git a/source-recipes/mount b/source-recipes/mount new file mode 100644 index 00000000..6883a081 --- /dev/null +++ b/source-recipes/mount @@ -0,0 +1,7 @@ +name=mount +version=0 +source_dir="tools/mount" + +regenerate() { + true +} diff --git a/tools/mount/Makefile b/tools/mount/Makefile new file mode 100644 index 00000000..e1935576 --- /dev/null +++ b/tools/mount/Makefile @@ -0,0 +1,14 @@ +.phony: all install +CC=x86_64-astral-gcc +LD=x86_64-astral-gcc +all: mount + +install: + mkdir -p "$(DESTDIR)/$(PREFIX)/bin/" + cp mount "$(DESTDIR)/$(PREFIX)/bin/mount" + +mount: main.o + $(LD) $(LDFLAGS) -o $@ $^ + +main.o: main.c + $(CC) -c $(CFLAGS) -o $@ $< diff --git a/tools/mount/main.c b/tools/mount/main.c new file mode 100644 index 00000000..7774bb5f --- /dev/null +++ b/tools/mount/main.c @@ -0,0 +1,44 @@ +#include +#include +#include +#include +#include + +void usage(char *name) { + fprintf(stderr, "%s: usage: %s [-d device] mountpoint filesystem\n", name, name); + exit(EXIT_FAILURE); +} + +int main(int argc, char *argv[]) { + char *dev = NULL; + char *mountp = NULL; + char *fs = NULL; + bool devnext = false; + + for (int i = 1; i < argc; ++i) { + if (strcmp(argv[i], "-d") == 0) { + devnext = true; + continue; + } + + if (devnext) { + devnext = false; + dev = argv[i]; + } else if (mountp == NULL) + mountp = argv[i]; + else if (fs == NULL) + fs = argv[i]; + else + usage(argv[0]); + } + + if (mount == NULL || fs == NULL) + usage(argv[0]); + + if (mount(dev, mountp, fs, 0, NULL) == -1) { + perror("mount failed"); + return EXIT_FAILURE; + } + + return EXIT_SUCCESS; +}