diff --git a/.gitignore b/.gitignore index 07216f3..ce5df9d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ *~ _* *.o +*.a *.d *.asm *.sym diff --git a/Makefile b/Makefile index 39a99d7..62bca73 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,6 @@ K=kernel U=user +P=programs OBJS = \ $K/entry.o \ @@ -11,6 +12,7 @@ OBJS = \ $K/spinlock.o \ $K/string.o \ $K/main.o \ + $K/rust.a \ $K/vm.o \ $K/proc.o \ $K/swtch.o \ @@ -63,6 +65,10 @@ CFLAGS += -ffreestanding -fno-common -nostdlib -mno-relax CFLAGS += -I. CFLAGS += $(shell $(CC) -fno-stack-protector -E -x c /dev/null >/dev/null 2>&1 && echo -fno-stack-protector) +RUSTC = rustc +TARGET_TRIPLE = riscv64gc-unknown-none-elf +RUSTFLAGS = -C soft-float=n --target $(TARGET_TRIPLE) + # Disable PIE when possible (for Ubuntu 16.10 toolchain) ifneq ($(shell $(CC) -dumpspecs 2>/dev/null | grep -e '[^f]no-pie'),) CFLAGS += -fno-pie -no-pie @@ -89,6 +95,12 @@ tags: $(OBJS) _init ULIB = $U/ulib.o $U/usys.o $U/printf.o $U/umalloc.o +%.a: %.rs + $(RUSTC) $(RUSTFLAGS) --crate-type staticlib -o $@ -L $K $^ + +%.o: %.c *.h + $(CC) $(CFLAGS) -c $^ + _%: %.o $(ULIB) $(LD) $(LDFLAGS) -T $U/user.ld -o $@ $^ $(OBJDUMP) -S $@ > $*.asm @@ -116,22 +128,22 @@ mkfs/mkfs: mkfs/mkfs.c $K/fs.h $K/param.h .PRECIOUS: %.o UPROGS=\ - $U/_cat\ - $U/_echo\ - $U/_forktest\ - $U/_grep\ - $U/_init\ - $U/_kill\ - $U/_ln\ - $U/_ls\ - $U/_mkdir\ - $U/_rm\ - $U/_sh\ - $U/_stressfs\ - $U/_usertests\ - $U/_grind\ - $U/_wc\ - $U/_zombie\ + $P/_cat\ + $P/_echo\ + $P/_forktest\ + $P/_grep\ + $P/_grind\ + $P/_init\ + $P/_kill\ + $P/_ln\ + $P/_ls\ + $P/_mkdir\ + $P/_rm\ + $P/_sh\ + $P/_stressfs\ + $P/_usertests\ + $P/_wc\ + $P/_zombie\ fs.img: mkfs/mkfs README $(UPROGS) mkfs/mkfs fs.img README $(UPROGS) @@ -140,7 +152,7 @@ fs.img: mkfs/mkfs README $(UPROGS) clean: rm -f *.tex *.dvi *.idx *.aux *.log *.ind *.ilg \ - */*.o */*.d */*.asm */*.sym \ + */*.o */*.a */*.d */*.asm */*.sym \ $U/initcode $U/initcode.out $K/kernel fs.img \ mkfs/mkfs .gdbinit \ $U/usys.S \ diff --git a/kernel/main.c b/kernel/main.c index f0d3171..9eaa96e 100644 --- a/kernel/main.c +++ b/kernel/main.c @@ -6,6 +6,8 @@ volatile static int started = 0; +void rust_main(); + // start() jumps here in supervisor mode on all CPUs. void main() @@ -16,6 +18,7 @@ main() printf("\n"); printf("xv6 kernel is booting\n"); printf("\n"); + rust_main(); kinit(); // physical page allocator kvminit(); // create kernel page table kvminithart(); // turn on paging diff --git a/kernel/printf.c b/kernel/printf.c index 1a50203..6082602 100644 --- a/kernel/printf.c +++ b/kernel/printf.c @@ -59,6 +59,10 @@ printptr(uint64 x) consputc(digits[x >> (sizeof(uint64) * 8 - 4)]); } +void print(char *raw) { + printf("%s", raw); +} + // Print to the console. only understands %d, %x, %p, %s. void printf(char *fmt, ...) diff --git a/kernel/rust.rs b/kernel/rust.rs new file mode 100644 index 0000000..3cc2dcd --- /dev/null +++ b/kernel/rust.rs @@ -0,0 +1,26 @@ +#![no_std] +#![no_main] + +use core::ffi::{c_char, CStr}; + +extern "C" { + fn print(message: *const c_char); + fn panic(panic_message: *const c_char) -> !; +} + +#[no_mangle] +pub extern "C" fn rust_main() { + unsafe { + print( + CStr::from_bytes_with_nul(b"Hello from Rust!\0") + .unwrap() + .as_ptr(), + ); + } +} + + +#[panic_handler] +unsafe fn panic_wrapper(_panic_info: &core::panic::PanicInfo) -> ! { + panic(CStr::from_bytes_with_nul(b"panic from rust\0").unwrap_or_default().as_ptr()) +} diff --git a/mkfs/mkfs.c b/mkfs/mkfs.c index 1ec326b..c7585b1 100644 --- a/mkfs/mkfs.c +++ b/mkfs/mkfs.c @@ -132,6 +132,8 @@ main(int argc, char *argv[]) char *shortname; if(strncmp(argv[i], "user/", 5) == 0) shortname = argv[i] + 5; + else if(strncmp(argv[i], "programs/", 9) == 0) + shortname = argv[i] + 9; else shortname = argv[i]; diff --git a/user/cat.c b/programs/cat.c similarity index 100% rename from user/cat.c rename to programs/cat.c diff --git a/user/echo.c b/programs/echo.c similarity index 100% rename from user/echo.c rename to programs/echo.c diff --git a/user/forktest.c b/programs/forktest.c similarity index 100% rename from user/forktest.c rename to programs/forktest.c diff --git a/user/grep.c b/programs/grep.c similarity index 100% rename from user/grep.c rename to programs/grep.c diff --git a/user/grind.c b/programs/grind.c similarity index 100% rename from user/grind.c rename to programs/grind.c diff --git a/user/init.c b/programs/init.c similarity index 100% rename from user/init.c rename to programs/init.c diff --git a/user/kill.c b/programs/kill.c similarity index 100% rename from user/kill.c rename to programs/kill.c diff --git a/user/ln.c b/programs/ln.c similarity index 100% rename from user/ln.c rename to programs/ln.c diff --git a/user/ls.c b/programs/ls.c similarity index 100% rename from user/ls.c rename to programs/ls.c diff --git a/user/mkdir.c b/programs/mkdir.c similarity index 100% rename from user/mkdir.c rename to programs/mkdir.c diff --git a/user/rm.c b/programs/rm.c similarity index 100% rename from user/rm.c rename to programs/rm.c diff --git a/user/sh.c b/programs/sh.c similarity index 100% rename from user/sh.c rename to programs/sh.c diff --git a/user/stressfs.c b/programs/stressfs.c similarity index 100% rename from user/stressfs.c rename to programs/stressfs.c diff --git a/user/usertests.c b/programs/usertests.c similarity index 100% rename from user/usertests.c rename to programs/usertests.c diff --git a/user/wc.c b/programs/wc.c similarity index 100% rename from user/wc.c rename to programs/wc.c diff --git a/user/zombie.c b/programs/zombie.c similarity index 100% rename from user/zombie.c rename to programs/zombie.c