Skip to content

Commit bffe23e

Browse files
authored
Merge pull request #1650 from govindsi/feat/ucm-imx95-platform
Add support for UCM-iMX95 Evaluation Kit platform
2 parents 2567706 + 5ad68c5 commit bffe23e

17 files changed

+820
-20
lines changed

compulab/README.md

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# UCM-iMX95 SOM support
2+
3+
## Supported devices
4+
- [UCM-iMX95 System-on-Module](https://www.compulab.com/products/som-evaluation-kits/ucm-imx95-evaluation-kit/) (**ucm-imx95**) – based on the NXP i.MX95 SoC (A0 silicon), with device-specific boot components(OEI, SM, ATF), U-Boot, and Linux kernel support, including a NixOS configuration example.
5+
6+
## How to use
7+
This overlay provides configuration and hardware support for the **CompuLab UCM-iMX95** platform, based on the **NXP i.MX95 A0 silicon**. It enables generating NixOS images suitable for booting via U-Boot, using the CompuLab UCM-iMX95 Evaluation Kit carrier board.
8+
9+
### Boot flow
10+
The boot flow for the UCM-iMX95 platform follows the standard NXP i.MX95 sequence:
11+
12+
Boot ROM → OEI (initially in TCM, then DDR) → System Manager (SM) → ARM Trusted Firmware (ATF) → U-Boot → Linux kernel → NixOS userspace
13+
14+
Boot ROM initializes the SoC and loads OEI, which runs in TCM to perform early setup, then configures DDR and loads the System Manager (SM). SM completes SoC initialization and passes control to ATF, which handles secure world setup and then transfers execution to U-Boot, eventually booting the Linux kernel and NixOS root filesystem.
15+
16+
### Example NixOS configuration
17+
```nix
18+
{ nixos-hardware, }: {
19+
system = "aarch64-linux";
20+
modules = [
21+
nixos-hardware.nixosModules.ucm-imx95
22+
];
23+
}
24+
```
25+
26+
### Notes
27+
- The configuration, including device-tree, kernel, and bootloader components, is optimized for the UCM-iMX95 SoM and EVK.
28+
- The generated NixOS image supports booting from SD card or eMMC, depending on the hardware configuration.
29+
- The boot components (OEI in TCM/DDR, SM, ATF, U-Boot) follow the standard NXP release layout for i.MX95 platforms.
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
{
2+
lib,
3+
fetchFromGitHub,
4+
stdenv,
5+
buildPackages,
6+
pkgsCross,
7+
openssl,
8+
}:
9+
10+
let
11+
target-board = "imx95";
12+
in
13+
stdenv.mkDerivation rec {
14+
pname = "imx95-atf";
15+
version = "2.13.0";
16+
platform = target-board;
17+
enableParallelBuilding = true;
18+
19+
src = fetchFromGitHub {
20+
owner = "nxp-imx";
21+
repo = "imx-atf";
22+
rev = "28affcae957cb8194917b5246276630f9e6343e1";
23+
sha256 = "sha256-a8F+Lf8pwML+tCwawS0N/mrSXWPmFhlUeOg0MCRK3VE=";
24+
};
25+
26+
# Compiler dependencies
27+
depsBuildBuild = [ buildPackages.stdenv.cc ];
28+
nativeBuildInputs = [
29+
pkgsCross.aarch64-embedded.stdenv.cc
30+
openssl
31+
];
32+
33+
makeFlags = [
34+
"HOSTCC=$(CC_FOR_BUILD)"
35+
"CROSS_COMPILE=${pkgsCross.aarch64-embedded.stdenv.cc.targetPrefix}"
36+
"PLAT=${platform}"
37+
"SPD=opteed"
38+
"bl31"
39+
"LDFLAGS=-no-warn-rwx-segments"
40+
];
41+
42+
installPhase = ''
43+
runHook preInstall
44+
mkdir -p $out
45+
cp build/${target-board}/release/bl31.bin $out
46+
runHook postInstall
47+
'';
48+
49+
hardeningDisable = [ "all" ];
50+
dontStrip = true;
51+
52+
meta = with lib; {
53+
homepage = "https://github.com/nxp-imx/imx-atf";
54+
description = "Reference implementation of secure world software for ARMv8-A";
55+
license = licenses.bsd3;
56+
maintainers = [
57+
{
58+
name = "Govind Singh";
59+
email = "govind.singh@tii.ae";
60+
}
61+
];
62+
platforms = [ "aarch64-linux" ];
63+
};
64+
}
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
{
2+
callPackage,
3+
fetchFromGitHub,
4+
stdenv,
5+
clang,
6+
git,
7+
dtc,
8+
glibc,
9+
zlib,
10+
vim,
11+
}:
12+
let
13+
14+
imx95-atf = callPackage ./ucm-imx95-atf.nix { };
15+
imx95-firmware = callPackage ./ucm-imx95-firmware.nix { };
16+
imx95-uboot = callPackage ./ucm-imx95-uboot.nix { };
17+
imx95-optee-os = callPackage ./ucm-imx95-optee-os.nix { };
18+
imx95-sm-fw = callPackage ./ucm-imx95-sm-fw.nix { };
19+
imx95-oei-ddr = callPackage ./ucm-imx95-oei-ddr.nix { };
20+
imx95-oei-tcm = callPackage ./ucm-imx95-oei-tcm.nix { };
21+
src = fetchFromGitHub {
22+
owner = "nxp-imx";
23+
repo = "imx-mkimage";
24+
#tag: lf-6.6.52-2.2.1
25+
rev = "f620fb8ef7a04c8dbed8119880f5eeffe3e69746";
26+
sha256 = "sha256-JZlX122uZntCIISI1H3Hw+tnk+N/gBJpFFDaZoY8W3c=";
27+
};
28+
shortRev = builtins.substring 0 8 src.rev;
29+
in
30+
{
31+
imx95-boot = stdenv.mkDerivation rec {
32+
inherit src;
33+
name = "imx95-mkimage";
34+
version = "lf-6.6.52-2.2.1";
35+
36+
postPatch = ''
37+
substituteInPlace Makefile \
38+
--replace-fail 'git rev-parse --short=8 HEAD' 'echo ${shortRev}'
39+
substituteInPlace Makefile \
40+
--replace-fail 'CC = gcc' 'CC = clang'
41+
substituteInPlace iMX95/soc.mak \
42+
--replace-fail 'xxd' "${vim.xxd}/bin/xxd"
43+
substituteInPlace scripts/fspi_fcb_gen.sh \
44+
--replace-fail 'xxd' "${vim.xxd}/bin/xxd"
45+
substituteInPlace scripts/fspi_packer.sh \
46+
--replace-fail 'xxd' "${vim.xxd}/bin/xxd"
47+
patchShebangs scripts
48+
'';
49+
50+
nativeBuildInputs = [
51+
clang
52+
git
53+
dtc
54+
];
55+
56+
buildInputs = [
57+
glibc.static
58+
zlib
59+
zlib.static
60+
];
61+
62+
buildPhase = ''
63+
runHook preBuild
64+
65+
if [ -f ${imx95-uboot}/u-boot.bin ]; then
66+
install -m 0644 ${imx95-uboot}/u-boot.bin ./iMX95/u-boot.bin
67+
else
68+
cat ${imx95-uboot}/u-boot-nodtb.bin ${imx95-uboot}/ucm-imx95.dtb > ./iMX95/u-boot.bin
69+
fi
70+
install -m 0644 ${imx95-uboot}/u-boot-spl.bin ./iMX95/u-boot-spl.bin
71+
install -m 0644 ${imx95-uboot}/u-boot-nodtb.bin ./iMX95/u-boot-nodtb.bin
72+
install -m 0644 ${imx95-uboot}/ucm-imx95.dtb ./iMX95/ucm-imx95.dtb
73+
install -m 0644 ${imx95-optee-os}/tee.bin ./iMX95/tee.bin
74+
install -m 0644 ${imx95-atf}/bl31.bin ./iMX95/bl31.bin
75+
install -m 0644 ${imx95-sm-fw}/m33_image.bin ./iMX95/m33_image.bin
76+
install -m 0644 ${imx95-oei-ddr}/oei-m33-ddr.bin ./iMX95/oei-m33-ddr.bin
77+
install -m 0644 ${imx95-oei-tcm}/oei-m33-tcm.bin ./iMX95/oei-m33-tcm.bin
78+
install -m 0644 ${imx95-firmware}/ddr/lpddr5* ./iMX95/
79+
install -m 0644 ${imx95-firmware}/ahab/mx95a0-ahab-container.img ./iMX95/
80+
install -m 0644 ${imx95-firmware}/m7_image.bin ./iMX95/
81+
82+
make SOC=iMX95 REV=A0 OEI=YES LPDDR_TYPE=lpddr5 flash_all
83+
84+
runHook postBuild
85+
'';
86+
87+
installPhase = ''
88+
runHook preInstall
89+
mkdir -p $out/image
90+
install -m 0644 ./iMX95/flash.bin $out/image
91+
runHook postInstall
92+
'';
93+
};
94+
}
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
{
2+
stdenv,
3+
fetchurl,
4+
coreutils,
5+
bash,
6+
siliconRev ? "A0",
7+
...
8+
}:
9+
10+
stdenv.mkDerivation rec {
11+
pname = "nxp-firmware-imx95";
12+
version = "nxp-firmware-8.28-994fa14";
13+
14+
m7Firmware = fetchurl {
15+
url = "https://www.nxp.com/lgfiles/NMG/MAD/YOCTO/imx95-m7-demo-25.09.00.bin";
16+
sha256 = "sha256-3nA6uka6WPtXH5aZhaaKHKRM0tJ0pxHQdPEupNic1Ks=";
17+
};
18+
19+
ddrFirmware = fetchurl {
20+
url = "https://www.nxp.com/lgfiles/NMG/MAD/YOCTO/firmware-imx-8.28-994fa14.bin";
21+
sha256 = "sha256-VZlvNA6HglaFoAzTCZARiQZuyVRe5gdzT5QsPN5Nadw=";
22+
};
23+
24+
ahabFirmware = fetchurl {
25+
url = "https://www.nxp.com/lgfiles/NMG/MAD/YOCTO/firmware-ele-imx-2.0.2-89161a8.bin";
26+
sha256 = "sha256-LSnwpN42YroV9qfZBpcC1OrtQV2WoX8p1bEn8sb91jQ=";
27+
};
28+
29+
nativeBuildInputs = [
30+
coreutils
31+
bash
32+
];
33+
34+
dontUnpack = true;
35+
dontStrip = true;
36+
37+
installPhase = ''
38+
mkdir -p $out
39+
export SILICON=${siliconRev}
40+
41+
# M7 firmware
42+
echo "Copying M7 firmware..."
43+
cp ${m7Firmware} $out/m7_image.bin
44+
45+
# DDR firmware
46+
cp ${ddrFirmware} ./firmware-imx-8.28-994fa14.bin
47+
chmod +x firmware-imx-8.28-994fa14.bin
48+
./firmware-imx-8.28-994fa14.bin --auto-accept
49+
50+
mkdir -p $out/ddr
51+
# Resolve wildcard and verify at least one file matches
52+
lpddr5_files=(firmware-imx-8.28-994fa14/firmware/ddr/synopsys/lpddr5*v202409.bin)
53+
if [ ''${#lpddr5_files[@]} -eq 0 ]; then
54+
echo "ERROR: No lpddr5*v202409.bin file found in firmware/ddr/synopsys/" >&2
55+
exit 1
56+
fi
57+
cp "''${lpddr5_files[@]}" $out/ddr/
58+
59+
# AHAB container
60+
cp ${ahabFirmware} ./firmware-ele-imx-2.0.2-89161a8.bin
61+
chmod +x firmware-ele-imx-2.0.2-89161a8.bin
62+
./firmware-ele-imx-2.0.2-89161a8.bin --auto-accept
63+
64+
mkdir -p $out/ahab
65+
if [ "$SILICON" = "A0" ]; then
66+
cp firmware-ele-imx-2.0.2-89161a8/mx95a0-ahab-container.img $out/ahab/
67+
elif [ "$SILICON" = "B0" ]; then
68+
cp firmware-ele-imx-2.0.2-89161a8/mx95b0-ahab-container.img $out/ahab/
69+
else
70+
echo "ERROR: Invalid SILICON value '$SILICON'. Must be 'A0' or 'B0'." >&2
71+
exit 1
72+
fi
73+
'';
74+
}
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
{
2+
lib,
3+
buildLinux,
4+
fetchFromGitHub,
5+
...
6+
}@args:
7+
buildLinux (
8+
args
9+
// rec {
10+
version = "6.6.36";
11+
name = "imx95-linux";
12+
13+
# modDirVersion needs to be x.y.z, will automatically add .0 if needed
14+
modDirVersion = version;
15+
16+
defconfig = "compulab-mx95_defconfig";
17+
18+
# https://github.com/NixOS/nixpkgs/pull/366004
19+
# introduced a breaking change that if a module is declared but it is not being used it will fail.
20+
ignoreConfigErrors = true;
21+
22+
kernelPatches = [
23+
];
24+
25+
autoModules = false;
26+
27+
extraConfig = ''
28+
CRYPTO_TLS m
29+
TLS y
30+
MD_RAID0 m
31+
MD_RAID1 m
32+
MD_RAID10 m
33+
MD_RAID456 m
34+
DM_VERITY m
35+
LOGO y
36+
FRAMEBUFFER_CONSOLE_DEFERRED_TAKEOVER n
37+
FB_EFI n
38+
EFI_STUB y
39+
EFI y
40+
VIRTIO y
41+
VIRTIO_PCI y
42+
VIRTIO_BLK y
43+
DRM_VIRTIO_GPU y
44+
EXT4_FS y
45+
USBIP_CORE m
46+
USBIP_VHCI_HCD m
47+
USBIP_HOST m
48+
USBIP_VUDC m
49+
'';
50+
51+
src = fetchFromGitHub {
52+
owner = "compulab-yokneam";
53+
repo = "linux-compulab";
54+
# tag: linux-compulab_6.6.36
55+
rev = "b93daaad0807fb15d4f3f1a6e5be843ac7532ef7";
56+
sha256 = "sha256-wCeuGXBTz3H6OFWBA1M1/t/9WgxBVjQ8FU/wvAUVW2w=";
57+
};
58+
meta = with lib; {
59+
homepage = "https://github.com/compulab-yokneam/linux-compulab";
60+
license = licenses.gpl2Only;
61+
maintainers = [
62+
{
63+
name = "Govind Singh";
64+
email = "govind.singh@tii.ae";
65+
}
66+
];
67+
platforms = [ "aarch64-linux" ];
68+
};
69+
}
70+
// (args.argsOverride or { })
71+
)

0 commit comments

Comments
 (0)