diff --git a/Makefile b/Makefile index 11e11cd..399afff 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,8 @@ K=kernel U=user +BOOTLOADER = ./external/rustsbi-qemu.bin + OBJS = \ $K/entry.o \ $K/start.o \ @@ -163,7 +165,7 @@ ifndef CPUS CPUS := 3 endif -QEMUOPTS = -machine virt -bios none -kernel $K/kernel -m 128M -smp $(CPUS) -nographic +QEMUOPTS = -machine virt -bios $(BOOTLOADER) -kernel $K/kernel -m 128M -smp $(CPUS) -nographic QEMUOPTS += -global virtio-mmio.force-legacy=false QEMUOPTS += -drive file=fs.img,if=none,format=raw,id=x0 QEMUOPTS += -device virtio-blk-device,drive=x0,bus=virtio-mmio-bus.0 @@ -185,10 +187,12 @@ fmt: cd ./rs_src/xv6/ && make fmt .PHONY: rs-os +RS_KERNEL := ./rs_src/xv6/xv6-kernel/target/riscv64gc-unknown-none-elf/release/xv6-kernel rs-os: $(OBJS) $K/kernel.ld $U/initcode cd ./rs_src/xv6/ && make all -RS_KERNEL := ./rs_src/xv6/xv6-kernel/target/riscv64gc-unknown-none-elf/release/xv6-kernel -RS_QEMUOPTS = -machine virt -bios none -kernel $(RS_KERNEL) -m 128M -smp $(CPUS) -nographic + rust-objcopy --binary-architecture=riscv64 $(RS_KERNEL) --strip-all -O binary $(RS_KERNEL).bin +RS_QEMUOPTS = -machine virt -bios $(BOOTLOADER) -device loader,file=$(RS_KERNEL).bin,addr=0x80200000 +RS_QEMUOPTS += -m 128M -smp $(CPUS) -nographic RS_QEMUOPTS += -global virtio-mmio.force-legacy=false RS_QEMUOPTS += -drive file=fs.img,if=none,format=raw,id=x0 RS_QEMUOPTS += -device virtio-blk-device,drive=x0,bus=virtio-mmio-bus.0 @@ -196,6 +200,10 @@ RS_QEMUOPTS += -device virtio-blk-device,drive=x0,bus=virtio-mmio-bus.0 rs-qemu: rs-os fs.img $(QEMU) $(RS_QEMUOPTS) +rs-qemu-gdb: rs-os .gdbinit fs.img + @echo "*** Now run 'gdb' in another window." 1>&2 + $(QEMU) $(RS_QEMUOPTS) -S $(QEMUGDB) + debug-sym: $K/kernel rs-os $(OBJDUMP) -t $K/kernel | sed '1,/SYMBOL TABLE/d; s/ .* / /; /^$$/d' > debug_c.sym $(OBJDUMP) -t $(RS_KERNEL) | sed '1,/SYMBOL TABLE/d; s/ .* / /; /^$$/d' > debug_rs.sym @@ -203,3 +211,9 @@ debug-sym: $K/kernel rs-os show-debug-sym: debug-sym diff -u --color debug_c.sym debug_rs.sym + +conn-gdb: + (gdb \ + -ex 'file $(RS_KERNEL)' \ + -ex 'set arch riscv:rv64' \ + -ex 'target remote localhost:${GDBPORT}') diff --git a/external/rustsbi-qemu.bin b/external/rustsbi-qemu.bin new file mode 100644 index 0000000..463cfa9 Binary files /dev/null and b/external/rustsbi-qemu.bin differ diff --git a/kernel/entry.S b/kernel/entry.S index 5ab365e..1d7975d 100644 --- a/kernel/entry.S +++ b/kernel/entry.S @@ -3,19 +3,17 @@ # kernel.ld causes the following code to # be placed at 0x80000000. .section .text -.global _entry -_entry: - # set up a stack for C. - # stack0 is declared in start.c, - # with a 4096-byte stack per CPU. - # sp = stack0 + (hartid * 4096) - la sp, stack0 - li a0, 1024*4 - csrr a1, mhartid - addi a1, a1, 1 - mul a0, a0, a1 - add sp, sp, a0 - # jump to start() in start.c - call start +.global _start +_start: + la sp, boot_stack_top + call main + + .section .bss.stack + .globl boot_stack_lower_bound +boot_stack_lower_bound: + .space 4096 * 16 + .globl boot_stack_top +boot_stack_top: + spin: j spin diff --git a/kernel/kernel.ld b/kernel/kernel.ld index ee04f22..c906469 100644 --- a/kernel/kernel.ld +++ b/kernel/kernel.ld @@ -1,13 +1,13 @@ OUTPUT_ARCH( "riscv" ) -ENTRY( _entry ) +ENTRY( _start ) SECTIONS { /* - * ensure that entry.S / _entry is at 0x80000000, + * ensure that entry.S / _start is at 0x80000000, * where qemu's -kernel jumps. */ - . = 0x80000000; + . = 0x80200000; .text : { *(.text .text.*) diff --git a/kernel/main.c b/kernel/main.c index dd35d9c..c6da4a5 100644 --- a/kernel/main.c +++ b/kernel/main.c @@ -14,19 +14,32 @@ void c_main() { printf("\n"); printf("xv6 kernel is booting\n"); printf("\n"); - kinit(); // physical page allocator - kvminit(); // create kernel page table - kvminithart(); // turn on paging - procinit(); // process table - trapinit(); // trap vectors - trapinithart(); // install kernel trap vector - plicinit(); // set up interrupt controller - plicinithart(); // ask PLIC for device interrupts - binit(); // buffer cache - iinit(); // inode table - fileinit(); // file table - virtio_disk_init(); // emulated hard disk - userinit(); // first user process + kinit(); + printf("[OK] physical page allocator\n"); + kvminit(); + printf("[OK] create kernel page table\n"); + kvminithart(); + printf("[OK] turn on paging\n"); + procinit(); + printf("[OK] process table\n"); + trapinit(); + printf("[OK] trap vectors\n"); + trapinithart(); + printf("[OK] install kernel trap vector\n"); + plicinit(); + printf("[OK] set up interrupt controller\n"); + plicinithart(); + printf("[OK] ask PLIC for device interrupts\n"); + binit(); + printf("[OK] buffer cache\n"); + iinit(); + printf("[OK] inode table\n"); + fileinit(); + printf("[OK] file table\n"); + virtio_disk_init(); + printf("[OK] emulated hard disk\n"); + userinit(); + printf("[OK] first user process\n"); __sync_synchronize(); started = 1; } else { diff --git a/kernel/memlayout.h b/kernel/memlayout.h index abaea7d..85ecf88 100644 --- a/kernel/memlayout.h +++ b/kernel/memlayout.h @@ -44,7 +44,7 @@ // the kernel expects there to be RAM // for use by the kernel and user pages // from physical address 0x80000000 to PHYSTOP. -#define KERNBASE 0x80000000L +#define KERNBASE 0x80200000L #define PHYSTOP (KERNBASE + 128 * 1024 * 1024) // map the trampoline page to the highest address, diff --git a/shell.nix b/shell.nix index 0a8c373..c55afee 100644 --- a/shell.nix +++ b/shell.nix @@ -2,5 +2,5 @@ let pkgs = import {}; in pkgs.pkgsCross.riscv64.mkShell { - packages = with pkgs; [alejandra clang-tools fd gcc qemu]; + packages = with pkgs; [alejandra cargo-binutils clang-tools fd gcc gdb qemu]; }