Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
22 changes: 19 additions & 3 deletions meta-secluso-os/pi-debug-image.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,13 @@ distro: secluso
# We use 'secluso-image-minimal' to include our own recipes on top of core-image-minimal
# Located in recipes-core/images/secluso-pi-image-minimal.bb
target: secluso-pi-image-minimal
# Optional local source override for camera hub in debug builds
# This should point at the local core repository root (not camera_hub)
# Example:
# SECLUSO_CAMERA_HUB_USE_LOCAL=1 SECLUSO_CAMERA_HUB_LOCAL_SRC=/home/john/core kas build pi-debug-image.yml
env:
SECLUSO_CAMERA_HUB_USE_LOCAL: null
SECLUSO_CAMERA_HUB_LOCAL_SRC: null
repos:
# We create a layer for secluso-os.
# This allows us to use our own wic/ file. Additionally, we have conf/ if we need it.
Expand Down Expand Up @@ -118,7 +125,7 @@ local_conf_header:
# meta-raspberrypi sets WKS_FILE with a weak assignment (?=), so we don't need a force override
# wks is a custom configuration script used by the wic tool to define the partitioning layout
# override theirs with our modified version
WKS_FILE:raspberrypi0-2w-64 = "sdcard-raspberrypi.wks"
WKS_FILE = "sdcard-raspberrypi.wks"

# Reference: https://wiki.yoctoproject.org/wiki/Reproducible_Builds
# These should be default values. We re-affirm them here to be safe.
Expand Down Expand Up @@ -159,13 +166,22 @@ local_conf_header:
ENABLE_CAMERA = "0"
ENABLE_I2C = "1"
# Ensure the ov5647 & imx219 overlays are built and deployed to /boot/overlays/
KERNEL_DEVICETREE:append:raspberrypi0-2w-64 = " overlays/ov5647.dtbo"
KERNEL_DEVICETREE:append:raspberrypi0-2w-64 = " overlays/imx219.dtbo"
KERNEL_DEVICETREE:append = " overlays/ov5647.dtbo"
KERNEL_DEVICETREE:append = " overlays/imx219.dtbo"

# Ensure the kernel modules are installed into the image. Needed to properly load in the camera into libcamera
# Not all kernel-modules need to be included for proper operation.
# TODO: Remove unnecesary kernel modules
IMAGE_INSTALL:append = " kmod i2c-tools kernel-modules"

# Install ALSA userspace tooling and our own ALSA configuration recipe.
# secluso-alsa-config provides the capture devices used by camera_hub (eg. mic_processed).
IMAGE_INSTALL:append = " alsa-utils alsa-state opus-tools secluso-alsa-config"
# Ensure our I2S microphone overlay is built and put in to /boot/overlays/
KERNEL_DEVICETREE:append = " overlays/i2s-ics43432-mic.dtbo"
# Enable the Pi I2S controller and load the ICS43432 microphone overlay at boot.
# We additionally enable the PWM overlay for the IR light on GPIO 13.
RPI_EXTRA_CONFIG += "\ndtparam=i2s=on\ndtoverlay=i2s-ics43432-mic\ndtoverlay=pwm,pin=13,func=4\n"

# Referenced from https://hub.mender.io/t/how-to-configure-networking-using-systemd-in-yocto-project/1097
# This installs the necessary firmware to connect to WiFi. See LICENSE_FLAGS_ACCEPTED for a relevant discussion.
Expand Down
9 changes: 9 additions & 0 deletions meta-secluso-os/pi-official-image.yml
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,15 @@ local_conf_header:
# Not all kernel-modules need to be included for proper operation.
# TODO: Remove unnecesary kernel modules
IMAGE_INSTALL:append = " kmod i2c-tools kernel-modules"

