diff --git a/.gitignore b/.gitignore index 6738f91..3d6f0d2 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ Cargo.lock build target initfs/bin +filesystem/bin diff --git a/.gitmodules b/.gitmodules index 5d13505..ea9df03 100644 --- a/.gitmodules +++ b/.gitmodules @@ -16,3 +16,9 @@ [submodule "programs/coreutils"] path = programs/coreutils url = https://github.com/redox-os/coreutils.git +[submodule "schemes/redoxfs"] + path = schemes/redoxfs + url = https://github.com/redox-os/redoxfs +[submodule "programs/extrautils"] + path = programs/extrautils + url = https://github.com/redox-os/extrautils.git diff --git a/Makefile b/Makefile index 7b4e165..53fe4f4 100644 --- a/Makefile +++ b/Makefile @@ -32,8 +32,11 @@ clean: cargo clean --manifest-path programs/ion/Cargo.toml cargo clean --manifest-path programs/login/Cargo.toml cargo clean --manifest-path programs/coreutils/Cargo.toml + cargo clean --manifest-path programs/extrautils/Cargo.toml cargo clean --manifest-path schemes/example/Cargo.toml + cargo clean --manifest-path schemes/redoxfs/Cargo.toml rm -rf initfs/bin + rm -rf filesystem/bin rm -rf build FORCE: @@ -57,7 +60,7 @@ qemu: $(KBUILD)/harddrive.bin else LD=ld QEMUFLAGS+=-machine q35 -smp 4 -m 256 - ifeq ($(kvm),yes) + ifneq ($(kvm),no) QEMUFLAGS+=-enable-kvm -cpu host endif ifeq ($(vga),no) @@ -74,7 +77,7 @@ else %.list: % objdump -C -M intel -D $< > $@ -$(KBUILD)/harddrive.bin: $(KBUILD)/kernel bootloader/$(ARCH)/** +$(KBUILD)/harddrive.bin: $(KBUILD)/kernel $(BUILD)/filesystem.bin bootloader/$(ARCH)/** nasm -f bin -o $@ -D ARCH_$(ARCH) -ibootloader/$(ARCH)/ bootloader/$(ARCH)/harddrive.asm qemu: $(KBUILD)/harddrive.bin @@ -147,37 +150,23 @@ initfs/bin/%: programs/%/Cargo.toml programs/%/src/** $(BUILD)/libstd.rlib strip $@ rm $@.d -initfs/bin/%: programs/coreutils/Cargo.toml programs/coreutils/src/bin/%.rs $(BUILD)/libstd.rlib +initfs/bin/%: schemes/%/Cargo.toml schemes/%/src/** $(BUILD)/libstd.rlib mkdir -p initfs/bin $(CARGO) rustc --manifest-path $< --bin $* $(CARGOFLAGS) -o $@ strip $@ rm $@.d -initfs/bin/%: schemes/%/Cargo.toml schemes/%/src/** $(BUILD)/libstd.rlib - mkdir -p initfs/bin - $(CARGO) rustc --manifest-path $< $(CARGOFLAGS) -o $@ - strip $@ - rm $@.d +initfs_drivers: \ + initfs/bin/ahcid \ + initfs/bin/pcid -coreutils: \ - initfs/bin/cat \ - initfs/bin/echo \ - initfs/bin/env \ - initfs/bin/ls \ - initfs/bin/printenv \ - initfs/bin/pwd \ - initfs/bin/realpath +initfs_schemes: \ + initfs/bin/redoxfs $(BUILD)/initfs.rs: \ - initfs/bin/ahcid \ - initfs/bin/pcid \ - initfs/bin/ps2d \ - initfs/bin/vesad \ initfs/bin/init \ - initfs/bin/ion \ - initfs/bin/login \ - coreutils \ - initfs/bin/example + initfs_drivers \ + initfs_schemes echo 'use collections::BTreeMap;' > $@ echo 'pub fn gen() -> BTreeMap<&'"'"'static [u8], (&'"'"'static [u8], bool)> {' >> $@ echo ' let mut files: BTreeMap<&'"'"'static [u8], (&'"'"'static [u8], bool)> = BTreeMap::new();' >> $@ @@ -190,3 +179,109 @@ $(BUILD)/initfs.rs: \ find initfs -type f -o -type l | cut -d '/' -f2- | sort | awk '{printf(" files.insert(b\"%s\", (include_bytes!(\"../../initfs/%s\"), false));\n", $$0, $$0)}' >> $@ echo ' files' >> $@ echo '}' >> $@ + +filesystem/bin/%: drivers/%/Cargo.toml drivers/%/src/** $(BUILD)/libstd.rlib + mkdir -p filesystem/bin + $(CARGO) rustc --manifest-path $< $(CARGOFLAGS) -o $@ + strip $@ + rm $@.d + +filesystem/bin/%: programs/%/Cargo.toml programs/%/src/** $(BUILD)/libstd.rlib + mkdir -p filesystem/bin + $(CARGO) rustc --manifest-path $< $(CARGOFLAGS) -o $@ + strip $@ + rm $@.d + +filesystem/bin/%: programs/coreutils/Cargo.toml programs/coreutils/src/bin/%.rs $(BUILD)/libstd.rlib + mkdir -p filesystem/bin + $(CARGO) rustc --manifest-path $< --bin $* $(CARGOFLAGS) -o $@ + strip $@ + rm $@.d + +filesystem/bin/%: programs/extrautils/Cargo.toml programs/extrautils/src/bin/%.rs $(BUILD)/libstd.rlib + mkdir -p filesystem/bin + $(CARGO) rustc --manifest-path $< --bin $* $(CARGOFLAGS) -o $@ + strip $@ + rm $@.d + +filesystem/bin/%: schemes/%/Cargo.toml schemes/%/src/** $(BUILD)/libstd.rlib + mkdir -p filesystem/bin + $(CARGO) rustc --manifest-path $< --bin $* $(CARGOFLAGS) -o $@ + strip $@ + rm $@.d + +drivers: \ + filesystem/bin/ps2d \ + filesystem/bin/vesad + +coreutils: \ + filesystem/bin/basename \ + filesystem/bin/cat \ + filesystem/bin/clear \ + filesystem/bin/cp \ + filesystem/bin/cut \ + filesystem/bin/date \ + filesystem/bin/du \ + filesystem/bin/echo \ + filesystem/bin/env \ + filesystem/bin/false \ + filesystem/bin/head \ + filesystem/bin/ls \ + filesystem/bin/mkdir \ + filesystem/bin/mv \ + filesystem/bin/printenv \ + filesystem/bin/pwd \ + filesystem/bin/realpath \ + filesystem/bin/reset \ + filesystem/bin/rmdir \ + filesystem/bin/rm \ + filesystem/bin/seq \ + filesystem/bin/sleep \ + filesystem/bin/tail \ + filesystem/bin/time \ + filesystem/bin/touch \ + filesystem/bin/true \ + filesystem/bin/wc \ + filesystem/bin/yes + #filesystem/bin/free filesystem/bin/ps filesystem/bin/shutdown filesystem/bin/test + +extrautils: \ + filesystem/bin/calc \ + filesystem/bin/cksum \ + filesystem/bin/cur \ + filesystem/bin/grep \ + filesystem/bin/less \ + filesystem/bin/mdless \ + filesystem/bin/mtxt \ + filesystem/bin/rem \ + #filesystem/bin/dmesg filesystem/bin/info filesystem/bin/man filesystem/bin/watch + + +schemes: \ + filesystem/bin/example + +$(BUILD)/filesystem.bin: \ + drivers \ + coreutils \ + schemes \ + filesystem/bin/ion \ + filesystem/bin/login + rm -rf $@ $(BUILD)/filesystem/ + echo exit | cargo run --manifest-path schemes/redoxfs/Cargo.toml --bin redoxfs-utility $@ + mkdir -p $(BUILD)/filesystem/ + cargo run --manifest-path schemes/redoxfs/Cargo.toml --bin redoxfs-fuse $@ $(BUILD)/filesystem/ & + sleep 2 + -cp -RL filesystem/* $(BUILD)/filesystem/ + sync + -fusermount -u $(BUILD)/filesystem/ + rm -rf $(BUILD)/filesystem/ + +mount: FORCE + mkdir -p $(KBUILD)/harddrive/ + cargo run --manifest-path schemes/redoxfs/Cargo.toml --bin redoxfs-fuse $(KBUILD)/harddrive.bin $(KBUILD)/harddrive/ & + sleep 2 + +unmount: FORCE + sync + -fusermount -u $(KBUILD)/harddrive/ + rm -rf $(KBUILD)/harddrive/ diff --git a/arch/x86_64/src/acpi/mod.rs b/arch/x86_64/src/acpi/mod.rs index f44bd07..245450d 100644 --- a/arch/x86_64/src/acpi/mod.rs +++ b/arch/x86_64/src/acpi/mod.rs @@ -5,7 +5,7 @@ use core::intrinsics::{atomic_load, atomic_store}; use core::sync::atomic::Ordering; use interrupt; -use memory::{allocate_frame, Frame}; +use memory::{allocate_frames, Frame}; use paging::{entry, ActivePageTable, Page, PhysicalAddress, VirtualAddress}; use start::{kstart_ap, AP_READY}; @@ -59,11 +59,8 @@ pub fn init_sdt(sdt: &'static Sdt, active_table: &mut ActivePageTable) { if ap_local_apic.flags & 1 == 1 { // Allocate a stack // TODO: Allocate contiguous - let stack_start = allocate_frame().expect("no more frames in acpi stack_start").start_address().get() + ::KERNEL_OFFSET; - for _i in 0..62 { - allocate_frame().expect("no more frames in acpi stack"); - } - let stack_end = allocate_frame().expect("no more frames in acpi stack_end").start_address().get() + 4096 + ::KERNEL_OFFSET; + let stack_start = allocate_frames(64).expect("no more frames in acpi stack_start").start_address().get() + ::KERNEL_OFFSET; + let stack_end = stack_start + 64 * 4096; let ap_ready = TRAMPOLINE as *mut u64; let ap_cpu_id = unsafe { ap_ready.offset(1) }; diff --git a/bootloader/x86_64/harddrive.asm b/bootloader/x86_64/harddrive.asm index c0f228b..b2c0255 100644 --- a/bootloader/x86_64/harddrive.asm +++ b/bootloader/x86_64/harddrive.asm @@ -17,3 +17,5 @@ kernel_file: .end: .length equ kernel_file.end - kernel_file .length_sectors equ .length / 512 + +incbin "build/userspace/filesystem.bin" diff --git a/drivers/ahcid/src/ahci/hba.rs b/drivers/ahcid/src/ahci/hba.rs index 015b733..a5b3a13 100644 --- a/drivers/ahcid/src/ahci/hba.rs +++ b/drivers/ahcid/src/ahci/hba.rs @@ -218,15 +218,13 @@ impl HbaPort { } pub fn ata_dma(&mut self, block: u64, sectors: usize, write: bool, clb: &mut Dma<[HbaCmdHeader; 32]>, ctbas: &mut [Dma; 32], buf: &mut Dma<[u8; 256 * 512]>) -> Result { - println!("AHCI {:X} DMA BLOCK: {:X} SECTORS: {} WRITE: {}", (self as *mut HbaPort) as usize, block, sectors, write); + //println!("AHCI {:X} DMA BLOCK: {:X} SECTORS: {} WRITE: {}", (self as *mut HbaPort) as usize, block, sectors, write); assert!(sectors > 0 && sectors < 256); self.is.write(u32::MAX); if let Some(slot) = self.slot() { - println!("Slot {}", slot); - let cmdheader = &mut clb[slot as usize]; cmdheader.cfl.write(((size_of::() / size_of::()) as u8)); @@ -268,12 +266,10 @@ impl HbaPort { cmdfis.counth.write((sectors >> 8) as u8); } - println!("Busy Wait"); while self.tfd.readf((ATA_DEV_BUSY | ATA_DEV_DRQ) as u32) {} self.ci.writef(1 << slot, true); - println!("Completion Wait"); while self.ci.readf(1 << slot) { if self.is.readf(HBA_PORT_IS_TFES) { return Err(Error::new(EIO)); diff --git a/initfs/etc/init.rc b/initfs/etc/init.rc index e46d40d..a24336f 100644 --- a/initfs/etc/init.rc +++ b/initfs/etc/init.rc @@ -1,5 +1,5 @@ -initfs:bin/vesad -initfs:bin/ps2d initfs:bin/pcid initfs:etc/pcid.toml -#initfs:bin/example -initfs:bin/login display: initfs:bin/ion +initfs:bin/redoxfs disk:0 +file:bin/vesad +file:bin/ps2d +file:bin/login display: file:bin/ion diff --git a/kernel/scheme/user.rs b/kernel/scheme/user.rs index a02b2b7..dd415cc 100644 --- a/kernel/scheme/user.rs +++ b/kernel/scheme/user.rs @@ -216,6 +216,30 @@ impl Scheme for UserScheme { result } + fn mkdir(&self, path: &[u8], mode: usize) -> Result { + let inner = self.inner.upgrade().ok_or(Error::new(ENODEV))?; + let address = inner.capture(path)?; + let result = inner.call(SYS_MKDIR, address, path.len(), mode); + let _ = inner.release(address); + result + } + + fn rmdir(&self, path: &[u8]) -> Result { + let inner = self.inner.upgrade().ok_or(Error::new(ENODEV))?; + let address = inner.capture(path)?; + let result = inner.call(SYS_RMDIR, address, path.len(), 0); + let _ = inner.release(address); + result + } + + fn unlink(&self, path: &[u8]) -> Result { + let inner = self.inner.upgrade().ok_or(Error::new(ENODEV))?; + let address = inner.capture(path)?; + let result = inner.call(SYS_UNLINK, address, path.len(), 0); + let _ = inner.release(address); + result + } + fn dup(&self, file: usize) -> Result { let inner = self.inner.upgrade().ok_or(Error::new(ENODEV))?; inner.call(SYS_DUP, file, 0, 0) @@ -247,6 +271,14 @@ impl Scheme for UserScheme { inner.call(SYS_FEVENT, file, flags, 0) } + fn fpath(&self, file: usize, buf: &mut [u8]) -> Result { + let inner = self.inner.upgrade().ok_or(Error::new(ENODEV))?; + let address = inner.capture_mut(buf)?; + let result = inner.call(SYS_FPATH, file, address, buf.len()); + let _ = inner.release(address); + result + } + fn fstat(&self, file: usize, stat: &mut Stat) -> Result { let inner = self.inner.upgrade().ok_or(Error::new(ENODEV))?; let address = inner.capture_mut(stat)?; diff --git a/kernel/syscall/fs.rs b/kernel/syscall/fs.rs index 91c36e4..17ffec6 100644 --- a/kernel/syscall/fs.rs +++ b/kernel/syscall/fs.rs @@ -62,6 +62,72 @@ pub fn open(path: &[u8], flags: usize) -> Result { }).ok_or(Error::new(EMFILE)) } +/// mkdir syscall +pub fn mkdir(path: &[u8], mode: usize) -> Result { + let path_canon = { + let contexts = context::contexts(); + let context_lock = contexts.current().ok_or(Error::new(ESRCH))?; + let context = context_lock.read(); + context.canonicalize(path) + }; + + let mut parts = path_canon.splitn(2, |&b| b == b':'); + let namespace_opt = parts.next(); + let reference_opt = parts.next(); + + let namespace = namespace_opt.ok_or(Error::new(ENOENT))?; + let scheme = { + let schemes = scheme::schemes(); + let (_scheme_id, scheme) = schemes.get_name(namespace).ok_or(Error::new(ENOENT))?; + scheme.clone() + }; + scheme.mkdir(reference_opt.unwrap_or(b""), mode) +} + +/// rmdir syscall +pub fn rmdir(path: &[u8]) -> Result { + let path_canon = { + let contexts = context::contexts(); + let context_lock = contexts.current().ok_or(Error::new(ESRCH))?; + let context = context_lock.read(); + context.canonicalize(path) + }; + + let mut parts = path_canon.splitn(2, |&b| b == b':'); + let namespace_opt = parts.next(); + let reference_opt = parts.next(); + + let namespace = namespace_opt.ok_or(Error::new(ENOENT))?; + let scheme = { + let schemes = scheme::schemes(); + let (_scheme_id, scheme) = schemes.get_name(namespace).ok_or(Error::new(ENOENT))?; + scheme.clone() + }; + scheme.rmdir(reference_opt.unwrap_or(b"")) +} + +/// Unlink syscall +pub fn unlink(path: &[u8]) -> Result { + let path_canon = { + let contexts = context::contexts(); + let context_lock = contexts.current().ok_or(Error::new(ESRCH))?; + let context = context_lock.read(); + context.canonicalize(path) + }; + + let mut parts = path_canon.splitn(2, |&b| b == b':'); + let namespace_opt = parts.next(); + let reference_opt = parts.next(); + + let namespace = namespace_opt.ok_or(Error::new(ENOENT))?; + let scheme = { + let schemes = scheme::schemes(); + let (_scheme_id, scheme) = schemes.get_name(namespace).ok_or(Error::new(ENOENT))?; + scheme.clone() + }; + scheme.unlink(reference_opt.unwrap_or(b"")) +} + /// Close syscall pub fn close(fd: usize) -> Result { let file = { @@ -92,12 +158,22 @@ pub fn dup(fd: usize) -> Result { file }; - let scheme = { - let schemes = scheme::schemes(); - let scheme = schemes.get(file.scheme).ok_or(Error::new(EBADF))?; - scheme.clone() + let new_id = { + let scheme = { + let schemes = scheme::schemes(); + let scheme = schemes.get(file.scheme).ok_or(Error::new(EBADF))?; + scheme.clone() + }; + scheme.dup(file.number)? }; - scheme.dup(file.number) + + let contexts = context::contexts(); + let context_lock = contexts.current().ok_or(Error::new(ESRCH))?; + let context = context_lock.read(); + context.add_file(::context::file::File { + scheme: file.scheme, + number: new_id + }).ok_or(Error::new(EMFILE)) } /// Register events for file diff --git a/kernel/syscall/mod.rs b/kernel/syscall/mod.rs index 2815091..d799da0 100644 --- a/kernel/syscall/mod.rs +++ b/kernel/syscall/mod.rs @@ -32,11 +32,14 @@ pub extern fn syscall(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize SYS_OPEN => open(validate_slice(b as *const u8, c)?, d), SYS_CLOSE => close(b), SYS_WAITPID => waitpid(b, c, d), + SYS_UNLINK => unlink(validate_slice(b as *const u8, c)?), SYS_EXECVE => exec(validate_slice(b as *const u8, c)?, validate_slice(d as *const [usize; 2], e)?), SYS_CHDIR => chdir(validate_slice(b as *const u8, c)?), SYS_LSEEK => lseek(b, c, d), SYS_GETPID => getpid(), SYS_FSTAT => fstat(b, &mut validate_slice_mut(c as *mut Stat, 1)?[0]), + SYS_MKDIR => mkdir(validate_slice(b as *const u8, c)?, d), + SYS_RMDIR => rmdir(validate_slice(b as *const u8, c)?), SYS_DUP => dup(b), SYS_BRK => brk(b), SYS_FTRUNCATE => ftruncate(b, c), @@ -59,5 +62,11 @@ pub extern fn syscall(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize } } - Error::mux(inner(a, b, c, d, e, f, stack)) + let result = inner(a, b, c, d, e, f, stack); + + if let Err(ref err) = result { + println!("{}, {}, {}, {}: {}", a, b, c, d, err); + } + + Error::mux(result) } diff --git a/libstd b/libstd index 29a6cab..4dbfda1 160000 --- a/libstd +++ b/libstd @@ -1 +1 @@ -Subproject commit 29a6cab11d6e84c422917724ef0eca2bcc2c6589 +Subproject commit 4dbfda17c3c2e2a0d88687a42151fc8a81f28ca0 diff --git a/programs/extrautils b/programs/extrautils new file mode 160000 index 0000000..049f539 --- /dev/null +++ b/programs/extrautils @@ -0,0 +1 @@ +Subproject commit 049f539aa40af8d1b0f93898a5967437c852d6ce diff --git a/programs/login/src/main.rs b/programs/login/src/main.rs index 1e0ca13..ca273fb 100644 --- a/programs/login/src/main.rs +++ b/programs/login/src/main.rs @@ -11,6 +11,8 @@ pub fn main() { let sh = args.next().expect("login: no sh provided"); let sh_args: Vec = args.collect(); + env::set_current_dir("file:").expect("login: failed to cd to file:"); + let _ = syscall::close(2); let _ = syscall::close(1); let _ = syscall::close(0); @@ -26,9 +28,8 @@ pub fn main() { command.arg(arg); } - command.env("HOME", "initfs:"); - command.env("PWD", "initfs:bin"); - command.env("PATH", "initfs:bin"); + command.env("HOME", "file:home"); + command.env("PATH", "file:bin"); command.env("COLUMNS", "80"); command.env("LINES", "30"); command.env("TTY", &tty); diff --git a/schemes/redoxfs b/schemes/redoxfs new file mode 160000 index 0000000..36b3cf0 --- /dev/null +++ b/schemes/redoxfs @@ -0,0 +1 @@ +Subproject commit 36b3cf04a9d35b85d481acdf99494fc535152cf0