Merge pull request #9 from redox-os/redoxfs

Implement Filesystem
This commit is contained in:
Jeremy Soller 2016-09-28 11:27:17 -06:00 committed by GitHub
commit 96c269abe6
14 changed files with 266 additions and 49 deletions

1
.gitignore vendored
View file

@ -2,3 +2,4 @@ Cargo.lock
build
target
initfs/bin
filesystem/bin

6
.gitmodules vendored
View file

@ -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

143
Makefile
View file

@ -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/

View file

@ -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) };

View file

@ -17,3 +17,5 @@ kernel_file:
.end:
.length equ kernel_file.end - kernel_file
.length_sectors equ .length / 512
incbin "build/userspace/filesystem.bin"

View file

@ -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<HbaCmdTable>; 32], buf: &mut Dma<[u8; 256 * 512]>) -> Result<usize> {
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::<FisRegH2D>() / size_of::<u32>()) 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));

View file

@ -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

View file

@ -216,6 +216,30 @@ impl Scheme for UserScheme {
result
}
fn mkdir(&self, path: &[u8], mode: usize) -> Result<usize> {
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<usize> {
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<usize> {
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<usize> {
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<usize> {
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<usize> {
let inner = self.inner.upgrade().ok_or(Error::new(ENODEV))?;
let address = inner.capture_mut(stat)?;

View file

@ -62,6 +62,72 @@ pub fn open(path: &[u8], flags: usize) -> Result<usize> {
}).ok_or(Error::new(EMFILE))
}
/// mkdir syscall
pub fn mkdir(path: &[u8], mode: usize) -> Result<usize> {
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<usize> {
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<usize> {
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<usize> {
let file = {
@ -92,12 +158,22 @@ pub fn dup(fd: usize) -> Result<usize> {
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

View file

@ -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)
}

2
libstd

@ -1 +1 @@
Subproject commit 29a6cab11d6e84c422917724ef0eca2bcc2c6589
Subproject commit 4dbfda17c3c2e2a0d88687a42151fc8a81f28ca0

1
programs/extrautils Submodule

@ -0,0 +1 @@
Subproject commit 049f539aa40af8d1b0f93898a5967437c852d6ce

View file

@ -11,6 +11,8 @@ pub fn main() {
let sh = args.next().expect("login: no sh provided");
let sh_args: Vec<String> = 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);

1
schemes/redoxfs Submodule

@ -0,0 +1 @@
Subproject commit 36b3cf04a9d35b85d481acdf99494fc535152cf0