501 lines
17 KiB
Bash
501 lines
17 KiB
Bash
#!/usr/bin/env bash
|
|
# SPDX-License-Identifier: (GPL-2.0-only OR MIT)
|
|
# Copyright (C) 2026 Amlogic, Inc. All rights reserved
|
|
################################################################################
|
|
# Amlbian ADLA Compilation Module
|
|
#
|
|
# Purpose: ADLA compilation with Hook support and aml-comp integration
|
|
# Provides: ADLA compilation, driver and library preparation
|
|
################################################################################
|
|
|
|
set -e
|
|
|
|
# Get script directory
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
AMLBIAN_DIR="$(dirname "$(dirname "${SCRIPT_DIR}")")"
|
|
BASE_DIR="$(dirname "$(dirname "${AMLBIAN_DIR}")")"
|
|
|
|
# Source common functions
|
|
if [[ -f "${AMLBIAN_DIR}/lib/function-common.sh" ]]; then
|
|
source "${AMLBIAN_DIR}/lib/function-common.sh"
|
|
fi
|
|
|
|
# ==============================================================================
|
|
# Shared Helper Functions
|
|
# ==============================================================================
|
|
|
|
# ------------------------------------------------------------------------------
|
|
# Step 1: Version and Package Information Definition
|
|
# ------------------------------------------------------------------------------
|
|
|
|
# Initialize common package metadata for ADLA driver
|
|
function _adla_driver_init_package_info() {
|
|
PKG_MAINTAINER="Armbian Build <build@armbian.com>"
|
|
PKG_DESCRIPTION="Amlogic ADLA NPU kernel driver"
|
|
PKG_NAME="aml-adla-driver"
|
|
PKG_VERSION="1.0"
|
|
PKG_ARCH="arm64"
|
|
DRIVER_NAME="adla_core"
|
|
DRIVER_MODULE="${DRIVER_NAME}.ko"
|
|
|
|
# Cross compilation settings
|
|
CROSS_COMPILE="${CROSS_COMPILE:-aarch64-linux-gnu-}"
|
|
}
|
|
|
|
# Initialize common package metadata for ADLA library
|
|
function _adla_lib_init_package_info() {
|
|
PKG_MAINTAINER="Armbian Build <build@armbian.com>"
|
|
PKG_DESCRIPTION="Amlogic ADLA NPU library"
|
|
PKG_NAME="aml-adla-lib"
|
|
PKG_VERSION="1.0"
|
|
PKG_ARCH="arm64"
|
|
LIB_DIR="aarch64-linux-gnu"
|
|
}
|
|
|
|
# ------------------------------------------------------------------------------
|
|
# Step 2: Build Directory Structure Setup
|
|
# ------------------------------------------------------------------------------
|
|
|
|
# Create layered build directory structure
|
|
# Parameters:
|
|
# $1 - base name (e.g. "${PKG_NAME}_${PKG_VERSION}_${PKG_ARCH}")
|
|
# Sets: TMP_DIR, BASE_BUILD_DIR, SOURCE_DIR, BUILD_DIR, INSTALL_DIR, PATCH_DIR,
|
|
# DEB_PACKAGE_DIR, DEBIAN_DIR
|
|
function _adla_create_build_dirs() {
|
|
local base_name="$1"
|
|
|
|
TMP_DIR="${AMLBIAN_DIR}/.tmp"
|
|
mkdir -p "${TMP_DIR}"
|
|
|
|
# 基础构建目录
|
|
BASE_BUILD_DIR="${TMP_DIR}/${base_name}"
|
|
|
|
rm -rf ${BASE_BUILD_DIR}
|
|
|
|
# 分层目录
|
|
SOURCE_DIR="${BASE_BUILD_DIR}/source" # 源码目录
|
|
BUILD_DIR="${BASE_BUILD_DIR}/build" # 编译目录
|
|
INSTALL_DIR="${BASE_BUILD_DIR}/install" # 安装目录
|
|
PATCH_DIR="${BASE_BUILD_DIR}/patch" # 补丁目录
|
|
|
|
# 创建所有目录
|
|
mkdir -p "${SOURCE_DIR}"
|
|
mkdir -p "${BUILD_DIR}"
|
|
mkdir -p "${INSTALL_DIR}"
|
|
mkdir -p "${PATCH_DIR}"
|
|
|
|
# 在BUILD_DIR下创建deb/包名目录
|
|
DEB_PACKAGE_DIR="${BUILD_DIR}/deb/${base_name}"
|
|
mkdir -p "${DEB_PACKAGE_DIR}"
|
|
|
|
# 安装目录的子目录
|
|
DEBIAN_DIR="${INSTALL_DIR}/DEBIAN"
|
|
mkdir -p "${DEBIAN_DIR}"
|
|
}
|
|
|
|
# Create standard install subdirectories for ADLA driver
|
|
function _adla_driver_create_install_dirs() {
|
|
local kernel_version="$1"
|
|
|
|
mkdir -p "${INSTALL_DIR}/lib/modules/${kernel_version}/kernel/drivers/amlogic/adla/"
|
|
}
|
|
|
|
# Create standard install subdirectories for ADLA library
|
|
function _adla_lib_create_install_dirs() {
|
|
mkdir -p "${INSTALL_DIR}/usr/lib"
|
|
}
|
|
|
|
# ------------------------------------------------------------------------------
|
|
# Step 3: Debian Packaging Scripts Creation
|
|
# ------------------------------------------------------------------------------
|
|
|
|
# Create Debian control file
|
|
# Parameters:
|
|
# $1 - package name
|
|
# $2 - package version
|
|
# $3 - package architecture
|
|
# $4 - maintainer
|
|
# $5 - description
|
|
# $6 - dependencies (optional)
|
|
# $7 - conflicts (optional)
|
|
# $8 - provides (optional)
|
|
# $9 - section (optional, default "kernel" for driver, "libs" for library)
|
|
function _adla_create_control_file() {
|
|
local pkg_name="$1"
|
|
local pkg_version="$2"
|
|
local pkg_arch="$3"
|
|
local maintainer="$4"
|
|
local description="$5"
|
|
local depends="${6:-}"
|
|
local conflicts="${7:-}"
|
|
local provides="${8:-}"
|
|
local section="${9:-kernel}"
|
|
|
|
display_alert "COMPILE-ADLA Creating control file DEBIAN/control" "info"
|
|
cat > "${DEBIAN_DIR}/control" <<EOF
|
|
Package: ${pkg_name}
|
|
Version: ${pkg_version}
|
|
Architecture: ${pkg_arch}
|
|
Maintainer: ${maintainer}
|
|
Depends: ${depends}
|
|
Conflicts: ${conflicts}
|
|
Provides: ${provides}
|
|
Section: ${section}
|
|
Priority: optional
|
|
Description: ${description}
|
|
EOF
|
|
}
|
|
|
|
# Create postinst script for ADLA driver
|
|
function _adla_driver_create_postinst() {
|
|
local kernel_version="$1"
|
|
display_alert "COMPILE-ADLA-DRIVER Creating post-installation script DEBIAN/postinst" "info"
|
|
cat > "${DEBIAN_DIR}/postinst" << EOF
|
|
#!/bin/sh
|
|
set -e
|
|
|
|
if [ "\$1" = "configure" ]; then
|
|
# Run depmod to update module dependencies
|
|
if [ -d "/lib/modules/${kernel_version}" ]; then
|
|
depmod -a "${kernel_version}"
|
|
else
|
|
echo "Warning: /lib/modules/${kernel_version} not found, skipping depmod"
|
|
fi
|
|
|
|
# Check if module can be loaded
|
|
if modprobe -n adla_core 2>/dev/null; then
|
|
echo "ADLA adla_core module can be loaded with 'modprobe adla_core'"
|
|
fi
|
|
|
|
echo "ADLA NPU driver installed successfully."
|
|
echo "Run 'sudo modprobe adla_core' to load the module."
|
|
fi
|
|
|
|
exit 0
|
|
EOF
|
|
chmod 755 "${DEBIAN_DIR}/postinst"
|
|
}
|
|
|
|
# Create prerm script for ADLA driver
|
|
function _adla_driver_create_prerm() {
|
|
local kernel_version="$1"
|
|
display_alert "COMPILE-ADLA-DRIVER Creating pre-removal script DEBIAN/prerm" "info"
|
|
cat > "${DEBIAN_DIR}/prerm" << EOF
|
|
#!/bin/sh
|
|
set -e
|
|
|
|
if [ "\$1" = "remove" ] || [ "\$1" = "deconfigure" ]; then
|
|
# Unload module if it's loaded
|
|
if lsmod | grep -q "adla_core"; then
|
|
modprobe -r adla_core 2>/dev/null || true
|
|
fi
|
|
|
|
# Remove module from kernel modules directory
|
|
rm -f /lib/modules/${kernel_version}/kernel/drivers/amlogic/adla/adla_core.ko 2>/dev/null || true
|
|
fi
|
|
|
|
exit 0
|
|
EOF
|
|
chmod 755 "${DEBIAN_DIR}/prerm"
|
|
}
|
|
|
|
# Create postinst script for ADLA library
|
|
function _adla_lib_create_postinst() {
|
|
display_alert "COMPILE-ADLA-LIB Creating post-installation script DEBIAN/postinst" "info"
|
|
cat > "${DEBIAN_DIR}/postinst" << EOF
|
|
#!/bin/sh
|
|
set -e
|
|
|
|
if [ "\$1" = "configure" ]; then
|
|
# Run ldconfig to update library cache
|
|
ldconfig
|
|
|
|
echo "ADLA NPU library installed successfully."
|
|
echo "The library files are installed in /usr/lib/"
|
|
fi
|
|
|
|
exit 0
|
|
EOF
|
|
chmod 755 "${DEBIAN_DIR}/postinst"
|
|
}
|
|
|
|
# Create prerm script for ADLA library
|
|
function _adla_lib_create_prerm() {
|
|
display_alert "COMPILE-ADLA-LIB Creating pre-removal script DEBIAN/prerm" "info"
|
|
cat > "${DEBIAN_DIR}/prerm" << EOF
|
|
#!/bin/sh
|
|
set -e
|
|
|
|
if [ "\$1" = "remove" ] || [ "\$1" = "deconfigure" ]; then
|
|
# Run ldconfig to update library cache
|
|
ldconfig
|
|
|
|
echo "ADLA NPU library removed successfully."
|
|
fi
|
|
|
|
exit 0
|
|
EOF
|
|
chmod 755 "${DEBIAN_DIR}/prerm"
|
|
}
|
|
|
|
# ------------------------------------------------------------------------------
|
|
# Step 4: Source/Vendor File Copying
|
|
# ------------------------------------------------------------------------------
|
|
|
|
# Copy ADLA driver files to install directory
|
|
function _adla_driver_copy_files() {
|
|
local kernel_version="$1"
|
|
display_alert "COMPILE-ADLA-DRIVER Copying ADLA driver files" "info"
|
|
|
|
local module_dir="${INSTALL_DIR}/lib/modules/${kernel_version}/kernel/drivers/amlogic/adla/"
|
|
|
|
# Source directory
|
|
local SRC_DIR="${BASE_DIR}/aml-comp/hardware/amlogic/adla_driver"
|
|
|
|
# Check if source exists
|
|
if [[ ! -d "${SRC_DIR}" ]]; then
|
|
display_alert "COMPILE-ADLA-DRIVER ADLA driver source code not found. Expected at: ${SRC_DIR}" "error"
|
|
exit 1
|
|
fi
|
|
|
|
# Copy source to source directory
|
|
display_alert "COMPILE-ADLA-DRIVER Copying source files to source directory" "info"
|
|
cp -r "${SRC_DIR}/"* "${SOURCE_DIR}/"
|
|
|
|
# Set up environment variables for build
|
|
KERNELDIR="${BASE_DIR}/aml-comp/kernel/aml-6.12"
|
|
STAGING_KERNEL_DIR="${KERNELDIR}"
|
|
|
|
# Check for kernel headers
|
|
if [[ ! -d "${KERNELDIR}" ]]; then
|
|
display_alert "COMPILE-ADLA-DRIVER Kernel headers directory not found at: ${KERNELDIR}" "error"
|
|
exit 1
|
|
fi
|
|
|
|
# Create symbolic link in common drivers directory (as per Yocto recipe)
|
|
local COMMON_DRIVERS_DIR="common_drivers/drivers"
|
|
if [[ -d "${KERNELDIR}/build" ]]; then
|
|
display_alert "COMPILE-ADLA-DRIVER Creating symbolic link in common drivers directory" "info"
|
|
mkdir -p "${KERNELDIR}/${COMMON_DRIVERS_DIR}"
|
|
ln -sfn "${SOURCE_DIR}" "${KERNELDIR}/${COMMON_DRIVERS_DIR}/adla_driver"
|
|
fi
|
|
|
|
# Change to source directory
|
|
cd "${SOURCE_DIR}"
|
|
|
|
# Build the kernel module
|
|
display_alert "COMPILE-ADLA-DRIVER Building ADLA NPU kernel module for kernel ${kernel_version}" "info"
|
|
|
|
# Set up build environment based on Yocto recipe
|
|
local EXTRA_OEMAKE="KOUT_DIR=${COMMON_DRIVERS_DIR}/adla_driver KERNEL_SRC=${KERNELDIR} KDIR=${KERNELDIR} ARCH=${PKG_ARCH} CROSS_COMPILE=${CROSS_COMPILE} KBUILD_OUTPUT=${KERNELDIR}/build Building_Yocto=1"
|
|
|
|
# Build the module
|
|
display_alert "COMPILE-ADLA-DRIVER Running make command" "info"
|
|
make -C "${SOURCE_DIR}" ${EXTRA_OEMAKE} modules
|
|
|
|
# Check if module was built
|
|
local KBUILD_OUTPUT="${KERNELDIR}/build"
|
|
if [[ -f "${KBUILD_OUTPUT}/${COMMON_DRIVERS_DIR}/adla_driver/adla/kmd/${DRIVER_MODULE}" ]]; then
|
|
display_alert "COMPILE-ADLA-DRIVER Module built successfully ${DRIVER_MODULE}" "info"
|
|
|
|
# Install module to INSTALL_DIR
|
|
display_alert "COMPILE-ADLA-DRIVER Installing module to install directory ${module_dir}" "info"
|
|
install -m 0644 "${KBUILD_OUTPUT}/${COMMON_DRIVERS_DIR}/adla_driver/adla/kmd/${DRIVER_MODULE}" "${module_dir}/"
|
|
|
|
# Remove symbolic link (as per Yocto recipe)
|
|
if [[ -L "${COMMON_DRIVERS_DIR}/adla_driver" ]]; then
|
|
rm "${COMMON_DRIVERS_DIR}/adla_driver"
|
|
fi
|
|
else
|
|
display_alert "COMPILE-ADLA-DRIVER Module build failed. Could not find ${DRIVER_MODULE}" "err"
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
# Copy ADLA library files to install directory
|
|
function _adla_lib_copy_files() {
|
|
display_alert "COMPILE-ADLA-LIB Copying ADLA library files" "info"
|
|
|
|
# Source directory
|
|
local SRC_DIR="${BASE_DIR}/aml-comp/vendor/amlogic/adla_lib"
|
|
|
|
# Check if source exists
|
|
if [[ ! -d "${SRC_DIR}" ]]; then
|
|
display_alert "COMPILE-ADLA-LIB ADLA library source code not found. Expected at: ${SRC_DIR}" "error"
|
|
exit 1
|
|
fi
|
|
|
|
# Copy source to source directory
|
|
display_alert "COMPILE-ADLA-LIB Copying source files to source directory" "info"
|
|
cp -r "${SRC_DIR}/"* "${SOURCE_DIR}/"
|
|
|
|
# Determine the correct library path based on configuration
|
|
local AML_CUST_SPEC="${AML_CUST_SPEC:-}"
|
|
local HOST_ARCH="${HOST_ARCH:-aarch64}"
|
|
|
|
display_alert "COMPILE-ADLA-LIB Building ADLA library AML_CUST_SPEC ${AML_CUST_SPEC}" "info"
|
|
display_alert "COMPILE-ADLA-LIB Building ADLA library HOST_ARCH ${HOST_ARCH}" "info"
|
|
|
|
local LIB_SOURCE_PATH=""
|
|
if [ "${AML_CUST_SPEC}" = "CUST_L_HUB_F" ]; then
|
|
if [ "${HOST_ARCH}" = "aarch64" ]; then
|
|
LIB_SOURCE_PATH="${SOURCE_DIR}/libraryso/starf/lib64"
|
|
else
|
|
LIB_SOURCE_PATH="${SOURCE_DIR}/libraryso/starf/lib"
|
|
fi
|
|
else
|
|
if [ "${HOST_ARCH}" = "aarch64" ]; then
|
|
LIB_SOURCE_PATH="${SOURCE_DIR}/libraryso/yocto/lib64"
|
|
else
|
|
LIB_SOURCE_PATH="${SOURCE_DIR}/libraryso/yocto/lib"
|
|
fi
|
|
fi
|
|
|
|
display_alert "COMPILE-ADLA-LIB Library source path: ${LIB_SOURCE_PATH}" "info"
|
|
|
|
# Check if library directory exists
|
|
if [[ ! -d "${LIB_SOURCE_PATH}" ]]; then
|
|
display_alert "COMPILE-ADLA-LIB ADLA library source not found at: ${LIB_SOURCE_PATH}" "err"
|
|
exit 1
|
|
fi
|
|
|
|
# Install .so files to INSTALL_DIR
|
|
display_alert "COMPILE-ADLA-LIB Installing ADLA library files to install directory" "info"
|
|
install -m 0644 "${LIB_SOURCE_PATH}"/*.so* "${INSTALL_DIR}/usr/lib/"
|
|
}
|
|
|
|
# ------------------------------------------------------------------------------
|
|
# Step 5: Debian Package Building
|
|
# ------------------------------------------------------------------------------
|
|
|
|
# Build Debian package from install directory
|
|
# Parameters:
|
|
# $1 - log prefix (e.g. "COMPILE-ADLA-DRIVER" or "COMPILE-ADLA-LIB")
|
|
# $2 - output deb filename (without path)
|
|
# Sets: OUTPUT_DEB
|
|
function _adla_build_deb_package() {
|
|
local log_prefix="$1"
|
|
local output_deb_name="$2"
|
|
|
|
# 将install目录内容拷贝到deb目录
|
|
display_alert "Copying install directory to deb package directory ${log_prefix}" "info"
|
|
cp -r "${INSTALL_DIR}/"* "${DEB_PACKAGE_DIR}/" 2>&1
|
|
|
|
# 基于deb目录打包
|
|
display_alert "Building Debian package from deb directory ${log_prefix}" "info"
|
|
dpkg-deb --build "${DEB_PACKAGE_DIR}" 2>&1
|
|
|
|
# Move to output directory
|
|
OUTPUT_DEB="${SRC}/output/${output_deb_name}"
|
|
mkdir -p "$(dirname "${OUTPUT_DEB}")"
|
|
mv "${DEB_PACKAGE_DIR}.deb" "${OUTPUT_DEB}"
|
|
|
|
display_alert "${log_prefix} Package built successfully ${output_deb_name}" "info"
|
|
display_alert "${log_prefix} Build directory preserved ${BASE_BUILD_DIR}" "info"
|
|
}
|
|
|
|
# Display build directory info
|
|
# Parameters:
|
|
# $1 - log prefix
|
|
function _adla_display_build_info() {
|
|
local log_prefix="$1"
|
|
display_alert "${log_prefix} Source dir: ${SOURCE_DIR}" "info"
|
|
display_alert "${log_prefix} Build dir: ${BUILD_DIR}" "info"
|
|
display_alert "${log_prefix} Install dir: ${INSTALL_DIR}" "info"
|
|
display_alert "${log_prefix} Patch dir: ${PATCH_DIR}" "info"
|
|
display_alert "${log_prefix} Deb package dir: ${DEB_PACKAGE_DIR}" "info"
|
|
}
|
|
|
|
# ==============================================================================
|
|
# Main Build Functions (Entry Points)
|
|
# ==============================================================================
|
|
|
|
# ------------------------------------------------------------------------------
|
|
# ADLA Driver Build
|
|
# Entry point: amlbian_build_adla_driver
|
|
# ------------------------------------------------------------------------------
|
|
|
|
function amlbian_build_adla_driver() {
|
|
set -e
|
|
|
|
# ---- Step 1: Version and Package Information ----
|
|
_adla_driver_init_package_info
|
|
# amlbian_checkout_toolchain
|
|
|
|
# Get kernel version for packaging
|
|
local KERNEL_VERSION=$(make -s -C "${BASE_DIR}/aml-comp/kernel/aml-6.12/build" kernelrelease 2>/dev/null || true)
|
|
if [[ -z "${KERNEL_VERSION}" ]]; then
|
|
KERNEL_VERSION="unknown-$(date +%Y%m%d)"
|
|
fi
|
|
display_alert "COMPILE-ADLA-DRIVER Building ADLA driver for kernel ${KERNEL_VERSION}" "info"
|
|
|
|
# ---- Step 2: Build Directory Setup ----
|
|
_adla_create_build_dirs "${PKG_NAME}_${PKG_VERSION}_${PKG_ARCH}"
|
|
_adla_driver_create_install_dirs "${KERNEL_VERSION}"
|
|
_adla_display_build_info "COMPILE-ADLA-DRIVER"
|
|
|
|
# ---- Step 3: Debian Packaging Scripts ----
|
|
_adla_create_control_file \
|
|
"${PKG_NAME}" "${PKG_VERSION}" "${PKG_ARCH}" "${PKG_MAINTAINER}" \
|
|
"${PKG_DESCRIPTION}" "" "" "" "kernel"
|
|
|
|
_adla_driver_create_postinst "${KERNEL_VERSION}"
|
|
_adla_driver_create_prerm "${KERNEL_VERSION}"
|
|
|
|
# ---- Step 4: Copy Source/Vendor Files ----
|
|
_adla_driver_copy_files "${KERNEL_VERSION}"
|
|
|
|
# ---- Step 5: Build Debian Package ----
|
|
_adla_build_deb_package "COMPILE-ADLA-DRIVER" "${PKG_NAME}_${PKG_VERSION}_${KERNEL_VERSION}_${PKG_ARCH}.deb"
|
|
|
|
return 0
|
|
}
|
|
|
|
# ------------------------------------------------------------------------------
|
|
# ADLA Library Build
|
|
# Entry point: amlbian_build_adla_lib
|
|
# ------------------------------------------------------------------------------
|
|
|
|
function amlbian_build_adla_lib() {
|
|
# ---- Step 1: Version and Package Information ----
|
|
_adla_lib_init_package_info
|
|
# amlbian_checkout_toolchain
|
|
|
|
# Get kernel version for packaging
|
|
local KERNEL_VERSION=$(make -s -C "${BASE_DIR}/aml-comp/kernel/aml-6.12/build" kernelrelease 2>/dev/null || true)
|
|
if [[ -z "${KERNEL_VERSION}" ]]; then
|
|
KERNEL_VERSION="unknown-$(date +%Y%m%d)"
|
|
fi
|
|
display_alert "COMPILE-ADLA-LIB Building ADLA library for kernel ${KERNEL_VERSION}" "info"
|
|
|
|
# ---- Step 2: Build Directory Setup ----
|
|
_adla_create_build_dirs "${PKG_NAME}_${PKG_VERSION}_${PKG_ARCH}"
|
|
_adla_lib_create_install_dirs
|
|
_adla_display_build_info "COMPILE-ADLA-LIB"
|
|
|
|
# ---- Step 3: Debian Packaging Scripts ----
|
|
_adla_create_control_file \
|
|
"${PKG_NAME}" "${PKG_VERSION}" "${PKG_ARCH}" "${PKG_MAINTAINER}" \
|
|
"${PKG_DESCRIPTION}" "" "" "" "libs"
|
|
|
|
_adla_lib_create_postinst
|
|
_adla_lib_create_prerm
|
|
|
|
# ---- Step 4: Copy Source/Vendor Files ----
|
|
_adla_lib_copy_files
|
|
|
|
# ---- Step 5: Build Debian Package ----
|
|
_adla_build_deb_package "COMPILE-ADLA-LIB" "${PKG_NAME}_${PKG_VERSION}_${PKG_ARCH}.deb"
|
|
|
|
return 0
|
|
}
|
|
|
|
# ------------------------------------------------------------------------------
|
|
# Main ADLA Build Function
|
|
# ------------------------------------------------------------------------------
|
|
|
|
function amlbian_build_adla() {
|
|
amlbian_build_adla_driver
|
|
amlbian_build_adla_lib
|
|
}
|