Giter Club home page Giter Club logo

riscv-rt's Introduction

crates.io crates.io Build Status

riscv-rt

Minimal runtime / startup for RISC-V CPU's.

This crate has moved to the riscv repository, and this repository is archived. Please direct issues and pull requests to the new repository.

This project is developed and maintained by the RISC-V team.

Documentation

Minimum Supported Rust Version (MSRV)

This crate is guaranteed to compile on stable Rust 1.59 and up. It might compile with older versions but that may change in any new patch release.

License

Copyright 2018-2022 RISC-V team

Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies.

THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

Code of Conduct

Contribution to this crate is organized under the terms of the Rust Code of Conduct, the maintainer of this crate, the RISC-V team, promises to intervene to uphold that code of conduct.

riscv-rt's People

Contributors

almindor avatar bors[bot] avatar coastalwhite avatar danc86 avatar disasm avatar dvc94ch avatar fintelia avatar hasheddan avatar iankronquist avatar ilya-epifanov avatar istankovic avatar ivq avatar jannic avatar jmerdich avatar kevin-vigor avatar khrs avatar laanwj avatar luojia65 avatar mabezdev avatar onsdagens avatar parkero avatar pftbest avatar pgraubner avatar richardeoin avatar romancardenas avatar sethp avatar simonsapin avatar smsxgli avatar taiki-e avatar tfx2001 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

riscv-rt's Issues

Update r0 to 1.0

We have now released r0 v1.0. Please do update to this stable version.

LiteX/VexRiscv support

Will this work on VexRiscv?
If not, what changes may be needed to enable support for this? Thanks!

Lots of rust-lld errors

I started writing a Rust application that looked pretty much exactly the same as the "empty" example, but when I compile it lots of rust-lld errors show up. I'm compiling with riscv32imac-unknown-none-elf, my rustc version is 1.56.

Here are the first 5:

          rust-lld: error: undefined symbol: UserTimer
          >>> referenced by riscv_rt.e45bfb96-cgu.4
          >>>               riscv_rt-5f3b7c942d92931d.riscv_rt.e45bfb96-cgu.4.rcgu.o:(__INTERRUPTS) in archive /home/nathan/Desktop/githubProjects/novusk/target/riscv32i-unknown-none-elf/debug/deps/libriscv_rt-5f3b7c942d92931d.rlib
          
          rust-lld: error: undefined symbol: SupervisorTimer
          >>> referenced by riscv_rt.e45bfb96-cgu.4
          >>>               riscv_rt-5f3b7c942d92931d.riscv_rt.e45bfb96-cgu.4.rcgu.o:(__INTERRUPTS) in archive /home/nathan/Desktop/githubProjects/novusk/target/riscv32i-unknown-none-elf/debug/deps/libriscv_rt-5f3b7c942d92931d.rlib
          
          rust-lld: error: undefined symbol: MachineTimer
          >>> referenced by riscv_rt.e45bfb96-cgu.4
          >>>               riscv_rt-5f3b7c942d92931d.riscv_rt.e45bfb96-cgu.4.rcgu.o:(__INTERRUPTS) in archive /home/nathan/Desktop/githubProjects/novusk/target/riscv32i-unknown-none-elf/debug/deps/libriscv_rt-5f3b7c942d92931d.rlib
          
          rust-lld: error: undefined symbol: UserExternal
          >>> referenced by riscv_rt.e45bfb96-cgu.4
          >>>               riscv_rt-5f3b7c942d92931d.riscv_rt.e45bfb96-cgu.4.rcgu.o:(__INTERRUPTS) in archive /home/nathan/Desktop/githubProjects/novusk/target/riscv32i-unknown-none-elf/debug/deps/libriscv_rt-5f3b7c942d92931d.rlib
          
          rust-lld: error: undefined symbol: SupervisorExternal
          >>> referenced by riscv_rt.e45bfb96-cgu.4
          >>>               riscv_rt-5f3b7c942d92931d.riscv_rt.e45bfb96-cgu.4.rcgu.o:(__INTERRUPTS) in archive /home/nathan/Desktop/githubProjects/novusk/target/riscv32i-unknown-none-elf/debug/deps/libriscv_rt-5f3b7c942d92931d.rlib
          
          rust-lld: error: too many errors emitted, stopping now (use -error-limit=0 to see all errors)

