目录


1. 嵌入式系统概述

嵌入式系统是一种软硬件可裁剪的专用计算机系统,通常用于特定应用场景(如智能设备、工控系统等)。与通用计算机系统不同,嵌入式系统通常资源有限,因此需要对其操作系统(如Linux)进行定制和剪裁。


2. 内核编译基础

a. 解压内核源码包
# 将内核源码包解压到Ubuntu系统中
tar -xzf linux-2.6.32.2-mini2440-20150709.tgz
b. 关键文件说明
  • xxx_defconfig:默认配置文件,通常位于 arch/arm/configs/ 目录下。
  • Kconfig:定义 make menuconfig 中可见的配置选项,每个子目录都有一个。会对我加入的参数做解释;
  • .config:保存 make menuconfig 后的配置结果,决定哪些模块被编译进内核。
  • Makefile:根据 .config 中的变量(如 X1=y)决定编译哪些文件。每一层目录都有对应的makefile

3. 内核配置与编译流程

以下指令均在linu顶层目录进行/linux2.6.32.2/

a. 拷贝默认配置
cp arch/arm/configs/config_mini2440_td35 .config
(隐藏文件需要ls -a才会出现)
b. 图形化配置
make menuconfig
  • 通过菜单界面修改配置,结果保存在 .config 中。
    注意!在make uImage之前出现bug把kernel下面的timeconst.pl文件夹第373行删掉
c. 编译内核
make uImage    # 生成uImage内核镜像

make modules   # 编译模块
make           # 编译全部(内核 + 模块)

在这里插入图片描述
上面图片这样就算编译成功 某某 is ready出现的时候

4. 内核镜像类型说明

在这里插入图片描述
这里出现异常:
这是ARM架构处理器运行程序时触发的未定义指令异常(Undefined Instruction Exception) ,属于硬件级错误,直接导致CPU复位。以下拆解关键信息和排查方向:


1. 核心错误:undefined instruction

  • 含义:CPU执行到了不认识的指令编码。可能原因:
    • 程序里有CPU不支持的指令集(比如用了ARMv7指令,却在ARMv5/ARM9内核运行 )。
    • 内存数据被破坏,指令区被覆写成无效数据(比如栈溢出、指针错误)。
    • 编译器配置错误(编译时选了错误的架构/指令集,导致生成的二进制指令不兼容 )。

2. 寄存器上下文解析(调试关键)

  • pc : [<3000801c>]
    • pc(程序计数器)是出错时正在执行的指令地址,可反汇编 0x3000801c 附近代码,看具体指令:
      arm-linux-objdump -d 你的程序 | grep -C5 3000801c
      
  • lr : [<33f01200>]lr(链接寄存器)保存函数调用返回地址,可辅助定位错误发生在哪个函数调用链。
  • Mode SVC_32:CPU处于32位管理模式(超级用户模式) ,说明错误发生在内核态或高权限代码(如果是用户程序触发,可能是非法指令触发了异常进入内核 )。

3. 典型排查方向

(1)指令集兼容性问题
  • 检查编译工具链:确认用的是 ARM9 兼容的编译器(比如 arm-linux-gnueabi-gcc 针对ARMv5/ARM9 ),而非更高版本(如ARMv7、ARM64 )。
  • 编译选项:确保 -march=armv5te(或开发板CPU对应的架构)、-mtune=arm920t 等选项正确,避免生成不兼容指令。
(2)内存破坏/非法指针
  • 检查栈溢出:递归过深、大数组局部变量可能撑爆栈(sp 地址 33affdd0 可结合栈大小判断)。
  • 指针越界:确认 pc 指向的地址是否属于程序代码段(正常应在代码加载区间,若在数据区,可能是指针错误跳转到无效地址 )。
(3)内核/驱动兼容性
  • 如果是加载内核模块或运行内核程序报错,检查内核配置:是否启用了不兼容的功能(比如内核用ARMv5编译,模块用ARMv7编译 )。

4. 总结:错误影响

  • 直接触发CPU异常,导致程序崩溃,系统打印寄存器信息后执行 Resetting CPU ...(复位CPU,重启或进入异常处理 )。
  • 常见于嵌入式开发(如 mini2440 这类ARM9开发板 ),解决核心是对齐编译工具链、指令集、内存管理三者的兼容性 。

如果是自己编译程序/内核,优先从编译选项、指令集配置查起;如果是运行别人的程序,重点检查内存访问是否越界~
**

修改上面的错误往往要把arch/arm/boot里面的Makefile文件具体地址64行代码修改成 下面图片中正确格式,然后重新编译检查地址是否修改成功

在这里插入图片描述

然后编译结果是下面的
tftp 0x30008000 uImage
**

在这里插入图片描述
出现异常的时候,应该把地址修改成0x30008040像上面的图片一样修改成功才能是正确的编译文件

  • Image:原始内核镜像,未经压缩。
  • zImage:压缩后的内核镜像,包含解压代码。
  • uImage:在 zImage 前加64字节头信息,供U-Boot等引导程序使用

5. 向内核添加新驱动/文件(以 demo.c 为例)

a. 编写源文件

drivers/char/ 下创建 demo.c

b. 修改 Makefile

drivers/char/Makefile 中添加:

obj-$(CONFIG_DOME) += demo.o   //注意大小写
c. 修改 Kconfig

drivers/char/Kconfig 中添加配置选项:

config DEMO
    bool "Hello driver support"
    default n
    help
      This is a simple hello driver.

在这里插入图片描述
修改成功后进vi config检查demo.o文件是否存在
然后再图形化界面make menuconfig中查看详细地址-----这就是活地址的作用:(location后面就是相应的地址层,进入后再括号里面的*即是选择与否,可以通过空格键来选择与否,也可以通过y键和n键来确定)在这里插入图片描述

d. 重新配置并编译
make menuconfig   # 在菜单中启用 HELLO 选项
make uImage       # 重新编译内核

最后去启动内核
tftp 0x30008000 uImage
bootm 0x30008000
如果结果中在TCP附近出现下面的带有#一行的信息则就是修改异常成功
在这里插入图片描述


Logo

openvela 操作系统专为 AIoT 领域量身定制,以轻量化、标准兼容、安全性和高度可扩展性为核心特点。openvela 以其卓越的技术优势,已成为众多物联网设备和 AI 硬件的技术首选,涵盖了智能手表、运动手环、智能音箱、耳机、智能家居设备以及机器人等多个领域。

更多推荐