Linux Kernel 之四 移植过程详解、STM32F769I-EVAL 开发板适配

  在之前的博文 Linux Kernel 之一 完整嵌入式 Linux 环境、构建工具、编译工具链、CPU 体系架构 中说了要一步步搭建整个嵌入式 Linux 运行环境,今天主要学习一下将 Linux 内核适配 STM32F769I-EVAL 开发板。

源码

  文中涉及的源代码均放到了我个人的 Github 上:https://github.com/ZCShou/BOARD-STM32F769I-EVAL这个仓库中包含了要搭建的完整嵌入式 Linux 环境的所有源代码,后续博文均以该仓库中的源码为基础来学习!
Linux Kernel 之四 移植过程详解、STM32F769I-EVAL 开发板适配_第1张图片

开发环境

  我这里使用的基本开发环境依旧是在之前博文中多次说明的 Ubuntu 22.04.1 LTS + Arm GNU Toolchain 11.3.Rel1,对应的 J-link 也依旧是 J-Link_Linux_V764e_x86_64.deb。该环境下需要注意的问题说明如下:
Linux Kernel 之四 移植过程详解、STM32F769I-EVAL 开发板适配_第2张图片

  1. 由于 Ubuntu 22.04 LTS 默认是标配 OpenSSL 3.x,而旧版 U-Boot 使用的是 OpenSSL 1.x,所以,该环境编译旧版 U-Boot(从 commit e927e21c 开始添加了相关处理) 将出现一堆警告,因此,后续使用 u-boot-v2022.10 这个版本为主:
    Linux Kernel 之四 移植过程详解、STM32F769I-EVAL 开发板适配_第3张图片
  2. Arm GNU Toolchain 10.2-2022.02 存在 BUG,导致编译 U-Boot 报错,不要使用这个版本!
    Linux Kernel 之四 移植过程详解、STM32F769I-EVAL 开发板适配_第4张图片
  3. 新版(Arm GNU Toolchain 10.3 之后的版本)的 Arm GNU Toolchain 在 Linux 上 GDB 需要 Python3.8 支持。然而,Ubuntu 22.04 默认的 Python 是 3.10。直接运行 arm-none-eabi-gdb 报错如下:
    Linux Kernel 之四 移植过程详解、STM32F769I-EVAL 开发板适配_第5张图片
    解决方法就是直接手动安装 Python3.8 即可。 旧版的 Arm GNU Toolchain 10.3 -2021.10 不需要 Python 支持
    sudo add-apt-repository ppa:deadsnakes/ppa -y
    sudo apt install python3.8
    

  我使用的是 VSCode 来查看 U-Boot + Kernel 源代码,为了查看方便,我把不需要的文件进行了隐藏,通过将不需要的文件排除在外,加快搜索等操作的执行,也避免了过多无用结果。以下是我的 VSCode 配置:

{
    "files.exclude": {
        "**/.git": true,
        "**/.svn": true,
        "**/.hg": true,
        "**/CVS": true,
        "**/.DS_Store": true,
        "u-boot-v2021.10":true,
        // arch
        "**/mips": true,
        "**/powerpc": true,
        "**/riscv": true,
        "**/ti": true,
        "**/x86": true,
        "**/sandbox": true,
        "**/arch/{arc,m68k,microblaze,mips,nios2,powerpc,riscv,sandbox,sh,x86,xtensa,um,sparc,s390,parisc,openrisc,nds32,ia64,hexagon,h8300,csky,arm64,alpha}": true,
        // cpu
        "**/arch/arm/cpu/{arm11,arm720t,arm920t,arm926ejs,arm946es,arm1136,arm1176,armv7,armv8}": true,
        // machine
        "**/arch/arm/mach-[^s]*": true,
        "**/arch/arm/mach-s[^t]*": true,
        "**/arch/arm/mach-st[^m]*": true,
        "**/arch/arm/mach-stm32[$^m]*": true,
        // dts
        "**/dts/[^s|^M|^i|^a|^d|^.]*": true,
        "**/dts/d[^t]*": true,
        "**/dts/i[^n]*": true,
        "**/dts/in[^c]*": true,
        "**/dts/a[^r]*": true,
        "**/dts/ar[^m]*": true,
        "**/dts/arm[^v]*": true,
        "**/dts/s[^t]*": true,
        "**/dts/st[^m|^-]*": true,
        "**/dts/stm32[^f]*": true,
        "**/dts/stm32f[^7]*": true,
        "**/dts/stm32f7[^6|4|^-]*": true,
        "**/dts/stm32f769-[^e|d|p]*": true,
        // configs
        "**/configs/[^s]*": true,
        "**/configs/s[^t]*": true,
        "**/configs/st[^m]*": true,
        "**/configs/stm[^3]*": true,
        // "**/configs/stm3[^2]*": true,
        "**/configs/stm32[^f|^_]*": true,
        "**/configs/stm32f[^7]*": true,
        // "**/configs/stm32f7[^6|^4]*": true,
        // "**/configs/stm32f769-[^e]*": true,
        // board
        "**/board/[^s]*": true,
        "**/board/s[^t]*": true,
        "**/board/ste": true,
        "**/board/sto*": true,
        "**/board/st/st[^m]*": true,
        "**/board/st/stm32[^f]*": true,
        // "**/board/st/stm32f[^7]*": true,
        // "**/board/st/stm32f7[^6|^4]*": true,
    },
    "editor.insertSpaces": false
}