Is there a linker script that I need? What's causing this?

Bizarre warning behavior around #[entry] macro and `&mut FnMut`

I'm running into a truly bizarre set of circumstances where the #[entry] macro seems to 'take credit for' warnings and errors inside the main function in a very specific case. I do not know if this is a rust bug, or a bug in the macro, or anything else, but:

#![no_std]
#![no_main]

use riscv_rt::entry;
use core::panic::PanicInfo;

#[panic_handler]
fn panic(_info: &PanicInfo) -> ! {
    loop {
    }
}

pub fn message<F>(
    on_event: &mut F,
) -> Result<(), ()>
where
    F: FnMut(),
{
    Ok(())
}

#[entry]
fn main() -> ! {
    loop {
        let mut unused = 0;
        message(&mut || { }).unwrap();
    }
}

When I build this, I get:

warning: unused variable: `on_event`
  --> src/main.rs:14:5
   |
14 |     on_event: &mut F,
   |     ^^^^^^^^ help: consider prefixing with an underscore: `_on_event`
   |
   = note: #[warn(unused_variables)] on by default

warning: unused variable: `unused`
  --> src/main.rs:22:1
   |
22 | #[entry]
   | ^ help: consider prefixing with an underscore: `_unused`

warning: variable does not need to be mutable
  --> src/main.rs:22:1
   |
22 | #[entry]
   | ^ help: remove this `mut`
   |
   = note: #[warn(unused_mut)] on by default

Note that all the warnings in main, are reported on the line of the macro.

  • Commenting out the message(...) line removes this behavior
  • Changing &mut F to instead consume the function F removes this behavior (so maybe it has to do with taking a reference to a temporary?)
  • Removing the line #[entry] removes this behavior

I tested with both nightly and stable, same result.

It isn't a very serious issue, I think it only affects reporting—though it's hard to fix warnings when they're all reported on the same line.

Here's the testcase as a crate: warntest.tar.gz

asm: Startup code traps into an illegal instruction

Working on a HAL that relies on riscv-rt for a rudimentary debugging binary, and the binary gets trapped into an illegal instruction.

The startup asm code appears to be what is trapping into the illegal instruction.

Here is the assembly:

0x00000000      97000000       auipc ra, 0x0
0x00000004      83b00001       ld ra, 16(ra)
0x00000008      8280           ret
0x0000000a      0100           nop
0x0000000c      13000000       nop
0x00000010      1800           addi a4, sp, 0
0x00000012      0021           fld fs0, 0(a0)
0x00000014      00000000       illegal
;-- _abs_start:
0x00000018      73504030       csrwi mie, 0

The first line loads pc + 0x0 into the return address, and the second loads the sixteenth offset from the return address into the return address. Then the pc jumps to ra with the ret instruction.

Please correct me if I'm wrong, but this is intended to jump to the _abs_start label, but is off by one instruction (0x14 is 20 = 16 + 0x4).

The above originates from the Rust asm in asm.rs:

    auipc ra, %pcrel_hi(1f)
    ld ra, %pcrel_lo(1b)(ra)
    jr ra
    .align  3
1:
    .dword _abs_start
    .option pop",
    "
_abs_start:
    .option norelax

This is for a riscv64gc-unknown-none-elf target.

Am I incorrect about the above situation, and doing something wrong in the HAL crate? Is there something in the memory.x script that could cause the Illegal Instruction fault?

New crates.io release

Would there be there any downsides to a new crates.io release with the latest changes on master?

Execution start address varies.

In some implementations, execution starting address may vary from what specified in the linker script, depending on conditions.

With GD32VF103, if an application is booted by DFU bootloader, PC is set to 0x0800_0000.
But when an application is booted directly, default value of PC after reset is 0x0000_0000.

  • note: DFU bootloader is hard-coded in ROM and it can't be modified.

I suppose care should be taken at the beginning of start-up code. Otherwise the application will not boot properly after reset. Mainly because SP will get initialized with wrong value.

It would be something like this.

