Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
0d5be98
Initial support for QNX8 QEMU emulation
jgetas Dec 3, 2025
f94b5ba
Split up top level README, replace SDP link with notes
jgetas Dec 5, 2025
1efd176
Fix in qnx8 README
jgetas Dec 15, 2025
afa9716
Add 'external/os_images+' to mkifs build file search path
jgetas Dec 17, 2025
4ebd5cd
Add external build information to README
jgetas Dec 17, 2025
0b09741
Add 'run' bazel target to run the QEMU images
jgetas Dec 17, 2025
4d58f32
Migrate to score_toolchains_qnx 0.0.6
jgetas Dec 17, 2025
7478d8c
Update qnx8/boards/qemu-arm64virt/run-qemu-arm64virt.sh
jgetas Jan 15, 2026
28d54f8
Update qnx8/boards/qemu-arm64virt/run-qemu-arm64virt.sh
jgetas Jan 15, 2026
9c5bc23
Update qnx8/README.md
jgetas Jan 15, 2026
44da728
Update qnx8/boards/qemu-x86_64/run-qemu-x86_64.sh
jgetas Jan 15, 2026
8823729
Add fsevmgr for inotify* support
jgetas Jan 19, 2026
ac6ba69
add sdp from artifactory
kgraeper Jan 13, 2026
46a0698
fix license-check workflow introduce configs for bazel
kgraeper Jan 19, 2026
94888a4
Add fixed bazel version
jgetas Jan 27, 2026
ffa3724
Fix inotify: launch fsevmgr before block device driver
jgetas Jan 28, 2026
3342899
QNX8 qemu: change virtual disk mount point to /opt/score
jgetas Feb 17, 2026
b4ef597
Add visibility attribute to qnx_ifs for qemu ARM64 and x86_64 builds
jgetas Mar 2, 2026
0e686c7
qnx8 qemu: migrate to rules_imagefs
jgetas Mar 20, 2026
10a40bc
Add dev_dependency true for register_toolchains
RacheleSetto Mar 24, 2026
83aaac0
Increase timeout value
RacheleSetto Mar 24, 2026
6238b05
qnx8: use current QNX provided SDP
jgetas Mar 26, 2026
e7c61d9
Merge branch 'main' into feature/initial_qnx_support
jgetas Mar 26, 2026
23adc4e
reinstalling project_config to fix license check
jgetas Mar 26, 2026
6d7448d
fix review findings
jgetas Mar 26, 2026
d43dfb1
Update qnx8/README.md
jgetas Mar 26, 2026
7e77555
add EOL at EOF, remove superfluous register_toolchain()
jgetas Mar 27, 2026
8e81222
Improved README
jgetas Mar 27, 2026
3f31ccf
Use rules_images 0.0.2
jgetas Mar 30, 2026
f8fea10
Update bazelversion, doc and x86_64 run script changes
jgetas Mar 31, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions .bazelrc
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,19 @@ test --test_output=errors

common --registry=https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/
common --registry=https://bcr.bazel.build
common --host_platform=@score_bazel_platforms//:x86_64-linux

# ------------------------------------------------------------------------------
# QNX toolchain settings
# Common QNX build settings

# mkifs is not a target platform specific tool, the host would be sufficient. But there is only
# target platform specific toolchains defined for QNX in this repo.
# Use --config=qnx8_0 for QNX platform builds
common:qnx8_0 --incompatible_strict_action_env
common:qnx8_0 --sandbox_writable_path=/var/tmp

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please use name as in other repos ie arm64-qnx8

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I could do this but this is supposed to be used for x86_64 as well, because it is independent from target architecture - just using the host sdp. I did not want to create 2 configs with duplicate content.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if " score_qnx_ifs_toolchain//:ifs-aarch64-qnx-sdp_8.0.0" is host x86 and target qnx8 arch/x86(is it ?) then why not the same here ?

common:qnx8_0 --platforms=@score_bazel_platforms//:aarch64-qnx-sdp_8.0.0-posix
common:qnx8_0 --credential_helper=*.qnx.com=%workspace%/tools/qnx_credential_helper.py
Comment thread
jgetas marked this conversation as resolved.

build:qnx8_0 --extra_toolchains=@score_qnx_ifs_toolchain//:ifs-aarch64-qnx-sdp_8.0.0

2 changes: 1 addition & 1 deletion .bazelversion
Original file line number Diff line number Diff line change
@@ -1 +1 @@
8.3.0
8.4.2
2 changes: 1 addition & 1 deletion LICENSE.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,4 @@ Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
limitations under the License.
34 changes: 34 additions & 0 deletions MODULE.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,37 @@ module(
version = "1.0",
)

