Skip to content

Commit 259670a

Browse files
committed
Add ecall-based syscall entry point
Architecture-specific implementations require direct linkage to override weak symbols. Archives extract objects only when symbols are unresolved, skipping strong overrides when weak symbols satisfy references. Introduce trap-based syscall entry using ecall instruction and modify build system to link entry point before archive, ensuring architecture override takes precedence at link time.
1 parent 5be6893 commit 259670a

File tree

3 files changed

+53
-3
lines changed

3 files changed

+53
-3
lines changed

Makefile

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ deps += $(LIB_OBJS:%.o=%.o.d)
2929
APPS := coop echo hello mqueues semaphore mutex cond \
3030
pipes pipes_small pipes_struct prodcons progress \
3131
rtsched suspend test64 timer timer_kill \
32-
cpubench test_libc
32+
cpubench test_libc umode
3333

3434
# Output files for __link target
3535
IMAGE_BASE := $(BUILD_DIR)/image
@@ -66,9 +66,9 @@ $(APPS): %: rebuild $(BUILD_APP_DIR)/%.o linmo
6666
# Link target - creates all output files
6767
__link: $(IMAGE_FILES)
6868

69-
$(IMAGE_BASE).elf: $(BUILD_APP_DIR)/*.o $(BUILD_DIR)/liblinmo.a
69+
$(IMAGE_BASE).elf: $(BUILD_APP_DIR)/*.o $(BUILD_DIR)/liblinmo.a $(ENTRY_OBJ)
7070
$(VECHO) " LD\t$@\n"
71-
$(Q)$(LD) $(LDFLAGS) -T$(LDSCRIPT) -Map $(IMAGE_BASE).map -o $@ $(BUILD_APP_DIR)/*.o -L$(BUILD_DIR) -llinmo
71+
$(Q)$(LD) $(LDFLAGS) -T$(LDSCRIPT) -Map $(IMAGE_BASE).map -o $@ $(BUILD_APP_DIR)/*.o $(ENTRY_OBJ) -L$(BUILD_DIR) -llinmo
7272

7373
$(IMAGE_BASE).lst: $(IMAGE_BASE).elf
7474
$(VECHO) " DUMP\t$@\n"

arch/riscv/build.mk

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,14 @@ HAL_OBJS := boot.o hal.o muldiv.o
7474
HAL_OBJS := $(addprefix $(BUILD_KERNEL_DIR)/,$(HAL_OBJS))
7575
deps += $(HAL_OBJS:%.o=%.o.d)
7676

77+
# Architecture-specific syscall entry point requiring direct linkage.
78+
# Archives only extract objects when symbols are unresolved. Since the generic
79+
# syscall dispatcher provides a weak symbol, the archive mechanism would skip
80+
# the strong override. Direct linking ensures the architecture-specific
81+
# implementation takes precedence at link time.
82+
ENTRY_OBJ := $(BUILD_KERNEL_DIR)/entry.o
83+
deps += $(ENTRY_OBJ).d
84+
7785
$(BUILD_KERNEL_DIR)/%.o: $(ARCH_DIR)/%.c | $(BUILD_DIR)
7886
$(VECHO) " CC\t$@\n"
7987
$(Q)$(CC) $(CFLAGS) -o $@ -c -MMD -MF $@.d $<

arch/riscv/entry.c

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/* RISC-V Kernel Entry Points
2+
*
3+
* This file implements architecture-specific entry mechanisms into the kernel,
4+
* primarily the system call trap interface using the RISC-V ecall instruction.
5+
*
6+
* System Call Calling Convention (RISC-V ABI):
7+
* - a7 (x17): System call number
8+
* - a0 (x10): Argument 1 / Return value
9+
* - a1 (x11): Argument 2
10+
* - a2 (x12): Argument 3
11+
*
12+
* The ecall instruction triggers an environment call exception that transfers
13+
* control to the M-mode exception handler (hal.c), which then dispatches to
14+
* the appropriate system call implementation via the syscall table.
15+
*/
16+
17+
#include <sys/syscall.h>
18+
19+
/* Architecture-specific syscall implementation using ecall trap.
20+
* This overrides the weak symbol defined in kernel/syscall.c.
21+
*/
22+
int syscall(int num, void *arg1, void *arg2, void *arg3)
23+
{
24+
register int a0 asm("a0") = (int) arg1;
25+
register int a1 asm("a1") = (int) arg2;
26+
register int a2 asm("a2") = (int) arg3;
27+
register int a7 asm("a7") = num;
28+
29+
/* Execute ecall instruction to trap into M-mode.
30+
* The M-mode exception handler will:
31+
* 1. Save the current task context
32+
* 2. Dispatch to the syscall handler based on a7
33+
* 3. Place the return value in a0
34+
* 4. Restore context and return to user mode via mret
35+
*/
36+
asm volatile("ecall"
37+
: "+r"(a0) /* a0 is both input (arg1) and output (retval) */
38+
: "r"(a1), "r"(a2), "r"(a7)
39+
: "memory", "cc");
40+
41+
return a0;
42+
}

0 commit comments

Comments
 (0)