_start:
/* Some implementations may start execution at address 0 . */
.if __riscv_xlen == 32
    lui ra, %hi(_abs_start)
    jr %lo(_abs_start)(ra)
.endif

.if __riscv_xlen == 64
    auipc ra, %pcrel_hi(.L0)
    ld ra, %lo(.L0)(ra)
    jr ra
    .align 3, 0
.L0:
    .dword _abs_start
.endif

_abs_start:

I'm not sure whether this is appropriate for riscv64 platforms.

build using -mcmodel = medany

I'm trying to port this crate to a new board targeting riscv64gc.

The original link script is https://github.com/kendryte/kendryte-standalone-sdk/blob/master/lds/kendryte.ld

My memory.x:

MEMORY
{
  RAM : ORIGIN = 0x80000000, LENGTH = (6 * 1024 * 1024)
}

This device don't have flash in its cpu address space. So I replace FLASH in link.x to RAM

I try to rebuild asm.S in riscv-rt and riscv

riscv64-unknown-elf-gcc -mabi=lp64 -march=rv64gc  -mcmodel=medany -c asm.S -o bin/riscv-rt.o
riscv64-unknown-elf-ar crs bin/riscv64gc-unknown-none-elf.a bin/riscv-rt.o

Build and output is

note: rust-lld: error: H:\board\K210\rust-test\target\riscv64gc-unknown-none-elf\debug\deps\libriscv_rt-5900706913d05900.rlib(riscv-rt.o):(.init+0x0): relocation R_RISCV_HI20 out of range: 2147487184 is not in [-2147483648, 2147483647]
          rust-lld: error: H:\board\K210\rust-test\target\riscv64gc-unknown-none-elf\debug\deps\libriscv_rt-5900706913d05900.rlib(riscv-rt.o):(.init+0x4): relocation R_RISCV_LO12_I out of range: 2147487184 is not in [-2147483648, 2147483647]
          rust-lld: error: H:\board\K210\rust-test\target\riscv64gc-unknown-none-elf\debug\deps\libriscv_rt-5900706913d05900.rlib(riscv-rt.o):(.init+0x8): relocation R_RISCV_HI20 out of range: 2153775104 is not in [-2147483648, 2147483647]
          rust-lld: error: H:\board\K210\rust-test\target\riscv64gc-unknown-none-elf\debug\deps\libriscv_rt-5900706913d05900.rlib(riscv-rt.o):(.init+0xC): relocation R_RISCV_LO12_I out of range: 2153775104 is not in [-2147483648, 2147483647]
          rust-lld: error: src\main.rs:5:(.text.main+0x4): relocation R_RISCV_HI20 out of range: 2147483900 is not in [-2147483648, 2147483647]
          rust-lld: error: src\main.rs:5:(.text.main+0x8): relocation R_RISCV_LO12_I out of range: 2147483900 is not in [-2147483648, 2147483647]
          rust-lld: error: H:\board\K210\riscv\src\register\mtvec.rs:44:(.text._ZN5riscv8register5mtvec5write17hf4b8713aebc80d04E+0x30): relocation R_RISCV_HI20 out of range: 2147484944 is not in [-2147483648, 2147483647]
          rust-lld: error: H:\board\K210\riscv\src\register\mtvec.rs:44:(.text._ZN5riscv8register5mtvec5write17hf4b8713aebc80d04E+0x34): relocation R_RISCV_LO12_I out of range: 2147484944 is not in [-2147483648, 2147483647]
          rust-lld: error: H:\board\K210\riscv-rt\src\lib.rs:224:(.init.rust+0x4): relocation R_RISCV_HI20 out of range: 2147485136 is not in [-2147483648, 2147483647]
          rust-lld: error: H:\board\K210\riscv-rt\src\lib.rs:224:(.init.rust+0x8): relocation R_RISCV_LO12_I out of range: 2147485136 is not in [-2147483648, 2147483647]
          rust-lld: error: H:\board\K210\riscv-rt\src\lib.rs:224:(.init.rust+0xC): relocation R_RISCV_HI20 out of range: 2147485136 is not in [-2147483648, 2147483647]
          rust-lld: error: H:\board\K210\riscv-rt\src\lib.rs:224:(.init.rust+0x10): relocation R_RISCV_LO12_I out of range: 2147485136 is not in [-2147483648, 2147483647]
          rust-lld: error: H:\board\K210\riscv-rt\src\lib.rs:225:(.init.rust+0x1E): relocation R_RISCV_HI20 out of range: 2147485136 is not in [-2147483648, 2147483647]
          rust-lld: error: H:\board\K210\riscv-rt\src\lib.rs:225:(.init.rust+0x22): relocation R_RISCV_LO12_I out of range: 2147485136 is not in [-2147483648, 2147483647]
          rust-lld: error: H:\board\K210\riscv-rt\src\lib.rs:225:(.init.rust+0x26): relocation R_RISCV_HI20 out of range: 2147485136 is not in [-2147483648, 2147483647]
          rust-lld: error: H:\board\K210\riscv-rt\src\lib.rs:225:(.init.rust+0x2A): relocation R_RISCV_LO12_I out of range: 2147485136 is not in [-2147483648, 2147483647]
          rust-lld: error: H:\board\K210\riscv-rt\src\lib.rs:225:(.init.rust+0x2E): relocation R_RISCV_HI20 out of range: 2147485136 is not in [-2147483648, 2147483647]
          rust-lld: error: H:\board\K210\riscv-rt\src\lib.rs:225:(.init.rust+0x32): relocation R_RISCV_LO12_I out of range: 2147485136 is not in [-2147483648, 2147483647]
          rust-lld: error: H:\board\K210\riscv-rt\src\lib.rs:232:(.init.rust+0x46): relocation R_RISCV_HI20 out of range: 2147483788 is not in [-2147483648, 2147483647]
          rust-lld: error: H:\board\K210\riscv-rt\src\lib.rs:232:(.init.rust+0x4A): relocation R_RISCV_LO12_I out of range: 2147483788 is not in [-2147483648, 2147483647]
          rust-lld: error: too many errors emitted, stopping now (use -error-limit=0 to see all errors)