# Install ALSA userspace tooling and our own ALSA configuration recipe.
# secluso-alsa-config provides the capture devices used by camera_hub (eg. mic_processed).
IMAGE_INSTALL:append = " alsa-utils alsa-state opus-tools secluso-alsa-config"
# Ensure our I2S microphone overlay is built and put in to /boot/overlays/
KERNEL_DEVICETREE:append = " overlays/i2s-ics43432-mic.dtbo"
# Enable the Pi I2S controller and load the ICS43432 microphone overlay at boot.
# We additionally enable the PWM overlay for the IR light on GPIO 13.
RPI_EXTRA_CONFIG += "\ndtparam=i2s=on\ndtoverlay=i2s-ics43432-mic\ndtoverlay=pwm,pin=13,func=4\n"

# Referenced from https://hub.mender.io/t/how-to-configure-networking-using-systemd-in-yocto-project/1097
# This installs the necessary firmware to connect to WiFi. See LICENSE_FLAGS_ACCEPTED for a relevant discussion.
Expand Down
15 changes: 15 additions & 0 deletions meta-secluso-os/recipes-bsp/alsa-state/alsa-state.bbappend
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# SPDX-License-Identifier: GPL-3.0-only
# Copyright (C) 2026 Secluso, Inc.
# Additional terms apply; see the NOTICE file in the repository root.

do_install:append() {
rm -f ${D}${sysconfdir}/asound.conf
rmdir --ignore-fail-on-non-empty ${D}${sysconfdir}
}

FILES:${PN}:remove = "${sysconfdir}/asound.conf"
CONFFILES:${PN}:remove = "${sysconfdir}/asound.conf"

# Make wrapper package installable after removing the stock asound.conf
RDEPENDS:${PN} += "alsa-states"
ALLOW_EMPTY:${PN} = "1"
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/dts-v1/;
/plugin/;

/ {
compatible = "brcm,bcm2835";

fragment@0 {
target-path = "/";
__overlay__ {
ics43432_codec: ics43432-codec {
#sound-dai-cells = <0>;
compatible = "invensense,ics43432";
status = "okay";
};
};
};

fragment@1 {
target = <&i2s_clk_producer>;
__overlay__ {
#sound-dai-cells = <0>;
status = "okay";
};
};

fragment@2 {
target = <&sound>;
sound_overlay: __overlay__ {
compatible = "simple-audio-card";
simple-audio-card,format = "i2s";
simple-audio-card,name = "ICS43432Mic";
simple-audio-card,bitclock-slave = <&mic_codec>;
simple-audio-card,frame-slave = <&mic_codec>;
status = "okay";

simple-audio-card,cpu {
sound-dai = <&i2s_clk_producer>;
dai-tdm-slot-num = <2>;
dai-tdm-slot-width = <32>;
};

mic_codec: simple-audio-card,codec {
sound-dai = <&ics43432_codec>;
};
};
};

__overrides__ {
card-name = <&sound_overlay>, "simple-audio-card,name";
};
};
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,22 @@

FILESEXTRAPATHS:prepend := "${THISDIR}/files:"

SRC_URI:append = " file://disable-ikconfig.cfg"
SRC_URI:append = " file://disable-ikconfig.cfg file://i2s-ics43432-mic-overlay.dts"

do_configure:append() {
install -m 0644 ${UNPACKDIR}/i2s-ics43432-mic-overlay.dts \
${S}/arch/arm/boot/dts/overlays/i2s-ics43432-mic-overlay.dts

awk '
/i2s-ics43432-mic\.dtbo/ {
next
}
/^dtbo-\$\(CONFIG_ARCH_BCM2835\) \+= \\$/ {
print
print " i2s-ics43432-mic.dtbo \\"
next
}
{ print }
' ${S}/arch/arm/boot/dts/overlays/Makefile > ${S}/arch/arm/boot/dts/overlays/Makefile.new
mv ${S}/arch/arm/boot/dts/overlays/Makefile.new ${S}/arch/arm/boot/dts/overlays/Makefile
}
25 changes: 25 additions & 0 deletions meta-secluso-os/recipes-multimedia/alsa/files/asound.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# SPDX-License-Identifier: GPL-3.0-only
# Copyright (C) 2026 Secluso, Inc.
# Additional terms apply; see the NOTICE file in the repository root.

