Skip to content

Commit

Permalink
Add built-in swtfb client and enable musl builds on rM 2 (#78)
Browse files Browse the repository at this point in the history
Co-authored-by: Pierre Fenoll <pierrefenoll@gmail.com>
  • Loading branch information
LinusCDE and fenollp committed Dec 8, 2021
1 parent f2fd996 commit 33033a9
Show file tree
Hide file tree
Showing 13 changed files with 481 additions and 101 deletions.
42 changes: 29 additions & 13 deletions .github/workflows/build.yml
@@ -1,8 +1,7 @@
on: [push, pull_request]

name: Continuous integration

jobs:

check:
name: Check
runs-on: ubuntu-latest
Expand All @@ -11,33 +10,47 @@ jobs:
- uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: nightly
target: armv7-unknown-linux-gnueabihf
toolchain: stable
target: ${{ env.TARGET }}
override: true
components: rustfmt
- uses: actions-rs/cargo@v1
with:
command: check
use-cross: true
args: --target armv7-unknown-linux-gnueabihf
args: --target ${{ env.TARGET }}

test:
name: Test Suite
name: Test Suite on gnueabihf
runs-on: ubuntu-latest
env:
TARGET: armv7-unknown-linux-gnueabihf
steps:
- uses: actions/checkout@v2
- uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: nightly
target: armv7-unknown-linux-gnueabihf
toolchain: stable
target: ${{ env.TARGET }}
override: true
components: rustfmt
- uses: actions-rs/cargo@v1
with:
command: test
use-cross: true
args: --target armv7-unknown-linux-gnueabihf
args: --target ${{ env.TARGET }}
test-local:
name: Test Suite
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: stable
- uses: actions-rs/cargo@v1
with:
command: test

fmt:
name: Rustfmt
Expand All @@ -47,8 +60,8 @@ jobs:
- uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: nightly
target: armv7-unknown-linux-gnueabihf
toolchain: stable
target: ${{ env.TARGET }}
override: true
components: rustfmt
- uses: actions-rs/cargo@v1
Expand All @@ -65,11 +78,14 @@ jobs:
with:
profile: minimal
toolchain: stable
target: armv7-unknown-linux-gnueabihf
target: ${{ env.TARGET }}
override: true
components: rustfmt, clippy
- uses: actions-rs/cargo@v1
with:
command: clippy
use-cross: true
args: --target armv7-unknown-linux-gnueabihf -- -D warnings
args: --target ${{ env.TARGET }} -- -D warnings

env:
TARGET: armv7-unknown-linux-musleabihf
22 changes: 12 additions & 10 deletions .github/workflows/demo.yml
Expand Up @@ -3,15 +3,16 @@ name: Build for reMarkable
jobs:

demo:
name: Demo
name: Demo with gnueabihf
runs-on: ubuntu-latest
env:
TARGET: armv7-unknown-linux-gnueabihf
steps:
- uses: actions/checkout@v2
- uses: actions-rs/toolchain@v1
with:
toolchain: nightly
profile: minimal
toolchain: stable
target: ${{ env.TARGET }}
override: true
components: rustfmt
Expand All @@ -20,13 +21,6 @@ jobs:
use-cross: true
command: build
args: --target ${{ env.TARGET }} --release --example demo
- uses: softprops/action-gh-release@v1
if: startsWith(github.ref, 'refs/tags/')
with:
files: |
./target/${{ env.TARGET }}/release/demo
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

demo-with-musl:
name: Demo with musl
Expand All @@ -37,7 +31,8 @@ jobs:
- uses: actions/checkout@v2
- uses: actions-rs/toolchain@v1
with:
toolchain: nightly
profile: minimal
toolchain: stable
target: ${{ env.TARGET }}
override: true
components: rustfmt
Expand All @@ -46,3 +41,10 @@ jobs:
use-cross: true
command: build
args: --target ${{ env.TARGET }} --release --example demo
- uses: softprops/action-gh-release@v1
if: startsWith(github.ref, 'refs/tags/')
with:
files: |
./target/${{ env.TARGET }}/release/demo
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
5 changes: 5 additions & 0 deletions Cargo.toml
Expand Up @@ -41,6 +41,11 @@ name = "spy"
path = "examples/spy.rs"
crate-type = ["dylib"]

[[example]]
name = "swtfb_sysv_spy"
path = "examples/swtfb_sysv_spy.rs"
crate-type = ["dylib"]

[[example]]
name = "demo"
path = "examples/demo.rs"
Expand Down
14 changes: 7 additions & 7 deletions Makefile
@@ -1,5 +1,5 @@
# For musl, use: armv7-unknown-linux-musleabihf
TARGET ?= armv7-unknown-linux-gnueabihf
# For non-musl, use: armv7-unknown-linux-gnueabihf
TARGET ?= armv7-unknown-linux-musleabihf

DEVICE_IP ?= '10.11.99.1'
DEVICE_HOST ?= root@$(DEVICE_IP)
Expand All @@ -8,10 +8,10 @@ all: library examples

.PHONY: examples
examples:
cargo build --examples --release --target=$(TARGET)
cargo build --examples --release --target=armv7-unknown-linux-gnueabihf

demo:
cargo build --example demo --release --target=$(TARGET)
cargo build --example demo --release --target=armv7-unknown-linux-gnueabihf

x-demo:
cross build --example demo --release --target=$(TARGET)
Expand All @@ -22,7 +22,7 @@ deploy-x-demo: x-demo
ssh $(DEVICE_HOST) 'RUST_BACKTRACE=1 RUST_LOG=debug ./demo'

bench:
cargo build --examples --release --target=$(TARGET) --features "enable-runtime-benchmarking"
cargo build --examples --release --target=armv7-unknown-linux-gnueabihf --features "enable-runtime-benchmarking"

.PHONY: docker-env
docker-env:
Expand All @@ -42,10 +42,10 @@ examples-docker: docker-env
-v cargo-registry:/home/builder/.cargo/registry \
-w /home/builder/libremarkable \
rust-build-remarkable:latest \
cargo build --examples --release --target=$(TARGET)
cargo build --examples --release --target=armv7-unknown-linux-gnueabihf

library:
cargo build --release --target=$(TARGET)
cargo build --release --target=armv7-unknown-linux-gnueabihf

test:
# Notice we aren't using the armv7 target here
Expand Down
11 changes: 6 additions & 5 deletions README.md
Expand Up @@ -77,18 +77,19 @@ The `--release` argument is important as this enables optimizations and without
#### Building with [`cross`](https://github.com/rust-embedded/cross)
*Building this way does not require reMarkable's toolchain nor building on Ubuntu 16.04 with Docker so setting up should be easier.*

Install `cross` with `cargo install cross`. Make sure the reMarkable toolchain is not in use first.

To build, deploy and run the `demo`, simply:
```shell
make deploy-x-demo
make TARGET=armv7-unknown-linux-gnueabihf deploy-x-demo
# This builds with
# cross build --example demo --release --target=armv7-unknown-linux-gnueabihf
# then deploys the demo
```
##### Using [`musl`](https://musl.libc.org/)
Make sure to build with `lto = true` otherwise `musl` symbols may be improperly resolved (call to `mmap` fails).

1. Install `cross` with `cargo install cross` (make sure the reMarkable toolchain is not in use first)
1. Compile with `cross build --example demo --release --target=armv7-unknown-linux-musleabihf` (or `TARGET=armv7-unknown-linux-musleabihf make x-demo`)
1. Run the demo: `TARGET=armv7-unknown-linux-musleabihf make deploy-x-demo`
1. Compile with `cross build --example demo --release --target=armv7-unknown-linux-musleabihf` (or `make x-demo`)
1. Run the demo: `make deploy-x-demo`

**Regarding apps for the rM2**: `musl`-built apps do not write to the framebuffer of rM2 devices as some work is required regarding `LD_PRELOAD` to enable the use of [`rm2fb`](https://github.com/ddvk/remarkable2-framebuffer). In the meantime you should use the `gnueabihf` target.
**Regarding apps for the rM2**: you will need the [display](https://github.com/ddvk/remarkable2-framebuffer) package from [Toltec](https://toltec-dev.org/). Only the server part though as the client is built into this lib.
49 changes: 49 additions & 0 deletions examples/swtfb_sysv_spy.rs
@@ -0,0 +1,49 @@
use libc::{c_int, c_void, key_t, msqid_ds, size_t};
use redhook::{hook, real};

use libremarkable::framebuffer::swtfb_client;

hook! {
unsafe fn msgget(key: key_t, msgflg: c_int) -> c_int => msgget_spy {
let res = real!(msgget)(key, msgflg);
eprintln!("Spy: msgget({:#x}, {:#x}) => {:#x}", key, msgflg, res);
res
}
}

hook! {
unsafe fn msgctl(msqid: c_int, cmd: c_int, buf: *mut msqid_ds) -> c_int => msgctl_spy {
let res = real!(msgctl)(msqid, cmd, buf);
eprintln!("Spy: msgctl({:#x}, {:#x}, {:?}) => {}", msqid, cmd, buf, res);
res
}
}

hook! {
unsafe fn msgsnd(msqid: c_int, msgp: *const c_void, msgsz: size_t, msgflg: c_int) -> c_int => msgsnd_spy {
let res = real!(msgsnd)(msqid, msgp, msgsz, msgflg);
eprintln!("Spy: msgsnd({:#x}, {:?}, {}, {:#x}) => {}", msqid, msgp, msgsz, msgflg, res);
if msgsz == std::mem::size_of::<swtfb_client::swtfb_update>() {
let msg = &*(msgp as *const swtfb_client::swtfb_update);
eprintln!("Spy: msgsnd: Message: swt_update.mtype: {:?}, data: ... }}", msg.mtype);
let data_str_formatted = match msg.mtype {
swtfb_client::MSG_TYPE::INIT_t => {
format!("...")
},
swtfb_client::MSG_TYPE::UPDATE_t => {
format!("{:?}", msg.data.update)
},
swtfb_client::MSG_TYPE::XO_t => {
format!("{:?}", msg.data.xochitl_update)
},
swtfb_client::MSG_TYPE::WAIT_t => {
format!("{:?}", msg.data.wait_update)
}
};
eprintln!("Spy: msgsnd: Message: swt_update.data: {}", data_str_formatted);
}else {
eprintln!("Spy: msgsnd: Error: Message is not sizeof(swtfb_update) (expected {}, got {})", std::mem::size_of::<swtfb_client::swtfb_update>(), msgsz)
}
res
}
}
4 changes: 3 additions & 1 deletion src/appctx.rs
Expand Up @@ -86,7 +86,9 @@ impl<'a> ApplicationContext<'a> {
on_wacom: fn(&mut ApplicationContext<'_>, WacomEvent),
on_touch: fn(&mut ApplicationContext<'_>, MultitouchEvent),
) -> ApplicationContext<'static> {
let framebuffer = Box::new(core::Framebuffer::from_path("/dev/fb0"));
let framebuffer = Box::new(core::Framebuffer::from_path(
crate::device::CURRENT_DEVICE.get_framebuffer_path(),
));
let yres = framebuffer.var_screen_info.yres;
let xres = framebuffer.var_screen_info.xres;

Expand Down
20 changes: 20 additions & 0 deletions src/device.rs
Expand Up @@ -31,6 +31,22 @@ impl Model {
Err(ErrorKind::UnknownVersion(machine_name.to_owned()))
}
}

/// Path for gen 1 can be used as long as the rm2fb shim is active:
/// LD_PRELOAD="/opt/lib/librm2fb_client.so.1" <YOUR_BINARY> or
/// rm2fb-client YOUR_BINARY
/// https://github.com/ddvk/remarkable2-framebuffer/
/// If `/dev/shm/swtfb.01` is used for the framebuffer, the
/// internal swtfb_client will be used. This enables the use
/// of musl builds. But the rm2fb server must still be installed.
///
/// TODO: Use proper path (needs breaking change for FramebufferBase::from_path() !)
pub fn framebuffer_path(&self) -> &'static str {
match self {
Model::Gen1 => "/dev/fb0",
Model::Gen2 => "/dev/shm/swtfb.01",
}
}
}

pub static CURRENT_DEVICE: Lazy<Device> = Lazy::new(Device::new);
Expand Down Expand Up @@ -118,4 +134,8 @@ impl Device {
Model::Gen2 => "max77818_battery",
}
}

pub fn get_framebuffer_path(&self) -> &'static str {
self.model.framebuffer_path()
}
}

0 comments on commit 33033a9

Please sign in to comment.