It seems rustc don't have a option to build using -mcmodel=medany and default to -mcmodel = medlow

In sifive's blog,-mcmodel=medlow generate R_RISCV_HI20/R_RISCV_LO12_I and -mcmodel=medany generate R_RISCV_PCREL_HI20/R_RISCV_PCREL_LO12_I

Doesn't compile with the latest nightly toolchain.

The project works fine before I update the toolchain today. And then it seems to be faild to linking now:
And I update the riscv-rt = "0.8.0" to the latest riscv-rt = "0.9", which still doesn't work.

error: linking with `rust-lld` failed: exit code: 1
  |
  = note: "rust-lld" "-flavor" "gnu" "C:\\Users\\Tnze\\AppData\\Local\\Temp\\rustcFQvI1O\\symbols.o" "C:\\Users\\Tnze\\Documents\\Projects\\Embedded\\the-gift\\target\\riscv32imac-unknown-none-elf\\release\\deps\\the_gift-25721c29c540d9b1.the_gift.acb574d6-cgu.0.rcgu.o" "C:\\Users\\Tnze\\Documents\\Projects\\Embedded\\the-gift\\target\\riscv32imac-unknown-none-elf\\release\\deps\\the_gift-25721c29c540d9b1.the_gift.acb574d6-cgu.1.rcgu.o" "C:\\Users\\Tnze\\Documents\\Projects\\Embedded\\the-gift\\target\\riscv32imac-unknown-none-elf\\release\\deps\\the_gift-25721c29c540d9b1.the_gift.acb574d6-cgu.10.rcgu.o" "C:\\Users\\Tnze\\Documents\\Projects\\Embedded\\the-gift\\target\\riscv32imac-unknown-none-elf\\release\\deps\\the_gift-25721c29c540d9b1.the_gift.acb574d6-cgu.11.rcgu.o" "C:\\Users\\Tnze\\Documents\\Projects\\Embedded\\the-gift\\target\\riscv32imac-unknown-none-elf\\release\\deps\\the_gift-25721c29c540d9b1.the_gift.acb574d6-cgu.12.rcgu.o" "C:\\Users\\Tnze\\Documents\\Projects\\Embedded\\the-gift\\target\\riscv32imac-unknown-none-elf\\release\\deps\\the_gift-25721c29c540d9b1.the_gift.acb574d6-cgu.13.rcgu.o" "C:\\Users\\Tnze\\Documents\\Projects\\Embedded\\the-gift\\target\\riscv32imac-unknown-none-elf\\release\\deps\\the_gift-25721c29c540d9b1.the_gift.acb574d6-cgu.14.rcgu.o" "C:\\Users\\Tnze\\Documents\\Projects\\Embedded\\the-gift\\target\\riscv32imac-unknown-none-elf\\release\\deps\\the_gift-25721c29c540d9b1.the_gift.acb574d6-cgu.15.rcgu.o" "C:\\Users\\Tnze\\Documents\\Projects\\Embedded\\the-gift\\target\\riscv32imac-unknown-none-elf\\release\\deps\\the_gift-25721c29c540d9b1.the_gift.acb574d6-cgu.2.rcgu.o" "C:\\Users\\Tnze\\Documents\\Projects\\Embedded\\the-gift\\target\\riscv32imac-unknown-none-elf\\release\\deps\\the_gift-25721c29c540d9b1.the_gift.acb574d6-cgu.3.rcgu.o" "C:\\Users\\Tnze\\Documents\\Projects\\Embedded\\the-gift\\target\\riscv32imac-unknown-none-elf\\release\\deps\\the_gift-25721c29c540d9b1.the_gift.acb574d6-cgu.4.rcgu.o" "C:\\Users\\Tnze\\Documents\\Projects\\Embedded\\the-gift\\target\\riscv32imac-unknown-none-elf\\release\\deps\\the_gift-25721c29c540d9b1.the_gift.acb574d6-cgu.5.rcgu.o" "C:\\Users\\Tnze\\Documents\\Projects\\Embedded\\the-gift\\target\\riscv32imac-unknown-none-elf\\release\\deps\\the_gift-25721c29c540d9b1.the_gift.acb574d6-cgu.6.rcgu.o" "C:\\Users\\Tnze\\Documents\\Projects\\Embedded\\the-gift\\target\\riscv32imac-unknown-none-elf\\release\\deps\\the_gift-25721c29c540d9b1.the_gift.acb574d6-cgu.7.rcgu.o" "C:\\Users\\Tnze\\Documents\\Projects\\Embedded\\the-gift\\target\\riscv32imac-unknown-none-elf\\release\\deps\\the_gift-25721c29c540d9b1.the_gift.acb574d6-cgu.8.rcgu.o" "C:\\Users\\Tnze\\Documents\\Projects\\Embedded\\the-gift\\target\\riscv32imac-unknown-none-elf\\release\\deps\\the_gift-25721c29c540d9b1.the_gift.acb574d6-cgu.9.rcgu.o" "--as-needed" "-L" "C:\\Users\\Tnze\\Documents\\Projects\\Embedded\\the-gift\\target\\riscv32imac-unknown-none-elf\\release\\deps" "-L" "C:\\Users\\Tnze\\Documents\\Projects\\Embedded\\the-gift\\target\\release\\deps" "-L" "C:\\Users\\Tnze\\Documents\\Projects\\Embedded\\the-gift\\target\\riscv32imac-unknown-none-elf\\release\\build\\the-gift-fdb32f53c09e7cd1\\out" "-L" "C:\\Users\\Tnze\\Documents\\Projects\\Ey-x86_64-pc-windows-msvc\\lib\\rustlib\\riscv32imac-unknown-none-elf\\lib\\librustc_std_workspace_core-47c3987b2c3217d4.rlib" "C:\\Users\\Tnze\\.rustup\\toolchains\\nightly-x86_64-pc-windows-msvc\\lib\\rustlib\\riscv32imac-unknown-none-elf\\lib\\libcore-5f51ee8cf12ea786.rlib" "C:\\Users\\Tnze\\.rustup\\toolchains\\nightly-x86_64-pc-windows-msvc\\lib\\rustlib\\riscv32imac-unknown-none-elf\\lib\\libcompiler_builtins-2ae83c8d0fb9bfcd.rlib" "-Bdynamic" "-znoexecstack" "-L" "C:\\Users\\Tnze\\.rustup\\toolchains\\nightly-x86_64-pc-windows-msvc\\lib\\rustlib\\riscv32imac-unknown-none-elf\\lib" "-o" "C:\\Users\\Tnze\\Documents\\Projects\\Embedded\\the-gift\\target\\riscv32imac-unknown-none-elf\\release\\deps\\the_gift-25721c29c540d9b1" "--gc-sections" "-O1" "-Tmemory-cb.x" "-Tlink.x"  = note: rust-lld: error: C:\Users\Tnze\Documents\Projects\Embedded\the-gift\target\riscv32imac-unknown-none-elf\release\build\riscv-rt-3ec61bb139669965\out\link.x:58: expected filename pattern          >>>     (*(.trap));          >>>     ^

