嵌入式arm-linux开发应用层第三方库头文件包含问题

🗣️前言 一般来说在本机开发应用linux应用程序,直接安装对应的包就行,但是在嵌入式linux开发过程中,因为架构不同,可能没有相应的包。这里推荐一种标准的开发方法。这种方法可以直接统一使用一个库及其相应的头文件,不会导致各种不匹配。 ⚙️解决方法 直接使用buildroot(或者其他根文件系统构建工具)构建根文件系统,他会在buildroot源码根文件夹中的output\host\arm-buildroot-linux-gnueabihf\sysroot\usr\include中生成你选择的库相应的头文件,将这些头文件加进去即可使用。 比如我使用的是vscode+clangd来开发,为了让vscode编辑器能解析头文件包含,需要在项目根目录创建一个.clangd文件(也可使其他方法),写入如下内容 CompileFlags: Add: - --target=arm-linux-gnueabihf - --sysroot=/home/ydteng/workspace/imx6ull/buildroot/output/host/arm-buildroot-linux-gnueabihf/sysroot 然后为了编译器也能正常识别,也需要加上sysroot选项,这里以libcurl库为例,一条示例编译命令如下 arm-linux-gnueabihf-gcc api_face.c -o curl_test -lcurl --sysroot=/home/ydteng/workspace/imx6ull/buildroot/output/host/arm-buildroot-linux-gnueabihf/sysroot # 一定要加上-lcurl 🔚结语 🗂️引用参考

一月 20, 2026 · 1 分钟 · 22 字 · Me

linux kernel-6.18-x86架构启动流程

