Skip to content

Remove the 'required-features' attribute from Cargo.toml to avoid potential issues with 'make vf2'#135

Open
PassingThroughStarDust wants to merge 4 commits intoStarry-OS:mainfrom
PassingThroughStarDust:main
Open

Remove the 'required-features' attribute from Cargo.toml to avoid potential issues with 'make vf2'#135
PassingThroughStarDust wants to merge 4 commits intoStarry-OS:mainfrom
PassingThroughStarDust:main

Conversation

@PassingThroughStarDust
Copy link
Copy Markdown

A slightly small change for Cargo.toml to avoid potential issues

Thanks @Oveln for helping to reproduce the bugs and analyze the root cause, as well as for providing suggestions for patches.

There's a little bug with current Starry's Cargo.toml: if running make build and then run make vf2, we will get a compiled binary but this binary cannot run on VisionFive2 board: board will stuck with no any output.

I was trapped by this bug for a long time. I insisted that it was the problem with my own code. But in the end I discovered that it's a problem with the definition in Cargo.toml of recent commits. The following is my description of the problem:

Phenomenon 1: "make vf2" does not work for new cloned source code

$ make rootfs #(optional, doesn't matter to 'make vf2' but matter to 'make build')
$ make vf2              
make ARCH=riscv64 APP_FEATURES=vf2 MYPLAT=axplat-riscv64-visionfive2 BUS=mmio build
make[1]: Entering directory 'path/to/StarryOS'
make[2]: Entering directory 'path/to/StarryOS/make'
axconfig-gen defconfig.toml path/to/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/axplat-riscv64-visionfive2-0.1.0-pre.2/axconfig.toml  -w arch=riscv64 -w platform=visionfive2 -o "path/to/StarryOS/.axconfig.toml" -w plat.phys-memory-size=1073741824
make[2]: Leaving directory 'path/to/StarryOS/make'
make[2]: Entering directory 'path/to/StarryOS/make'
axconfig-gen defconfig.toml path/to/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/axplat-riscv64-visionfive2-0.1.0-pre.2/axconfig.toml  -w arch=riscv64 -w platform=visionfive2 -o "path/to/StarryOS/.axconfig.toml" -w plat.phys-memory-size=1073741824 -c "path/to/StarryOS/.axconfig.toml"
    Building App: Starry, Arch: riscv64, Platform: visionfive2, App type: rust
cargo -C path/to/StarryOS build -Z unstable-options --target riscv64gc-unknown-none-elf --target-dir path/to/StarryOS/target --release  --features "axfeat/myplat axfeat/bus-mmio axfeat/dwarf vf2"
    Finished `release` profile [optimized] target(s) in 0.06s
cp: cannot stat 'path/to/StarryOS/target/riscv64gc-unknown-none-elf/release/starryos': No such file or directory
make[2]: *** [build.mk:51: _cargo_build] Error 1
make[2]: Leaving directory 'path/to/StarryOS/make'
make[1]: *** [Makefile:45: build] Error 2
make[1]: Leaving directory 'path/to/StarryOS'
make: *** [Makefile:58: vf2] Error 2

According to the output, the make vf2 command failed because, although the Rust build completed successfully, the build system tried to copy an output file named starryos from the directory target/riscv64gc-unknown-none-elf/release/:

# make/build.mk

_cargo_build: oldconfig
     
     ...

     # The operation that tries to copy target/riscv64gc-unknown-none-elf/release/starryos
     @cp $(rust_elf) $(OUT_ELF)

     ...

but that file does not exist:

cp: cannot stat 'path/to/StarryOS/target/riscv64gc-unknown-none-elf/release/starryos': No such file or directory

This caused the make process to stop with an error. The reason is that Rust build did not generate a binary named starryos in the expected location.

phenomenon 2: "make vf2" runs successfully if running "make build" beforehand but the generated binaries cannot run on VisionFive2

# Run `make build` first, cargo started to build StarryOS for `riscv64-qemu-virt`
$ make build
make[1]: Entering directory 'path/to/StarryOS/make'
axconfig-gen defconfig.toml path/to/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/axplat-riscv64-qemu-virt-0.3.1-pre.6/axconfig.toml  -w arch=riscv64 -w platform=riscv64-qemu-virt -o "path/to/StarryOS/.axconfig.toml" -w plat.phys-memory-size=1073741824
make[1]: Leaving directory 'path/to/StarryOS/make'
make[1]: Entering directory 'path/to/StarryOS/make'
axconfig-gen defconfig.toml path/to/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/axplat-riscv64-qemu-virt-0.3.1-pre.6/axconfig.toml  -w arch=riscv64 -w platform=riscv64-qemu-virt -o "path/to/StarryOS/.axconfig.toml" -w plat.phys-memory-size=1073741824 -c "path/to/StarryOS/.axconfig.toml"
    Building App: Starry, Arch: riscv64, Platform: riscv64-qemu-virt, App type: rust