warning: `the-gift` (bin "the-gift") generated 9 warningserror: could not compile `the-gift` due to previous error; 9 warnings emitted

The problem is occured here:

(*(.trap));

Implement multi-core support

In order to support FU540 SoC we need to do something with multiple harts running the same code.
There are several problems on the way:

  • You can't run the same initialization code multiple times (especially r0::zero_bss and r0::init_data)
  • You need to decide which hart will be "main"
    • For M-mode we can just choose hart 0 as it's always present
    • For S-mode the situation is tricky: you may not have hart 0, but you can use atomics for this.
  • You need to decide what to do with the rest of the harts. Thay can be parked, but you need a way to unpark them.
  • You need to allocate stack region for all of the harts. With multiple harts the situation is a bit complicated: you need to know stack size in advance. This stack size can depend on the main application and it's resource usage.

My proposition is the following:

  • Add support for just M-mode for now, use hart 0 as the "main" hart.
  • Parked harts will busy-wait for a non-zero value of some flag.
  • Harts will be unparked all at once (for simplicity) with a function call (start_other_harts?).
  • Allocate stack for the other harts upon unparking: pass stack size as an argument.
  • After unparking harts will execute the same code as hart 0 except for main-hart-related initialization. In user application these harts can be distinguished by hart id and parked/unparked again (with CLINT signalling mechanism, for example) if necessary.