运行环境

  我使用的嵌入式环境是 STM32F769I-EVAL 板子。STM32F769I-EVAL 板子使用的 STM32F769NI 这个 MCU,STM32F769NI 这款 MCU 采用的是 ARM Cortex-M7 的核心,指令集架构是 ARMv7m。此外,还需要注意,这个板子上的的串口的 RX 默认是断开,需要用短路帽连接起来。

  Linux 内核本身提供了对于 STM32 的支持,不过并没有提供 STM32F769I-EVAL 板子对应的设备树文件。配置文件是 ./arch/arm/configs/stm32_defconfig。不过,这个文件更像是一个 DEMO,其中的有些内容并不符合我们的 STM32F769I-EVAL 开发板,本篇博文的移植主要就是添加对于 STM32F769I-EVAL 板子的支持。

移植过程

  绝大多数情况下,移植工作都不是从零开始。Linux Kernel 中默认提供了对于 STM32F769-disco 的支持,STM32F769I-EVAL 的移植完全可以参考它来进行。此外,在博文 U-Boot 之二 移植过程详解、 STM32F769I-EVAL 开发板适配 已经将学习过设备树相关的适配,而 U-Boot 的设备数文件和 Linux 内核中的是基本一致的。
Linux Kernel 之四 移植过程详解、STM32F769I-EVAL 开发板适配_第6张图片

  1. 增加 STM32F769-eval 设备树文件:./arch/arm/boot/dts/stm32f769.dtsi./arch/arm/boot/dts/stm32f769-eval.dtsstm32f769.dtsi 是直接复制的 stm32f746.dtsi 然后更名的,没有任何修改;stm32f769-pinctrl.dtsi 原来就存在,不需要改动;stm32f769-eval.dts 是直接复制的 stm32f769-disco.dts,然后做了如下更改:
    Linux Kernel 之四 移植过程详解、STM32F769I-EVAL 开发板适配_第7张图片

  2. 将新增的 stm32f769-eval.dts 添加到 ./arch/arm/boot/dts/Makefile 中,否则编译系统不会编译我们新增的设备树文件。
    Linux Kernel 之四 移植过程详解、STM32F769I-EVAL 开发板适配_第8张图片

  3. 编辑 ./arch/arm/mach-stm32/board-dt.c,在其中增加自己的 MCU 。由于 Linux 本身提供了对于 STM32F769-disco 开发板的支持,因此这里面已经有了 STM32F769,因此,我们 board-dt.c 不要更改。
    Linux Kernel 之四 移植过程详解、STM32F769I-EVAL 开发板适配_第9张图片
      此外,还需要在 MCU 这一级的 Kconfig 文件 ./arch/arm/mach-stm32/Kconfig 中添加我们的 MCU。同样,由于 Kconfig 中已经存在 MAC_STM32F769 了,这里我也不需要更改。此外,这里默认选择了全部 MCU,我修改为只选中 STM32F769。也可以后面在 menuconfig 中手动更改,效果是一样的。
    Linux Kernel 之四 移植过程详解、STM32F769I-EVAL 开发板适配_第10张图片

  4. 将 STM32 的配置添加到 ARM 架构这一级的 ./arch/arm/Kconfig 配置系统中。同样,由于 Linux 本身提供了对于 STM32F769-disco 开发板的支持,因此这里面已经有了 ./arch/arm/mach-stm32/Kconfig,因此,不需要更改。
    Linux Kernel 之四 移植过程详解、STM32F769I-EVAL 开发板适配_第11张图片
    这里需要注意,我们的 STM32F769 是没有 mmu 的,因此,实际在 ./arch/arm/Kconfig-nommu 文件中有很多真多我们的 MCU 的默认配置,这里不需要修改,后面可以直接使用 stm32_deconfig 文件中的配置覆盖这些默认配置。
    Linux Kernel 之四 移植过程详解、STM32F769I-EVAL 开发板适配_第12张图片

  5. 将 ARM 架构添加到架构一级的总的 Kconfig 系统 ./arch/Kconfig 中。同样,由于 Linux 本身提供了对于 STM32 的支持,这里不需要改动。
    Linux Kernel 之四 移植过程详解、STM32F769I-EVAL 开发板适配_第13张图片

  6. 修改默认的配置文件:./arch/arm/configs/stm32_defconfig。在 Linux Kernel 中,所有 STM32 共用这一个配置文件,这个文件中的部分内容并不能适合我们的开发板。如果不想修改这个文件,我们可以直接新建一个 stm32f769_defconfig,主要修改如下:
    Linux Kernel 之四 移植过程详解、STM32F769I-EVAL 开发板适配_第14张图片

    1. 修改 DRAM 的地址和大小
    2. 取消 XIP,因为 STM32F769 的内部 FLASH 放不开我们的 Image。

    之所以在这个配置文件中修改配置是为了不用每次编译都在 ARCH=arm CROSS_COMPILE=arm-none-eabi- make O=build_stm32 menuconfig 进行修改,一劳永逸!

