setup.md (4095B)
1 # Setting up your environment 2 3 You will need a cross compiler (riscv32-elf-gcc), debugger (riscv-elf-gdb), and emulator (qemu-system-riscv32). 4 5 See "Installing GCC and GDB" or "Building GCC and GDB" below for instructions. 6 7 Qemu is a bit more complicated -- we need a custom version that has support for peripherals compatible with the FPGA SoC. 8 9 See "Building Qemu" below. 10 11 Once you have the compiler, debugger, and emulator installed, you can tell the build system 12 where to find them by editing 'local.mk' at the root of this project: 13 ``` makefile 14 XTOOLCHAIN := /path/to/bin/riscv32-elf- 15 QEMU := /path/to/bin/qemu-system-riscv32 16 ``` 17 18 Note that the toolchain path is a prefix, omitting `gcc` because the makefile will stick `gdb`, `objdump`, `ld`, etc on the end as needed. 19 20 Once you're all set up, proceed to "Checking out and building" below. 21 22 23 ## Installing GCC and GDB Ubuntu 24 This should work on Ubuntu 20.04.4LTS or newer. Not sure about older versions. 25 ``` 26 sudo apt-get install gcc-riscv64-unknown-elf gdb-multiarch 27 ``` 28 That should get you `riscv64-unknown-elf-gcc` and `gdb-multiarch`, and you 29 can add the following to your `local.mk`: 30 31 ``` makefile 32 XTOOLCHAIN := /usr/bin/riscv64-unknown-elf- 33 QEMU := /usr/bin/qemu-system-riscv32 34 ``` 35 36 Note that the toolchain is 64-bit by default, and the qemu system is 32-bit; the compiler arguments in the main 37 Makefile specify that a 32-bit binary should be built. 38 39 ## Building GCC and GDB (if needed) 40 41 [Travis](https://github.com/travisg) has a handy set of scripts to checkout and build gcc and gdb 42 43 You may need to install some packages (libgmp-dev for sure) for this to succeed. If it fails, find the missing package and let me know so I can update these instructions. 44 45 ``` 46 $ git clone git@github.com:travisg/toolchains.git 47 $ cd toolchains 48 $ ./doit -f -a riscv32 49 ``` 50 51 On success you'll end up with `riscv32-elf-11.2.0-Linux-x86_64` with `bin/riscv32-elf-*` inside. 52 53 I like to keep all my cross compilers in a common place, so I do this: 54 ``` 55 $ mv riscv32-elf-11.2.0-Linux-x86_64/ /toolchain/riscv32-11.2.0 56 ``` 57 58 ## Alternate Toolchain Build 59 60 I haven't tried this, but it's the official-ish RISCV toolchain build system and looks like it should build gcc, gdb, and qemu: 61 https://github.com/riscv-collab/riscv-gnu-toolchain 62 63 Be sure to configure it for 32bit riscv. 64 65 ## Building Qemu 66 67 You need to check out the modified qemu from github and select the "workshop" branch to build: 68 69 ``` 70 git clone https://github.com/swetland/qemu.git 71 cd qemu 72 git checkout -b workshop origin/workshop 73 ./configure --prefix=/toolchain/qemu --target-list=riscv32-softmmu 74 make -j32 75 ``` 76 77 You could use `make install` to install qemu at the specified prefix, but since you may have to update it from time to time 78 it's easiest to just configure things to point to the binary in the build itself. Modify your `local.mk` to include: 79 ``` makefile 80 QEMU := /path/to/qemu/build/qemu-system-riscv32 81 ``` 82 83 ## Updating Qemu 84 85 You may have to refresh your build from time to time... 86 ``` 87 git remote update 88 git rebase origin/workshop 89 make clean 90 make -j32 91 make install 92 ``` 93 94 ## Checking out and building 95 96 ``` 97 $ git clone git@github.com:swetland/os-workshop.git 98 $ cd os-workshop 99 $ make 100 ``` 101 102 There are some simple projects, defined in `project/*.mk` 103 104 Build results appear in `out/<projectname>/...` (objects, etc), `out/<projectname>.elf` (the binary), and `out/<projectname>.lst` (disasembly of the binary, handy for debugging). 105 106 You can run a project under qemu with `make run.<projectname>` or under qemu, ready for gdb connection with `make debug.<projectname>` 107 108 To exit qemu: `CTRL-A` `X` 109 110 To bring up the qemu console: `CTRL-A` `C` 111 112 ## Using GDB with QEMU 113 114 In one terminal: 115 ``` 116 $ make debug.mandelbrot 117 ``` 118 119 In another: 120 ``` 121 $ riscv32-elf-gdb out/mandelbrot.elf 122 ... 123 Reading symbols from out/mandelbrot.elf... 124 (gdb) target remote :7777 125 0x00001000 in ?? () 126 (gdb) break main 127 Breakpoint 1 at 0x8000002c: file misc/mandelbrot.c, line 7. 128 (gdb) cont 129 Continuing. 130 131 Breakpoint 1, main (argc=0, argv=0x0) at misc/mandelbrot.c:7 132 7 int top = 1000, bottom = -1000, ystep = 50; 133 (gdb) 134 ```