@rust-embedded/riscv Any ideas?

Accessing parameters passed in register by the previous boot stage

When running freestanding RISC-V code in QEMU, a "Flattened Device Tree" is loaded in memory that can be parsed in order to find out what devices are being emulated and what addresses they’re memory-mapped at. A few parameters are passed through a registers when first running firmware code, with the address of this in register a1. Unfortunately this stuff is severely undocumented but the same convention exists in coreboot and in OpenSBI.

With riscv-rt 0.8.1, by the time any Rust code runs all registers have been cleared so the DTF pointer cannot be found in a1. I have a workaround but it relies on QEMU internals that might change across versions.

Would it make sense for riscv-rt at the very beginning of _abs_start to copy these arguments registers (or perhaps just a1) into some symbol in RAM?

Code doesn't run with full `main` signature.

I am testing the riscv-crates repository with effectively rust-lang/rust#52787 (I compiled my own version, but the changes should be the same at the end of the day) and found that I could not get the examples to actually run on the HiFive1 board. After some debugging, I tracked it down to:

https://github.com/riscv-rust/riscv-rt/blob/eb45c67890f862037c7475329e4fbc5683fe9e03/src/lib.rs#L183

and

https://github.com/riscv-rust/riscv-rt/blob/eb45c67890f862037c7475329e4fbc5683fe9e03/src/lib.rs#L259-L261

After changing it to:

fn main() -> isize;

and

unsafe {
    main();
}

the blink_delay and hello_world apps started working.

Relocation R_RISCV_ALIGN linker error

Since commit 8340e74. a unsupported relocation is generated in the .a file while linking a binary for riscv64gc-unknown-none-elf:

  = note: rust-lld: error: asm.S:36:(.init+0xA): relocation R_RISCV_ALIGN requires unimplemented linker relaxation; recompile with -mno-relax

Adding the suggested -mno-relax to the assembler linex does not help. Reverting the commit however, works.