# Capture the left slot from the ICS-43432 mic and let ALSA plug handle format/rate/channel conversion for mono 16 kHz pipelines.
pcm.mic_mono {
type plug
slave.pcm "hw:ICS43432Mic,0"
ttable.0.0 1
}

pcm.mic_processed {
type softvol
slave.pcm "mic_mono"
control {
name "Mic Gain"
card "ICS43432Mic"
}
max_dB 30.0
}

ctl.!default {
type hw
card "ICS43432Mic"
}
16 changes: 16 additions & 0 deletions meta-secluso-os/recipes-multimedia/alsa/secluso-alsa-config_1.0.bb
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# SPDX-License-Identifier: GPL-3.0-only
# Copyright (C) 2026 Secluso, Inc.
# Additional terms apply; see the NOTICE file in the repository root.

SUMMARY = "ALSA configuration for the ICS-43432 debug mic pipeline"
LICENSE = "MIT"
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"

SRC_URI = "file://asound.conf"

do_install() {
install -d ${D}${sysconfdir}
install -m 0644 ${UNPACKDIR}/asound.conf ${D}${sysconfdir}/asound.conf
}

FILES:${PN} = "${sysconfdir}/asound.conf"
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,8 @@ SRC_URI += " \
crate://crates.io/ocb3/0.1.0 \
crate://crates.io/once_cell/1.21.4 \
crate://crates.io/opaque-debug/0.3.1 \
crate://crates.io/opusic-c/1.6.1 \
crate://crates.io/opusic-sys/0.7.3 \
crate://crates.io/openssl-probe/0.2.1 \
crate://crates.io/p256/0.13.2 \
crate://crates.io/p384/0.13.1 \
Expand Down Expand Up @@ -534,6 +536,8 @@ SRC_URI[num-traits-0.2.19.sha256sum] = "071dfc062690e90b734c0b2273ce72ad0ffa95f0
SRC_URI[ocb3-0.1.0.sha256sum] = "c196e0276c471c843dd5777e7543a36a298a4be942a2a688d8111cd43390dedb"
SRC_URI[once_cell-1.21.4.sha256sum] = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50"
SRC_URI[opaque-debug-0.3.1.sha256sum] = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381"
SRC_URI[opusic-c-1.6.1.sha256sum] = "89f8e9c909466f15e60277212cc4fec082c68a5e1c9f6e373eee716fec2fed47"
SRC_URI[opusic-sys-0.7.3.sha256sum] = "2804e694ef0de3b4cbb254de565053b7cb48d3398df7fd60c6c62bed40c5372a"
SRC_URI[openssl-probe-0.2.1.sha256sum] = "7c87def4c32ab89d880effc9e097653c8da5d6ef28e6b539d313baaacfbafcbe"
SRC_URI[p256-0.13.2.sha256sum] = "c9863ad85fa8f4460f9c48cb909d38a0d689dba1f6f6988a5e3e0d31071bcd4b"
SRC_URI[p384-0.13.1.sha256sum] = "fe42f1670a52a47d448f14b6a5c61dd78fce51856e68edaa38f7ae3a46b8d6b6"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
# Referenced https://github.com/facebook/openbmc/blob/5bf12b96fd7797c84798049bc404581be8390bc7/meta-facebook/meta-catalina/recipes-catalina/satellite-relay/satellite-relay_0.1.0.bb

# Inheriting cargo is what will build the crate here.
inherit cargo cargo-update-recipe-crates systemd
inherit cargo cargo-update-recipe-crates systemd externalsrc