cargo -C path/to/StarryOS build -Z unstable-options --target riscv64gc-unknown-none-elf --target-dir path/to/StarryOS/target --release  --features "axfeat/defplat axfeat/dwarf qemu"
   
    ...

   Compiling starry-kernel v0.2.0-preview.2 (path/to/StarryOS/kernel)

    ...

   Compiling starryos v0.2.0-preview.2 (path/to/StarryOS)
    Finished `release` profile [optimized] target(s) in 15.63s
./dwarf.sh path/to/StarryOS/StarryOS_riscv64-qemu-virt.elf rust-objcopy --binary-architecture=riscv64
rust-objcopy --binary-architecture=riscv64 path/to/StarryOS/StarryOS_riscv64-qemu-virt.elf --strip-all -O binary path/to/StarryOS/StarryOS_riscv64-qemu-virt.bin
make[1]: Leaving directory 'path/to/StarryOS/make'

# Run 'make vf2' then, this time Cargo built successful
$ make vf2  
make ARCH=riscv64 APP_FEATURES=vf2 MYPLAT=axplat-riscv64-visionfive2 BUS=mmio build
make[1]: Entering directory 'path/to/StarryOS'
make[2]: Entering directory 'path/to/StarryOS/make'
axconfig-gen defconfig.toml path/to/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/axplat-riscv64-visionfive2-0.1.0-pre.2/axconfig.toml  -w arch=riscv64 -w platform=visionfive2 -o "path/to/StarryOS/.axconfig.toml" -w plat.phys-memory-size=1073741824
make[2]: Leaving directory 'path/to/StarryOS/make'
make[2]: Entering directory 'path/to/StarryOS/make'
axconfig-gen defconfig.toml path/to/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/axplat-riscv64-visionfive2-0.1.0-pre.2/axconfig.toml  -w arch=riscv64 -w platform=visionfive2 -o "path/to/StarryOS/.axconfig.toml" -w plat.phys-memory-size=1073741824 -c "path/to/StarryOS/.axconfig.toml"
    Building App: Starry, Arch: riscv64, Platform: visionfive2, App type: rust
cargo -C path/to/StarryOS build -Z unstable-options --target riscv64gc-unknown-none-elf --target-dir path/to/StarryOS/target --release  --features "axfeat/myplat axfeat/bus-mmio axfeat/dwarf vf2"
    Finished `release` profile [optimized] target(s) in 0.06s
./dwarf.sh path/to/StarryOS/StarryOS_visionfive2.elf rust-objcopy --binary-architecture=riscv64
rust-objcopy --binary-architecture=riscv64 path/to/StarryOS/StarryOS_visionfive2.elf --strip-all -O binary path/to/StarryOS/StarryOS_visionfive2.bin
make[2]: Leaving directory 'path/to/StarryOS/make'
make[1]: Leaving directory 'path/to/StarryOS'

Although make vf2 executes successfully after make build, analyzing the headers of StarryOS_visionfive2.elf reveals that it shares identical address metadata with StarryOS_riscv64-qemu-virt.elf.

$ readelf --headers StarryOS_visionfive2.elf
ELF Header:
  Magic:   7f 45 4c 46 02 01 01 03 00 00 00 00 00 00 00 00 
  Class:                             ELF64
  Data:                              2's complement, little endian
  Version:                           1 (current)
  OS/ABI:                            UNIX - GNU
  ABI Version:                       0
  Type:                              EXEC (Executable file)
  Machine:                           RISC-V
  Version:                           0x1
  Entry point address:               0xffffffc080200000
  Start of program headers:          64 (bytes into file)
  Start of section headers:          45276264 (bytes into file)
  Flags:                             0x5, RVC, double-float ABI
  Size of this header:               64 (bytes)
  Size of program headers:           56 (bytes)
  Number of program headers:         12
  Size of section headers:           64 (bytes)
  Number of section headers:         28
  Section header string table index: 26