仅作为一个临时笔记,之前分析的,不一定准确 linux内核启动流程,以x86_64为例(解释一下,这里的x86是架构,64是位数),内核版本:6.18-rc4,大概率不准确,但是对理解大体流程还是很有用的 { 文件: arch/x86/boot/header.S 函数/段: _start 跳转: start_of_setup,_start直接无条件跳转,其中下面是无条件的跳转代码 .byte 0xeb # short (2-byte) jump .byte start_of_setup-1f 说明: 在arch/x86/boot/setup.ld中有一段是ENTRY(_start),定义了入口是_start,.ld文件是链接配置文件 } 一直往下运行,会运行到start_of_setup,然后继续执行。 --> { 文件: arch/x86/boot/header.S 函数/段: start_of_setup 跳转: main,最后的 calll main 执行了跳转 说明: 无 } --> { 文件: arch/x86/boot/main.c 函数/段: main 跳转: go_to_protected_mode 说明: 无 } --> { 文件: arch/x86/boot/pm.c 函数/段: go_to_protected_mode 跳转: protected_mode_jump 说明: protected_mode_jump是一个在汇编中实现的函数,定义在arch/x86/boot/boot.h } --> { 文件: arch/x86/boot/pmjump.S 函数/段: protected_mode_jump 跳转: startup_64,一直运行到arch/x86/boot/pmjump.S的最后运行跳转汇编代码jmpl *%eax,其中eax的值在protected_mode_jump(u32 entrypoint, u32 bootparams)的entrypoint中指定的 说明: protected_mode_jump是一个在汇编中实现的函数,定义在arch/x86/boot/boot.h } #####################不确定的部分 --> 先到head_32.S中的startup_32??? { 文件: arch/x86/boot/compressed/head_32.S 函数/段: startup_32,定义位置为SYM_FUNC_START(startup_32),最后通过jmp *%eax跳转到64。不清楚为什么必须先经过32才能再到64 跳转: startup_64 说明: 可通过arch/x86/boot/compressed下的/vmlinux.lds或vmlinux.lds.S知道startup_64也是一个入口 } --> 还是直接到到head_64.S中的startup_32,然后直接运行后面的startup_32??? { 文件: arch/x86/boot/compressed/head_64.S 函数/段: startup_32,定义位置为SYM_FUNC_START(startup_32),不跳转,直接继续运行到startup_64。不清楚为什么必须先经过32才能再到64 跳转: 直接运行startup_64 说明: 可通过arch/x86/boot/compressed下的/vmlinux.lds或vmlinux.lds.S知道startup_64也是一个入口 } ####################### { 文件: arch/x86/boot/compressed/head_64.S 函数/段: startup_64,定义位置为SYM_CODE_START(startup_64) 跳转: startup_64,注意这个是另一个文件的startup_64,通过jmp *%rax跳转到解压后内核的地址 说明: 可通过arch/x86/boot/compressed下的/vmlinux.lds或vmlinux.lds.S知道startup_64也是一个入口 } --> { 文件: arch/x86/kernel/head_64.S 函数/段: startup_64 跳转: common_startup_64,通过jmp *.Lcommon_startup_64(%rip)跳转,其中.Lcommon_startup_64通过SYM_DATA_LOCAL(.Lcommon_startup_64, .quad common_startup_64)将common_startup_64的地址赋值给.Lcommon_startup_64 说明: 可通过arch/x86/boot/compressed下的/vmlinux.lds或vmlinux.lds.S知道startup_64也是一个入口 } --> { 文件: arch/x86/kernel/head_64.S 函数/段: common_startup_64,在SYM_INNER_LABEL(common_startup_64, SYM_L_LOCAL)是入口 跳转: Lsetup_cpu,通过最后的 jmp .Lsetup_cpu 跳转 说明: } --> { 文件: arch/x86/kernel/head_64.S 函数/段: Lsetup_cpu,在SYM_INNER_LABEL(common_startup_64, SYM_L_LOCAL)是入口 跳转: 执行完Lsetup_cpu段之后没有跳转,继续运行后面的段,直到段Ljump_to_C_code的callq *initial_code(%rip) 说明: } --> { 文件: arch/x86/kernel/head64.c 函数/段: x86_64_start_kernel,终于进入c函数了,后面的跳转就好找了 跳转: x86_64_start_reservations 说明: } --> { 文件: arch/x86/kernel/head64.c 函数/段: x86_64_start_reservations,终于进入c函数了,后面的跳转就好找了 跳转: 说明: }

一月 11, 2026 · 1 分钟 · 169 字 · Me

x86架构下ubuntu交叉编译器(arm-linux-gnueabihf-)直接下载使用arm架构的库

🗣️前言 (重要:不建议这样做,因为可能因为环境不一样,导致库不完全一样,最终运行报错。还是按部就班的按照根文件系统中存在的库进行开发。可见新方法:https://www.cnblogs.com/ydteng/p/19504068) 这里以libcurl库为例,本文提供的方法能直接安装,不用自己编译。但是会和x86架构的库冲突,如果安装了这个,再开发x86架构的软件就需要重新安装对应架构的库。这里建议是将一个环境作为一种平台的开发,不要混用。 🔧安装步骤 🛹卸载x86版本的libcurl # 卸载x86版本的libcurl sudo apt remove --purge libcurl4-openssl-dev sudo apt-get autoremove 🧨配置arm源 以清华源为例,参考网页 x86架构:https://mirrors.tuna.tsinghua.edu.cn/help/ubuntu/ arm等架构:https://mirrors.tuna.tsinghua.edu.cn/help/ubuntu-ports/ 完整配置文件如下,记得一定要加入Architectures: amd64或Architectures: Architectures: armhf # 下面是x86架构的软件源 Types: deb URIs: https://mirrors.tuna.tsinghua.edu.cn/ubuntu Suites: noble noble-updates noble-backports Components: main restricted universe multiverse Architectures: amd64 # 重要,必须要加 Signed-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg # 以下安全更新软件源包含了官方源与镜像站配置,如有需要可自行修改注释切换 Types: deb URIs: http://security.ubuntu.com/ubuntu/ Suites: noble-security Components: main restricted universe multiverse Architectures: amd64 # 重要,必须要加 Signed-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg # 下面是Ubuntu Ports软件仓库,也就是arm等架构的软件源 Types: deb URIs: https://mirrors.tuna.tsinghua.edu.cn/ubuntu-ports Suites: noble noble-updates noble-backports Components: main restricted universe multiverse Architectures: armhf # 重要,必须要加 Signed-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg # 以下安全更新软件源包含了官方源与镜像站配置,如有需要可自行修改注释切换 Types: deb URIs: http://ports.ubuntu.com/ubuntu-ports/ Suites: noble-security Components: main restricted universe multiverse Architectures: armhf # 重要,必须要加 Signed-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg 🛫安装arm版本lincurl sudo dpkg --add-architecture armhf # 为了让系统知道可以使用arm架构的库 sudo apt update sudo apt install libcurl4-openssl-dev:armhf # 好像大部分都是openssl后端,也可以是libcurl4-gnutls-dev:armhf 安装完成之后,会在\usr\include\arm-linux-gnueabihf生成相应的头文件 ...

一月 11, 2026 · 1 分钟 · 138 字 · Me

imx6ull芯片引脚相关知识(命名、配置步骤)

前言 不仅局限于imx6ull芯片,对于其他ARM芯片应该是通用的 命名规则 配置步骤 引脚复用功能配置(选择外设功能,IOMUXC MUX) 引脚电气特性配置(驱动能力、上下拉、速度等,IOMUXC PAD) 外设功能控制器配置(UART / I2C / CSI / GPIO 等外设寄存器)

一月 10, 2026 · 1 分钟 · 16 字 · Me

正点原子阿尔法开发板imx6ull在linux-kernel-6.12.y上移植ov5640摄像头驱动

ov5640设备树修改 i2ctool的一些使用 文件:drivers/media/platform/mxc/capture/mx6s_capture.c是芯片CSI控制器驱动 drivers/media/platform/mxc/capture/ov5640_v2.c是摄像头配置驱动 模块安装 linux-kernel-6.12.y的ov5640驱动默认编译成的是模块,需要进行安装,当然也可直接单独运行模块或者直接编译进内核,这里使用较为正规的方式。使用如下命令会将模块自动安装到INSTALL_MOD_PATH的bin目录下,linux也会自动加载,无需手动加载。 #!/bin/sh make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- modules_prepare make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- M=drivers/media/platform/mxc/capture modules # 编译模块 make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- modules_install INSTALL_MOD_PATH=/your/rootfs/path # 安装模块 最小改动的移植,使用自带驱动的YUYV格式(不完美) 驱动部分,只需要将旧的正点原子驱动中的屏幕配置加入到新的驱动中即可,也可直加入自己屏幕对应的配置部分。一般需要在ov5640_mode添加内容,相应的添加reg_value结构体对应的数据,然后还有ov5640_mode_info_data结构体内添加对应内容。而应用层部分,需要做较大的修改,需要修改成YUYV格式的配置,并且需要进行YUYV->RGB565的转换。显示的不完美,屏幕会被分成两部分,并且左右部分进行了互换。改动部分已在注释中标出。 详细代码:https://github.com/ydteng/ov5640-driver/tree/main/YUYV 尽量跟正点原子官方原版一样的 这个改动较多,最需要注意的是ov5640_subdev_video_ops和ov5640_subdev_pad_ops的区别,别的其实还好移植。这两个的区别主要是新版本将ov5640_subdev_video_ops的一些接口放到了ov5640_subdev_pad_ops里面,并且删除了try_mbus_fmt,合并到了set_fmt使用fmt->which进行判断,具体如下: 查看代码 static struct v4l2_subdev_video_ops ov5640_subdev_video_ops = { .g_parm = ov5640_g_parm, .s_parm = ov5640_s_parm, .g_std = ov5640_g_std, /* 也算是一个过时接口,写的很简单 */ /* 旧版本驱动这里有下面这些 .s_mbus_fmt = ov5640_s_fmt, .g_mbus_fmt = ov5640_g_fmt, .try_mbus_fmt = ov5640_try_fmt, .enum_mbus_fmt = ov5640_enum_fmt, */ }; static const struct v4l2_subdev_pad_ops ov5640_subdev_pad_ops = { .enum_frame_size = ov5640_enum_framesizes, .enum_frame_interval = ov5640_enum_frameintervals, /* 新版本的从v4l2_subdev_video_ops移动到了v4l2_subdev_pad_ops,变成了下面这些接口 */ .enum_mbus_code = ov5640_enum_code, /* 对应旧版本enum_mbus_fmt */ .set_fmt = ov5640_set_fmt, /* 对应旧版本s_mbus_fmt*/ .get_fmt = ov5640_get_fmt, /* 对应旧版本g_mbus_fmt */ /* 删除了try_mbus_fmt,合并到了set_fmt使用fmt->which == V4L2_SUBDEV_FORMAT_TRY进行判断, if (format->which == V4L2_SUBDEV_FORMAT_TRY){这里可以写旧版本的ov5640_try_fmt函数中的内容} */ };

十二月 27, 2025 · 1 分钟 · 108 字 · Me

linux设备树相关知识杂项

新建节点: i2c2: i2c@021a0000 { compatible = “fsl,imx6ul-i2c”; reg = <0x021a0000 0x4000>; }; [label:] node-name[@unit-address] { [properties definitions] [child nodes] } 其中lable和unit-address可以没有 修改节点(覆盖、新增): &i2c2 { status = “okay”; // 覆盖原来的status clock-frequency = <400000>; // 新增属性 }; &是引用节点的意思 设备树也是这样的,一个根节点,包含CPU,然后在包含一些控制器,控制器下面再挂在一些外部设备 问:为啥我吧iomuxc_snvs节点的引脚,写道iomuxc中,也能正常工作? 难道不是根据这两个节点的根地址进行计算的? 发现了一点:网络驱动的复位引脚,就算我注释了,也照样能用 大问题:一个引脚设备树中,写道iomuxc和iomuxc_snvs中一样吗?到时候试验下 设备树的lable好像全树中,只能有一个

十二月 23, 2025 · 1 分钟 · 42 字 · Me

正点原子移植linux-imx6.12的一个容易犯得问题

删除掉其他占用的引脚,两个地方,一定不要漏掉。 spi-4 { compatible = “spi-gpio”; pinctrl-names = “default”; pinctrl-0 = <&pinctrl_spi4>; status = “okay”; sck-gpios = <&gpio5 11 0>; mosi-gpios = <&gpio5 10 0>; # 第一个地方 /* cs-gpios = <&gpio5 7 GPIO_ACTIVE_LOW>;*/ num-chipselects = <1>; #address-cells = <1>; #size-cells = <0>; gpio_spi: gpio@0 { compatible = “fairchild,74hc595”; gpio-controller; #gpio-cells = <2>; reg = <0>; registers-number = <1>; registers-default = /bits/ 8 <0x57>; spi-max-frequency = <100000>; # 第二个地方 /* enable-gpios = <&gpio5 8 GPIO_ACTIVE_LOW>;*/ }; };

十二月 20, 2025 · 1 分钟 · 76 字 · Me

正点原子阿尔法开发板imx6ull芯片移植u-boot (v2025.04)和linux kernel (v6.12.y)

🍌u-boot 移植 ✂️前言 正点原子文档教程中的uboot移植,太老旧了,为了学习最新的技术,故进行最新u-boot的移植。而且网上很多教程说的太复杂了,其实很多步骤都不用做。下面是我试验后精简的配置过程。 ⌨️开发环境 开发板:正点原子阿尔法开发板v2.4以后 系统环境:ubuntu24.04 u-boot版本:v2025.04,下载地址:https://github.com/nxp-imx/uboot-imx 交叉编译器:arm-linux-gnueabihf- (版本v13.3) 🛠️移植步骤 移植操作是基于mx6ull_14x14_evk_emmc进行的,主要分为两大部分,一部分是文件的复制和简单修改,一部分是驱动的移植,其中文件复制修改部分可结合正点原子驱动开发指南《第三十三章 U-Boot移植 》食用,驱动的移植部分参考《第三十七章 Linux内核移植》 📃配置文件移植 复制路径configs/下的mx6ull_14x14_evk_emmc_defconfig一份命名为mx6ull_alientek_emmc_defconfig,然后修改字段 CONFIG_TARGET_MX6ULL_14X14_EVK=y改为CONFIG_TARGET_MX6ULL_ALIENTEK_EMMC=y CONFIG_DEFAULT_DEVICE_TREE="imx6ull-14x14-evk-emmc"改为CONFIG_DEFAULT_DEVICE_TREE="imx6ull-alientek-emmc" 🦊头文件移植 将include/configs路径下的mx6ullevk.h复制一份重命名为mx6ull_alientek_emmc.h,然后 将开头的 #ifndef __MX6ULLEVK_CONFIG_H #define __MX6ULLEVK_CONFIG_H 修改为 #ifndef __MX6ULL_ALIENTEK_EMMC_CONFIG_H #define __MX6ULL_ALIENTEK_EMMC_CONFIG_H 📁板级文件夹移植 将文件夹board/freescale/mx6ullevk复制一份为board/freescale/mx6ull_alientek_emmc,将mx6ullevk.c重命名为mx6ull_alientek_emmc.c,然后修改相关文件 1. c文件 可以不修改 2. Makefile 目标修改为对应的名字:obj-y := mx6ull_alientek_emmc.o 3. MAINTAINERS 好像只是一些版本修改说明,可以不修改?修改后的如下: MX6ULLEVK BOARD M: Peng Fan <peng.fan@nxp.com> S: Maintained F: board/freescale/mx6ull_alientek_emmc/ F: include/configs/mx6ull_alientek_emmc.h F: configs/mx6ull_alientek_emmc_defconfig F: configs/mx6ull_14x14_evk_plugin_defconfig F: configs/mx6ulz_14x14_evk_defconfig 4. Kconfig 同样替换为自己的目录或者文件名 if TARGET_MX6ULL_ALIENTEK_EMMC || TARGET_MX6ULL_9X9_EVK config SYS_BOARD default "mx6ull_alientek_emmc" config SYS_VENDOR default "freescale" config SYS_CONFIG_NAME default "mx6ull_alientek_emmc" config IMX_CONFIG default "board/freescale/mx6ull_alientek_emmc/imximage.cfg" config TEXT_BASE default 0x87800000 endif 5. imximage.cfg和imximage_lpddr2.cfg 都是将下面这个路径替换成自己移植的新的目录,修改后的 ...

十二月 20, 2025 · 3 分钟 · 627 字 · Me

正点原子移植最新u-boot(v2025.04)启动不显示CPU等板子banner信息的解决方法

❔问题描述: 根据网上的教程移植u-boot之后,启动后会如下图所示,不显示版本、CPU和内存等信息。直接从Core开始打印。或者u-boot中执行reset后就正常显示,按reset按钮后还是显示不全。 这是正常的 🟰解决方法: 在移植过程中需要修改defconfig的这个字段CONFIG_DEFAULT_DEVICE_TREE="imx6ull-alientek-emmc",等号后面的是设备树的名称,注意一定要创建一个这样的设备树文件:xxx-u-boot.dtsi,其中xxx就是设备树文件名称,比如这里就是imx6ull-alientek-emmc-u-boot.dtsi,我是从imx6ull-14x14-evk-emmc-u-boot.dtsi复制来的,因为我移植就是参考的imx6ull-14x14-evk-emmc这块板子。一定要区分好名字。很多移植教程中都遗漏了这个文件的移植。 👨‍🎓原因分析 本质上的原因我也还没搞懂;表面原因就是u-boot在编译的时候会自动寻找这个xxx-u-boot.dtsi的文件,然后自动包含进去。所以可以看到没有显式的包含也能正常的使用。

十二月 20, 2025 · 1 分钟 · 7 字 · Me

嵌入式linux开发环境对比

原汁原味的linux物理机最好,但是用不习惯 然后就是vmware虚拟机,如果不频繁切换局域网还好,但是实验室局域网切换太频繁了 WSL2相当于一个物理机,但是实际稳定性不如真正物理机和vmware虚拟机,比如我想插入个读卡器都需要单独下个软件才行。 综上:目前在实验室的环境,还是选择WSL2吧,等后面有稳定网络的时候可以再换成vmware虚拟机。或者没什么致命问题,用着WSL2也挺好吧?

十二月 18, 2025 · 1 分钟 · 4 字 · Me