定制 Linux Kernel Driver 編譯示例
1). 簡(jiǎn)介
Linux Kernel 通常包含了常見的硬件驅(qū)動(dòng),只需要通過 Kernel Configuration 來使能即可。不過有的時(shí)候還是會(huì)遇到需要針對(duì)特定硬件或者功能來開發(fā)定制化驅(qū)動(dòng)的場(chǎng)景,本文就用一個(gè)簡(jiǎn)單的 Hello World 設(shè)備驅(qū)動(dòng)示例相關(guān)驅(qū)動(dòng)的開發(fā)編譯調(diào)試流程。
本文所演示的平臺(tái)來自于 Toradex Verdin i.MX8MP 嵌入式平臺(tái)。
2. 準(zhǔn)備
a). Verdin i.MX8MP ARM核心版配合Dahlia 載板,并連接調(diào)試串口用于測(cè)試
3). Linux Kernel 源碼下載和編譯
a). 參考這里文章說明,下載適用于 Verdin iMX8MP 的 Linux Kernel 源碼,以及配置交叉編譯 SDK。本文演示使用基于 NXP Downstream Kernel 版本進(jìn)行操作,如果需要使用 Upstream Kernel 版本,除了上述文章說明也可以參考這里
./ 首先下載對(duì)應(yīng)版本的 Linux Kernel 源代碼。如果是 Upstream Kernel 版本,下載源碼后還需要應(yīng)用一系列補(bǔ)丁文件:
---------------------------------------
$ cd
$ git clone -b toradex_6.6-2.2.x-imx git://git.toradex.com/linux-toradex.git
---------------------------------------
./ 參考這里說明下載交叉編譯 tool chain,根據(jù)具體使用應(yīng)用平臺(tái)選擇 32-bit 還是 64-bit 版本,本文這里針對(duì) i.MX8MP 平臺(tái)使用 64-bit 版本:
---------------------------------------
$ cd ~
$ wget -O arm-gnu-toolchain-12.3.rel1-x86_64-aarch64-none-linux-gnu.tar.xz "https://developer.arm.com/-/media/Files/downloads/gnu/12.3.rel1/binrel/arm-gnu-toolchain-12.3.rel1-x86_64-aarch64-none-linux-gnu.tar.xz?rev=cf8baa0ef2e54e9286f0409cdda4f66c&hash=4E1BA6BFC2C09EA04DBD36C393C9DD3A"
$ tar xvf arm-gnu-toolchain-12.3.rel1-x86_64-aarch64-none-linux-gnu.tar.xz
$ ln -s arm-gnu-toolchain-12.3.rel1-x86_64-aarch64-none-linux-gnu gcc-linaro
---------------------------------------
./ 在準(zhǔn)備進(jìn)行后續(xù)編譯的 Terminal 終端窗口下 export 相關(guān) tool chain 環(huán)境變量:
---------------------------------------
$ export ARCH=arm64
$ export DTC_FLAGS="-@"
$ export PATH=~/gcc-linaro/bin/:$PATH
$ export CROSS_COMPILE=aarch64-none-linux-gnu-
---------------------------------------
b). 參考這里說明下載針對(duì) Verdin i.MX8MP 硬件的初始化 Kernel Configuration 文件,然后配置
---------------------------------------
$ cd
$ cp kernel-config linux-toradex/.config
$ cd linux-toradex/
$ make olddefconfig
---------------------------------------
c). 由于 NXP i.MX8 系列 SoC 默認(rèn) Yocto Linux GPU 驅(qū)動(dòng)使用 out of tree 驅(qū)動(dòng),而單獨(dú)編譯 Kernel 源碼時(shí)候則需要將 built-in 版本 GPU 驅(qū)動(dòng)使能,否則顯示相關(guān)就會(huì)異常。當(dāng)然后續(xù)如果采用 built-in 方式編譯定制化驅(qū)動(dòng)也需要在這里使能
---------------------------------------
$ make menuconfig
Device Drivers > MXC support drivers > MXC Vivante GPU support
<*> MXC Vivante GPU support
---------------------------------------
./ 當(dāng)然也可以將如下配置直接添加到上述步驟 b 下載的 kernel-config 文件中去使能
---------------------------------------
CONFIG_MXC_GPU_VIV=y
---------------------------------------
d). 編譯 Kernel Binary Image
---------------------------------------
$ make -j$(nproc) Image.gz 2>&1 | tee build.log
---------------------------------------
e). 編譯和打包 Kernel Modules
---------------------------------------
$ make -j$(nproc) modules
//在 Kernel 源碼目錄 linux-toradex 外創(chuàng)建 kernel-modules 目錄
$ mkdir ../kernel-modules
// 通過pwd 命令獲取 kernel-modules 目錄路徑
$ cd ../kernel-modules
$ pwd
// 部署 kernel modules
$ cd ../linux-toradex
$ sudo -E env "PATH=$PATH" make INSTALL_MOD_PATH=
// 打包 kernel modules
$ cd ../kernel-modules
$ tar cjvf kernel-modules.tar.bz2 lib/modules/*
---------------------------------------
f). 上傳生成的 Image.gz 和 kenrel-modules.tar.bz2 文件到 Verdin i.MX8MP 模塊,這里使用 ssh 網(wǎng)絡(luò)上傳,也可以使用 SD卡/U盤復(fù)制
---------------------------------------
$ cd ../linux-toradex/
$ scp arch/arm64/boot/Image.gz ../kernel-modules/kernel-modules.tar.bz2 root@
---------------------------------------
g). 在 Verdin i.MX8MP 上面部署新的 Linux Kernel 和 Kernel Modules,重啟后新的部署生效
---------------------------------------
root@verdin-imx8mp-06849028:~# cd /home/root
root@verdin-imx8mp-06849028:/home/root# cp Image.gz /boot/
root@verdin-imx8mp-06849028:/home/root# cd /
root@verdin-imx8mp-06849028:/# tar xvf ~/kernel-modules.tar.bz2
root@verdin-imx8mp-06849028:/# reboot
---------------------------------------
4). 定制 Linux Driver 采用 Out-of-Tree 方式單獨(dú)編譯部署
a). 在 Kernel 源碼目錄 linux-toradex 外創(chuàng)建定制驅(qū)動(dòng)工作目錄,并創(chuàng)建驅(qū)動(dòng)源碼 c 代碼以及 Makefile 文件
-------------------------------
$ mkdir ../hello-world-driver
$ cd ../hello-world-driver/
$ tree -L 1
.
├── hello_world.c
└── Makefile
-------------------------------
./ 驅(qū)動(dòng)源代碼文件為 hello_world.c,完整代碼如下:
-------------------------------
#include
#include
#include
#include
static struct class *hello_class;
static struct device *hello_device;
static int __init hello_init(void)
{
int ret;
// 創(chuàng)建一個(gè)設(shè)備類
hello_class = class_create("hello_debug");
if (IS_ERR(hello_class)) {
ret = PTR_ERR(hello_class);
pr_err("Failed to create class: %d\n", ret);
return ret;
}
// 創(chuàng)建一個(gè)設(shè)備實(shí)例
hello_device = device_create(hello_class, NULL, 0, NULL, "hello%d", 0);
if (IS_ERR(hello_device)) {
ret = PTR_ERR(hello_device);
pr_err("Failed to create device: %d\n", ret);
class_destroy(hello_class);
return ret;
}
// 使用 dev_dbg 輸出調(diào)試信息
dev_dbg(hello_device, "Hello, world! Debug message enabled.\n");
pr_info("Hello module loaded successfully.\n");
return 0;
}
static void __exit hello_exit(void)
{
dev_dbg(hello_device, "Goodbye, world! Debug message enabled.\n");
device_destroy(hello_class, 0);
class_destroy(hello_class);
pr_info("Hello module unloaded.\n");
}
module_init(hello_init);
module_exit(hello_exit);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("A simple hello-world kernel module with dev_dbg");
MODULE_AUTHOR("Toradex");
-------------------------------
### 代碼創(chuàng)建一個(gè) hello 設(shè)備類和實(shí)例,在正常掛載和移除時(shí)候通過 pr_info 命令來打印正常系統(tǒng)信息;同時(shí)通過 dev_dbg 命令來打印調(diào)試信息 ###
-------------------------------
// module loaded
dev_dbg(hello_device, "Hello, world! Debug message enabled.\n");
pr_info("Hello module loaded successfully.\n");
// module unloaded
dev_dbg(hello_device, "Goodbye, world! Debug message enabled.\n");
pr_info("Hello module unloaded.\n");
-------------------------------
./ Makefile 文件完整代碼:
-------------------------------
obj-m += hello_world.o
# Linux Kernel Path(Modify accordingly)
KDIR ?= /
all:
make -C $(KDIR) M=$(PWD) ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE) modules
clean:
make -C $(KDIR) M=$(PWD) ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE) clean
-------------------------------
### KDIR 指定 linux-toradex Kernel 源代碼路徑,根據(jù)實(shí)際情況修改 ###
b). 編譯并將生成的 hello_world.ko 驅(qū)動(dòng)文件上傳到 Verdin i.MX8MP $HOME 目錄
-------------------------------
$ make
$ scp hello_world.ko root@
-------------------------------
c). 加載測(cè)試,由于未使能 DEBUG,因此只有 pr_info 信息被打印輸出(確保Linux log level 設(shè)置要支持,詳細(xì)說明可以查看這里)
-------------------------------
root@verdin-imx8mp-06849028:~# insmod hello_world.ko
[ 3746.252795] hello_world: loading out-of-tree module taints kernel.
[ 3746.261753] Hello module loaded successfully.
root@verdin-imx8mp-06849028:~# dmesg |grep hello
[ 3746.252795] hello_world: loading out-of-tree module taints kernel.
root@verdin-imx8mp-06849028:~# rmmod hello_world.ko
[ 3808.225680] Hello module unloaded.
root@verdin-imx8mp-06849028:~# dmesg |grep hello
[ 3746.252795] hello_world: loading out-of-tree module taints kernel.
-------------------------------
d). 使能靜態(tài) DEBUG 測(cè)試 (需要重新編譯驅(qū)動(dòng)源代碼)
./ Linux Kernel 支持 debug 信息顯示,需要如下配置:
-------------------------------
Kernel hacking → Kernel debugging (CONFIG_DEBUG_KERNEL=y)
Kernel hacking → Compile-time checks and compiler options Debug information → Disable debug information (CONFIG_DEBUG_INFO_NONE=y)
Kernel hacking → Debug Filesystem (CONFIG_DEBUG_FS=y)
-------------------------------
./ 編譯定制驅(qū)動(dòng)源碼時(shí)候使能 DEBUG:
i). 在驅(qū)動(dòng)源碼 C 文件所有頭文件聲明之前增加如下聲明:
-------------------------------
#define DEBUG
-------------------------------
Ii). 在 MakeFile 文件增加如下任一 CFLAGS 聲明:
-------------------------------
// 針對(duì)某一個(gè)驅(qū)動(dòng)文件生效
CFLAGS_hello_world.o := -DDEBUG
// 對(duì)于 Makefile 編譯的所有驅(qū)動(dòng)文件生效
EXTRA_CFLAGS += -DDEBUG
-------------------------------
./ 通過上述任一種方式使能 DEBUG 后加載測(cè)試,debug 信息被打印到 Linux log buffer,可以通過 dmesg 查看到:
-------------------------------
root@verdin-imx8mp-06849028:~# insmod hello_world.ko
[ 635.927571] hello_world: loading out-of-tree module taints kernel.
[ 635.934286] Hello module loaded successfully.
root@verdin-imx8mp-06849028:~# dmesg |grep hello
[ 635.927571] hello_world: loading out-of-tree module taints kernel.
[ 635.934274] hello_debug hello0: Hello, world! Debug message enabled.
root@verdin-imx8mp-06849028:~# rmmod hello_world.ko
[ 679.999629] Hello module unloaded.
root@verdin-imx8mp-06849028:~# dmesg |grep hello
[ 635.927571] hello_world: loading out-of-tree module taints kernel.
[ 635.934274] hello_debug hello0: Hello, world! Debug message enabled.
[ 679.999479] hello_debug hello0: Goodbye, world! Debug message enabled.
-------------------------------
e). 使能動(dòng)態(tài) DEBUG 測(cè)試 (無需重新編譯源代碼)
./ Linux Kernel 支持動(dòng)態(tài) debug 顯示,和靜態(tài) debug 信息相比優(yōu)勢(shì)是無需重新編譯驅(qū)動(dòng)或者 Kernel 源代碼,而且沒有靜態(tài)編譯 debug 代碼負(fù)擔(dān),只在需要顯示的時(shí)候動(dòng)態(tài)顯示。
./ 支持 Dynamic Debug 需要使能如下 Kernel 配置,更多詳細(xì)說明請(qǐng)見這里:
-------------------------------
Kernel hacking → Debug Filesystem (CONFIG_DEBUG_FS=y)
Kernel hacking → printk and dmesg options → Enable dynamic printk() support (CONFIG_DYNAMIC_DEBUG=y)
-------------------------------
./ 使能 Hello_world 驅(qū)動(dòng) Dynamic Debug 功能:
-------------------------------
// 如果已經(jīng)默認(rèn)掛載則不需要重復(fù)操作
$ mount -t debugfs none /sys/kernel/debug/
// 加載驅(qū)動(dòng),此時(shí) DEBUG 未使能
root@verdin-imx8mp-06849028:~# insmod hello_world.ko
[ 359.310527] hello_world: loading out-of-tree module taints kernel.
[ 359.317172] Hello module loaded successfully.
root@verdin-imx8mp-06849028:~# dmesg |grep hello
[ 359.310527] hello_world: loading out-of-tree module taints kernel.
// Dynamic Debug 也未使能 hello_world 驅(qū)動(dòng) Debug 信息打印
root@verdin-imx8mp-06849028:~# cat /sys/kernel/debug/dynamic_debug/control |grep hello
/home/simon/local/tdx_source_local/imx8/v7.2-20250619/hello-world-driver/hello_world.c:40 [hello
_world]hello_exit =_ "Goodbye, world! Debug message enabled.\n"
/home/simon/local/tdx_source_local/imx8/v7.2-20250619/hello-world-driver/hello_world.c:32 [hello
_world]hello_init =_ "Hello, world! Debug message enabled.\n"
// 使能 Dynamic Debug
root@verdin-imx8mp-06849028:~# echo "file hello_world.c +p" > /sys/kernel/debug/dynamic_debug/co
ntrol
root@verdin-imx8mp-06849028:~# cat /sys/kernel/debug/dynamic_debug/control |grep hello
/home/simon/local/tdx_source_local/imx8/v7.2-20250619/hello-world-driver/hello_world.c:40 [hello
_world]hello_exit =p "Goodbye, world! Debug message enabled.\n"
/home/simon/local/tdx_source_local/imx8/v7.2-20250619/hello-world-driver/hello_world.c:32 [hello
_world]hello_init =p "Hello, world! Debug message enabled.\n"
// 卸載驅(qū)動(dòng),此時(shí) Dynamic Debug 已經(jīng)生效,Debug 信息已經(jīng)可以打印
root@verdin-imx8mp-06849028:~# rmmod hello_world.ko
[ 400.480206] Hello module unloaded.
root@verdin-imx8mp-06849028:~# dmesg |grep hello
[ 359.310527] hello_world: loading out-of-tree module taints kernel.
[ 400.480054] hello_debug hello0: Goodbye, world! Debug message enabled.
-------------------------------
5). 定制 Linux Driver 采用集成到 Linux Kernel 源代碼中一起編譯部署
a). 在 Kernel 源碼目錄 linux-toradex 外創(chuàng)建定制驅(qū)動(dòng)工作目錄,并創(chuàng)建驅(qū)動(dòng)源碼 c 代碼以及 Kconfig 和 Makefile 文件
-------------------------------
// 進(jìn)入 Linux Kernel 源碼
$ cd
// 在 Character 驅(qū)動(dòng)下創(chuàng)建 Hello_world 驅(qū)動(dòng)
$ mkdr drivers/char/hello_world_driver
$ cd drivers/char/hello_world_driver/
$ tree -L 1
.
├── hello_world.c
├── Kconfig
└── Makefile
-------------------------------
./ 驅(qū)動(dòng)源代碼文件 hello_world.c 和章節(jié)3 中一致無需任何修改。
./ Kconfig 文件完整代碼,用于 Kernel Configuration 的相關(guān)驅(qū)動(dòng)配置說明:
------------------------------
#
# Hello World Driver
#
config HELLO_WORLD
tristate "Hello World Driver"
depends on ARM || ARM64
help
This is a simple hello world driver for testing.
------------------------------
./ Makefile 文件完整代碼:
------------------------------
#
# Makefile for hello world driver
#
#
obj-$(CONFIG_HELLO_WORLD) += hello_world.o
# Enable Debug Info
#CFLAGS_hello_world.o := -DDEBUG
#EXTRA_CFLAGS += -DDEBUG
------------------------------
b). 修改高一級(jí) Kconfig 和 Makefile 文件增加 Hello_world 驅(qū)動(dòng)相關(guān)配置
------------------------------
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
index 86cb16e65d88..d9c09281c841 100644
--- a/drivers/char/Kconfig
+++ b/drivers/char/Kconfig
@@ -423,5 +423,6 @@ config ADI
driver include crash and makedumpfile.
source "drivers/char/imx_amp/Kconfig"
+source "drivers/char/hello_world_driver/Kconfig"
endmenu
diff --git a/drivers/char/Makefile b/drivers/char/Makefile
index b84b1a6db304..142d00e1d883 100644
--- a/drivers/char/Makefile
+++ b/drivers/char/Makefile
@@ -45,3 +45,4 @@ obj-$(CONFIG_XILLYBUS_CLASS) += xillybus/
obj-$(CONFIG_POWERNV_OP_PANEL) += powernv-op-panel.o
obj-$(CONFIG_ADI) += adi.o
obj-$(CONFIG_HAVE_IMX_AMP) += imx_amp/
+obj-$(CONFIG_HELLO_WORLD) += hello_world_driver/
------------------------------
c). Built-in 方式編譯,將 Hello_world 驅(qū)動(dòng)編譯進(jìn) Kernel Binary Image
./ 配置內(nèi)核并重新編譯 Kernel Image:
------------------------------
$ cd
$ make menuconfig
Device Drivers > Character devices
<*> Hello World Driver
$ make -j$(nproc) Image.gz 2>&1 | tee build.log
------------------------------
./ 和章節(jié) 3 同樣方法將 Kernel Image 上傳到 Verdin i.MX8MP 并部署后重啟測(cè)試,驅(qū)動(dòng)加載成功:
------------------------------
root@verdin-imx8mp-06849028:~# dmesg |grep Hello
[ 1.577391] Hello module loaded successfully.
------------------------------
./ 使能靜態(tài) DEBUG 功能:
### 兩種使能代碼方式 ###
i). 在驅(qū)動(dòng)源碼 C 文件所有頭文件聲明之前增加如下聲明:
-------------------------------
#define DEBUG
-------------------------------
Ii). 在 MakeFile 文件增加如下任一 CFLAGS 聲明:
-------------------------------
// 針對(duì)某一個(gè)驅(qū)動(dòng)文件生效
CFLAGS_hello_world.o := -DDEBUG
// 針對(duì)一個(gè) Kernel 配置驅(qū)動(dòng)生效
ccflags-$(CONFIG_HELLO_WORLD) += -DDEBUG
// 對(duì)于 Makefile 編譯的所有配置驅(qū)動(dòng)生效
EXTRA_CFLAGS += -DDEBUG
-------------------------------
### 通過上述任一種方式使能 DEBUG 后加載測(cè)試,debug 信息被打印到 Linux log buffer,可以通過 dmesg 查看到 ###
-------------------------------
root@verdin-imx8mp-06849028:~# dmesg |grep Hello
[ 1.575157] hello_debug hello0: Hello, world! Debug message enabled.
[ 1.575165] Hello module loaded successfully.
------------------------------
./ 使能動(dòng)態(tài) DEBUG 功能:
------------------------------
// 默認(rèn)未使能
root@verdin-imx8mp-06849028:~# cat /sys/kernel/debug/dynamic_debug/control |grep hello
drivers/char/hello_world_driver/hello_world.c:32 [hello_world]hello_init =_ "Hello, world! Debug
message enabled.\n"
drivers/char/hello_world_driver/hello_world.c:40 [hello_world]hello_exit =_ "Goodbye, world! Deb
ug message enabled.\n"
// 通過設(shè)置 U-Boot 環(huán)境變量在啟動(dòng)過程使能
root@verdin-imx8mp-06849028:~# fw_setenv tdxargs 'dyndbg=\\"file hello_world.c +p;\\"'
root@verdin-imx8mp-06849028:~# fw_printenv tdxargs
tdxargs=dyndbg=\\"file hello_world.c +p;\\"
root@verdin-imx8mp-06849028:~# reboot
// 重啟后 Dynamic Debug 使能
root@verdin-imx8mp-06849028:~# cat /sys/kernel/debug/dynamic_debug/control |grep hello
drivers/char/hello_world_driver/hello_world.c:32 [hello_world]hello_init =p "Hello, world! Debug
message enabled.\n"
drivers/char/hello_world_driver/hello_world.c:40 [hello_world]hello_exit =p "Goodbye, world! Deb
ug message enabled.\n"
// Debug log 打印
root@verdin-imx8mp-06849028:~# dmesg |grep Hello
[ 1.579354] hello_debug hello0: Hello, world! Debug message enabled.
[ 1.579363] Hello module loaded successfully.
------------------------------
d). Kernel Module 方式編譯,將 Hello_world 驅(qū)動(dòng)編譯為 Kernel Module
./ 配置內(nèi)核并重新編譯 Kernel Image 和 Kernel Modules:
------------------------------
$ cd
$ make menuconfig
Device Drivers > Character devices
$ make -j$(nproc) Image.gz 2>&1 | tee build.log
$ make -j$(nproc) modules
------------------------------
./ 和章節(jié) 3 同樣方法將 Kernel Image 和 Kernel Modules 壓縮包上傳到 Verdin i.MX8MP 并部署后重啟測(cè)試,驅(qū)動(dòng)加載成功:
------------------------------
root@verdin-imx8mp-06849028:~# modprobe hello_world
[ 69.862475] Hello module loaded successfully.
root@verdin-imx8mp-06849028:~# dmesg |grep Hello
[ 69.862475] Hello module loaded successfully.
------------------------------
./ 使能靜態(tài) DEBUG 功能,使能方式和上述 Built-in 編譯方式一致,這里不再贅述。
./ 使能動(dòng)態(tài) DEBUG 功能:
------------------------------
// 默認(rèn)未使能
root@verdin-imx8mp-06849028:~# cat /sys/kernel/debug/dynamic_debug/control |grep hello
drivers/char/hello_world_driver/hello_world.c:32 [hello_world]hello_init =_ "Hello, world! Debug
message enabled.\n"
drivers/char/hello_world_driver/hello_world.c:40 [hello_world]hello_exit =_ "Goodbye, world! Deb
ug message enabled.\n"
// 通過設(shè)置 U-Boot 環(huán)境變量或者 Modprobe 配置文件在加載 Hello_world 驅(qū)動(dòng)過程使能
i). U-Boot 環(huán)境變量
root@verdin-imx8mp-06849028:~# fw_setenv tdxargs 'hello_world.dyndbg=\\"+p;\\"'
root@verdin-imx8mp-06849028:~# fw_printenv tdxargs
tdxargs=hello_world.dyndbg=\\"+p;\\"
ii). Modprobe 配置文件
root@verdin-imx8mp-06849028:~# vi /etc/modprobe.d/test_debug.conf
options hello_world dyndbg=+p
root@verdin-imx8mp-06849028:~# reboot
// 重啟后 Dynamic Debug 使能
root@verdin-imx8mp-06849028:~# modprobe hello_world
[ 43.410229] Hello module loaded successfully.
root@verdin-imx8mp-06849028:~# cat /sys/kernel/debug/dynamic_debug/control |grep hello
drivers/char/hello_world_driver/hello_world.c:40 [hello_world]hello_exit =p "Goodbye, world! Deb
ug message enabled.\n"
drivers/char/hello_world_driver/hello_world.c:32 [hello_world]hello_init =p "Hello, world! Debug
message enabled.\n"
// Debug log 打印
root@verdin-imx8mp-06849028:~# dmesg |grep Hello
[ 43.410211] hello_debug hello0: Hello, world! Debug message enabled.
[ 43.410229] Hello module loaded successfully.
------------------------------
6). 總結(jié)
本文基于 NXP i.MX8MP 處理器平臺(tái)演示了定制化 Linux Hello World 設(shè)備驅(qū)動(dòng)開發(fā)編譯和調(diào)試流程。

提交
在 NXP i.MX 95 上運(yùn)行 Zephyr 實(shí)現(xiàn)非對(duì)稱多核處理
HDMI 顯示器熱插拔對(duì)應(yīng)顯示應(yīng)用啟停測(cè)試
Yocto meta-toradex-security layer 創(chuàng)建加密數(shù)據(jù)分區(qū)應(yīng)用說明
NXP iMX8MP ARM 平臺(tái)多屏幕克隆顯示測(cè)試
Yocto meta-toradex-security layer 創(chuàng)建獨(dú)立數(shù)據(jù)分區(qū)