Section Headers:
  [Nr] Name              Type             Address           Offset
       Size              EntSize          Flags  Link  Info  Align
  [ 0]                   NULL             0000000000000000  00000000
       0000000000000000  0000000000000000           0     0     0
  [ 1] .text             PROGBITS         ffffffc080200000  00001000
       00000000001e2000  0000000000000000  AX       0     0     4096
  [ 2] .rodata           PROGBITS         ffffffc0803e2000  001e3000
       0000000000042808  0000000000000000 AMS       0     0     4096
  [ 3] .init_array       INIT_ARRAY       ffffffc080424810  00225810
       0000000000000000  0000000000000000  AR       0     0     16
  [ 4] .debug_abbrev     PROGBITS         ffffffc080424810  00225810
       00000000000513ac  0000000000000000   A       0     0     1
  [ 5] .debug_addr       PROGBITS         ffffffc080475bbc  00276bbc
       0000000000000000  0000000000000000   A       0     0     1
  [ 6] .debug_aranges    PROGBITS         ffffffc080475bbc  00276bbc
       0000000000026360  0000000000000000   A       0     0     1
  [ 7] .debug_info       PROGBITS         ffffffc08049bf1c  0029cf1c
       000000000108202d  0000000000000000   A       0     0     1
  [ 8] .debug_line       PROGBITS         ffffffc08151df49  0131ef49
       000000000033354a  0000000000000000   A       0     0     1
  [ 9] .debug_line_str   PROGBITS         ffffffc081851493  01652493
       0000000000000dd6  0000000000000000   A       0     0     1
  [10] .debug_ranges     PROGBITS         ffffffc081852269  01653269
       000000000034e8e0  0000000000000000   A       0     0     1
  [11] .debug_rnglists   PROGBITS         ffffffc081ba0b49  019a1b49
       000000000000b6c1  0000000000000000   A       0     0     1
  [12] .debug_str        PROGBITS         ffffffc081bac20a  019ad20a
       0000000000b29521  0000000000000000   A       0     0     1
  [13] .debug_str_o[...] PROGBITS         ffffffc0826d572b  024dc074
       0000000000000000  0000000000000000   A       0     0     1
  [14] .data             PROGBITS         ffffffc0826d6000  024d7000
       00000000000031a0  0000000000000000  WA       0     0     4096
  [15] .tdata            PROGBITS         ffffffc0826d91a0  024da1a0
       0000000000000000  0000000000000000  WA       0     0     16
  [16] .tbss             PROGBITS         ffffffc0826d91a0  024da1a0
       0000000000000000  0000000000000000  WA       0     0     16
  [17] linkme_IRQ        PROGBITS         ffffffc0826d91a0  024da1a0
       0000000000000008  0000000000000000 WAR       0     0     8
  [18] linkm2_IRQ        PROGBITS         ffffffc0826d91a8  024da1a8
       0000000000000008  0000000000000000  AR       0     0     8
  [19] linkme_PAGE_FAULT PROGBITS         ffffffc0826d91b0  024da1b0
       0000000000000008  0000000000000000 WAR       0     0     8
  [20] linkm2_PAGE_FAULT PROGBITS         ffffffc0826d91b8  024da1b8
       0000000000000008  0000000000000000  AR       0     0     8
  [21] scope_local       PROGBITS         ffffffc0826d91c0  024da1c0
       0000000000000040  0000000000000000   A       0     0     8
  [22] .percpu           PROGBITS         0000000000000000  024db000
       00000000000000c0  0000000000000000  WA       0     0     8
  [23] .bss              NOBITS           ffffffc0826db000  024dc000
       0000000000066000  0000000000000000  WA       0     0     4096
  [24] .riscv.attributes RISCV_ATTRIBUTE  0000000000000000  024dc000
       0000000000000074  0000000000000000           0     0     1
  [25] .symtab           SYMTAB           0000000000000000  024dc078
       0000000000573708  0000000000000018          27   236797     8
  [26] .shstrtab         STRTAB           0000000000000000  02a4f780
       000000000000013a  0000000000000000           0     0     1
  [27] .strtab           STRTAB           0000000000000000  02a4f8ba
       00000000000de3ab  0000000000000000           0     0     1
Key to Flags:
  W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
  L (link order), O (extra OS processing required), G (group), T (TLS),
  C (compressed), x (unknown), o (OS specific), E (exclude),
  R (retain), D (mbind), p (processor specific)

