Skip to content

Commit 5898e86

Browse files
Implement RISC-V 32I ISA (#6)
* Add unimplemented RISC-V 32I ISA * Implement RV32I architecture - Updated utils.h to support 32-bit memory operations and removed obsolete functions. - Deprecate hardware.c and instructions.c as part of the transition to a new architecture. - Updated utililities in utils.c to use 32-bit rv32i compatible instructions - Remove the bulk of test_utils.c temporarily - Update compiler documentation to explain installation of toolchain. Note: still incomplete * Add syscall support, improve memory handling, implement example embeddable hello.c * Deprecate docs/ directory in favour of GitHub wiki * Update PR request template to remove reference to docs
1 parent 69defc9 commit 5898e86

19 files changed

Lines changed: 1217 additions & 753 deletions

.github/PULL_REQUEST_TEMPLATE.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ Please ensure the following before requesting a merge:
77

88
- [ ] I have read and agree to the repository's [CONTRIBUTING.md](https://github.com/lachlanharrisdev/virtualised-binary-obfuscation/blob/main/CONTRIBUTING.md) and [LICENSE.md](https://github.com/lachlanharrisdev/virtualised-binary-obfuscation/blob/main/LICENSE.md).
99
- [ ] All tests pass locally (`make`, `make test`).
10-
- [ ] Relevant documentation has been updated (`README.md`, `docs/`).
10+
- [ ] Relevant documentation has been updated (`README.md`, GitHub wiki(s)).
1111
- [ ] Code follows the repository's style and formatting guidelines.
1212
- [ ] I have added/updated relevant tests.
1313

.gitignore

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,5 +64,11 @@ dkms.conf
6464
bin/
6565
*.key*
6666

67+
riscv-gnu-toolchain-rv32i/
68+
6769
test/**/*
68-
!test/**/*.c
70+
!test/**/*.c
71+
72+
*.bin
73+
*.app
74+
*.img

Makefile

Lines changed: 91 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,37 @@ DIR = bin
55
BIN = $(DIR)/vbo
66
PYTHON ?= python3
77

8-
SRC_COMMON = src/instructions.c src/utils.c src/hardware.c
8+
# minimal RISCV32I VM build
9+
SRC_COMMON = src/riscv32i.c src/utils.c
910
SRC_MAIN = src/main.c $(SRC_COMMON)
1011

1112
FLAGS = -Wall -Wextra -Werror -g -std=c11 -pedantic
1213

14+
# RISC-V cross toolchain (see docs/compiler.md)
15+
RV_PREFIX ?= ~/.local/xPacks/riscv-none-elf-gcc/xpack-riscv-none-elf-gcc-14.2.0-3/bin/riscv-none-elf-
16+
RV_GCC := $(RV_PREFIX)gcc
17+
RV_OBJCOPY:= $(RV_PREFIX)objcopy
18+
19+
# Example app pipeline
20+
OUT_DIR ?= out
21+
EXAMPLES_DIR ?= examples
22+
APP_SRC ?= $(EXAMPLES_DIR)/hello.c
23+
APP_ELF := $(OUT_DIR)/app.elf
24+
APP_BIN := $(OUT_DIR)/app.bin
25+
APP_IMG := $(OUT_DIR)/app.img
26+
ORIGIN ?= 0x3000
27+
28+
define ensure_rv_toolchain
29+
@if ! command -v $(RV_GCC) >/dev/null 2>&1; then \
30+
echo "[Make] Missing toolchain: $(RV_GCC). See docs/compiler.md to install and add to PATH."; \
31+
exit 1; \
32+
fi
33+
@if ! command -v $(RV_OBJCOPY) >/dev/null 2>&1; then \
34+
echo "[Make] Missing tool: $(RV_OBJCOPY). Check your riscv-none-elf toolchain installation."; \
35+
exit 1; \
36+
fi
37+
endef
38+
1339
EMBED_IMAGE ?=
1440
EMBED_OBJ :=
1541
ifneq ($(strip $(EMBED_IMAGE)),)
@@ -18,7 +44,7 @@ endif
1844

1945
TEST_DIR = test
2046

21-
.PHONY: all build clean test distclean
47+
.PHONY: all build clean test distclean app image embed run demo clean-app test-integration test-all help
2248

2349
all: build
2450

@@ -34,10 +60,71 @@ clean:
3460
rm -f $(BIN)
3561
rm -f $(TEST_DIR)/test_utils
3662
rm -f images/vbo_image.o
63+
rm -rf $(OUT_DIR)
3764

3865
distclean: clean
3966

4067
test:
41-
$(CC) $(INC) $(TEST_DIR)/test_utils.c src/utils.c src/hardware.c -o $(TEST_DIR)/test_utils $(FLAGS)
68+
$(CC) $(INC) $(TEST_DIR)/test_utils.c src/utils.c src/riscv32i.c -o $(TEST_DIR)/test_utils $(FLAGS)
4269
$(TEST_DIR)/test_utils
43-
rm $(TEST_DIR)/test_utils
70+
rm $(TEST_DIR)/test_utils
71+
72+
# Run both unit and integration tests (integration is skipped if toolchain is missing)
73+
test-all: test test-integration
74+
75+
# --- App build pipeline ---
76+
77+
$(OUT_DIR):
78+
mkdir -p $(OUT_DIR)
79+
80+
app: $(APP_ELF)
81+
82+
$(APP_ELF): $(APP_SRC) | $(OUT_DIR)
83+
$(call ensure_rv_toolchain)
84+
$(RV_GCC) \
85+
-march=rv32i -mabi=ilp32 -nostdlib -ffreestanding -Os -s -fno-pic \
86+
-Wl,--build-id=none -Wl,-Ttext=$(ORIGIN) -Wl,-e,_start \
87+
-Iinclude -o $@ $<
88+
89+
$(APP_BIN): $(APP_ELF) | $(OUT_DIR)
90+
$(RV_OBJCOPY) -O binary $< $@
91+
92+
image: $(APP_IMG)
93+
94+
$(APP_IMG): $(APP_BIN) | $(OUT_DIR)
95+
$(PYTHON) -c 'import sys,struct; o=int(sys.argv[1],16) if str(sys.argv[1]).startswith("0x") else int(sys.argv[1]); open(sys.argv[2],"wb").write(struct.pack(">I",o)+open(sys.argv[3],"rb").read())' \
96+
$(ORIGIN) $@ $<
97+
98+
# Embed convenience: uses APP_IMG if EMBED_IMAGE not provided
99+
embed: image
100+
$(MAKE) build EMBED_IMAGE=$(APP_IMG)
101+
102+
run: build image
103+
$(BIN) $(APP_IMG)
104+
105+
demo: embed run
106+
107+
clean-app:
108+
rm -rf $(OUT_DIR)
109+
110+
# Integration test (optional): requires toolchain, builds hello and checks output
111+
test-integration: build
112+
@if ! command -v $(RV_GCC) >/dev/null 2>&1 || ! command -v $(RV_OBJCOPY) >/dev/null 2>&1; then \
113+
echo "[Test] Skipping integration test (toolchain not found). See docs/compiler.md"; \
114+
exit 0; \
115+
fi
116+
@$(MAKE) --no-print-directory image
117+
@echo "[Test] Running integration test (hello)"
118+
@out=$$($(BIN) $(APP_IMG)); echo "$$out" | grep -q "Hello from RV32I VM" && echo "[Test] OK" || (echo "[Test] FAIL"; exit 1)
119+
120+
help:
121+
@echo "Targets:"
122+
@echo " build - Build the VM"
123+
@echo " app - Build example app (set APP_SRC=...)"
124+
@echo " image - Make flat image with origin header from app"
125+
@echo " embed - Embed image and rebuild VM"
126+
@echo " run - Run VM with built image"
127+
@echo " demo - Build+embed+run example app end-to-end"
128+
@echo " test - Run unit tests"
129+
@echo " test-all - Run unit + integration tests (if toolchain available)"
130+
@echo " clean / distclean- Remove build artifacts"

docs/compiler.md

Lines changed: 0 additions & 14 deletions
This file was deleted.

docs/isa.md

Lines changed: 0 additions & 16 deletions
This file was deleted.

docs/obfuscation.md

Lines changed: 0 additions & 14 deletions
This file was deleted.

docs/vm.md

Lines changed: 0 additions & 65 deletions
This file was deleted.

examples/hello.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#include <stdint.h>
2+
#include "rv32_syscalls.h"
3+
4+
static const char msg[] = "Hello from RV32I VM\n";
5+
6+
int main(void) {
7+
sys_write(1, msg, (uint32_t)(sizeof(msg) - 1));
8+
return 0;
9+
}
10+
11+
extern int main(void);
12+
__attribute__((noreturn)) void _start(void) {
13+
sys_exit(main());
14+
}

0 commit comments

Comments
 (0)