开发板适配

  上面的移植仅仅是在 Linux Kernel 中添加了 STM32F769I-EVAL 的支持,接下来还需要根据 STM32F769I-EVAL 的手册修改移植的文件内容,使其完全符合 STM32F769I-EVAL 中各种资源的定义。

  注意,Linux Kernel 中的设备树与 U-Boot 中的基本是一致的(U-Boot 的文件就来自于 Linux Kernel),因此,完全可以直接参照在 在博文 U-Boot 之二 移植过程详解、 STM32F769I-EVAL 开发板适配 中的适配过程。甚至直接对比文件复制相关改动即可。
Linux Kernel 之四 移植过程详解、STM32F769I-EVAL 开发板适配_第15张图片

DRAM: 16 MiB

  根据 STM32F769I-EVAL 手册说明,DRAM 应该是 32MB,这里显示是 16 MiB,显然是不对的。
在这里插入图片描述
STM32F769I-EVAL 手册中说 DRAM 芯片是 IS42S32800G-6BLI,我们需要根据手册,修改 FMC 在设备树文件中有描述。
Linux Kernel 之四 移植过程详解、STM32F769I-EVAL 开发板适配_第16张图片

MMC: no card present

  STM32F769-EVAL 开发板上是有 SD 卡的。但是这里显示没有卡。不出意外的话,这里是由于 STM32F769-Disco 与 STM32F769-EVAL 在这方面配置不同导致。下图是两款开发板关于 SD 卡的说明:
Linux Kernel 之四 移植过程详解、STM32F769I-EVAL 开发板适配_第17张图片
  从中我们可以看出,两款开发板使用的 SDMMC 并不相同!EVAL 开发板有两个 SD 卡插槽:SD1 -> SDMMC1SD2 -> SDMMC2。而 Discovery 板子只有一个 SD卡插槽:SD -> SDMMC2。关键在于 SDMMC2 的管脚使用是不一样的!

  1. EVAL 板子需要我们修改一下板子的硬件,如上图红色框中所示。从修改便捷性来说,我们直接使用 SD2 即可,只需要配置 JP7 即可
    Linux Kernel 之四 移植过程详解、STM32F769I-EVAL 开发板适配_第18张图片
  2. MicroSDcard _detect 引脚需要更改。但是这里有个问题。EVAL 板子中,这个引脚是连接到扩展 IO 的,如何配置到设备树还没处理!不过,我们可以找个临时处理方法:我们借用 PC13 这个引脚,因为正好这个引脚是高电平,正好可以表示 SD 卡插入。
    Linux Kernel 之四 移植过程详解、STM32F769I-EVAL 开发板适配_第19张图片

参考

  1. Linux 官方文档
  2. https://linux-kernel-labs.github.io/refs/pull/187/merge/lectures/intro.html

你可能感兴趣的:(Linux,Kernel,linux,stm32,移植,kernel,EVAL)