NXP

Freescale Layerscape 嵌入式系统构建笔记

2019-07-12 12:44发布

索引

  • 目标
  • 系统硬件组成
  • 启动流程
  • 环境搭建
  • u-boot 移植
  • Kernel移植
  • 文件系统移植

目标

研究Freescale Layerscape CPU启动流程, 根据硬件组成修改U-Boot并移植,研究BSP,最终修改Kernel并移植文件系统

系统硬件组成

以Freescale Layerscape LS2080A 为例,Freescale同样提供了LS2080ARDB开发板作为硬件设计和调试开发板。LS2080A CPU组成:LS2080A-BLOCK-DIAGRAM.jpg内部集成8核ARM A57架构CPU。RDB板结构:LS2080A-RDB-BD.jpg在RDB板中,系统集成了NOR FLASH与NAND FLASH 与 8GB DDR4,主要的启动代码如U-Boot将会存放在Nor Flash中。关键地址分配:memmap-1.jpgmemmap-2.jpgmemmap-3.jpg

启动流程

  1. CPU上电
  2. CPU POR
  3. 根据RCW初始化芯片内关键模块和时钟
  4. CPU 从零地址读取指令, 根据Memory Map, 零地址是芯片内部Boot ROM,称为IBR(Internal boot ROM),属于pre-bootloader阶段,完成后将CPU从NOR/NAND/SD/SPI中启动bootloader(U-Boot),也就是将地址从0x0000_0000_0000跳转到0x0005_1000_0000的IFC域中去
  5. U-Boot初始化高级外设,加载Kernel

环境搭建

  • 准备linux环境,此处用的是:
    linux-mint-17.3 Cinnamon 64-bit 2.8.6
  • 如果需要用到最新U-Boot支持的图形化配置属性,安装ncruses库
    sudo apt-get install libncurses-dev 不同平台安装名称与方式不同
  • 安装git
  • 下载U-Boot
    git clone git://git.denx.de/u-boot.git
  • 下载交叉编译器,LS2080A需要用ARMv8编译器
    直接下载
    http://releases.linaro.org/14.08/components/toolchain/binaries/
  • 解压缩交叉编译器
    tar -xjvf gcc-linaro-aarch64-linux-gnu-4.9-2014.08_linux.tar.bz2
  • 安装dtc(device tree compiler)
    • 下载
    git clone https://git.kernel.org/pub/scm/utils/dtc/dtc.git
    • 编译
    export ARCH=''
    make dtc
    make
    • 设置dtc环境变量
    export PATH=$PATH:/path/to/dtc
  • 配置u-boot编译器相关:
    • 设置ARCH
      export ARCH='arm64'
    • 设置CROSS_COMPILE:
      export CROSS_COMPILE='aarch64-linux-gnu-'
    • 设置交叉编译器地址
      export PATH=$PATH:/abs_path/gcc-linaro..._linux/bin/
  • 编译命令
    • clean命令
      make mrproper
    • 配置目标
      make ls2080ardb_defconfig
    • 编译
      make
    • 图形化配置*
      make menuconfig

u-boot 介绍(2016.07 -rc3)

!u-boot根目录下的README对u-boot的一些简介和指南。
u-boot 的更新速度很快,不同版本的u-boot结构有可能会发生变化,同时不同厂商会提供u-boot以增加对其硬件的支持, 本次使用的板子是freescale 的LS2080ARDB板,在2016.07-rc3中的u-boot已经添加了对其的支持,直接编译下载即可,为了增加难度,会创建一个新的板子,并完成移植。
  • u-boot结构(加粗为需要修改的地方)
名称说明archCPU结构,支持PPC, ARM,MIPS,AVR32等众多CPUapi与CPU相关的一些APIarch与CPU相关的一些APIboard存放开发板的相关文件commonMISC体系下独立功能configs板级相关的配置文件disk磁盘驱动doc文档drivers常用设备驱动dts设备树examples独立程序的一些例程fs文件系统,支持cramfs, ext2, jffs2等include头文件,各种硬件的支持文件lib所有架构公用的一些库文件net网络协议相关post上电自检scripts脚本与makefile文件test测试文件tools编译u-boot的工具
  • 板级初始化
一般而言会首先执行CPU相关的start.S文件,一般存放在 arch下面,如arch/arm/cpu/armv8/start.S
在这一级初始化过程中会执行如lowlevel_init等CPU相关的底层初始化。
  • 板级配置文件
与板子相关的配置文件存放在:
include/configs/.h
board///

在这些文件中将会定义一些板子的配置,如CPU类型,板子类型,时钟,系统启动选项等。

u-boot浅析

在2011年以后u-boot的启动方式分为了两种流程,SPL与U-Boot常规模式,二者遵循同样的规则,但是代码流程二者几乎独立,通过宏定义 CONFIG_SPL_FRAMEWORK 来区分。
  1. 启动入口位于