# ------------------------------------------------------------------------------
# QNX toolchains

bazel_dep(name = "score_rules_imagefs", version = "0.0.2")

imagefs = use_extension("@score_rules_imagefs//extensions:imagefs.bzl", "imagefs", dev_dependency = True)
imagefs.sdp(
name = "score_qnx_imagefs_toolchain_pkg",
url = "https://www.qnx.com/download/download/87174/installation_qnx_803_260305.tar.xz",
Comment thread
jgetas marked this conversation as resolved.
sha256 = "9039fd6a4a639f06ea977afb93963a6fe8f8c46db727066709370d999c7232e0",
build_file = "//:sdp.BUILD",

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

its not going to work for others or ? this is dev dep anyway.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

? What do you mean? The sdp.BUILD? I wanted to have this in the rules_imagefs, but Nikola objected. Therefore I had to add it here. The content is IMHO generic for all QNX SDPs. So I don't expect this file will change.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am asking whether each consumer of this repo now needs to have this file ? since imagefs.sdp( is dev_dep here so it not exposed.

)

imagefs.toolchain(
name = "score_qnx_ifs_toolchain",
sdp_to_import = "@score_qnx_imagefs_toolchain_pkg",
sdp_version = "8.0.0",
target_cpu = "aarch64",
target_os = "qnx",
type = "ifs",
)

use_repo(
imagefs,
"score_qnx_imagefs_toolchain_pkg",
"score_qnx_ifs_toolchain",
)

# ------------------------------------------------------------------------------
# General purpose Bazel extensions

# Compliance and licensing toolchain
bazel_dep(name = "score_tooling", version = "1.1.0")
bazel_dep(name = "score_python_basics", version = "0.3.0")
Expand All @@ -23,3 +54,6 @@ bazel_dep(name = "score_python_basics", version = "0.3.0")
bazel_dep(name = "score_format_checker", version = "0.1.1")
bazel_dep(name = "aspect_rules_lint", version = "1.3.1")
bazel_dep(name = "buildifier_prebuilt", version = "7.3.1")

# Platform definitions
bazel_dep(name = "score_bazel_platforms", version = "0.0.3")
28 changes: 26 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,30 @@
# os_images
# OS images

OS Images for testing and deliveries
This module creates OS images intended for testing S-CORE software:

* bootable [QNX IFS images using the QNX 8 SDP](qnx8/README.md).
* bootable Linux image: TODO

**Motivation**

The basic idea is to have generic OS images for *testing* and *verifying* S-CORE binaries. Main purposes:

* re-usable for multiple use cases: unit-, component-, binary- and system tests and demonstrations
* stuffed with common OS utilities: shell-, file-, test utilities
* no need for rebuilding OS images to match the use case - use cases are realized by a separate partition image created by the user/tester which is attached at OS boot time and is containing files required for the use case.

**Features**:

* Launches `sshd` service for remote control (user `root`, empty password by default).
* Supports attaching a user-created file system to `/` (root) in case of QNX. Linux: TODO. By placing some files on this file system the user can make these adaptions:
* Configure hostname and network IP address.
* Add an autostart script launched at the end of the OS startup to start arbitrary tasks.

=> users can focus on creating the file system with content to match their use cases and *use* the OS image of their choice.

## Usage

For detailed instructions on pre-requisites, building, running, and configuring QNX images, see [qnx8/README.md](qnx8/README.md).

## License

Expand Down
5 changes: 5 additions & 0 deletions project_config.bzl
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# project_config.bzl
PROJECT_CONFIG = {
"asil_level": "QM",
"source_code": ["python"],
}
257 changes: 257 additions & 0 deletions qnx8/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,257 @@
# OS images for QNX 8

```
+-------------------+ +- - - - - - - - - - - - - -+
| QNX IFS | | Custom qnx6fs filesystem |
| | | (not part of OS image) |
| (base OS files) | | (user files) |
+-------------------+ +- - - - - - - - - - - - - -+
```

The QNX OS images generated by this repo are intended to be generic images which serve
as a base for custom use-cases like testing. They implement the basic OS services like
block device, network device, system logging, ... support and provide standard QNX
system libraries.

The QNX IFS image is by nature of QNX boot image file system _read-only_. In order
to use it in a custom use case it should be paired with a custom qnx6fs file system which
can either be populated as OS run-time or before-hand by creating a qnx6fs image offline.
See section _Using QNX OS images for custom use-case_ below.

Following QNX 8 OS images can be created:

* QEMU aarch64 "virt" image using virtio block and network drivers.
* QEMU x86_64 image using virtio block and network drivers.

## Using QNX OS images for custom use-case

