Skip to content

fix(riscv64): boot StarryOS with RustSBI on riscv64 without IllegalInstruction trap#131

Draft
LetsWalkInLine wants to merge 2 commits intoStarry-OS:mainfrom
LetsWalkInLine:fix/rustsbi-boot-failure-130
Draft

fix(riscv64): boot StarryOS with RustSBI on riscv64 without IllegalInstruction trap#131
LetsWalkInLine wants to merge 2 commits intoStarry-OS:mainfrom
LetsWalkInLine:fix/rustsbi-boot-failure-130

Conversation

@LetsWalkInLine
Copy link

Closes #130

Background

When booting StarryOS with RustSBI on riscv64, the kernel could panic with:

  • Unhandled trap Exception(IllegalInstruction)
  • sepc=0xffffffc08037499c
  • stval=0xf2000053
  • stack trace around axtask::run_queue::switch_to

The same image could boot with default BIOS, indicating a firmware-dependent init assumption.

Root Cause

The fp-simd path could execute before FP state was explicitly initialized for this boot path.
With RustSBI, this exposed an initialization gap and resulted in an illegal instruction trap.

Changes

  1. kernel/src/entry.rs

    • Added riscv64-specific early init helper:
      • init_riscv_fp_state()
      • sets riscv::register::sstatus::FS to FS::Dirty
    • Called it at the beginning of entry::init() before user init work.
  2. make/Makefile

    • Added configurable variable:
      • QEMU_BIOS ?= default
    • Documented QEMU_BIOS in QEMU options comment block.
  3. make/qemu.mk

    • Updated riscv64 QEMU args:
      • from -bios default
      • to -bios $(QEMU_BIOS)

This allows direct reproduction and verification with RustSBI via:

make run QEMU_BIOS=../rustsbi-prototyper-dynamic.bin

Validation Performed

  • A-group (before fix): RustSBI boot reproduced IllegalInstruction trap.
  • B diagnostic (temporary): removing fp-simd removed the trap, confirming FP-state relation.
  • A-fixed (with final fix, fp-simd enabled): RustSBI boot reached shell successfully.
  • Default BIOS control: still boots to shell successfully.
  • ci-test: passes (Boot into BusyBox shell).

Impact

Files Included In This PR

  • kernel/src/entry.rs

  • make/Makefile

  • make/qemu.mk

  • I’m still learning kernel development, so feedback is very welcome.

  • If any part of this fix should be done differently, I’m happy to revise.

Booting StarryOS with RustSBI on riscv64 could panic with
IllegalInstruction
(stval=0xf2000053) during task scheduling. Initialize sstatus.FS early
in kernel
entry to make fp-simd execution state explicit and avoid
firmware-dependent boot behavior.

Closes Starry-OS#130
- Introduce a configurable `QEMU_BIOS` make variable to avoid hardcoded
  `-bios default` in QEMU run arguments for `riscv64`.
- Keep the default behavior unchanged by setting `QEMU_BIOS ?= default`,
  so existing `make run` workflows are not affected.
- Wire `qemu_args-riscv64` to use `-bios $(QEMU_BIOS)` and document this
  option in make argument help comments.
- This change is intended to simplify local validation for RustSBI boot
  scenarios (e.g. `rustsbi-prototyper-dynamic.bin`) while keeping
  runtime semantics backward-compatible.

Closes Starry-OS#130
Copilot AI review requested due to automatic review settings March 20, 2026 10:00
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes a riscv64 boot failure under RustSBI by explicitly enabling the kernel’s FP/SIMD execution state early in kernel init, and adds a Make/QEMU knob to swap BIOS images for easier reproduction/validation.

Changes:

  • Add a riscv64-only early init helper to set sstatus.FS, preventing IllegalInstruction traps when FP/SIMD code runs under RustSBI.
  • Add QEMU_BIOS ?= default to Makefile options and route riscv64 QEMU -bios through it.
  • Update build/run docs in the Makefile to mention the new QEMU option.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

File Description
kernel/src/entry.rs Enables RISC-V FP/SIMD state via sstatus.FS before initproc setup.
make/Makefile Adds QEMU_BIOS variable and documents it in the QEMU options list.
make/qemu.mk Uses -bios $(QEMU_BIOS) for riscv64 QEMU runs.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +19 to +30
#[cfg(target_arch = "riscv64")]
#[inline]
fn init_riscv_fp_state() {
use riscv::register::sstatus::{self, FS};
unsafe { sstatus::set_fs(FS::Dirty) };
}

/// Initialize and run initproc.
pub fn init(args: &[String], envs: &[String]) {
#[cfg(target_arch = "riscv64")]
init_riscv_fp_state();

Copy link

Copilot AI Mar 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sstatus.FS is a per-hart CSR on RISC-V. Initializing it only in entry::init() (which appears to run once during initproc setup) may leave secondary harts with FS=Off, so any FP/SIMD instruction executed on those harts could still trap. Consider moving this to an earlier per-CPU/hart init hook (e.g., in the platform/axruntime CPU bring-up path) or otherwise ensuring it runs on every hart before scheduling begins there.

Copilot uses AI. Check for mistakes.
# - `MEM`: Memory size (default is 128M)
# - `DISK_IMG`: Path to the virtual disk image
# - `ACCEL`: Enable hardware acceleration (KVM on linux)
# - `QEMU_BIOS`: QEMU BIOS firmware path (default is `default`)
Copy link

Copilot AI Mar 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The QEMU_BIOS help text says it's a “firmware path”, but the default value is the special QEMU selector default (not a filesystem path). Consider rewording to clarify it can be either default or a BIOS/firmware image path so users don’t assume it must be a path.

Suggested change
# - `QEMU_BIOS`: QEMU BIOS firmware path (default is `default`)
# - `QEMU_BIOS`: QEMU BIOS selector (`default`) or firmware image path (default is `default`)

Copilot uses AI. Check for mistakes.
@AsakuraMizu
Copy link
Contributor

@LetsWalkInLine
Copy link
Author

LetsWalkInLine commented Mar 20, 2026

Contributor

Thanks for the guidance — makes sense.
I agree this should be fixed in axcpu rather than StarryOS.
I’ll move the fix upstream to axcpu as suggested.
Marking this PR as draft for now, and I’ll return with a follow-up once upstream is ready.

@LetsWalkInLine LetsWalkInLine marked this pull request as draft March 20, 2026 10:30
@AsakuraMizu
Copy link
Contributor

Contributor

Thanks for the guidance — makes sense. I agree this should be fixed in axcpu rather than StarryOS. I’ll move the fix upstream to axcpu as suggested. Marking this PR as draft for now, and I’ll return with a follow-up once upstream is ready.

A kindly reminder: you can work upon dev branch of axcpu and submit PRs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[bug] 使用RustSBI启动StarryOS失败

3 participants