-
Notifications
You must be signed in to change notification settings - Fork 4
Add Rust version #13
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Add Rust version #13
Changes from all commits
2f9f5f0
89b6d9f
e1029a6
b32f242
1ccb36c
4f518b4
1d59284
51a01d1
1a97195
49dbe79
4efefdf
260cd84
b72c26f
30edcdb
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| [target.x86_64-unknown-linux-gnu] | ||
| linker = "x86_64-linux-gnu-gcc" | ||
| rustflags = [ | ||
| "-Clink-args=-nostartfiles", | ||
| "-Clink-args=-Wl,-n,-N,--no-dynamic-linker,--build-id=none", | ||
| "-Crelocation-model=static" | ||
| ] | ||
|
|
||
| [target.aarch64-unknown-linux-gnu] | ||
| linker = "aarch64-linux-gnu-gcc" | ||
| rustflags = [ | ||
| "-Clink-args=-nostartfiles", | ||
| "-Clink-args=-Wl,-n,-N,--no-dynamic-linker,--build-id=none", | ||
| "-Crelocation-model=static" | ||
| ] |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| FROM mcr.microsoft.com/devcontainers/rust:1-bookworm | ||
|
|
||
| RUN apt-get update \ | ||
| && apt-get install -y \ | ||
| binutils-aarch64-linux-gnu binutils-x86-64-linux-gnu \ | ||
| gcc-aarch64-linux-gnu gcc-x86-64-linux-gnu \ | ||
| make nasm qemu-user-static \ | ||
| && rm -rf /var/lib/apt/lists/* |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| // For format details, see https://aka.ms/devcontainer.json. For config options, see the | ||
| // README at: https://github.com/devcontainers/templates/tree/main/src/rust | ||
| { | ||
| "name": "Rust", | ||
| // Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile | ||
| "dockerFile": "Dockerfile", | ||
|
|
||
| // Use 'mounts' to make the cargo cache persistent in a Docker Volume. | ||
| // "mounts": [ | ||
| // { | ||
| // "source": "devcontainer-cargo-cache-${devcontainerId}", | ||
| // "target": "/usr/local/cargo", | ||
| // "type": "volume" | ||
| // } | ||
| // ] | ||
|
|
||
| // Features to add to the dev container. More info: https://containers.dev/features. | ||
| // "features": {}, | ||
|
|
||
| // Use 'forwardPorts' to make a list of ports inside the container available locally. | ||
| // "forwardPorts": [], | ||
|
|
||
| // Use 'postCreateCommand' to run commands after the container is created. | ||
| "postCreateCommand": "rustc --version" | ||
|
|
||
| // Configure tool-specific properties. | ||
| // "customizations": {}, | ||
|
|
||
| // Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root. | ||
| // "remoteUser": "root" | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| # To get started with Dependabot version updates, you'll need to specify which | ||
| # package ecosystems to update and where the package manifests are located. | ||
| # Please see the documentation for more information: | ||
| # https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates | ||
| # https://containers.dev/guide/dependabot | ||
|
|
||
| version: 2 | ||
| updates: | ||
| - package-ecosystem: "devcontainers" | ||
| directory: "/" | ||
| schedule: | ||
| interval: weekly |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,41 +1,25 @@ | ||
| name: Build & Test | ||
| on: | ||
| - push | ||
| push: | ||
| branches: [ main, rust ] | ||
| pull_request: | ||
| branches: [ main ] | ||
|
|
||
| jobs: | ||
| build: | ||
| runs-on: ubuntu-latest | ||
| timeout-minutes: 10 | ||
| steps: | ||
| - name: Checkout Repo | ||
| uses: actions/checkout@v2 | ||
|
|
||
| - name: Install dependencies | ||
| run: | | ||
| sudo apt-get update -y | ||
| sudo apt-get install -y make nasm binutils binutils-aarch64-linux-gnu | ||
| uses: actions/checkout@v5 | ||
|
|
||
| - name: Build via Makefile | ||
| run: make ci_build | ||
| - name: Build and run Dev Container task | ||
| uses: devcontainers/ci@v0.3 | ||
| with: | ||
| runCmd: make -s ci_tests | ||
|
|
||
| - name: Public artifact | ||
| uses: actions/upload-artifact@v1 | ||
| - name: Publish artifact | ||
| uses: actions/upload-artifact@v4 | ||
| with: | ||
| name: Build Artifact | ||
| path: out/ | ||
|
|
||
| test: | ||
| runs-on: ubuntu-latest | ||
| timeout-minutes: 10 | ||
| steps: | ||
| - name: Checkout Repo | ||
| uses: actions/checkout@v2 | ||
|
|
||
| - name: Install dependencies | ||
| run: | | ||
| sudo apt-get update -y | ||
| sudo apt-get install -y make nasm binutils binutils-aarch64-linux-gnu | ||
| sudo wget https://github.com/multiarch/qemu-user-static/releases/download/v7.1.0-2/qemu-aarch64-static -O /usr/sbin/qemu-aarch64-static | ||
| sudo chmod +x /usr/sbin/qemu-aarch64-static | ||
|
|
||
| - name: Run Tests | ||
| run: make ci_tests |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,2 +1,3 @@ | ||
| .idea | ||
| out/ | ||
| target/ |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| [workspace] | ||
| resolver = "2" | ||
| members = ["rs-nap"] | ||
|
|
||
| [profile.release] | ||
| strip = true | ||
| opt-level = "z" | ||
| codegen-units = 1 | ||
| panic = "abort" | ||
| lto = true |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| [package] | ||
| name = "rs-nap" | ||
| version = "0.1.0" | ||
| edition = "2021" | ||
|
|
||
| # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html | ||
|
|
||
| [dependencies] |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,60 @@ | ||
| # Rust rewrite | ||
|
|
||
| ## Goals | ||
|
|
||
| ### Feature parity | ||
|
|
||
| - [x] Maintain roughly the same binary size | ||
| - [x] Zero requirements other than the linux kernel | ||
| - [x] Increased readability over assembly | ||
| - [x] Shared code base for all architectures | ||
|
|
||
| ### Architecture support | ||
|
|
||
| - [x] x86_64 implementation | ||
| - [x] aarch64 implementation | ||
|
|
||
| #### Architecture specific implementation notes | ||
|
|
||
| For each new architecture: | ||
|
|
||
| 1. Add a file to the `support` subfolder which implements | ||
| - The startup code (`_start`) to get arguments from the stack | ||
| - and the following linux kernel service calls | ||
| - `sys_exit` to call `exit` | ||
| - `sys_write` to call `write` to stdout 1 | ||
| - and `sys_sleep` | ||
| 2. Add a platform specific entry to `support.rs` in the form of a `cfg_attr` | ||
| 3. Add a platform target to `.cargo/config.toml` | ||
| 4. Add a toolchain target to `rust-toolchain.toml` | ||
| 5. Update this `README.md` with the new platform build and run commands | ||
| 6. Update any CI/CD (future) to build the binary for the target platform | ||
|
|
||
| ## Run on a native processor | ||
|
|
||
| ```sh | ||
| # Build | ||
| cargo build --release | ||
| # Display file size | ||
| ls -lah ./target/release/rs-nap | ||
| # Run for 3 seconds | ||
| ./target/release/rs-nap 3 | ||
| ``` | ||
|
|
||
| ## Run on an emulated processor | ||
|
|
||
| ```sh | ||
| # Install cross compiler and emulation layer | ||
|
|
||
| # Debian-based distros | ||
| sudo apt -y install gcc-aarch64-linux-gnu binutils-aarch64-linux-gnu qemu-user-static | ||
| ``` | ||
|
|
||
| ```sh | ||
| # Build | ||
| cargo build --target aarch64-unknown-linux-gnu --release | ||
| # Display file size | ||
| ls -lah target/aarch64-unknown-linux-gnu/release/rs-nap | ||
| # Run for 3 seconds | ||
| qemu-aarch64-static target/aarch64-unknown-linux-gnu/release/rs-nap 3 | ||
| ``` |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,52 @@ | ||
| #![no_std] | ||
| #![no_main] | ||
|
|
||
| mod support; | ||
| use support::*; | ||
| use core::slice::from_raw_parts as mkslice; | ||
|
|
||
| #[no_mangle] | ||
| pub unsafe fn nap(args: &[*const u8]) -> ! { | ||
| let mut sleep_time:usize = 10; | ||
| let mut good_input:bool = false; | ||
|
|
||
| if args.len() > 1 { | ||
| (sleep_time, good_input) = get_sleep_time(args[1]); | ||
| } | ||
|
|
||
| sleep(sleep_time, good_input); | ||
|
|
||
| print_str(b"Done!\n"); | ||
| sys_exit(0) | ||
| } | ||
|
|
||
| pub unsafe fn sleep(mut sleep_time: usize, good_input: bool) { | ||
| if good_input == false { | ||
| sleep_time = 10; | ||
| print_str(b"Bad input. "); | ||
| } | ||
|
|
||
| print_str(b"Sleeping for "); | ||
| print_num(sleep_time); | ||
| print_str(b" seconds...\n"); | ||
|
|
||
| sys_sleep(sleep_time); | ||
| } | ||
|
|
||
| unsafe fn get_sleep_time(arg: *const u8) -> (usize, bool) { | ||
| let (seconds,_) = from_radix_10(mkslice(arg, strlen(arg))); | ||
| (seconds, seconds > 0 && seconds < 1000000000) | ||
| } | ||
|
|
||
| #[no_mangle] | ||
| unsafe fn get_args(stack_top: *const u8) { | ||
| let argc = *(stack_top as *const usize); | ||
| let argv = stack_top.add(8) as *const *const u8; | ||
| let args = mkslice(argv, argc as usize); | ||
| nap(args) | ||
| } | ||
|
|
||
| #[panic_handler] | ||
| unsafe fn my_panic(_info: &core::panic::PanicInfo) -> ! { | ||
| sys_exit(255) | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,17 @@ | ||
| #[cfg(all(target_arch="x86_64", target_os="linux"))] | ||
| #[path="support/x86_64.rs"] | ||
| mod arch_support; | ||
|
|
||
| #[cfg(all(target_arch="aarch64", target_os="linux"))] | ||
| #[path="support/aarch64.rs"] | ||
| mod arch_support; | ||
|
|
||
| #[cfg(not(target_os="linux"))] | ||
| #[path="support/generic.rs"] | ||
| mod arch_support; | ||
|
|
||
| pub use arch_support::*; | ||
|
|
||
| #[path="support/noarch.rs"] | ||
| mod noarch; | ||
| pub use noarch::*; |
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,47 @@ | ||||||
| use core::arch::{asm,naked_asm}; | ||||||
|
|
||||||
| mod interop; | ||||||
| use interop::timespec; | ||||||
|
|
||||||
| #[no_mangle] | ||||||
| #[unsafe(naked)] | ||||||
| unsafe extern "C" fn _start() { | ||||||
| // Move the stack pointer before it gets clobbered | ||||||
| naked_asm!( | ||||||
| "mov fp, sp", | ||||||
| "mov x0, fp", | ||||||
| "bl get_args" | ||||||
| ) | ||||||
| } | ||||||
|
|
||||||
| pub unsafe fn sys_exit(exit_code:usize) -> ! { | ||||||
| asm!("svc 0", | ||||||
| in("w8") 93, | ||||||
| in("x0") exit_code, | ||||||
| options(nostack, noreturn) | ||||||
| ) | ||||||
| } | ||||||
|
|
||||||
| pub unsafe fn sys_write(buffer: *const u8, count: usize) { | ||||||
| asm!("svc #0", | ||||||
|
||||||
| asm!("svc #0", | |
| asm!("svc 0", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[nitpick] Comparing boolean values with
== falseis not idiomatic in Rust. Use!good_inputinstead.