```
+-------------------+ +---------------------------+
| QNX IFS | | Custom qnx6fs filesystem |
| | | |
| (base OS files) | | (user files) |
+-------------------+ +---------------------------+
| mount point: /opt/score |
+-------------------------------+
```

The QNX OS image generated by this repo is intended to be generic and shall not be modified for custom use cases.
In order to use it for example in a test setup, create a custom partition and put your test files on it.
See the sections below for instructions.
In case of QEMU, add the partition to a disk image and pass it to QEMU. See for example the `run-qemu.sh`:

```
-drive file=$SCORE_DISK,if=none,id=drv0 -device virtio-blk-device,drive=drv0
```

The QNX OS tries to mount the first `qnx6fs` partition on the disk image to `/opt/score`.

### Attaching a user-created QNX6fs file system

The QNX startup script (see `qnx8/boards/<board>/initscript`) calls `mount-fs.sh` which tries to mount a file system to the system.
By default, the partition is mounted at `/` (root) and therefore a user sees a virtual file system with a combination of the IFS and the mounted file system. The path manager resolves path names first on the mounted partition, then on the IFS. This means all files on partition extend or even eclipse files on the IFS. For more information see https://www.qnx.com/developers/docs/8.0/com.qnx.doc.neutrino.sys_arch/topic/proc_Resolving_pathnames.html.

The generated QEMU launch script `run-qemu.sh` attaches a virtual disk `disk-score.qcow2` to the image. If it does not exist, it creates an empty virtual QEMU disk with size of 512MB before launching QEMU.

#### Creating a file system on-line

When starting up the QEMU VM with an empty virtual QEMU disk, no partitions are there. With the following commands you can create a partition and a qnx6fs file system which then gets mounted automatically on following boots:

```bash
# initialize /dev/hd0 with GUID partition table
pted /dev/hd0 init -g
# Create a qnx6fs partition with 99% disk size and name 'scorefs'
pted /dev/hd0 add -t qnx6 -p 99 -n scorefs
# Re-read the partition table
mount -e /dev/hd0
# Create QNX6 file system
mkqnx6fs /dev/hd0.qnx6.0
# Either mount the partition...
mount /dev/hd0.qnx6.0 /opt/score
# ... or reboot to let the partition be mounted automatically at boot time
# shutdown
```

After reboot you'll see in the startup messages that a partition is found and mounted:

```
[...]
---> Mounting file systems
Mounting filesystem /dev/hd0.qnx6.0 to /opt/score
[...]
```

#### Creating a file system offline