SUMMARY = "Recipe to build and install Secluso Camera Hub"
HOMEPAGE = "https://github.com/secluo/core"
Expand All @@ -17,6 +17,9 @@ LIC_FILES_CHKSUM = "file://LICENSE;md5=b769fddc23425484f6d001e49426c2ee"
SRC_URI = "git://github.com/secluso/core.git;nobranch=1;protocol=https"
SRCREV = "7bcbb4e4785fddab7f309b9535b29b98d54136fc"

SECLUSO_CAMERA_HUB_USE_LOCAL ?= "0"
SECLUSO_CAMERA_HUB_LOCAL_SRC ?= ""

# Cargo fingerprints local path crates using their absolute source path
# Thus, we copy the workspace to a canonical location before compiling.
REPRODUCIBLE_SOURCE_DIR = "/tmp/yocto-reproducible-sources/${BPN}-${PV}-${TARGET_SYS}"
Expand All @@ -38,6 +41,37 @@ RUSTFLAGS += " --remap-path-prefix=${WORKDIR}=/usr/src/debug/${PN}/${PV}"
RUSTFLAGS += " --remap-path-prefix=${S}=/usr/src/debug/${PN}/${PV}/sources"
RUSTFLAGS += " --remap-path-prefix=${CARGO_HOME}=cargo_home"

# opusic-sys compiles bundled C sources via a cargo build script.
# Rust path remaps alone are thus not enough to rewrite __FILE__ strings that would embed TMPDIR into the binary.
CFLAGS += " -ffile-prefix-map=${WORKDIR}=/usr/src/debug/${PN}/${PV}"
CFLAGS += " -ffile-prefix-map=${S}=/usr/src/debug/${PN}/${PV}/sources"
CFLAGS += " -ffile-prefix-map=${CARGO_HOME}=cargo_home"

python __anonymous() {
import os

if d.getVar("SECLUSO_CAMERA_HUB_USE_LOCAL") != "1":
d.setVar("S", d.getVar("REPRODUCIBLE_SOURCE_DIR"))
return

local_src = d.getVar("SECLUSO_CAMERA_HUB_LOCAL_SRC")
if not local_src:
bb.fatal("SECLUSO_CAMERA_HUB_USE_LOCAL=1 requires SECLUSO_CAMERA_HUB_LOCAL_SRC to be set to the local core repository root")
if not os.path.isdir(local_src):
bb.fatal("SECLUSO_CAMERA_HUB_LOCAL_SRC does not exist or is not a directory: %s" % local_src)

# externalsrc points the recipe directly at the user's local core checkout.
# This is only intended for debug image workflows where we want to iterate without doing git commits across machines
d.setVar("EXTERNALSRC", local_src)
d.setVar("EXTERNALSRC_BUILD", os.path.join(d.getVar("WORKDIR"), "externalsrc-build"))
d.setVar("S", local_src)
# BitBake does not automatically notice arbitrary source edits (stale cache)
# Thus, in local debug mode, we rebuild the packaging pipeline every time we run
for task in ("do_compile", "do_install", "do_package", "do_packagedata",
"do_package_qa", "do_package_write_rpm"):
d.setVarFlag(task, "nostamp", "1")
}

# https://wiki.koansoftware.com/index.php/Add_a_systemd_service_file_into_a_Yocto_image
SYSTEMD_AUTO_ENABLE = "enable"
SYSTEMD_SERVICE:${PN} = "secluso_camera_hub.service"
Expand All @@ -49,6 +83,11 @@ python do_unpack:append() {
import os
import shutil

# When externalsrc is enabled, the source tree is already the caller's local checkout.
# Thus, we skip the reproducible copy step that is only needed for the pinned git for releases for reproducibility
if d.getVar("SECLUSO_CAMERA_HUB_USE_LOCAL") == "1":
return

source_dir = os.path.join(d.getVar("WORKDIR"), "sources", f"{d.getVar('BPN')}-{d.getVar('PV')}")
reproducible_source_dir = d.getVar("S")

Expand Down