arch/arm/cpu/armv8/start.S中,完成了:
i. cpu reset, 包括IRQ/FIQ/EA等
ii. jump to lowlevel_init完成对应处理器相关的操作,armv8下式完成GIC的初始化
iii. jump to main
此时C语言环境尚无初始化,没有堆栈可用,也不能使用SoC中的片内外设
  • 跳转到arch/arm/lib/crt0_64.S, 完成了:
    i. 初始化C语言环境,栈和全局数据,部分的RAM
    ii. 调用board_init_f() ,初始化RAM等
    此时已经完成了全局数据与栈的初始化,但是BSS尚不能用,无法使用全局/静态变量区
    iii.跳转到board_init_r()
  • 跳转到common/board_r.c的board_init_r()中
    i. 之后程序会根据init_sequence_r完成初始化
    ii. 最终run_main_loop
    iii. 例如ls2080axxx.c中定义了checkboard()
    iv. 在 commonoard_info.c中封装为show_board_info(void)
    v. 而show_board_info()则在init_sequence_r中被注册
    vi. 最终会在在board_init_r的循环中被执行。
  • 也就是说,u-boot前期完成了CPU相关的底层初始化和基本的C语言环境初始化,随后初始化过程都在init_sequence_f[]中声明,并在board_init_r中的:
    for (i = 0; i < ARRAY_SIZE(init_sequence_r); i++)
    init_sequence_r[i] += gd->reloc_off;
    所调用.

u-boot 修改与移植

假设我们新设计了一个板子,板子是根据RDB板修改而来,起名为LS2080AXXX
  1. 复制defconfig文件,创建自己的defconfig文件
    cp configs/ls2080ardb_defconfig configs/ls2080axxx_defconfig
  2. 修改ls2080axxx_defconfig,指明新的板名
    修改CONFIG_TARGET_LS2080ARDB=y 为 CONFIG_TARGET_LS2080AXXX=y
  3. 在boards下创建板级配置文件
    cp -r board/freescale/ls2080ardb board/freescale/ls2080axxx
  4. board/freescale/ls2080axxx 下存放的是板子相关代码,根据板子的差异进行修改
    ,这里把所有rdb相关的文件和名称全部修改为xxx
  5. 修改board/freescale/ls2080axxx/Kconfig
    修改 if TARGET_LS2080ARDB 为 if TARGET_LS2080AXXX
    修改 SYS_BOARD 内容为 ls2080axxx
    如果SYS_VENDOR内容被修改为abcde,那么文件路径应该都是 board/abced/....
    修改SYS_CONFIG_NAME为ls2080axxx
  • 修改board/freescale/ls2080axxx/Makefile
    修改ls2080ardb 为 ls2080axxx
  • 创建include下头文件
    cp include/configs/ls2080ardb.h include/configs/ls2080axxx.h
    在头文件中添加: #define CONFIG_LS2080AXXX
  • 修改arch下编译配置文件
    vim arch/arm/Kconfig
  • Kconfig中添加内容
config TARGET_LS2080AXXX bool "Support ls2080axxx" select ARM64 select ARMV8_MULTIENTRY select SUPPORT_SPL help ls2080axxx 文件后部添加
source "board/freescale/ls2080axxx/Kconfig"
指明板子配置文件
  1. 编译
    指明编译器类型,如上一章所述
    make mrproper
    make ls2080axxx_defconfig
    make
  2. 编译后的u-boot.bin烧写到flash相关位置即可,烧写地址和板子的设计与CPU启动相关

u-boot 烧写

  • LS2080ARDB NOR FLASH 空间分配
名称当前BANK第二BANKMC0x5803000000x584300000DPL0x5807000000x584700000DPC0x5808000000x584800000AIOP0x5809000000x584900000PHY0x5810000000x585000000u-boot0x5801000000x584100000RCW0x5800000000x584000000两个BANK都可以存放启动代码,可以将用户代码存放在第二BANK中,这样并不会破坏默认BANK中的内容,方便调试,想要启动第二BANK内容的代码,需要在启动默认BANK的u-boot后再敲命令:
qixis_reset altbank
  • 烧写u-boot
  • 使用Tera Term通过串口连接RDB板
  • 默认u-boot后中断autoboot
  • 输入载入内存命令
    loady 81000000
  • 打开xmodem, 发送u-boot.bin
  • 传输完成后架设大小为0x227b28
  • 输入擦除flash命令
    erase 584100000 227b28
  • 输入拷贝命令
    cp.b 81000000 584100000 227b28
  • 输入重启到第二BANK指令
    qixis_reset altbank

Linux Kernel

TBD.. 小礼物走一走,来简书关注我 赞赏支持

作者:v0cbc
链接:https://www.jianshu.com/p/82c15cb32281
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。