From 77472140aa6dc8553a7935fe064f575f4fa25e03 Mon Sep 17 00:00:00 2001 From: AI Dev Date: Fri, 6 Nov 2026 04:59:40 +0000 Subject: [PATCH 1/3] ambarella: s3l: build for the Cortex-A9 the SoC has s3l_lite_defconfig targeted a Cortex-A7 with VFPv4. The S3L is a Cortex-A9 with NEON and VFPv3 (cpuinfo in OpenIPC/ipctool#266: part 0xc09, features "neon vfpv3"). With those flags gcc emits sdiv and vfma, which an A9 does not have, so a plain integer division can take SIGILL. The A9 flags call __aeabi_idiv for the same code. Buildroot resolves the new config to -mcpu=cortex-a9 -mfpu=neon. --- br-ext-chip-ambarella/configs/s3l_lite_defconfig | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/br-ext-chip-ambarella/configs/s3l_lite_defconfig b/br-ext-chip-ambarella/configs/s3l_lite_defconfig index 29a9729a68..068bb68adf 100644 --- a/br-ext-chip-ambarella/configs/s3l_lite_defconfig +++ b/br-ext-chip-ambarella/configs/s3l_lite_defconfig @@ -1,8 +1,10 @@ # Architecture BR2_arm=y -BR2_cortex_a7=y +BR2_cortex_a9=y BR2_ARM_EABI=y -BR2_ARM_FPU_NEON_VFPV4=y +BR2_ARM_ENABLE_NEON=y +BR2_ARM_ENABLE_VFP=y +BR2_ARM_FPU_NEON=y BR2_ARM_INSTRUCTIONS_THUMB2=y # Toolchain From 3089e815ec2d4b5d6cfe10c2d133d4e867e4d6ca Mon Sep 17 00:00:00 2001 From: AI Dev Date: Fri, 6 Nov 2026 04:59:40 +0000 Subject: [PATCH 2/3] ambarella: s3l: load the drivers at boot load_ambarella was an empty file, so S70vendor ran it and nothing came up. It now loads iav and what it needs, then the sensor, then the DSP microcode, which is the vendor's order. iav registers no device class, so mdev never makes /dev/iav or /dev/ucode and the script does. The sensor comes from the environment, or from ipcinfo. The microcode and load_ucode are Ambarella's and are not in this package: the script uses them if present, and says video will not start if not. --- .../files/script/load_ambarella | 99 +++++++++++++++++++ 1 file changed, 99 insertions(+) diff --git a/general/package/legacy/ambarella-osdrv-s3l/files/script/load_ambarella b/general/package/legacy/ambarella-osdrv-s3l/files/script/load_ambarella index e69de29bb2..8724498e7c 100755 --- a/general/package/legacy/ambarella-osdrv-s3l/files/script/load_ambarella +++ b/general/package/legacy/ambarella-osdrv-s3l/files/script/load_ambarella @@ -0,0 +1,99 @@ +#!/bin/sh +# +# Ambarella S3L driver bring-up, in the vendor's order: iav and what it needs, +# then the sensor, then the DSP microcode. +# +# iav registers plain character devices and no device class, so mdev never sees +# them and the nodes have to be made here. The major comes from /proc/devices; +# the minors are fixed. +# +# The microcode (orccode.bin, orcme.bin, default_binary.bin) and the load_ucode +# tool are Ambarella's and are not part of this package. Without them the +# drivers load and the DSP does not start, so no video. Drop them in place and +# this script uses them. + +vendor=$(ipcinfo -v) +ucode_dir=/lib/firmware + +log_vendor() { + logger -s -p daemon.info -t "${vendor:-ambarella}" "$1" +} + +load() { + mod=$1 + shift + grep -q "^${mod} " /proc/modules && return 0 + # modprobe, not insmod: iav needs dsp, hw_timer, imgproc and vout, and + # modules.dep knows that. + modprobe "${mod}" "$@" +} + +make_node() { + major=$(awk -v name="$1" '$2 == name { print $1; exit }' /proc/devices) + if [ -z "${major}" ]; then + log_vendor "No $1 in /proc/devices, /dev/$1 not created" + return 1 + fi + [ -c "/dev/$1" ] || mknod -m 666 "/dev/$1" c "${major}" "$2" +} + +sensor_module() { + case "$1" in + ov4689 | ov2718 | imx290 | imx274 | imx326) + echo "$1_mipi" + ;; + ar0230 | ar0237 | imx172 | imx178 | imx226) + echo "$1" + ;; + esac +} + +load_sensor() { + sensor=$(fw_printenv -n sensor 2>/dev/null) + [ -n "${sensor}" ] || sensor=$(ipcinfo -s 2>/dev/null) + sensor=$(echo "${sensor}" | tr 'A-Z' 'a-z') + + if [ -z "${sensor}" ]; then + log_vendor "No sensor in the environment and none detected" + return 1 + fi + + module=$(sensor_module "${sensor}") + if [ -z "${module}" ]; then + log_vendor "No driver in this package for sensor ${sensor}" + return 1 + fi + + load "${module}" || log_vendor "Failed to load ${module}" +} + +load_microcode() { + if ! command -v load_ucode >/dev/null || [ ! -f "${ucode_dir}/orccode.bin" ]; then + log_vendor "No DSP microcode on this image, video will not start" + return 1 + fi + + load_ucode "${ucode_dir}" >/dev/null || log_vendor "load_ucode failed" +} + +insert_ko() { + if ! load iav; then + log_vendor "Failed to load iav" + return 1 + fi + + make_node iav 0 + make_node ucode 1 + load_sensor + load_microcode +} + +case "$1" in + -i | "") + insert_ko + ;; + *) + echo "Usage: $0 [-i]" + exit 1 + ;; +esac From a4f6d05687490c3c593ae352b4fb4b804edd1fb6 Mon Sep 17 00:00:00 2001 From: AI Dev Date: Fri, 6 Nov 2026 05:29:56 +0000 Subject: [PATCH 3/3] ambarella: s3l: review of the loader Device nodes are now root-only: nothing needs them world-writable. A stored sensor=unknown no longer stops detection, the same way load_goke handles it. Exact driver names are accepted. A bare imx290 or imx326 still means MIPI, since ipcinfo cannot tell the interface, and the LVDS drivers are reached with imx290_lvds and imx326_lvds. --- .../files/script/load_ambarella | 31 ++++++++++++++----- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/general/package/legacy/ambarella-osdrv-s3l/files/script/load_ambarella b/general/package/legacy/ambarella-osdrv-s3l/files/script/load_ambarella index 8724498e7c..0a9fed01f2 100755 --- a/general/package/legacy/ambarella-osdrv-s3l/files/script/load_ambarella +++ b/general/package/legacy/ambarella-osdrv-s3l/files/script/load_ambarella @@ -8,9 +8,10 @@ # the minors are fixed. # # The microcode (orccode.bin, orcme.bin, default_binary.bin) and the load_ucode -# tool are Ambarella's and are not part of this package. Without them the -# drivers load and the DSP does not start, so no video. Drop them in place and -# this script uses them. +# tool are Ambarella's and are not part of this package, and the stock tool is +# a glibc armhf binary that will not run on this musl image. Without them the +# drivers load and the DSP does not start, so no video. Drop working ones in +# place and this script uses them. vendor=$(ipcinfo -v) ucode_dir=/lib/firmware @@ -34,14 +35,27 @@ make_node() { log_vendor "No $1 in /proc/devices, /dev/$1 not created" return 1 fi - [ -c "/dev/$1" ] || mknod -m 666 "/dev/$1" c "${major}" "$2" + [ -c "/dev/$1" ] || mknod -m 600 "/dev/$1" c "${major}" "$2" } +# ipcinfo reports a bare name and cannot tell the interface, so a bare name +# means MIPI. imx290 and imx326 also come as LVDS drivers, reached by setting +# sensor=imx290_lvds or sensor=imx326_lvds. sensor_module() { case "$1" in ov4689 | ov2718 | imx290 | imx274 | imx326) echo "$1_mipi" ;; + *_mipi) + case "$1" in + ov4689_mipi | ov2718_mipi | imx290_mipi | imx274_mipi | imx326_mipi) + echo "$1" + ;; + esac + ;; + imx290_lvds | imx326_lvds) + echo "${1%_lvds}" + ;; ar0230 | ar0237 | imx172 | imx178 | imx226) echo "$1" ;; @@ -49,9 +63,12 @@ sensor_module() { } load_sensor() { - sensor=$(fw_printenv -n sensor 2>/dev/null) - [ -n "${sensor}" ] || sensor=$(ipcinfo -s 2>/dev/null) - sensor=$(echo "${sensor}" | tr 'A-Z' 'a-z') + sensor=$(fw_printenv -n sensor 2>/dev/null | tr 'A-Z' 'a-z') + # A failed probe may have been stored as "unknown". That must not stop + # this one from trying again. + if [ -z "${sensor}" ] || [ "${sensor}" = unknown ]; then + sensor=$(ipcinfo -s 2>/dev/null | tr 'A-Z' 'a-z') + fi if [ -z "${sensor}" ]; then log_vendor "No sensor in the environment and none detected"