lupyuen.org/articles/rust4.html

632 lines
34 KiB
HTML
Raw Normal View History

2024-04-12 19:18:02 +08:00
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="generator" content="rustdoc">
<title>Rust Custom Target for QEMU RISC-V on Apache NuttX RTOS</title>
<!-- Begin scripts/articles/*-header.html: Article Header for Custom Markdown files processed by rustdoc, like chip8.md -->
<meta property="og:title"
content="Rust Custom Target for QEMU RISC-V on Apache NuttX RTOS"
data-rh="true">
<meta property="og:description"
content=""
data-rh="true">
<meta name="description"
content="">
<meta property="og:image"
content="https://lupyuen.github.io/images/rust4-title.jpg">
<meta property="og:type"
content="article" data-rh="true">
<link rel="canonical"
href="https://lupyuen.codeberg.page/articles/rust4.html" />
<!-- End scripts/articles/*-header.html -->
<!-- Begin scripts/rustdoc-header.html: Header for Custom Markdown files processed by rustdoc, like chip8.md -->
<link rel="alternate" type="application/rss+xml" title="RSS Feed for lupyuen" href="/rss.xml" />
<link rel="stylesheet" type="text/css" href="../normalize.css">
<link rel="stylesheet" type="text/css" href="../rustdoc.css" id="mainThemeStyle">
<link rel="stylesheet" type="text/css" href="../dark.css">
<link rel="stylesheet" type="text/css" href="../light.css" id="themeStyle">
<link rel="stylesheet" type="text/css" href="../prism.css">
<script src="../storage.js"></script><noscript>
<link rel="stylesheet" href="../noscript.css"></noscript>
<link rel="shortcut icon" href="../favicon.ico">
<style type="text/css">
#crate-search {
background-image: url("../down-arrow.svg");
}
</style>
<!-- End scripts/rustdoc-header.html -->
</head>
<body class="rustdoc">
<!--[if lte IE 8]>
<div class="warning">
This old browser is unsupported and will most likely display funky
things.
</div>
<![endif]-->
<!-- Begin scripts/rustdoc-before.html: Pre-HTML for Custom Markdown files processed by rustdoc, like chip8.md -->
<!-- Begin Theme Picker -->
<div class="theme-picker" style="left: 0"><button id="theme-picker" aria-label="Pick another theme!"><img src="../brush.svg"
width="18" alt="Pick another theme!"></button>
<div id="theme-choices"></div>
</div>
<!-- Theme Picker -->
<!-- End scripts/rustdoc-before.html -->
<h1 class="title">Rust Custom Target for QEMU RISC-V on Apache NuttX RTOS</h1>
<nav id="TOC"><ul>
2024-04-13 00:51:30 +08:00
<li><a href="#software-vs-hardware-floating-point">1 Software vs Hardware Floating-Point</a><ul></ul></li>
2024-04-15 08:44:59 +08:00
<li><a href="#rust-wont-double-float">2 Rust Wont Double-Float</a><ul></ul></li>
2024-04-13 23:25:52 +08:00
<li><a href="#custom-target-for-rust">3 Custom Target for Rust</a><ul></ul></li>
<li><a href="#build-the-rust-core-library">4 Build the Rust Core Library</a><ul></ul></li>
<li><a href="#nuttx-links-ok-with-rust">5 NuttX Links OK with Rust</a><ul></ul></li>
<li><a href="#rust-build-for-64-bit-risc-v">6 Rust Build for 64-bit RISC-V</a><ul></ul></li>
2024-04-15 07:36:02 +08:00
<li><a href="#whats-next">7 Whats Next</a><ul></ul></li>
<li><a href="#appendix-rust-compiler-options">8 Appendix: Rust Compiler Options</a><ul></ul></li></ul></nav><p>📝 <em>22 Apr 2024</em></p>
2024-04-12 19:18:02 +08:00
<p><img src="https://lupyuen.github.io/images/rust4-title.jpg" alt="Rust Apps on Apache NuttX RTOS and QEMU RISC-V" /></p>
2024-04-12 19:40:46 +08:00
<div style="text-align: center">
<p><a href="https://github.com/Swordfish90/cool-retro-term"><em>Thanks to cool-retro-term!</em></a></p>
</div>
2024-04-13 00:51:30 +08:00
<p>Last article we were compiling <a href="TODO"><strong>Rust Apps</strong></a> for <a href="TODO"><strong>Apache NuttX RTOS</strong></a> (QEMU RISC-V 32-bit). And we hit a <strong>baffling error</strong></p>
<div class="example-wrap"><pre class="language-bash"><code>$ make
riscv64-unknown-elf-ld: libapps.a
hello_rust_1.o:
can&#39;t link soft-float modules with double-float modules
</code></pre></div>
<p>Lets solve the problem! We dive inside the internals of <strong>C-to-Rust Interop</strong></p>
<ul>
<li>
<p>Rust compiles for <strong>Soft-Float</strong>, but NuttX expects <strong>Double-Float</strong></p>
<p>(Software vs Hardware Floating-Point)</p>
</li>
<li>
<p>But Rust <strong>doesnt support Double-Float</strong> (by default)</p>
</li>
<li>
<p>So we create a <strong>Rust Custom Target</strong> for Double-Float</p>
</li>
<li>
<p>Rebuild the <strong>Rust Core Library</strong> for Double-Float</p>
</li>
<li>
<p>And our Rust App <strong>builds OK with NuttX</strong>!</p>
</li>
</ul>
<p>TODO: Pic of double float vs soft float </p>
<h1 id="software-vs-hardware-floating-point"><a class="doc-anchor" href="#software-vs-hardware-floating-point">§</a>1 Software vs Hardware Floating-Point</h1>
2024-04-12 19:18:02 +08:00
<p>TODO</p>
2024-04-15 10:45:47 +08:00
<p>TODO: Compile nuttx, Hello.c</p>
2024-04-12 19:40:46 +08:00
<p>But the rest of NuttX is Double-Precision Hardware Floating-Point!</p>
<p>(<code>-march=rv32imafdc -mabi=ilp32d</code>)</p>
<div class="example-wrap"><pre class="language-bash"><code>$ make --trace
...
riscv64-unknown-elf-gcc \
-c \
-fno-common \
-Wall \
-Wstrict-prototypes \
-Wshadow \
-Wundef \
-Wno-attributes \
-Wno-unknown-pragmas \
-Wno-psabi \
-Os \
-fno-strict-aliasing \
-fomit-frame-pointer \
-ffunction-sections \
-fdata-sections \
-g \
-march=rv32imafdc \
-mabi=ilp32d \
-isystem nuttx/include \
-D__NuttX__ \
-DNDEBUG \
-pipe \
-I &quot;apps/include&quot; \
-Dmain=hello_main \
hello_main.c \
2024-04-15 10:45:47 +08:00
-o hello_main.c...apps.examples.hello.o
</code></pre></div>
<p>TODO: Target, Rustc</p>
<p>Thats because <a href="https://lupyuen.github.io/articles/rust3#how-nuttx-compiles-rust-apps">NuttX builds Rust Apps</a> for <code>riscv32i-unknown-none-elf</code> (Software Floating-Point)…</p>
<div class="example-wrap"><pre class="language-bash"><code>## Compile `hello_rust_main.rs` to `hello_rust.o`
## for Rust Target: RISC-V 32-bit (Soft-Float)
rustc \
--edition 2021 \
--emit obj \
-g \
--target riscv32i-unknown-none-elf \
-C panic=abort \
-O \
hello_rust_main.rs \
-o hello_rust_main.rs...apps.examples.hello_rust.o
</code></pre></div>
<p>Watch closely as we compare <strong>GCC Compiler</strong> with <strong>Rust Compiler</strong></p>
2024-04-15 11:32:01 +08:00
<span style="font-size:90%">
2024-04-15 10:45:47 +08:00
<div><table><thead><tr><th>GCC Compiler</th><th>Rust Compiler</th></tr></thead><tbody>
2024-04-15 10:58:04 +08:00
<tr><td><em>riscv64-unknown-elf-gcc</em> <br>      <em>hello_main.c</em></td><td><em>rustc</em> <br>      <em>hello_rust_main.rs</em></td></tr>
<tr><td><em>-march</em> <br>     <strong>rv32imafdc</strong></td><td><em>target</em> <br>    <strong>riscv32i-unknown-none-elf</strong></td></tr>
<tr><td><em>-mabi</em> <br>     <strong>ilp32d</strong></td><td></td></tr>
2024-04-15 10:45:47 +08:00
</tbody></table>
2024-04-15 11:32:01 +08:00
</div></span>
<p><em>Hmmm something different about the Floats…</em></p>
<p>Yep GCC supports (Double-Precision) <strong>Hardware Floating-Point</strong></p>
<p>Rust Compiler only supports <strong>Software Floating-Point</strong>!</p>
<span style="font-size:90%">
<div><table><thead><tr><th>GCC Compiler</th><th>Rust Compiler</th></tr></thead><tbody>
<tr><td><strong>rv32imafdc</strong></td><td><strong>riscv32i</strong></td></tr>
<tr><td>- <strong>I</strong>: Integer</td><td>- <strong>I</strong>: Integer</td></tr>
<tr><td>- <strong>F</strong>: Single Hard-Float</td><td><em>(Soft-Float)</em></td></tr>
<tr><td>- <strong>D</strong>: Double Hard-Float</td><td><em>(Soft-Float)</em></td></tr>
</tbody></table>
</div></span>
2024-04-15 11:53:07 +08:00
<p>And thats why GCC Linker wont link the binaries!</p>
2024-04-15 11:32:01 +08:00
<p>To verify, we dump the <strong>ELF Headers</strong> for GCC and Rust Compiler Outputs…</p>
<div class="example-wrap"><pre class="language-bash"><code>## ELF Header for GCC Output:
## Double-Precision Hardware Floating-Point
2024-04-15 10:45:47 +08:00
$ riscv64-unknown-elf-readelf \
--file-header --arch-specific \
../apps/examples/hello/*hello.o
ELF Header:
Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
Class: ELF32
Data: 2&#39;s complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: REL (Relocatable file)
Machine: RISC-V
Version: 0x1
Entry point address: 0x0
Start of program headers: 0 (bytes into file)
Start of section headers: 3776 (bytes into file)
Flags: 0x5, RVC, double-float ABI
Size of this header: 52 (bytes)
Size of program headers: 0 (bytes)
Number of program headers: 0
Size of section headers: 40 (bytes)
Number of section headers: 26
Section header string table index: 25
Attribute Section: riscv
File Attributes
Tag_RISCV_stack_align: 16-bytes
Tag_RISCV_arch: &quot;rv32i2p0_m2p0_a2p0_f2p0_d2p0_c2p0&quot;
2024-04-15 11:32:01 +08:00
## ELF Header for Rust Compiler Output
## Software Floating-Point
2024-04-15 10:45:47 +08:00
$ riscv64-unknown-elf-readelf \
--file-header --arch-specific \
../apps/examples/hello_rust/*hello_rust.o
ELF Header:
Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
Class: ELF32
Data: 2&#39;s complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: REL (Relocatable file)
Machine: RISC-V
Version: 0x1
Entry point address: 0x0
Start of program headers: 0 (bytes into file)
Start of section headers: 10240 (bytes into file)
Flags: 0x0
Size of this header: 52 (bytes)
Size of program headers: 0 (bytes)
Number of program headers: 0
Size of section headers: 40 (bytes)
Number of section headers: 29
Section header string table index: 1
Attribute Section: riscv
File Attributes
Tag_RISCV_stack_align: 16-bytes
Tag_RISCV_arch: &quot;rv32i2p1&quot;
</code></pre></div>
<p>Change rust to double float </p>
<p>We have a problem compiling <a href="https://lupyuen.github.io/articles/rust3#software-vs-hardware-floating-point">Rust Apps for QEMU RISC-V 32-bit</a></p>
<div class="example-wrap"><pre class="language-bash"><code>$ make
LD: nuttx
riscv64-unknown-elf-ld: nuttx/nuttx/staging/libapps.a
(hello_rust_main.rs...nuttx.apps.examples.hello_rust_1.o):
can&#39;t link soft-float modules with double-float modules
riscv64-unknown-elf-ld: failed to merge target specific data of file
nuttx/staging/libapps.a
(hello_rust_main.rs...nuttx.apps.examples.hello_rust_1.o)
2024-04-15 08:44:59 +08:00
</code></pre></div>
<p>TODO: Pic of Rust Wont Double-Float</p>
<h1 id="rust-wont-double-float"><a class="doc-anchor" href="#rust-wont-double-float">§</a>2 Rust Wont Double-Float</h1>
2024-04-15 07:36:02 +08:00
<p>TODO</p>
<p>Change Rust target</p>
<p>Nope doesnt work</p>
<p>Here are the targets</p>
<p>Need custom target</p>
<p>Gcc targets</p>
2024-04-12 19:40:46 +08:00
<p><em>Does Rust support Double-Precision Hardware Floating-Point?</em></p>
<p>Were looking for a Rust Target like <code>riscv32gc-unknown-none-elf</code></p>
<div class="example-wrap"><pre class="language-bash"><code>$ rustup target list | grep riscv
riscv32i-unknown-none-elf
riscv32imac-unknown-none-elf
riscv32imc-unknown-none-elf
riscv64gc-unknown-linux-gnu
riscv64gc-unknown-none-elf
riscv64imac-unknown-none-elf
</code></pre></div>
<p>But nope its not supported! So we create a Rust Custom Target for <code>riscv32gc-unknown-none-elf</code></p>
<ul>
<li><a href="https://docs.rust-embedded.org/embedonomicon/custom-target.html">Custom Target for Rust</a></li>
</ul>
2024-04-15 07:36:02 +08:00
<p><em>How to see the Targets supported by GCC?</em></p>
<p>Like this…</p>
<div class="example-wrap"><pre class="language-bash"><code>$ riscv64-unknown-elf-gcc --target-help
Supported ABIs (for use with the -mabi= option):
ilp32 ilp32d ilp32e ilp32f lp64 lp64d lp64f
</code></pre></div>
<p><a href="https://gcc.gnu.org/onlinedocs/gcc/RISC-V-Options.html#index-mabi-5">(As explained here)</a></p>
2024-04-15 11:53:07 +08:00
<p>TODO: Pic of Custom Target for Rust</p>
2024-04-15 07:36:02 +08:00
<h1 id="custom-target-for-rust"><a class="doc-anchor" href="#custom-target-for-rust">§</a>3 Custom Target for Rust</h1>
<p>TODO</p>
2024-04-12 19:40:46 +08:00
<p>Lets dump the Rust Targets <code>riscv32i</code> and <code>riscv64gc</code> to compare…</p>
<div class="example-wrap"><pre class="language-bash"><code>$ rustc \
+nightly \
-Z unstable-options \
--print target-spec-json \
--target riscv32i-unknown-none-elf
{
&quot;arch&quot;: &quot;riscv32&quot;,
&quot;atomic-cas&quot;: false,
&quot;cpu&quot;: &quot;generic-rv32&quot;,
&quot;data-layout&quot;: &quot;e-m:e-p:32:32-i64:64-n32-S128&quot;,
&quot;eh-frame-header&quot;: false,
&quot;emit-debug-gdb-scripts&quot;: false,
&quot;is-builtin&quot;: true,
&quot;linker&quot;: &quot;rust-lld&quot;,
&quot;linker-flavor&quot;: &quot;ld.lld&quot;,
&quot;llvm-target&quot;: &quot;riscv32&quot;,
&quot;max-atomic-width&quot;: 0,
&quot;panic-strategy&quot;: &quot;abort&quot;,
&quot;relocation-model&quot;: &quot;static&quot;,
&quot;target-pointer-width&quot;: &quot;32&quot;
}
$ rustc \
+nightly \
-Z unstable-options \
--print target-spec-json \
--target riscv64gc-unknown-none-elf
{
&quot;arch&quot;: &quot;riscv64&quot;,
&quot;code-model&quot;: &quot;medium&quot;,
&quot;cpu&quot;: &quot;generic-rv64&quot;,
&quot;data-layout&quot;: &quot;e-m:e-p:64:64-i64:64-i128:128-n32:64-S128&quot;,
&quot;eh-frame-header&quot;: false,
&quot;emit-debug-gdb-scripts&quot;: false,
&quot;features&quot;: &quot;+m,+a,+f,+d,+c&quot;,
&quot;is-builtin&quot;: true,
&quot;linker&quot;: &quot;rust-lld&quot;,
&quot;linker-flavor&quot;: &quot;ld.lld&quot;,
&quot;llvm-abiname&quot;: &quot;lp64d&quot;,
&quot;llvm-target&quot;: &quot;riscv64&quot;,
&quot;max-atomic-width&quot;: 64,
&quot;panic-strategy&quot;: &quot;abort&quot;,
&quot;relocation-model&quot;: &quot;static&quot;,
&quot;supported-sanitizers&quot;: [
&quot;kernel-address&quot;
],
&quot;target-pointer-width&quot;: &quot;64&quot;
}
</code></pre></div>
<p>Based on the above, we create our Rust Custom Target: <a href="riscv32gc-unknown-none-elf.json">riscv32gc-unknown-none-elf.json</a></p>
<div class="example-wrap"><pre class="language-json"><code>{
&quot;arch&quot;: &quot;riscv32&quot;,
&quot;cpu&quot;: &quot;generic-rv32&quot;,
&quot;data-layout&quot;: &quot;e-m:e-p:32:32-i64:64-n32-S128&quot;,
&quot;eh-frame-header&quot;: false,
&quot;emit-debug-gdb-scripts&quot;: false,
&quot;features&quot;: &quot;+m,+a,+f,+d,+c&quot;,
&quot;linker&quot;: &quot;rust-lld&quot;,
&quot;linker-flavor&quot;: &quot;ld.lld&quot;,
&quot;llvm-abiname&quot;: &quot;ilp32d&quot;,
&quot;llvm-target&quot;: &quot;riscv32&quot;,
&quot;max-atomic-width&quot;: 0,
&quot;panic-strategy&quot;: &quot;abort&quot;,
&quot;relocation-model&quot;: &quot;static&quot;,
&quot;target-pointer-width&quot;: &quot;32&quot;
}
</code></pre></div>
<p>Which is based on <code>riscv32i</code> with these changes…</p>
<ul>
<li>
<p>Removed <code>&quot;atomic-cas&quot;: false</code></p>
</li>
<li>
<p>Added <code>&quot;features&quot;: &quot;+m,+a,+f,+d,+c&quot;</code></p>
</li>
<li>
<p>Removed <code>&quot;is-builtin&quot;: true</code></p>
</li>
<li>
<p>Added <code>&quot;llvm-abiname&quot;: &quot;ilp32d&quot;</code></p>
<p>(<code>ilp32d</code> comes from <code>make --trace</code> above)</p>
<p><a href="https://lupyuen.github.io/articles/rust#custom-rust-target-for-bl602">(More about <code>llvm-abiname</code>)</a></p>
</li>
</ul>
2024-04-15 11:53:07 +08:00
<p>TODO: Pic of Rust Core Library</p>
2024-04-15 07:36:02 +08:00
<h1 id="build-the-rust-core-library"><a class="doc-anchor" href="#build-the-rust-core-library">§</a>4 Build the Rust Core Library</h1>
<p>TODO</p>
2024-04-12 19:40:46 +08:00
<p>Now we build the Rust Core Library for <code>riscv32gc</code></p>
<div class="example-wrap"><pre class="language-bash"><code>## Verify our Custom Target
rustc \
--print cfg \
--target riscv32gc-unknown-none-elf.json
## Build the Rust Core Library for `riscv32gc`
## Ignore the error: `app already exists`
cargo new app
pushd app
cargo clean
## Ignore the error: `can&#39;t find crate for std`
cargo build \
-Zbuild-std=core,alloc \
--target ../riscv32gc-unknown-none-elf.json
popd
</code></pre></div>
<p>We rebuild our Rust App with the new Rust Custom Target (linked to our Rust Core Library)…</p>
<div class="example-wrap"><pre class="language-bash"><code>## Compile our Rust App.
## Changed the target to riscv32gc-unknown-none-elf.json
rustc \
--edition 2021 \
--emit obj \
-g \
--target riscv32gc-unknown-none-elf.json \
-C panic=abort \
-O \
../apps/examples/hello_rust/hello_rust_main.rs \
-o ../apps/examples/hello_rust/*hello_rust.o \
\
-C incremental=app/target/riscv32gc-unknown-none-elf/debug/incremental \
-L dependency=app/target/riscv32gc-unknown-none-elf/debug/deps \
-L dependency=app/target/debug/deps \
--extern noprelude:alloc=`ls app/target/riscv32gc-unknown-none-elf/debug/deps/liballoc-*.rlib` \
--extern noprelude:compiler_builtins=`ls app/target/riscv32gc-unknown-none-elf/debug/deps/libcompiler_builtins-*.rlib` \
--extern noprelude:core=`ls app/target/riscv32gc-unknown-none-elf/debug/deps/libcore-*.rlib` \
-Z unstable-options
## Dump the ELF Header. Should show:
## Flags: 0x5, RVC, double-float ABI
riscv64-unknown-elf-readelf \
2024-04-15 10:45:47 +08:00
--file-header --arch-specific \
2024-04-12 19:40:46 +08:00
../apps/examples/hello_rust/*hello_rust.o
## NuttX should link and execute correctly now
cp \
../apps/examples/hello_rust/*hello_rust.o \
../apps/examples/hello_rust/*hello_rust_1.o
pushd ../nuttx
make
qemu-system-riscv32 \
-semihosting \
-M virt,aclint=on \
-cpu rv32 \
-smp 8 \
-bios none \
-kernel nuttx \
-nographic
popd
</code></pre></div>
<p>And it works!</p>
2024-04-15 07:36:02 +08:00
<h1 id="nuttx-links-ok-with-rust"><a class="doc-anchor" href="#nuttx-links-ok-with-rust">§</a>5 NuttX Links OK with Rust</h1>
<p>TODO</p>
2024-04-12 19:40:46 +08:00
<p><em>Our Rust App links OK! Has the ELF Header changed?</em></p>
<p>Yep the ELF Header has changed from Soft-Float to Double-Float…</p>
<div class="example-wrap"><pre class="language-bash"><code>## Before Custom Target
$ riscv64-unknown-elf-readelf \
2024-04-15 10:45:47 +08:00
--file-header --arch-specific \
2024-04-12 19:40:46 +08:00
../apps/examples/hello_rust/*hello_rust_1.o
ELF Header:
Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
Class: ELF32
Data: 2&#39;s complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: REL (Relocatable file)
Machine: RISC-V
Version: 0x1
Entry point address: 0x0
Start of program headers: 0 (bytes into file)
Start of section headers: 10240 (bytes into file)
Flags: 0x0
Size of this header: 52 (bytes)
Size of program headers: 0 (bytes)
Number of program headers: 0
Size of section headers: 40 (bytes)
Number of section headers: 29
Section header string table index: 1
Attribute Section: riscv
File Attributes
Tag_RISCV_stack_align: 16-bytes
Tag_RISCV_arch: &quot;rv32i2p1&quot;
## After Custom Target
$ riscv64-unknown-elf-readelf \
2024-04-15 10:45:47 +08:00
--file-header --arch-specific \
2024-04-12 19:40:46 +08:00
../apps/examples/hello_rust/*hello_rust.o
ELF Header:
Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
Class: ELF32
Data: 2&#39;s complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: REL (Relocatable file)
Machine: RISC-V
Version: 0x1
Entry point address: 0x0
Start of program headers: 0 (bytes into file)
Start of section headers: 10352 (bytes into file)
Flags: 0x5, RVC, double-float ABI
Size of this header: 52 (bytes)
Size of program headers: 0 (bytes)
Number of program headers: 0
Size of section headers: 40 (bytes)
Number of section headers: 29
Section header string table index: 1
Attribute Section: riscv
File Attributes
Tag_RISCV_stack_align: 16-bytes
Tag_RISCV_arch: &quot;rv32i2p1_m2p0_a2p1_f2p2_d2p2_c2p0_zicsr2p0&quot;
## Which looks similar to other C Binaries
$ riscv64-unknown-elf-readelf \
2024-04-15 10:45:47 +08:00
--file-header --arch-specific \
2024-04-12 19:40:46 +08:00
../apps/examples/hello/*hello.o
ELF Header:
Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
Class: ELF32
Data: 2&#39;s complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: REL (Relocatable file)
Machine: RISC-V
Version: 0x1
Entry point address: 0x0
Start of program headers: 0 (bytes into file)
Start of section headers: 3776 (bytes into file)
Flags: 0x5, RVC, double-float ABI
Size of this header: 52 (bytes)
Size of program headers: 0 (bytes)
Number of program headers: 0
Size of section headers: 40 (bytes)
Number of section headers: 26
Section header string table index: 25
Attribute Section: riscv
File Attributes
Tag_RISCV_stack_align: 16-bytes
Tag_RISCV_arch: &quot;rv32i2p0_m2p0_a2p0_f2p0_d2p0_c2p0&quot;
</code></pre></div>
2024-04-15 07:36:02 +08:00
<p>How would Linux Kernel handle these uncommon targets?</p>
<p>This Rust Compiler Issue might be relevant…</p>
<ul>
<li><a href="https://github.com/rust-lang/rust/issues/65024">Allow building for hard-float targets in RISC-V</a></li>
</ul>
<h1 id="rust-build-for-64-bit-risc-v"><a class="doc-anchor" href="#rust-build-for-64-bit-risc-v">§</a>6 Rust Build for 64-bit RISC-V</h1>
<p>TODO</p>
<p><strong>Exercise for the Reader:</strong> Last article we TODO</p>
<div class="example-wrap"><pre class="language-bash"><code>$ tools/configure.sh rv-virt:nsh64
$ make menuconfig
## TODO: Enable &quot;Hello Rust Example&quot;
$ make
RUSTC: hello_rust_main.rs error: Error loading target specification:
Could not find specification for target &quot;riscv64i-unknown-none-elf&quot;.
Run `rustc --print target-list` for a list of built-in targets
make[2]: *** [nuttx/apps/Application.mk:275: hello_rust.o] Error 1
make[1]: *** [Makefile:51: nuttx/apps/examples/hello_rust_all] Error 2
make: *** [tools/LibTargets.mk:232: nuttx/apps/libapps.a] Error 2
</code></pre></div>
<p>Which says that <em>riscv64i-unknown-none-elf</em> isnt a valid Rust Target.</p>
<p>(Should be <em>riscv64gc-unknown-none-elf</em> instead)</p>
<p>Fix the build?
Custom Target?
(10 points)</p>
<h1 id="whats-next"><a class="doc-anchor" href="#whats-next">§</a>7 Whats Next</h1>
<p>TODO</p>
<p>Many Thanks to my <a href="https://github.com/sponsors/lupyuen"><strong>GitHub Sponsors</strong></a> (and the awesome NuttX Community) for supporting my work! This article wouldnt have been possible without your support.</p>
<ul>
<li>
<p><a href="https://github.com/sponsors/lupyuen"><strong>Sponsor me a coffee</strong></a></p>
</li>
<li>
<p><a href="https://github.com/lupyuen/nuttx-ox64"><strong>My Current Project: “Apache NuttX RTOS for Ox64 BL808”</strong></a></p>
</li>
<li>
<p><a href="https://github.com/lupyuen/nuttx-star64"><strong>My Other Project: “NuttX for Star64 JH7110”</strong></a></p>
</li>
<li>
<p><a href="https://github.com/lupyuen/pinephone-nuttx"><strong>Older Project: “NuttX for PinePhone”</strong></a></p>
</li>
<li>
<p><a href="https://lupyuen.github.io"><strong>Check out my articles</strong></a></p>
</li>
<li>
<p><a href="https://lupyuen.github.io/rss.xml"><strong>RSS Feed</strong></a></p>
</li>
</ul>
<p><em>Got a question, comment or suggestion? Create an Issue or submit a Pull Request here…</em></p>
<p><a href="https://github.com/lupyuen/lupyuen.github.io/blob/master/src/rust4.md"><strong>lupyuen.github.io/src/rust4.md</strong></a></p>
<h1 id="appendix-rust-compiler-options"><a class="doc-anchor" href="#appendix-rust-compiler-options">§</a>8 Appendix: Rust Compiler Options</h1>
<p>TODO</p>
2024-04-12 19:40:46 +08:00
<p><em>How did we figure out the rustc options?</em></p>
<p><code>cargo build</code> will call <code>rustc</code> with a whole bunch of options.</p>
<p>We ran <code>cargo build -v</code> to dump the <code>rustc</code> options that were used to compile a Rust App with our Custom Rust Core Library for <code>riscv32gc</code></p>
<div class="example-wrap"><pre class="language-bash"><code>$ cargo build -v \
-Zbuild-std=core,alloc \
--target ../riscv32gc-unknown-none-elf.json
Compiling compiler_builtins v0.1.101
Compiling core v0.0.0 ($HOME/.rustup/toolchains/nightly-x86_64-apple-darwin/lib/rustlib/src/rust/library/core)
Running `$HOME/.rustup/toolchains/nightly-x86_64-apple-darwin/bin/rustc --crate-name build_script_build --edition=2018 $HOME/.cargo/registry/src/index.crates.io-6f17d22bba15001f/compiler_builtins-0.1.101/build.rs --error-format=json --json=diagnostic-rendered-ansi,artifacts,future-incompat --diagnostic-width=94 --crate-type bin --emit=dep-info,link -C embed-bitcode=no -C debuginfo=2 -C split-debuginfo=unpacked --cfg &#39;feature=&quot;compiler-builtins&quot;&#39; --cfg &#39;feature=&quot;core&quot;&#39; --cfg &#39;feature=&quot;default&quot;&#39; --cfg &#39;feature=&quot;rustc-dep-of-std&quot;&#39; -C metadata=9bd0bac7535b33a8 -C extra-filename=-9bd0bac7535b33a8 --out-dir $HOME/riscv/nuttx-rust-app/app/target/debug/build/compiler_builtins-9bd0bac7535b33a8 -Z force-unstable-if-unmarked -L dependency=$HOME/riscv/nuttx-rust-app/app/target/debug/deps --cap-lints allow`
Running `$HOME/.rustup/toolchains/nightly-x86_64-apple-darwin/bin/rustc --crate-name core --edition=2021 $HOME/.rustup/toolchains/nightly-x86_64-apple-darwin/lib/rustlib/src/rust/library/core/src/lib.rs --error-format=json --json=diagnostic-rendered-ansi,artifacts,future-incompat --diagnostic-width=94 --crate-type lib --emit=dep-info,metadata,link -C embed-bitcode=no -C debuginfo=2 -C metadata=d271c6ebb87f9b41 -C extra-filename=-d271c6ebb87f9b41 --out-dir $HOME/riscv/nuttx-rust-app/app/target/riscv32gc-unknown-none-elf/debug/deps --target $HOME/riscv/nuttx-rust-app/riscv32gc-unknown-none-elf.json -Z force-unstable-if-unmarked -L dependency=$HOME/riscv/nuttx-rust-app/app/target/riscv32gc-unknown-none-elf/debug/deps -L dependency=$HOME/riscv/nuttx-rust-app/app/target/debug/deps --cap-lints allow`
Running `$HOME/riscv/nuttx-rust-app/app/target/debug/build/compiler_builtins-9bd0bac7535b33a8/build-script-build`
Compiling rustc-std-workspace-core v1.99.0 ($HOME/.rustup/toolchains/nightly-x86_64-apple-darwin/lib/rustlib/src/rust/library/rustc-std-workspace-core)
Running `$HOME/.rustup/toolchains/nightly-x86_64-apple-darwin/bin/rustc --crate-name rustc_std_workspace_core --edition=2021 $HOME/.rustup/toolchains/nightly-x86_64-apple-darwin/lib/rustlib/src/rust/library/rustc-std-workspace-core/lib.rs --error-format=json --json=diagnostic-rendered-ansi,artifacts,future-incompat --diagnostic-width=94 --crate-type lib --emit=dep-info,metadata,link -C embed-bitcode=no -C debuginfo=2 -C metadata=52e0df2b2cc19b6e -C extra-filename=-52e0df2b2cc19b6e --out-dir $HOME/riscv/nuttx-rust-app/app/target/riscv32gc-unknown-none-elf/debug/deps --target $HOME/riscv/nuttx-rust-app/riscv32gc-unknown-none-elf.json -Z force-unstable-if-unmarked -L dependency=$HOME/riscv/nuttx-rust-app/app/target/riscv32gc-unknown-none-elf/debug/deps -L dependency=$HOME/riscv/nuttx-rust-app/app/target/debug/deps --extern core=$HOME/riscv/nuttx-rust-app/app/target/riscv32gc-unknown-none-elf/debug/deps/libcore-d271c6ebb87f9b41.rmeta --cap-lints allow`
Running `$HOME/.rustup/toolchains/nightly-x86_64-apple-darwin/bin/rustc --crate-name compiler_builtins --edition=2018 $HOME/.cargo/registry/src/index.crates.io-6f17d22bba15001f/compiler_builtins-0.1.101/src/lib.rs --error-format=json --json=diagnostic-rendered-ansi,artifacts,future-incompat --diagnostic-width=94 --crate-type lib --emit=dep-info,metadata,link -C embed-bitcode=no -C debuginfo=2 --cfg &#39;feature=&quot;compiler-builtins&quot;&#39; --cfg &#39;feature=&quot;core&quot;&#39; --cfg &#39;feature=&quot;default&quot;&#39; --cfg &#39;feature=&quot;rustc-dep-of-std&quot;&#39; -C metadata=cd0d33c2bd30ca51 -C extra-filename=-cd0d33c2bd30ca51 --out-dir $HOME/riscv/nuttx-rust-app/app/target/riscv32gc-unknown-none-elf/debug/deps --target $HOME/riscv/nuttx-rust-app/riscv32gc-unknown-none-elf.json -Z force-unstable-if-unmarked -L dependency=$HOME/riscv/nuttx-rust-app/app/target/riscv32gc-unknown-none-elf/debug/deps -L dependency=$HOME/riscv/nuttx-rust-app/app/target/debug/deps --extern core=$HOME/riscv/nuttx-rust-app/app/target/riscv32gc-unknown-none-elf/debug/deps/librustc_std_workspace_core-52e0df2b2cc19b6e.rmeta --cap-lints allow --cfg &#39;feature=&quot;unstable&quot;&#39; --cfg &#39;feature=&quot;mem&quot;&#39;`
Compiling alloc v0.0.0 ($HOME/.rustup/toolchains/nightly-x86_64-apple-darwin/lib/rustlib/src/rust/library/alloc)
Running `$HOME/.rustup/toolchains/nightly-x86_64-apple-darwin/bin/rustc --crate-name alloc --edition=2021 $HOME/.rustup/toolchains/nightly-x86_64-apple-darwin/lib/rustlib/src/rust/library/alloc/src/lib.rs --error-format=json --json=diagnostic-rendered-ansi,artifacts,future-incompat --diagnostic-width=94 --crate-type lib --emit=dep-info,metadata,link -C embed-bitcode=no -C debuginfo=2 -C metadata=5d7bc2e4f3c29e08 -C extra-filename=-5d7bc2e4f3c29e08 --out-dir $HOME/riscv/nuttx-rust-app/app/target/riscv32gc-unknown-none-elf/debug/deps --target $HOME/riscv/nuttx-rust-app/riscv32gc-unknown-none-elf.json -Z force-unstable-if-unmarked -L dependency=$HOME/riscv/nuttx-rust-app/app/target/riscv32gc-unknown-none-elf/debug/deps -L dependency=$HOME/riscv/nuttx-rust-app/app/target/debug/deps --extern compiler_builtins=$HOME/riscv/nuttx-rust-app/app/target/riscv32gc-unknown-none-elf/debug/deps/libcompiler_builtins-cd0d33c2bd30ca51.rmeta --extern core=$HOME/riscv/nuttx-rust-app/app/target/riscv32gc-unknown-none-elf/debug/deps/libcore-d271c6ebb87f9b41.rmeta --cap-lints allow`
Compiling app v0.1.0 ($HOME/riscv/nuttx-rust-app/app)
Running `$HOME/.rustup/toolchains/nightly-x86_64-apple-darwin/bin/rustc --crate-name app --edition=2021 src/main.rs --error-format=json --json=diagnostic-rendered-ansi,artifacts,future-incompat --diagnostic-width=94 --crate-type bin --emit=dep-info,link -C embed-bitcode=no -C debuginfo=2 -C metadata=1ff442e6481e1397 -C extra-filename=-1ff442e6481e1397 --out-dir $HOME/riscv/nuttx-rust-app/app/target/riscv32gc-unknown-none-elf/debug/deps --target $HOME/riscv/nuttx-rust-app/riscv32gc-unknown-none-elf.json -C incremental=$HOME/riscv/nuttx-rust-app/app/target/riscv32gc-unknown-none-elf/debug/incremental -L dependency=$HOME/riscv/nuttx-rust-app/app/target/riscv32gc-unknown-none-elf/debug/deps -L dependency=$HOME/riscv/nuttx-rust-app/app/target/debug/deps --extern &#39;noprelude:alloc=$HOME/riscv/nuttx-rust-app/app/target/riscv32gc-unknown-none-elf/debug/deps/liballoc-5d7bc2e4f3c29e08.rlib&#39; --extern &#39;noprelude:compiler_builtins=$HOME/riscv/nuttx-rust-app/app/target/riscv32gc-unknown-none-elf/debug/deps/libcompiler_builtins-cd0d33c2bd30ca51.rlib&#39; --extern &#39;noprelude:core=$HOME/riscv/nuttx-rust-app/app/target/riscv32gc-unknown-none-elf/debug/deps/libcore-d271c6ebb87f9b41.rlib&#39; -Z unstable-options`
error[E0463]: can&#39;t find crate for `std`
|
= note: the `riscv32gc-unknown-none-elf` target may not support the standard library
= note: `std` is required by `app` because it does not declare `#![no_std]`
= help: consider building the standard library from source with `cargo build -Zbuild-std`
error: cannot find macro `println` in this scope
--&gt; src/main.rs:2:5
|
2 | println!(&quot;Hello, world!&quot;);
| ^^^^^^^
error: `#[panic_handler]` function required, but not found
For more information about this error, try `rustc --explain E0463`.
error: could not compile `app` (bin &quot;app&quot;) due to 3 previous errors
Caused by:
process didn&#39;t exit successfully: `$HOME/.rustup/toolchains/nightly-x86_64-apple-darwin/bin/rustc --crate-name app --edition=2021 src/main.rs --error-format=json --json=diagnostic-rendered-ansi,artifacts,future-incompat --diagnostic-width=94 --crate-type bin --emit=dep-info,link -C embed-bitcode=no -C debuginfo=2 -C metadata=1ff442e6481e1397 -C extra-filename=-1ff442e6481e1397 --out-dir $HOME/riscv/nuttx-rust-app/app/target/riscv32gc-unknown-none-elf/debug/deps --target $HOME/riscv/nuttx-rust-app/riscv32gc-unknown-none-elf.json -C incremental=$HOME/riscv/nuttx-rust-app/app/target/riscv32gc-unknown-none-elf/debug/incremental -L dependency=$HOME/riscv/nuttx-rust-app/app/target/riscv32gc-unknown-none-elf/debug/deps -L dependency=$HOME/riscv/nuttx-rust-app/app/target/debug/deps --extern &#39;noprelude:alloc=$HOME/riscv/nuttx-rust-app/app/target/riscv32gc-unknown-none-elf/debug/deps/liballoc-5d7bc2e4f3c29e08.rlib&#39; --extern &#39;noprelude:compiler_builtins=$HOME/riscv/nuttx-rust-app/app/target/riscv32gc-unknown-none-elf/debug/deps/libcompiler_builtins-cd0d33c2bd30ca51.rlib&#39; --extern &#39;noprelude:core=$HOME/riscv/nuttx-rust-app/app/target/riscv32gc-unknown-none-elf/debug/deps/libcore-d271c6ebb87f9b41.rlib&#39; -Z unstable-options` (exit status: 1)
</code></pre></div>
2024-04-12 19:18:02 +08:00
<!-- Begin scripts/rustdoc-after.html: Post-HTML for Custom Markdown files processed by rustdoc, like chip8.md -->
<!-- Begin Theme Picker and Prism Theme -->
<script src="../theme.js"></script>
<script src="../prism.js"></script>
<!-- Theme Picker and Prism Theme -->
<!-- End scripts/rustdoc-after.html -->
</body>
</html>