索引
- 目标
- 系统硬件组成
- 启动流程
- 环境搭建
- u-boot 移植
- Kernel移植
- 文件系统移植
目标
研究Freescale Layerscape CPU启动流程, 根据硬件组成修改U-Boot并移植,研究BSP,最终修改Kernel并移植文件系统
系统硬件组成
以Freescale Layerscape LS2080A 为例,Freescale同样提供了LS2080ARDB开发板作为硬件设计和调试开发板。
LS2080A CPU组成:
内部集成8核ARM A57架构CPU。
RDB板结构:
在RDB板中,系统集成了NOR FLASH与NAND FLASH 与 8GB DDR4,主要的启动代码如U-Boot将会存放在Nor Flash中。
关键地址分配:
启动流程
- CPU上电
- CPU POR
- 根据RCW初始化芯片内关键模块和时钟
- 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域中去 - 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)
- 下载
- 编译
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/
- 设置ARCH
-
编译命令
- clean命令
make mrproper
- 配置目标
make ls2080ardb_defconfig
- 编译
make
- 图形化配置*
make menuconfig
- clean命令
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结构(加粗为需要修改的地方)
名称 | 说明 |
---|---|
arch | CPU结构,支持PPC, ARM,MIPS,AVR32等众多CPU |
api | 与CPU相关的一些API |
arch | 与CPU相关的一些API |
board | 存放开发板的相关文件 |
common | MISC体系下独立功能 |
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/<board_name>.h
board/<vender>/<board_name>/
在这些文件中将会定义一些板子的配置,如CPU类型,板子类型,时钟,系统启动选项等。
u-boot浅析
在2011年以后u-boot的启动方式分为了两种流程,SPL与U-Boot常规模式,二者遵循同样的规则,但是代码流程二者几乎独立,通过宏定义
CONFIG_SPL_FRAMEWORK
来区分。
- 启动入口位于
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. 在 common\board_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
复制defconfig文件,创建自己的defconfig文件
cp configs/ls2080ardb_defconfig configs/ls2080axxx_defconfig修改ls2080axxx_defconfig,指明新的板名
修改CONFIG_TARGET_LS2080ARDB=y 为 CONFIG_TARGET_LS2080AXXX=y在boards下创建板级配置文件
cp -r board/freescale/ls2080ardb board/freescale/ls2080axxxboard/freescale/ls2080axxx 下存放的是板子相关代码,根据板子的差异进行修改
,这里把所有rdb相关的文件和名称全部修改为xxx修改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/KconfigKconfig中添加内容
config TARGET_LS2080AXXX
bool "Support ls2080axxx"
select ARM64
select ARMV8_MULTIENTRY
select SUPPORT_SPL
help
ls2080axxx
文件后部添加
source "board/freescale/ls2080axxx/Kconfig"
指明板子配置文件
编译
指明编译器类型,如上一章所述
make mrproper
make ls2080axxx_defconfig
make编译后的u-boot.bin烧写到flash相关位置即可,烧写地址和板子的设计与CPU启动相关
u-boot 烧写
- LS2080ARDB NOR FLASH 空间分配
名称 | 当前BANK | 第二BANK |
---|---|---|
MC | 0x580300000 | 0x584300000 |
DPL | 0x580700000 | 0x584700000 |
DPC | 0x580800000 | 0x584800000 |
AIOP | 0x580900000 | 0x584900000 |
PHY | 0x581000000 | 0x585000000 |
u-boot | 0x580100000 | 0x584100000 |
RCW | 0x580000000 | 0x584000000 |
两个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..