A QNX file system can be created on the host using `mkqnx6fsimg` (see https://www.qnx.com/developers/docs/8.0/com.qnx.doc.neutrino.utilities/topic/m/mkqnx6fsimg.html).

The [rules_imagefs](https://github.com/eclipse-score/rules_imagefs) S-CORE module supports creating qnx6fs images by making use of the
QNX SDP utilities like `mkqnx6fsimg`.


## Pre-requisites

### QNX SDP

#### Using the S-CORE QNX SDP package

The default QNX SDP package is set up in the top-level `MODULE.bazel` of this repo. It downloads the package
from `qnx.com`. For being able to do this you need to use your MyQNX account credentials set up in your in
environment variables `SCORE_QNX_USER` and `SCORE_QNX_PASSWORD`. This can be accomplished in your `~/.bazelrc`:

```
build --action_env=SCORE_QNX_USER=<...>
build --action_env=SCORE_QNX_PASSWORD=<...>
```

#### Using a custom QNX SDP package

Building the QNX8 OS images requires a QNX SDP 8.0.3 (or later) available during build with following additional QNX SDP packages integrated:

* QNX® SDP 8.0 Networking - io-sock Virtio Drivers
* QNX® SDP 8.0 Virtualization Drivers (Block)
* QNX® SDP 8.0 QEMU Virtualization Drivers (Startup)

Add the URL of the QNX SDP tarball to the `MODULE.bazel`:

```
[...]

imagefs = use_extension("@score_rules_imagefs//extensions:imagefs.bzl", "imagefs", dev_dependency = True)
imagefs.sdp(
name = "score_qnx_imagefs_toolchain_pkg",
url = "http://link/to/your/qnx80x.tar.xz",
sha256 = "<your-qnx80x.tar.xz-sha256sum>",
build_file = "//:sdp.BUILD",
)

[...]

```

In case your QNX license requires to check out a license from a license server, you may want to add the
information to your local `~/.bazelrc`:

```
build --action_env=QNXLM_LICENSE_FILE=<...>
```

## Building QNX OS images

QEMU arm64 image using "virt" VM:

```bash
bazel build //qnx8/boards/qemu-arm64virt:all --config=qnx8_0
```

QEMU x86_64 image:

```bash
bazel build //qnx8/boards/qemu-x86_64:all --config=qnx8_0
```

In case of requiring an online QNX license checkout for the QNX SDP `mkifs` utility you might have to set the QNXLM_LICENSE_FILE environment variable with the link to the license server `--action_env=QNXLM_LICENSE_FILE=...`, for example:

```bash
bazel build --action_env=QNXLM_LICENSE_FILE=my@internal.qnx-license-server.com //qnx8/boards/qemu-arm64virt:all --config=qnx8_0
```

## Building QNX OS images from external module

Add a reference to this module to your `MODULE.bazel`:

```
bazel_dep(name = "os_images", version = "...")
```

Build it with the `@os_images//` prefix, the rest is identical like in the section above:

```bash
bazel build @os_images//qnx8/boards/qemu-... --config=qnx8_0
```

## Running the images

### Pre-requisites

In order to run the QEMU images on the host you must have `qemu-system-aarch64` and `qemu-system-x86_64` installed. The x86_64 QEMU run script uses `-accel kvm`, so the running user must have access to `/dev/kvm` for acceleration.

### Get started

After successful build you'll find the IFS binary and an exemplary run script in `bazel-out`:

```
bazel-out/k8-fastbuild/bin/qnx8/boards/qemu-arm64virt/run-qemu.sh
bazel-out/k8-fastbuild/bin/qnx8/boards/qemu-arm64virt/ifs-qemu-arm64virt.bin
bazel-out/k8-fastbuild/bin/qnx8/boards/qemu-x86_64/run-qemu.sh
bazel-out/k8-fastbuild/bin/qnx8/boards/qemu-x86_64/ifs-qemu-x86_64.bin
```
#### Run the images with bazel

QEMU arm64virt image:

```
bazel run //qnx8/boards/qemu-arm64virt:run
```

QEMU x86_64 image:

```
bazel run //qnx8/boards/qemu-x86_64:run
```

You'll get something like:

```
Welcome to QNX 8.0.0 on QEMU_virt !

---> Starting slogger2
---> Starting serial driver
---> Starting block driver
Path=0 -
target=0 lun=0 Direct-Access(0) - VIRTIO Rev:
---> Preparing /run using /dev/ram0
---> Mounting file systems
No root file system has been detected
---> Starting Ethernet driver
---> Setting up vtnet0 with ip address 192.168.120.20/24
---> Starting qconn
---> Starting sshd
---> Starting shell ... Have fun :-)
#
```

#### Run the images manually

In order to run the image, change into the directory with the IFS and execute the run script:

```
cd bazel-out/k8-fastbuild/bin/qnx8/boards/qemu-arm64virt
./run-qemu.sh
```

### Autostart script

If the file `/opt/score/autostart.sh` exists on the mounted file system, it is executed at the end of the OS image startup sequence.

### ssh from host into QEMU image

The QNX IFS images start up a `sshd` server. The user `root` has by default no password and `sshd` is configured to accept a root login w/o password.
The exemplary `run-qemu.sh` script configures QEMU to use QEMU user networking and sets up a port forwarding from localhost:2210 -> VM-IP 192.168.120.20:22. So you can open a ssh from host using:

```
ssh -p 2210 root@localhost
```

### Configuring custom IP address + host name

During the startup of the VM the network is being set up, *after* mounting the virtual file system. By default host name `qemu-arm64virt` or `qemu-x86_64` and IP address 192.168.120.20/24 is set up. **Before** setting these, the `net-start.sh` script tries to read a file `/opt/score/etc/settings/network`. By installing such a file on the virtual file system and adding variables one can configure hostname and IP address of the network interface:

```
# /opt/score/etc/settings/network
IP_ADDRESS_vtnet0="192.168.100.1/24"
HOSTNAME=myqemu
```

> NOTE: This changes only the IP address of the QNX network interface. In order to make the port forwardings of the QEMU user network function correctly you'll have to adapt the QEMU user networking configuration in the `run-qemu.sh` script according to your IP address/subnet.

16 changes: 16 additions & 0 deletions qnx8/boards/common/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
exports_files([
"common.build",
"ssh_host_ed25519_key",
"ssh_host_ed25519_key.pub",
"ssh_host_rsa_key",
"ssh_host_rsa_key.pub",
])

filegroup(
name = "common_files",
srcs = glob(["*"]),
visibility = [
"//qnx8/boards/qemu-arm64virt:__pkg__",
"//qnx8/boards/qemu-x86_64:__pkg__",
],
)
Loading
Loading