This is with rustc 1.45.0-nightly (74e804683 2020-05-30).

riscv64-unknown-elf-objdump -r  ./bin/riscv64imc-unknown-none-elf.a|less
RELOCATION RECORDS FOR [.init]:
OFFSET           TYPE              VALUE 
0000000000000000 R_RISCV_PCREL_HI20  .L1^B2
0000000000000000 R_RISCV_RELAX     *ABS*
0000000000000004 R_RISCV_PCREL_LO12_I  .L1^B1
0000000000000004 R_RISCV_RELAX     *ABS*
000000000000000a R_RISCV_ALIGN     *ABS*+0x0000000000000006
…

RAM init code violates pointer provenance and aliasing rules

RAM initialization currently passes pointers to these statics:

riscv-rt/src/lib.rs

Lines 346 to 355 in 47ece5f

// Boundaries of the .bss section
static mut _ebss: u32;
static mut _sbss: u32;
// Boundaries of the .data section
static mut _edata: u32;
static mut _sdata: u32;
// Initial values of the .data section (stored in Flash)
static _sidata: u32;

...to r0:

riscv-rt/src/lib.rs

Lines 381 to 382 in 47ece5f

r0::zero_bss(&mut _sbss, &mut _ebss);
r0::init_data(&mut _sdata, &mut _edata, &_sidata);

But since r0 will fill the entire memory range between the pointers, it ends up calling offset with values that create pointers well beyond the u32 the static is declared to contain. According to the docs of offset, this is UB:

Both the starting and resulting pointer must be either in bounds or one byte past the end of the same allocated object. Note that in Rust, every (stack-allocated) variable is considered a separate allocated object.

(every static also counts as its own "allocated object", I believe)

Moreover, the ptr::write and ptr::write_volatile calls in r0 also cause UB, because this invariant is violated:

dst must be valid for writes.

Where the validity of a pointer requires this:

For a pointer to be valid, it is necessary, but not always sufficient, that the pointer be dereferenceable: the memory range of the given size starting at the pointer must all be within the bounds of a single allocated object. Note that in Rust, every (stack-allocated) variable is considered a separate allocated object.

...but again, we are crossing between potentially many allocated objects (every static in the .data/.bss section).

Furthermore, writing to a static through a pointer not derived from that static might violate aliasing rules, but it isn't yet clear if this is the case today (I've asked the folks working on the unsafe code guidelines for clarification / guidance).

The most robust solution for this issue is to write the RAM init code in assembly instead of Rust, and run no Rust code at all until RAM is initialized.

(this issue was recently discovered to affect most -rt crates in the ecosystem; we do not believe it to cause practical issues at the moment)

rust produces a 2.1G executable

I'm trying to build a project for the HiFive board with the current rust nightly, commit ef8c163 of riscv-rt, and riscv32imac-unknown-none-elf toolchain, but I'm running into a strange issue.

The resulting executable is:

-rwxrwxr-x 2 user user 2.1G Feb 28 15:51 ./target/riscv32imac-unknown-none-elf/release/examples/blinky_delay

readelf -a shows that it's the .stack section that takes up all this space:

Section Headers:
  [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al
  [ 0]                   NULL            00000000 000000 000000 00      0   0  0
  [ 1] .text             PROGBITS        20400000 001000 000252 00  AX  0   0 16
  [ 2] .bss              NOBITS          80000000 002000 000004 00  WA  0   0  1
  [ 3] .data             PROGBITS        80000004 001252 000000 00  WA  0   0  1
  [ 4] .heap             PROGBITS        80000004 001254 000000 00   W  0   0  4
  [ 5] .stack            PROGBITS        80000004 001254 80004000 00   W  0   0  4
  [ 6] .debug_str        PROGBITS        00000000 80005254 00500a 01  MS  0   0  1

I'm using the link.x from this crate, and memory.x from e310x-hal (https://github.com/riscv-rust/e310x-hal/blob/master/memory.x) which indeed places RAM at offset 0x80000000.

This is the first time I'm working with rust on bare-metal. I suspect this is a problem with the linker script accidentally telling to provide data bits for the bss segments?

Migration to GitHub Actions

Any interest in a migration to GitHub Actions for this and the riscv crate?

Prompted by what looks like a regression in the rustfmt step. The travis backlogs have been pretty bad resulting in some long CI times which doesn't help.

I'd be happy to do the leg work.

Building this crate tries to use nonexistent std crate

When I try to build this crate, I get errors seemingly as a result of trying to find crate std, which confuses me because there is a line telling the compiler not to do that.
https://github.com/riscv-rust/riscv-rt/blob/9e7d5bcb51326e81c0a102237d08e94eb267c9dd/src/lib.rs#L159

My output:

jakobw@ubuntu:~/riscv/riscv-rt$ xargo build --verbose
+ "rustc" "--print" "sysroot"
+ RUSTFLAGS="--sysroot /home/jakobw/riscv/riscv-rust-toolchain/build/xargo/HOST"
+ "cargo" "build" "--verbose"
       Fresh bare-metal v0.1.1
   Compiling riscv-rt v0.1.3 (file:///home/jakobw/riscv/riscv-rt)
       Fresh r0 v0.2.2
       Fresh riscv v0.1.4 (file:///home/jakobw/riscv/riscv)
     Running `rustc --crate-name build_script_build build.rs --crate-type bin --emit=dep-info,link -C debuginfo=2 -C metadata=7bea7d42aad28252 -C extra-filename=-7bea7d42aad28252 --out-dir /home/jakobw/riscv/riscv-rt/target/debug/build/riscv-rt-7bea7d42aad28252 -C incremental=/home/jakobw/riscv/riscv-rt/target/debug/incremental -L dependency=/home/jakobw/riscv/riscv-rt/target/debug/deps --sysroot /home/jakobw/riscv/riscv-rust-toolchain/build/xargo/HOST`
error[E0463]: can't find crate for `std`

error: aborting due to previous error

For more information about this error, try `rustc --explain E0463`.
error: Could not compile `riscv-rt`.

Caused by:
  process didn't exit successfully: `rustc --crate-name build_script_build build.rs --crate-type bin --emit=dep-info,link -C debuginfo=2 -C metadata=7bea7d42aad28252 -C extra-filename=-7bea7d42aad28252 --out-dir /home/jakobw/riscv/riscv-rt/target/debug/build/riscv-rt-7bea7d42aad28252 -C incremental=/home/jakobw/riscv/riscv-rt/target/debug/incremental -L dependency=/home/jakobw/riscv/riscv-rt/target/debug/deps --sysroot /home/jakobw/riscv/riscv-rust-toolchain/build/xargo/HOST` (exit code: 101)

Any thoughts?

ELF output contains lots of zero data: linker script issue?

It could be that something is going wrong with the linker script. A binary of a small example is almost 7 MB in size:

-rwxrwxr-x 2 user user 6.7M Jun  2 18:13 target/riscv64gc-unknown-none-elf/release/interrupt

Using size, this seems to be allocated to data sections:

$ size target/riscv64gc-unknown-none-elf/release/interrupt
   text    data     bss     dec     hex filename
  38522 6176916   73732 6289170  5ff712 target/riscv64gc-unknown-none-elf/release/interrupt

Digigng further:

$ riscv64-unknown-elf-objdump -x target/riscv64gc-unknown-none-elf/release/interrupt
  4 .bss          00012004  000000008000a000  000000008000a000  0000abf8  2**12
                  ALLOC
  5 .heap         00000000  000000008001c004  000000008001c004  0000abf8  2**0
                  CONTENTS, ALLOC, LOAD, DATA
  6 .stack        005e3ffc  000000008001c004  000000008001c004  0000abf8  2**0
                  CONTENTS, ALLOC, LOAD, DATA

It seems the stack section is in the binary, padded fully with zeros:

riscv64-unknown-elf-objdump --section=.stack -s target/riscv64gc-unknown-none-elf/release/interrupt
Contents of section .stack:
 8001c004 00000000 00000000 00000000 00000000  ................
…
 805ffff4 00000000 00000000 00000000           ............    

I'm not sure why this is not treated like the .bss section, implicitly implied to be filled with zeros (the section is correctly labeled NOLOAD, but are not generated with ELF section type SHT_NOBITS).

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.