|
| 1 | +##### Compilation ##### |
| 2 | + |
| 3 | +RISCV_COMPILER_PREFIX := riscv64-buildroot-linux-gnu- |
| 4 | + |
| 5 | +# This is the final bootable OpenSBI + Linux image. |
| 6 | +elf := build/fw_payload.elf |
| 7 | + |
| 8 | +.PHONY: all |
| 9 | +all: $(elf) |
| 10 | + |
| 11 | +# Generic rule to download tools. |
| 12 | +downloads/%.tar.xz: %.url |
| 13 | + mkdir -p downloads |
| 14 | + curl --location '$(shell cat $<)' --output $@ |
| 15 | + |
| 16 | +# Rules to extract tools. For simplicity we strip the first directory component because it varies. |
| 17 | +build/gcc/bin/$(RISCV_COMPILER_PREFIX)gcc: downloads/gcc.tar.xz |
| 18 | + mkdir -p build/gcc |
| 19 | + tar --touch --directory build/gcc --strip-components=1 --extract --file downloads/gcc.tar.xz |
| 20 | + |
| 21 | +build/linux/Makefile: downloads/linux.tar.xz |
| 22 | + mkdir -p build/linux |
| 23 | + tar --touch --directory build/linux --strip-components=1 --extract --file downloads/linux.tar.xz |
| 24 | + |
| 25 | +build/opensbi/Makefile: downloads/opensbi.tar.xz |
| 26 | + mkdir -p build/opensbi |
| 27 | + tar --touch --directory build/opensbi --strip-components=1 --extract --file downloads/opensbi.tar.xz |
| 28 | + |
| 29 | +CROSS_COMPILE := $(shell pwd)/build/gcc/bin/$(RISCV_COMPILER_PREFIX) |
| 30 | + |
| 31 | +# Rule to build the Linux kernel. |
| 32 | +build/linux/arch/riscv/boot/Image: build/linux/Makefile build/gcc/bin/$(RISCV_COMPILER_PREFIX)gcc |
| 33 | + $(MAKE) -C build/linux CROSS_COMPILE=$(CROSS_COMPILE) ARCH=riscv defconfig |
| 34 | + $(MAKE) -C build/linux CROSS_COMPILE=$(CROSS_COMPILE) CONFIG_HVC_RISCV_SBI=y ARCH=riscv Image |
| 35 | + |
| 36 | +# Rule to build OpenSBI, with the Linux kernel embedded in it. |
| 37 | +# |
| 38 | +# FW_TEXT_START is 0 by default which doesn't leave space for the emulator bootloader. |
| 39 | +# 0x80000000 is the default start of Spike's memory. |
| 40 | +$(elf): build/opensbi/Makefile build/linux/arch/riscv/boot/Image build/gcc/bin/$(RISCV_COMPILER_PREFIX)gcc |
| 41 | + $(MAKE) -C build/opensbi FW_TEXT_START=0x80000000 FW_PAYLOAD=y FW_PAYLOAD_PATH=../linux/arch/riscv/boot/Image PLATFORM=generic CROSS_COMPILE=$(CROSS_COMPILE) |
| 42 | + cp build/opensbi/build/platform/generic/firmware/fw_payload.elf $(elf) |
| 43 | + |
| 44 | +# Path to Sail emulator. |
| 45 | +SAIL_SIM ?= ../../build/c_emulator/sail_riscv_sim |
| 46 | + |
| 47 | +build/sail.dts: $(SAIL_SIM) |
| 48 | + mkdir -p build |
| 49 | + $(SAIL_SIM) --print-device-tree >$@ |
| 50 | + |
| 51 | +build/sail.dtb: build/sail.dts |
| 52 | + mkdir -p build |
| 53 | + dtc $< -o $@ |
| 54 | + |
| 55 | +.PHONY: clean |
| 56 | +clean: |
| 57 | + rm -rf build |
| 58 | + |
| 59 | +.PHONY: distclean |
| 60 | +distclean: |
| 61 | + rm -rf build |
| 62 | + rm -rf downloads |
| 63 | + |
| 64 | +##### Running ##### |
| 65 | + |
| 66 | +# Number of instructions to run. The image does not include userspace; there |
| 67 | +# is no 'init' available, so it will crash at that point. It takes about |
| 68 | +# 200 million instructions to get to that point. Execution speed is around |
| 69 | +# 300 kIPS so it takes around 10 minutes. Spike and QEMU are much faster. |
| 70 | +LIMIT_INSTRUCTIONS := 20000000 |
| 71 | + |
| 72 | +# Run with the Sail emulator from this repo. |
| 73 | +.PHONY: sail |
| 74 | +sail: build/sail.dtb $(elf) $(SAIL_SIM) |
| 75 | + $(SAIL_SIM) --no-trace -p -l $(LIMIT_INSTRUCTIONS) --device-tree-blob build/sail.dtb $(elf) |
| 76 | + |
| 77 | +# Run the profiler. This requires gperftools and pprof: |
| 78 | +# |
| 79 | +# git clone https://github.com/gperftools/gperftools |
| 80 | +# cd gperftools |
| 81 | +# # There's CMake support but unfortunately it's broken. |
| 82 | +# # See https://github.com/gperftools/gperftools/issues/1576 |
| 83 | +# ./autogen.sh |
| 84 | +# ./configure |
| 85 | +# make -j4 |
| 86 | +# sudo make install |
| 87 | +# |
| 88 | +# go install github.com/google/pprof@latest |
| 89 | +# |
| 90 | +.PHONY: sail_profile |
| 91 | +sail_profile: build/sail.dtb $(elf) $(SAIL_SIM) |
| 92 | + rm -f build/prof.out |
| 93 | + CPUPROFILE=build/prof.out LD_PRELOAD=/usr/local/lib/libtcmalloc_and_profiler.so $(SAIL_SIM) --no-trace -p -l 2000000 --device-tree-blob build/sail.dtb $(elf) |
| 94 | + pprof -http : build/prof.out |
| 95 | + |
| 96 | +# Run with Spike: https://github.com/riscv-software-src/riscv-isa-sim |
| 97 | +.PHONY: spike |
| 98 | +spike: $(elf) |
| 99 | + spike --instructions=$(LIMIT_INSTRUCTIONS) $(elf) |
| 100 | + |
| 101 | +# Run with QEMU. |
| 102 | +.PHONY: qemu |
| 103 | +qemu: $(elf) |
| 104 | + qemu-system-riscv64 -M virt -m 256M -nographic -bios $(elf) |
0 commit comments