Program Headers:
  Type           Offset             VirtAddr           PhysAddr
                 FileSiz            MemSiz              Flags  Align
  LOAD           0x0000000000001000 0xffffffc080200000 0xffffffc080200000
                 0x00000000001e2000 0x00000000001e2000  R E    0x1000
  LOAD           0x00000000001e3000 0xffffffc0803e2000 0xffffffc0803e2000
                 0x00000000022f372b 0x00000000022f372b  R      0x1000
  LOAD           0x00000000024d7000 0xffffffc0826d6000 0xffffffc0826d6000
                 0x00000000000031a0 0x00000000000031a0  RW     0x1000
  LOAD           0x00000000024da1a0 0xffffffc0826d91a0 0xffffffc0826d91a0
                 0x0000000000000008 0x0000000000000008  RW     0x1000
  LOAD           0x00000000024da1a8 0xffffffc0826d91a8 0xffffffc0826d91a8
                 0x0000000000000008 0x0000000000000008  R      0x1000
  LOAD           0x00000000024da1b0 0xffffffc0826d91b0 0xffffffc0826d91b0
                 0x0000000000000008 0x0000000000000008  RW     0x1000
  LOAD           0x00000000024da1b8 0xffffffc0826d91b8 0xffffffc0826d91b8
                 0x0000000000000048 0x0000000000000048  R      0x1000
  LOAD           0x00000000024db000 0x0000000000000000 0xffffffc0826da000
                 0x00000000000000c0 0x00000000000000c0  RW     0x1000
  LOAD           0x00000000024dc000 0xffffffc0826db000 0xffffffc0826db000
                 0x0000000000000000 0x0000000000066000  RW     0x1000
  GNU_RELRO      0x00000000024d7000 0xffffffc0826d6000 0xffffffc0826d6000
                 0x00000000000031a0 0x00000000000031a0  R      0x1
  GNU_STACK      0x0000000000000000 0x0000000000000000 0x0000000000000000
                 0x0000000000000000 0x0000000000000000  RW     0x0
  RISCV_ATTRIBUT 0x00000000024dc000 0x0000000000000000 0x0000000000000000
                 0x0000000000000074 0x0000000000000074  R      0x1

 Section to Segment mapping:
  Segment Sections...
   00     .text 
   01     .rodata .init_array .debug_abbrev .debug_addr .debug_aranges .debug_info .debug_line .debug_line_str .debug_ranges .debug_rnglists .debug_str 
   02     .data 
   03     .tdata .tbss linkme_IRQ 
   04     linkm2_IRQ 
   05     linkme_PAGE_FAULT 
   06     linkm2_PAGE_FAULT scope_local 
   07     .percpu 
   08     .bss 
   09     .data 
   10     
   11     .riscv.attributes

In fact, StarryOS_riscv64-qemu-virt.elf is the same as StarryOS_visionfive2.elf. This indicating a bug: when running make vf2, Cargo used the starryos previously built to generate StarryOS_riscv64-qemu-virt.elf and StarryOS_riscv64-qemu-virt.bin. That's why StarryOS_riscv64-qemu-virt.bin on VisionFive2.

# 'cmp' Check
$ cmp StarryOS_riscv64-qemu-virt.elf StarryOS_visionfive2.elf
(no output, meaning that the two binaries are same)
$ cmp StarryOS_riscv64-qemu-virt.bin StarryOS_visionfive2.bin
(no output, meaning that the two binaries are same)

# Hash Code Check
$ if [[ $(sha256sum StarryOS_riscv64-qemu-virt.bin | awk '{print $1}') == $(sha256sum StarryOS_visionfive2.bin | awk '{print $1}') ]]; then echo "Same"; else echo "Different"; fi
Same

Explanation to the above phenomenons

The issues mentioned above stem from this specific section of the Workspace's Cargo.toml file:

# Cargo.toml

[[bin]]
name = "starryos"
path = "src/main.rs"
required-features = ["qemu"]

Line required-features = ["qemu"] defines a restriction that binary starryos will only be generated when feature qemu is enabled. Therefore, when run make vf2, althrough the compilation is successful, starryos will not be generated, causing the operation to copy starry to StarryOS_visionfive2.elf failed.

However, if we run make build, there'll be a starryos. If we then run make vf2 without cleaning the previous products, the copy operation will reuse this starryos to create StarryOS_visionfive2.elf. But this StarryOS_visionfive2 is essentially for riscv64-qemu-virt rather than for VisionFive2.

Patch Advices

For current enviroment, using required-features to restrict generation of starryos is unnecessary and may cause unexpected issues. It's better to delete required-features = ["qemu"] in Cargo.toml so both make build and make vf2 can generate new starryos. Patch is as follows:

diff --git a/Cargo.toml b/Cargo.toml
index cfcf9a3..1719ab3 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -70,7 +70,6 @@ vf2 = ["dep:axplat-riscv64-visionfive2", "axfeat/driver-sdmmc"]
 [[bin]]
 name = "starryos"
 path = "src/main.rs"
-required-features = ["qemu"]
 
 [dependencies]
 axfeat.workspace = true

Copilot AI review requested due to automatic review settings April 13, 2026 19:30
Copy link
Copy Markdown
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

Removes the required-features gate from the starryos binary target so make vf2 (and other non-qemu builds) reliably produces a fresh starryos executable instead of failing to copy it or reusing a previously built artifact.

Changes:

  • Remove required-features = ["qemu"] from the [[bin]] target in Cargo.toml.

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

@AsakuraMizu
Copy link
Copy Markdown
Contributor

Hi, we're moving our workflow to https://github.com/rcore-os/tgoskits.

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.

3 participants