|
4 | 4 |
|
5 | 5 | This project provides a minimal QNX 8.0 image designed to run on x86_64 QEMU virtual machines. It's specifically configured for the Eclipse SCORE (Safety Critical Object-Oriented Real-time Embedded) project, offering a lightweight yet functional QNX environment suitable for development, testing, and demonstration purposes. |
6 | 6 |
|
| 7 | +## Quick Start Guide |
| 8 | + |
| 9 | +### 1. Prerequisites |
| 10 | + |
| 11 | +Before starting, ensure the following tools are available on your Linux host: |
| 12 | + |
| 13 | +- **Bazel** |
| 14 | +- **QEMU** (with `qemu-bridge-helper` installed at `/usr/lib/qemu/qemu-bridge-helper`) |
| 15 | +- Valid **QNX SDP 8.0 license** from <https://www.qnx.com/>. See this YT video for more info <https://www.youtube.com/watch?v=DtWA5E-cFCo> |
| 16 | + |
| 17 | +### 2. Installation/ Configuration |
| 18 | + |
| 19 | +- **Clone the integration & toolchain repos** |
| 20 | + |
| 21 | +```bash |
| 22 | +git clone https://github.com/eclipse-score/reference_integration.git |
| 23 | +git clone https://github.com/eclipse-score/toolchains_qnx.git |
| 24 | +cd reference_integration/qnx_qemu |
| 25 | +``` |
| 26 | + |
| 27 | +Toolchain repo contains the Bazel rules and credential helper used to download and register the QNX SDP toolchain. |
| 28 | + |
| 29 | +- **Provide QNX download credentials** |
| 30 | + |
| 31 | +You can pass credentials via environment variables. |
| 32 | + |
| 33 | +```bash |
| 34 | +export SCORE_QNX_USER="<qnx_username>" |
| 35 | +export SCORE_QNX_PASSWORD="<qnx_password>" |
| 36 | +``` |
| 37 | + |
| 38 | +- **Download QNX Software Center for Linux** |
| 39 | + |
| 40 | +**Using GUI:** |
| 41 | + |
| 42 | +Download **QNX Software Center 2.0.4 Build 202501021438 - Linux Hosts** from the [QNX Software Center page](https://www.qnx.com/download/group.html?programid=29178), then install it. |
| 43 | + |
| 44 | +**Using CLI:** |
| 45 | + |
| 46 | +URL to installer must be determined manually: |
| 47 | + |
| 48 | +- Go to [QNX page]<https://blackberry.qnx.com/en> and log in using "SIGN IN". |
| 49 | + |
| 50 | +- Go to [QNX Software Center page]<https://www.qnx.com/download/group.html?programid=29178>. |
| 51 | + |
| 52 | +- Scroll down and click the link labeled `QNX Software Center <VERSION> Build <BUILD_NUMBER> - Linux Hosts`. |
| 53 | + |
| 54 | +- Right-click "Download Now" button and copy the installer URL. |
| 55 | + |
| 56 | +- Verify installer checksum after download! |
| 57 | + |
| 58 | +```bash |
| 59 | +# Create directory. |
| 60 | +mkdir ~/.qnx |
| 61 | +# Log-in and download installer. |
| 62 | +curl -v --cookie-jar ~/.qnx/myqnxcookies.auth --form "userlogin=$SCORE_QNX_USER" --form "password=$SCORE_QNX_PASSWORD" https://www.qnx.com/account/login.html -o login_response.html |
| 63 | +curl -v -L --cookie ~/.qnx/myqnxcookies.auth installer_URL > qnx-setup-lin.run |
| 64 | +# Verify checksum. |
| 65 | +sha256sum qnx-setup-lin.run |
| 66 | +# Make the installer executable. |
| 67 | +chmod +x ./qnx-setup-lin.run |
| 68 | +# Run installer. |
| 69 | +~/qnx-setup-lin.run force-override disable-auto-start agree-to-license-terms ~/qnxinstall |
| 70 | +``` |
| 71 | + |
| 72 | +- **Download QNX SDP 8.0** |
| 73 | + |
| 74 | +**Using GUI:** |
| 75 | + |
| 76 | +Using **QNX Software Center - Linux Hosts** we previously installed , install **QNX Software Development Platform 8.0**. |
| 77 | + |
| 78 | +**Using CLI:** |
| 79 | + |
| 80 | +```bash |
| 81 | +cd ~/qnxinstall/qnxsoftwarecenter |
| 82 | +./qnxsoftwarecenter_clt -syncLicenseKeys -myqnx.user="$SCORE_QNX_USER" -myqnx.password="$SCORE_QNX_PASSWORD" -addLicenseKey license_key -listLicenseKeys |
| 83 | +./qnxsoftwarecenter_clt -mirrorBaseline="qnx800" -myqnx.user="$SCORE_QNX_USER" -myqnx.password="$SCORE_QNX_PASSWORD" |
| 84 | +./qnxsoftwarecenter_clt -cleanInstall -destination ~/qnx800 -installBaseline com.qnx.qnx800 -myqnx.user="$SCORE_QNX_USER" -myqnx.password="$SCORE_QNX_PASSWORD" |
| 85 | +cd - > /dev/null |
| 86 | +``` |
| 87 | + |
| 88 | +This contains the toolchains and `license` folder required for activation. |
| 89 | +check this QNX link for more info <https://www.qnx.com/developers/docs/qsc/com.qnx.doc.qsc.inst_larg_org/topic/create_headless_installation_linux_macos.html> |
| 90 | + |
| 91 | +- **Source SDP environment** |
| 92 | + |
| 93 | +```bash |
| 94 | +source ~/qnx800/qnxsdp-env.sh |
| 95 | +#The commands below confirm the environment was sourced successfully. |
| 96 | +echo "$QNX_HOST" "$QNX_TARGET" |
| 97 | +``` |
| 98 | + |
| 99 | +- **Register QNX license** |
| 100 | + |
| 101 | +```bash |
| 102 | +sudo mkdir -p /opt/score_qnx/license |
| 103 | +sudo cp ~/.qnx/license/licenses /opt/score_qnx/license/licenses |
| 104 | +sudo chmod 644 /opt/score_qnx/license/licenses |
| 105 | +``` |
| 106 | + |
| 107 | +OR we can use symbolic linking |
| 108 | + |
| 109 | +```bash |
| 110 | +sudo install -d -m 755 /opt/score_qnx/license |
| 111 | +LIC_SRC="$(readlink -f "$HOME/.qnx/license/licenses")" |
| 112 | +sudo ln -sfn "$LIC_SRC" /opt/score_qnx/license/licenses |
| 113 | +chmod 644 "$LIC_SRC" |
| 114 | +``` |
| 115 | + |
| 116 | +- **Configure QEMU networking** |
| 117 | + |
| 118 | +to allow QEMU bridge helper to create TAP devices and to make sure **TUN** is available: |
| 119 | + |
| 120 | +Give qemu-bridge-helper the required capabilities. |
| 121 | + |
| 122 | +Make sure that bridge virbr0 is installed for successful QEMU startup |
| 123 | + |
| 124 | +```bash |
| 125 | +sudo apt update |
| 126 | +sudo apt install -y libvirt-daemon-system qemu-kvm |
| 127 | +sudo systemctl enable --now libvirtd |
| 128 | +sudo virsh net-define /usr/share/libvirt/networks/default.xml || true |
| 129 | +sudo virsh net-autostart default |
| 130 | +sudo virsh net-start default |
| 131 | +``` |
| 132 | + |
| 133 | +Create /etc/qemu if it doesn’t exist. |
| 134 | + |
| 135 | +```bash |
| 136 | +sudo install -d -m 755 /etc/qemu |
| 137 | +echo "allow virbr0" | sudo tee /etc/qemu/bridge.conf |
| 138 | +``` |
| 139 | + |
| 140 | +On Debian/Ubuntu (most common path): |
| 141 | + |
| 142 | +```bash |
| 143 | +sudo setcap cap_net_admin,cap_net_raw+ep /usr/lib/qemu/qemu-bridge-helper |
| 144 | +``` |
| 145 | + |
| 146 | +Verify: |
| 147 | + |
| 148 | +```bash |
| 149 | +getcap /usr/lib/qemu/qemu-bridge-helper |
| 150 | +# or |
| 151 | +getcap /usr/libexec/qemu-bridge-helper |
| 152 | +``` |
| 153 | + |
| 154 | +You should see: |
| 155 | + |
| 156 | +```bash |
| 157 | +/usr/lib/qemu/qemu-bridge-helper = cap_net_admin,cap_net_raw+ep |
| 158 | +``` |
| 159 | + |
| 160 | +Enable TUN device |
| 161 | + |
| 162 | +Make sure the TUN kernel module is loaded: |
| 163 | + |
| 164 | +```bash |
| 165 | +sudo modprobe tun |
| 166 | +``` |
| 167 | + |
| 168 | +Check that the device exists: |
| 169 | + |
| 170 | +```bash |
| 171 | +ls -l /dev/net/tun |
| 172 | +``` |
| 173 | + |
| 174 | +If successful, you’ll see: |
| 175 | + |
| 176 | +```bash |
| 177 | +crw-rw-rw- 1 root root 10, 200 ... /dev/net/tun |
| 178 | +``` |
| 179 | + |
| 180 | +### 3. Build & run the QNX image on qemu |
| 181 | + |
| 182 | +Run Bazel with the credential helper: |
| 183 | + |
| 184 | +```bash |
| 185 | +bazel build --config=x86_64-qnx \ |
| 186 | + --credential_helper=*.qnx.com=$(pwd)/../toolchains_qnx/tools/qnx_credential_helper.py \ |
| 187 | + //build:init |
| 188 | +``` |
| 189 | + |
| 190 | +- First run downloads ~1.6 GiB of QNX SDP |
| 191 | + |
| 192 | +- Resulting IFS: `bazel-bin/build/init.ifs` |
| 193 | + |
| 194 | +at this stage Build shall succeed. |
| 195 | + |
| 196 | +- **Run QNX in QEMU** |
| 197 | + |
| 198 | +verify bridge virbr0 is up and running |
| 199 | + |
| 200 | +```bash |
| 201 | +ip link show virbr0 |
| 202 | +``` |
| 203 | + |
| 204 | +- QEMU can use KVM for near-native performance. The wrapper below auto-enables **KVM** when available and falls back to **TCG** with a visible warning if /dev/kvm isn’t accessible |
| 205 | + |
| 206 | +```bash |
| 207 | +sudo tee /usr/local/bin/qemu-system-x86_64 >/dev/null <<'EOF' |
| 208 | +#!/usr/bin/env bash |
| 209 | +# Smart QEMU shim: auto-enable KVM when possible; warn & fall back otherwise. |
| 210 | +set -euo pipefail |
| 211 | +REAL="${QEMU_BIN:-/usr/bin/qemu-system-x86_64}" |
| 212 | +
|
| 213 | +have_kvm() { |
| 214 | + [[ -e /dev/kvm && -r /dev/kvm && -w /dev/kvm ]] || return 1 |
| 215 | + [[ -d /sys/module/kvm ]] && { [[ -d /sys/module/kvm_intel || -d /sys/module/kvm_amd ]] ; } || true |
| 216 | +} |
| 217 | +
|
| 218 | +args=("$@") |
| 219 | +want_kvm=false |
| 220 | +for a in "${args[@]}"; do |
| 221 | + [[ "$a" == "--enable-kvm" ]] && want_kvm=true |
| 222 | +done |
| 223 | +
|
| 224 | +if have_kvm; then |
| 225 | + $want_kvm || args+=(--enable-kvm) |
| 226 | +else |
| 227 | + # Strip any --enable-kvm and warn |
| 228 | + filtered=() |
| 229 | + for a in "${args[@]}"; do |
| 230 | + [[ "$a" == "--enable-kvm" ]] && continue |
| 231 | + filtered+=("$a") |
| 232 | + done |
| 233 | + args=("${filtered[@]}") |
| 234 | + echo "Warning: KVM not available: /dev/kvm missing or not accessible; using software emulation (TCG)." >&2 |
| 235 | + sleep 2 # fixed 2s pause so the warning is visible |
| 236 | +fi |
| 237 | +
|
| 238 | +exec "$REAL" "${args[@]}" |
| 239 | +EOF |
| 240 | +``` |
| 241 | + |
| 242 | +make the script executable |
| 243 | + |
| 244 | +```bash |
| 245 | +sudo chmod +x /usr/local/bin/qemu-system-x86_64 |
| 246 | +``` |
| 247 | + |
| 248 | +Tip: ensure /usr/local/bin comes before /usr/bin so the wrapper is used: |
| 249 | + |
| 250 | +```bash |
| 251 | +export PATH=/usr/local/bin:$PATH |
| 252 | +hash -r |
| 253 | +``` |
| 254 | + |
| 255 | +- Run QEMU |
| 256 | + |
| 257 | +```bash |
| 258 | +bazel run --config=x86_64-qnx //:run_qemu |
| 259 | +``` |
| 260 | + |
7 | 261 | ## Features |
8 | 262 |
|
9 | 263 | ### Core System Components |
@@ -134,11 +388,12 @@ bazel test --config=qemu-integration //:test_ssh_qemu --test_output=streamed |
134 | 388 | ``` |
135 | 389 |
|
136 | 390 | In order to provide credentials for qnx.com pass to bazel command: |
| 391 | + |
137 | 392 | ```bash |
138 | 393 | --credential_helper=*.qnx.com=<path_to_toolchains-qnx>/tools/qnx_credential_helper.py |
139 | 394 | ``` |
140 | | -See more in [toolchains_qnx README](https://github.com/eclipse-score/toolchains_qnx?tab=readme-ov-file#using-pre-packaged-qnx-80-sdp). |
141 | 395 |
|
| 396 | +See more in [toolchains_qnx README](https://github.com/eclipse-score/toolchains_qnx?tab=readme-ov-file#using-pre-packaged-qnx-80-sdp). |
142 | 397 |
|
143 | 398 | ## Running the System |
144 | 399 |
|
@@ -289,12 +544,14 @@ echo 1 | sudo tee /proc/sys/net/ipv4/ip_forward |
289 | 544 | ``` |
290 | 545 |
|
291 | 546 | In case of failed to parse default acl file /etc/qemu/bridge.conf' |
| 547 | + |
292 | 548 | 1. Check acl of `/etc/qemu/bridge.conf` |
293 | 549 | 2. If file does not exist; create that file and add the following line in it |
294 | 550 | `allow virbr0` |
295 | 551 | 3. Run qemu with Sudo as debug option in case of failure with acl |
296 | 552 |
|
297 | 553 | In case of error "Operation not permitted" for `qemu-bridge-helper` run |
| 554 | + |
298 | 555 | ```bash |
299 | 556 | sudo chmod u+s /usr/lib/qemu/qemu-bridge-helper |
300 | 557 | ``` |
@@ -626,11 +883,13 @@ The system is configured with port forwarding for network analysis: |
626 | 883 | ### Wireshark Analysis Workflow |
627 | 884 |
|
628 | 885 | 1. **Start QNX System**: |
| 886 | + |
629 | 887 | ```bash |
630 | 888 | bazel run --config=x86_64-qnx //:run_qemu_portforward |
631 | 889 | ``` |
632 | 890 |
|
633 | 891 | 2. **Launch Live Capture**: |
| 892 | + |
634 | 893 | ```bash |
635 | 894 | ./scripts/qnx_wireshark.sh wireshark "tcp" |
636 | 895 | ``` |
|
0 commit comments