ZLG IMX280A - 五步曲之三:uboot2017.09移植(下篇)
U-Boot的移植
U-Boot的移植之(一)基础篇:添加新的目标板定义本文使用最新的U-Boot-1.3.0-rc2。
U-Boot本身支持很多开发板,在其源代码中,每个板子都对应一个board/目录下的文件夹(笔者注:这并不确切,因为有的文件夹是供应商名称,下面可以有多个目标板目录,这里只考虑最简单的情况),以及include/configs/目录下的目标板配置头文件。
因此,要添加U-Boot对我们的目标板的支持,首先就是要建立目标板文件夹和配置头文件,并修改相关的Makefile。
下面以实例说明为U-Boot添加新的目标板定义的步骤和过程。
(1)在board/目录下建立目标板目录。
笔者的目标板是XSBASE270,处理器是PXA270。
由于U-Boot中本身支持很多开发板和处理器,可以从中找出与自己处理器型号相同或相近的开发板,在此基础上再做后续修改。
adsvix使用的也是PXA27x处理器,因此可以把它作为模板。
cd board/cp -arv adsvix xsbase270mv xsbase270/adsvix.c xsbase270/xsbase270.c(2)在include/configs/目录下建立目标板配置头文件。
cd include/configs/cp adsvix.hxsbase270.h(3)修改Makefile。
一是要在总的Makefile(U-Boot源码顶层目录下)中加入目标板的编译配置选项,这也可以参考adsvix的进行修改,只要把目标板名称改换为xsbase270即可:adsvix_config: unconfig@$(MKCONFIG) $(@:_config=) arm pxa adsvixxsbase270_config: unconfig@$(MKCONFIG) $(@:_config=) arm pxa xsbase270这里xsbase270与board/目录下目标板文件夹名称xsbase270一致。
uboot移植及基础学习
(转载自/caolisong/articles/754050.html)真的写得很好,很有参考价值,节约了很多时间,在此表示对大虾的敬佩!2006-08-17 u-boot移植1 首先,了解一下bootloader。
bootloader是系统加电后运行的第一段代码。
它要完成的工作就是初始化硬件设备,建立内存空间的映射图,这样为最终调用操作系统内核做好准备。
2 bootloader的操作模式(1)启动加载模式(bootloading)(2)下载模式(downloading)开发时要用(2),target board上的bootloader将通过串口或者网络等通信手段从host上下载内核映象和根文件系统映象等到ra m中。
3 bootloader的启动方式:网络启动、磁盘启动、flash启动。
4 bootloader的种类区分一下“bootloader”和“monitor”的概念。
bootloader只是引导设备并且执行主程序的固件;而monitor还提供了更多的命令行接口,可以进行调试、读写内存、烧写flash、配置环境变量等。
monitor在嵌入式系统开发过程中还可以提供很好的调试功能,开发完成后,就完全配置成了一个bootloader。
所以,习惯上把它们统称为bootloader。
我现在要使用的u-boot就是典型的monitor。
5 bootloader的启动流程搜集了一些资料,写的比较精彩,放在这里。
资料一:系统上电,检测BMS,选择系统的启动方式,如果BMS为高电平,则系统从片内ROM启动。
AT91RM9200的ROM上电后被映射到了0x0和0x100000处,在这两个地址处都可以访问到ROM。
由于9200的ROM中固化了一个BOOTLOAER程序。
所以PC从0X0处开始执行这个BOOTLOAER(准确的说应该是一级BOOTLOADER)。
这个BOOTLOER依次完成以下步骤:1. PLL SETUP设置PLLB产生48M时钟频率提供给USB DEVICE。
U-BOOT的启动流程及移植
11U-BOOT的启动流程及移植摘要:嵌入式系统一般没有通用的bootloader,u-boot是功能强大的bootlo ader开发软件,但相对也比较复杂。
文中对u-boot的启动流程作了介绍,详细给出了u-boot在S3C44B0开发板上的移植方法和步骤。
1Bootloader及u-boot简介Bootloader代码是芯片复位后进入操作系统之前执行的一段代码,主要用于完成由硬件启动到操作系统启动的过渡,从而为操作系统提供基本的运行环境,如初始化CPU、堆栈、存储器系统等。
Bootloader代码与CPU芯片的内核结构、具体型号、应用系统的配置及使用的操作系统等因素有关,其功能类似于PC机的BIOS程序。
由于bootloader和CPU及电路板的配置情况有关,因此不可能有通用的bootloader,开发时需要用户根据具体情况进行移植。
嵌入式Linux系统中常用的bootloader有armboot、redboot、blob、u-boot等,其中u-boot是当前比较流行,功能比较强大的bootloader,可以支持多种体系结构,但相对也比较复杂。
bootloader的实现依赖于CPU的体系结构,大多数bootloader都分为stage1和stage2两大部分。
Bootloader的基本原理见参考文献。
u-boot是sourceforge网站上的一个开放源代码的项目。
它可对PowerPC MPC5xx、MPC8xx、MPC82xx、MPC7xx、MPC74xx 、ARM(ARM7、ARM9、StrongARM、Xscale)、MIPS(4kc、5kc)、X86等处理器提供支持,支持的嵌入式操作系统有Linux、Vx-Works、NetBSD、QNX、RTEMS、ARTOS、LynxOS等,主要用来开发嵌入式系统初始化代码bootloader。
软件的主站点是http //sourceforge.net/projects/u-boot。
uboot——官网下载直接移植(一)
uboot——官⽹下载直接移植(⼀)1:uboot下载地址:ftp://ftp.denx.de/pub/u-boot/我们下载的版本是:u-boot-2013.10.tar.bz2;2:下载好以后,删除⾥⾯的相关⽂件因为三星是的s5pv1XX这个cpu做了很多个板⼦,我们在移植的时候虽然与三星的开发板不同但是⽤的cpu是相同的,所以我们再选择cpu相关⽂件的时候,要确定好哪个cpu与我们⽤的cpu是相同的,u-boot-2013.10\arch\arm\cpu\armv7\s5pc1xx 在⽬录下有s5pc1xx相关的配置⽂件;这就是我们要选⽤的cpu⽂件;3:相较与我们直接移植三星移植好的uboot,新版的uboot编译配置时有所不同;把主Makefile与board有关的配置信息⽂件分开了;我们可以根据board.cfg⽂件中的配置信息来确定我们⽤的是哪个开发板;打开board.cfg⽂件搜索s5pc1xx我们可以看到两个相关的开发板,goni、smdk100,我们先⽤goni开发板来进⾏移植;⾸先删除其它的⽆关⽂件:arch⽬录下:只保留arm⽂件夹;arm/cpu⽬录下的出armv7⽂件夹以外其他删除;arm/cpu/armv7⽬录下保留s5pc1xx 以及s5p_common这两个⽂件夹,其他的删除;board⽬录下:board⽬录下只保留samsung⽂件夹samsung⽬录下只保留goni、common⽂件夹之后⽤sourceinsight创建项⽬4:对主Makefile进⾏分析,之前我们make的时候⾸先要进⾏配置:make x210_sd_config,⽽在新uboot中的配置依赖于下⾯这个规则:我们进⾏配置的时候make s5p_goni_config 然后执⾏下⾯这段脚本相当于执⾏ ./mkcofig -A s5p_goniMKCONFIG变量还是mkconfig脚本,下⾯我们看⼀下mkconfig脚本如何⼯作:下⾯这段代码的作⽤:1if [ \( $# -eq 2 \) -a \( "$1" = "-A" \) ] ; then2 # Automatic mode3 line=`awk '($0 !~ /^#/ && $7 ~ /^'"$2"'$/) { print $1, $2, $3, $4, $5, $6, $7, $8 }' boards.cfg`4if [ -z "$line" ] ; then5 echo "make: *** No rule to make target \`$2_config'. Stop." >&26 exit 17 fi89set ${line}10 # add default board name if needed11 [ $# = 3 ] && set ${line} ${1}12 fi判断传参是否两个且第⼀个参数为 -A,如果是则对line赋值,line的值是通过在boards.cfg⽂件中查找第⼆个参数$2,并把这⼀⾏赋值给line,从前⾯内容我们可以看出line = Active arm armv7 s5pc1xx samsung goni s5p_goni -并且把这些由空格分开的字符赋值给$1-$8所以这段代码执⾏完以后的结果是:$1 = Active$2 = arm$3 = armv7$4 = s5pv1xx$5 = samsung$6 = goni$7 = s5p_goni$8 = -继续分析下⾯代码:这段代码实际中没有起到什么作⽤可忽略1while [ $# -gt 0 ] ; do2case"$1"in3 --) shift ; break ;;4 -a) shift ; APPEND=yes ;;5 -n) shift ; BOARD_NAME="${7%_config}" ; shift ;;6 -t) shift ; TARGETS="`echo $1 | sed 's:_: :g'` ${TARGETS}" ; shift ;;7 *) break ;;8 esac9 done1011 [ $# -lt 7 ] && exit 112 [ $# -gt 8 ] && exit 1下⾯代码:CONFIG_NAME="${7%_config}"[ "${BOARD_NAME}" ] || BOARD_NAME="${7%_config}"arch="$2"cpu=`echo $3 | awk 'BEGIN {FS = ":"} ; {print $1}'`spl_cpu=`echo $3 | awk 'BEGIN {FS = ":"} ; {print $2}'`if [ "$6" = "-" ] ; thenboard=${BOARD_NAME}elseboard="$6"fi[ "$5" != "-" ] && vendor="$5"[ "$4" != "-" ] && soc="$4"[ $# -gt 7 ] && [ "$8" != "-" ] && {# check if we have a board config name in the options field# the options field mave have a board config name and a list# of options, both separated by a colon (':'); the options are# separated by commas (',').## Check for board nametmp="${8%:*}"if [ "$tmp" ] ; thenCONFIG_NAME="$tmp"fi# Check if we only have a colon...if [ "${tmp}" != "$8" ] ; thenoptions=${8#*:}TARGETS="`echo ${options} | sed 's:,: :g'` ${TARGETS}"fi}config_name = s5p_goni_configBOARD_NAME = s5p_goni_configarch = armcpu = armv7spl_cpu = " "board = gonivendor = samsungsoc = s5pc1xx看下⾯信息:在这⾥第⼀打印出信息:Configuring for s5p_goni_config board...if [ "${ARCH}" -a "${ARCH}" != "${arch}" ]; thenecho "Failed: \$ARCH=${ARCH}, should be '${arch}' for ${BOARD_NAME}"1>&2exit 1fiif [ "$options" ] ; thenecho "Configuring for ${BOARD_NAME} - Board: ${CONFIG_NAME}, Options: ${options}" elseecho "Configuring for ${BOARD_NAME} board..."fi创建头⽂件的符号连接:if [ "$SRCTREE" != "$OBJTREE" ] ; thenmkdir -p ${OBJTREE}/includemkdir -p ${OBJTREE}/include2cd ${OBJTREE}/include2rm -f asmln -s ${SRCTREE}/arch/${arch}/include/asm asmLNPREFIX=${SRCTREE}/arch/${arch}/include/asm/cd ../includemkdir -p asmelsecd ./includerm -f asmln -s ../arch/${arch}/include/asm asmfirm -f asm/archif [ -z "${soc}" ] ; thenln -s ${LNPREFIX}arch-${cpu} asm/archelseln -s ${LNPREFIX}arch-${soc} asm/archfiif [ "${arch}" = "arm" ] ; thenrm -f asm/procln -s ${LNPREFIX}proc-armv asm/procfi符号连接1:/include/asm 连接到 /arch/arm/include/asm符号连接2: /include/asm/arch链接到 /arch/arm/include/asm/arch-s5pc1xx 符号链接3: /include/asm/proc链接到/arch/arm/include/asm/proc-armv看⼀下下⾯的代码:## Create include file for Make#( echo "ARCH = ${arch}"if [ ! -z "$spl_cpu" ] ; thenecho 'ifeq ($(CONFIG_SPL_BUILD),y)'echo "CPU = ${spl_cpu}"echo "else"echo "CPU = ${cpu}"echo "endif"elseecho "CPU = ${cpu}"fiecho "BOARD = ${board}"[ "${vendor}" ] && echo "VENDOR = ${vendor}"[ "${soc}" ] && echo "SOC = ${soc}"exit 0 ) > config.mk这段代码的作⽤是把ARCH = armCPU = armv7BOARD = gonivendor = samsungsoc = s5pc1xx 输出config.mk⽂件中看下⾯代码:# Assign board directory to BOARDIR variableif [ -z "${vendor}" ] ; thenBOARDDIR=${board}elseBOARDDIR=${vendor}/${board}fiBOARDDIR = samsung/goni再看最后⼀段代码:# Create board specific header file#if [ "$APPEND" = "yes" ] # Append to existing config file thenecho >> config.helse> config.h # Create new config filefiecho "/* Automatically generated - do not edit */" >>config.hfor i in ${TARGETS} ; doi="`echo ${i} | sed '/=/ {s/=/ /;q; } ; { s/$/ 1/; }'`"echo "#define CONFIG_${i}" >>config.h ;doneecho "#define CONFIG_SYS_ARCH \"${arch}\"" >> config.hecho "#define CONFIG_SYS_CPU \"${cpu}\"" >> config.hecho "#define CONFIG_SYS_BOARD \"${board}\"" >> config.h [ "${vendor}" ] && echo "#define CONFIG_SYS_VENDOR \"${vendor}\"" >> config.h [ "${soc}" ] && echo "#define CONFIG_SYS_SOC \"${soc}\"" >> config.hcat << EOF >> config.h#define CONFIG_BOARDDIR board/$BOARDDIR#include <config_cmd_defaults.h>#include <config_defaults.h>#include <configs/${CONFIG_NAME}.h>#include <asm/config.h>#include <config_fallbacks.h>#include <config_uncmd_spl.h>EOFexit 0上⾯这段代码的作⽤就是添加⼀些宏定义到config.h⽂件中:/* Automatically generated - do not edit */TARGETS为空所以不执⾏#define CONFIG_SYS_ARCH arm#define CONFIG_SYS_CPU armv7#define CONFIG_SYS_BOARD goni#define CONFIG_SYS_SOC s5pc1xxcat << EOF >> config.h 这句代码的作⽤是把下⾯内容写⼊config.h中,直到EOF;。
ZLG IMX280A - 五步曲之三:uboot2017.09移植(下篇)
csvM X28_DDR2_regis…1.xlsx101.25KB16100: 1*16 32200: 2*32 16400: 4*16 16800: 8*16 32400: 4*32 16160: 16*16表格信息:*上面需要准确填写的是行列地址总线宽度,bank数,CS数,数据总线宽度,时钟频率。
*tFAW不小于tRRD4倍,所以设置40ns。
*tRPA:如果数据手册不能找到tRPA,那么这么位置填入tRP。
*CASLAT:设置CAS LATCH周期,这个周期在ddr初始化时由ddr控制器对ddr设置。
*根据信号线计算ram大小,如下2 ^ (1cs + 3bank + 15row + 12col + 1datapath width) = 4GB:2、下载源码与建立baseline:2.1 源码下载略。
2.2 选择一个相近的平台,编写试编译通过:./setenv.shmake mx28evk_defconfigmake u-boot.sb*这里的sb文件是加密文件,而elftosb工具生成的可以通过-z参数选择是否加密。
*如果编译器是32位,但是系统是64位,那么安装32位兼容库即可:sudo apt install libc6-dev-i386 lib32z12.3 复制文件与修改配置:cp configs/mx28evk_defconfig configs/imx280a_defconfigcp configs/mx28evk_defconfig configs/imx280a_mmc_defconfigmkdir board/zlg/ && cp -rf board/freescale/mx28evk/ board/zlg/imx280a/ mv board/zlg/imx280a/mx28evk.c board/zlg/imx280a/imx280a.cvim board/zlg/imx280a/Kconfigvim board/zlg/imx280a/Makefilecp include/configs/mx28evk.h include/configs/imx280a.hvim include/configs/imx280a.h*vim ./arch/arm/include/asm/mach-types.h*从mx28手册可以得到内存起始物理地址:*删掉FEC,USB,SPI,LCD及额外环境变量的配置。
移植u-boot详细过程
编译信息最后两行:
arm-linux-objcopy --gap-fill=0xff -O srec u-boot u-boot.srec
arm-linux-objcopy --gap-fill=0xff -O binary u-boot u-boot.bin
到此交叉编译成功。
三.开始针对自己的开发板移植
B 是最简单的跳转指令。要注意的是,跳转指令的实际值不是绝对地址,而是相对地址——
是相对当前 PC 值的一个偏移量,它的值由汇编器计算得出。
BL 非常常用。它在跳转之前会在寄存器 LR(R14)中保存 PC 的当前内容。BL 的经典用法如下:
bl NEXT ; 跳转到 NEXT
……
NEXT
……mov pc, lr源自; 从子程序返回。ldr pc, _start_armboot
_start_armboot: .word start_armboot
这两条语句,ldr
pc, _start_armboot 指令把_start_armboot 这个标签的地方存放的内
容(也即是 start_armboot)移到 PC 寄存器里面,start_armboot 是一个函数地址,在编译的时
sbc2410x_config: unconfig @$(MKCONFIG) $(@:_config=) arm arm920t sbc2410x NULL s3c24x0 qljt2440_config : unconfig @$(MKCONFIG) $(@:_config=) arm arm920t qljt2440 qljt s3c24x0 /* 各项的意思如下:
1. 修改/cpu/arm920t/start.S 1.1 修改寄存器地址定义
ZLG IMX280A KERNEL - 五步曲之四:linux kernel 4.14.1移植(下篇)
五步曲之四:linux kernel 4.14.1移植(下篇)BY: john ding QQ: 343399208*编译器支持的kernel版本需要大于4.10.8,可以通过file ~/tools/arm-arm926-linux-gnueabihf/arm-arm926-linux-gnueabihf/sysroot/lib/libc-2.25.so查看到对linux版本的需求。
1、下载源码与建立baseline:1.1 下载源码略。
1.2 选择一个相近的平台,编写试编译通过。
cp arch/arm/boot/dts/imx28-evk.dts arch/arm/boot/dts/imx28-imx280a.dtscp arch/arm/configs/mxs_defconfig arch/arm/configs/mxs_imx280a_defconfig添加设备树:vim ./arch/arm/boot/dts/Makefilevim arch/arm/boot/dts/imx28-imx280a.dtsvim ./arch/arm/mach-mxs/mach-mxs.cmake mxs_imx280a_defconfigmake ARCH=arm menuconfig配置设备树append进kernel中:配置debug串口支持:*从串口驱动代码可知生成的串口名为ttyAMAx。
配置nand(gpmi支持,mtd支持,ubi支持,ubifs支持):配置mmc(sdio支持,mmc支持,initrd支持(注意initramfs与initrd的区别)):去掉lcd,fb等相关支持:设置编译器兼容性:选上浮点运算单元支持:cp .config arch/arm/configs/mxs_imx280a_defconfig设备树与menuconfig精简:vim arch/arm/boot/dts/imx280a.dtsmake mxs_imx280a_defconfigcp .config arch/arm/configs/mxs_imx280a_defconfig./build.sh:编译kernel。
u-boot移植心得
几经艰辛,终于基本完成了u-boot在s3c44b0的移植工作,在些记录一下在移植过程中所碰到的困难和解决方法(一些心得),作为日后参考之用,也希望能够帮到其它有需要的人^_^。
1.来由:在我搞完ucos后(本来我是想学uclinux的,不过在对系统一无所知的情况下,还是先学一下ucos比较实际^_^,从中也可以对系统有个清晰的概念),我意识到要搞系统的话一个功能强大的bootloader是必不可少的,而我的板上自带的是armboot(其实我个人觉得应用在ARM上的话armboot已经足够了,毕竟u-boot也是从armboot中发展过来的,纯属个人意见),如果我的板上自带光盘有已经移植好的armboot源代码供我参考的话,我想我也不会花这么多时间去搞u-boot,可恨的是我的光盘上只有armboot.bin这个二进制文件,而没有源文件,没办法,我下定主意自己搞一个,考虑了一番后我选择了u-boot,毕竟参考资料相对比较多,再我学完u-boot后再回头看armboot,简直是一个炉里出的饼,这是后话。
2.准备:说是容易,做起来却挺难。
因为编译u-boot要在linux环境下,而不能在我们平时所熟悉的ads下那么直观。
首先要建立好交叉编译环境,这个交叉编译环境可以自己来做,不过完全没必要,而且难度也挺大,一般是下载人家编译好的工具。
我刚开始在这里就郁闷了很久,现在会了以后觉得原来就是这么简单,在些我把方法说清楚,希望不会再有人为这个问题郁闷了^_^:1)在网上下载一个u-boot源代码,我用的是1.1.2版本的,最新的应该是1.1.4的吧,其实差不多,那就像我那样下载一个1.1.2版本的吧。
把源文件解压,这个应该不用说了吧,学过linux的人应该会,不会的话我想你继续做下去也困难,那就先装个linux用下吧(我用的是RedHat的,哦对了,编译程序是需要gcc 编译器的,所以安装方式一定要选择工作站哦^_^)。
uuboot 移植流程
uuboot 移植流程U-Boot 移植流程介绍U-Boot是一个开源的引导加载程序,常用于嵌入式系统中。
移植U-Boot可以将其适配到不同的硬件平台上,以满足特定需求。
本文将详细说明U-Boot移植的流程。
准备工作1.硬件选型:根据项目需求,选择适合的硬件平台。
2.获取源代码:从U-Boot官方网站或仓库下载最新版本的源代码。
3.安装交叉编译工具链:根据目标硬件平台的指令集架构,选择合适的交叉编译工具链,并进行安装。
4.了解目标硬件平台:熟悉目标硬件平台的架构、引导方式、存储器布局等相关信息。
移植流程1.配置编译环境:设置交叉编译工具链的环境变量,以确保正确编译U-Boot源代码。
2.配置U-Boot:修改U-Boot源代码中的配置文件,根据目标硬件平台的特性和需求进行相应配置。
–配置目标硬件平台的处理器类型、存储器布局等基本信息。
–配置启动方式,如通过网络(TFTP)或存储介质(SD卡、NAND Flash)等进行启动。
–配置启动流程,如引导加载程序的加载顺序、启动脚本等。
3.添加适配代码:根据目标硬件平台的需求,编写适配代码,包括引导加载程序和设备驱动等。
–引导加载程序:为目标硬件平台选择合适的程序入口点,配置启动参数,加载适配的设备驱动等。
–设备驱动:根据目标硬件平台的外设,编写相应的设备驱动代码,以支持外设的初始化和操作。
4.编译U-Boot:使用交叉编译工具链,编译修改后的U-Boot源代码。
–执行make clean清除之前的编译结果。
–执行make命令编译U-Boot源代码。
5.烧录和运行:将编译生成的U-Boot镜像烧录到目标硬件平台,并进行测试。
–根据目标硬件平台的烧录方式(串口、JTAG等),将U-Boot镜像烧录到目标设备。
–启动目标设备,观察U-Boot的启动信息是否正常输出,检查设备驱动是否正常加载。
6.调试和优化:根据实际情况,进行U-Boot的调试和性能优化。
–使用调试工具进行调试,如调试器、串口打印信息等。
u-boot移植过程
一、U-BOOT的目录结构 u-boot目录下有18个子目录,分别存放管理不通的源程序。
这些目录中所要存放的文件有其规则,可以分成三类。
■第一类目录与处理器体系结构或者开发板硬件直接相关;■第二类目录是一些通用的函数或者驱动程序;■第三类目录是u-boot的应用程序、工具或者文档。
Board:和一些已有开发板相关的文件,比如Makefile和u-boot.lds等都和具体开发板的硬件和地址分配有关。
Common:与体系结构无关的文件,实现各种命令的C文件。
CPU:CPU相关文件,其中的子目录都是以u-boot所支持的CPU为名,比如有子目录arm926ejs、mips、mpc8260和nios等,每个特定的子目录中都包括cpu.c 和interrupt.c和start.S。
其中cpu.c初始化cpu、设置指令cache和数据cache 等;interrupt.c设置系统的各种终端和异常,比如快速中断,开关中断、时钟中断、软件中断、预取中止和未定义指令等;start.S是u-boot启动时执行的第一个文件,他主要是设置系统堆栈和工作发式,为进入C程序奠定基础。
Disk:disk驱动的分区处理代码、Doc:文档。
Drivers:通用设备驱动程序,比如各种网卡、支持CFI的flash、串口和USB 总线等。
Dtt:数字温度测量器或者传感器的驱动Examples:一些独立运行的应用程序的例子。
Fs:支持文件系统的文件,u-boot现在支持cramfs、fat、fdos、jffs2、yaffs 和registerfs。
Include:头文件,还有对各种硬件平台支持的会变文件,系统的配置文件和对文件系统支持的文件。
Net:与网络有关的代码,BOOTP协议、TFTP协议RARP协议和NFS文件系统的实现。
Lib_ppc:存放对PowerPC体系结构通用的文件,主要用于实现PowerPC平台通用的函数,与PowerPC体系结构相关的代码。
Uboot启动流程分析和移植介绍
基于MPC83xx 的U-boot 启动流程分析和移植董 闯北京邮电大学信息与通信工程学院,北京(100876)E-mail :donix.dong@摘 要:本文首先引入Bootloader 的概念,接着介绍U-boot 这种引导程序,并以Freescale 32位微处理器MPC83xx 为例,结合代码详细分析了U-boot 的启动的各个阶段及最终引导Linux 内核的过程,最后,建立交叉编译环境,针对TC8313E 目标板,给出U-boot 移植与编译的基本步骤。
关键词:U-boot;MPC83xx;交叉编译;移植;嵌入式系统中图分类号:TP393.051.引言引导程序(Bootloader)是系统加电后运行的第一段软件代码,类似于PC 机中的引导加载程序BIOS 。
虽然引导程序仅在系统启动时运行非常短的时间,但对于嵌入式系统来说,这是一个非常重要的组成部分。
通过这段小程序,初始化必要的硬件设备,创建内核需要的一些信息并将这些信息传递给内核,从而将系统的软、硬件环境配置到一个合适的状态,最终调用操作系统内核,真正起到引导和加载内核的作用。
2. U-boot 介绍目前,嵌入式领域里出现了很多种类的Bootloader ,如Armboot 、Blob 、Redboot 、vivi 和U-boot 等,其中U-boot 是使用最广泛,功能最完善的。
U-boot (Universal Boot Loader)是从PPCBOOT 发展演化而来[1],其源码目录、编译形式与Linux 内核很相似,事实上,不少U-boot 源码就是相应的Linux 内核源程序的简化,尤其是一些设备的驱动程序,这从U-boot 源码的注释中就能体现。
U-boot 中Universal 有两层含义,一是U-boot 除了支持PowerPC 系列的处理器外,还能支持MIPS 、x86、ARM 、NIOS 、XScale 等诸多常用系列的处理器;另外一层含义则是U-boot 不仅仅支持嵌入式Linux 操作系统的引导,还支持OpenBSD, NetBSD, FreeBSD, SVR4, Solaris, VxWorks, LynxOS, pSOS, lrix, RTEMS, QNX, ARTOS 等操作系统的引导。
uboot移植心得
最近跑完裸机之后,便开始跑系统,但想着裸机与系统之间隔着个Bootloader,反正以前也没怎么深入研究,便说花一到两周时间来搞搞U-BOOT。
参考了fzb和赵春江两位大牛的,也研究了2010.06版本的和2011.06版本两个经典版本,也对比了TQ(我买的板是天嵌的)自己写的U-BOOT,学到了不少,也发现了很多东西,以下便记录以下自己的心得吧,以便以后可以自己参考下。
U-BOOT的两个阶段启动过程:(2010.06经典版来说)第一阶段:start.S的路径位于arch\arm\cpu\arm920t\这段汇编代码一般被称作第一阶段初始化代码。
主要作用是初始化运行环境;初始化内存;重新放置UBOOT代码到内存中;跳入到内存中执行第二段初始化代码1、关闭开门狗,屏蔽所有中断2、设置分频比3、bl cpu_init_crit() 关MMU,初始化内存bl lowlevel_init() 配置内存,修改内存刷新率参数等4、relocate判断当前代码是在NORFLASH还是RAMcopy_loop循环将FLASH代码复制至RAM中5、stack_setup栈设置clear_bss_bss_start到_bss_end之间的数据清06、ldr pc , start_armboot 跳转到第二阶段//=====================================================================第二阶段:board.c的路径位于arch/arm/lib/board.c,这段代码为U-BOOT的第二阶段初始化代码。
主要作用是初始化两个重要数据结构,对SDRAM的内存分配设置,对各种需要用到的外设进行初始化,最后循环跳入main_loop()函数二阶段start_armboot分为board_init_f 和 board_init_r两部分先执行的board_init_f部分:1、为gd数据结构分配地址,并清零2、执行init_fnc_ptr函数指针数组中的各个初始化函数,如下board_early_init_f ,timer_init ,env_init init_baudrate serial_initconsole_init_f display_banner dram_init3、A、分配SDRAM高64KB为TLB,用于U-BOOTB、分配SDRAM下一单元为U-BOOT代码段,数据段,BSS段(这里插一句,原来BSS段是用来存放未初始化的全局变量与静态变量)C、接着开辟malloc空间,存bd , gd , 3个字大小的异常堆空间4、将relorate的地址值赋给gd结构体相应变量(2011.06版本的,用于返回start.S)后执行的board_init_r部分:1、对gd , bd 数据结构赋值初始化2、各种外设初始化:初始化NORFLASH, NANDFLASH,初始化ONENAND FLASH初始化环境变量初始化PCI设置IP地址初始化各类外设:IIC、LCD、键盘、USB初始化控制台建立IRQ中断堆栈初始化以太网初始化跳转表(定义了U-Boot中基本的常用函数库)。
uboot2009移植
嵌入式Linux之我行——u-boot-2009.08在2440上的移植详解(一)(2009-11-27 10:46)分类:Bootloader移植篇嵌入式Linux之我行,主要讲述和总结了本人在学习嵌入式linux中的每个步骤。
一为总结经验,二希望能给想入门嵌入式Linux的朋友提供方便。
如有错误之处,谢请指正。
共享资源,欢迎转载:一、移植环境主机:VMWare--Fedora 9开发板:Mini2440--64MB Nand,Kernel:2.6.30.4编译器:arm-linux-gcc-4.3.2.tgzu-boot:u-boot-2009.08.tar.bz2二、移植步骤本次移植的功能特点包括:支持Nand Flash读写支持从Nor/Nand Flash启动支持CS8900或者DM9000网卡支持Yaffs文件系统支持USB下载(还未实现)1.了解u-boot主要的目录结构和启动流程,如下图。
u-boot的stage1代码通常放在cpu/xxxx/start.S文件中,他用汇编语言写成;u-boot的stage2代码通常放在lib_xxxx/board.c文件中,他用C语言写成。
各个部分的流程图如下:2. 建立自己的开发板项目并测试编译。
目前u-boot对很多CPU直接支持,可以查看board目录的一些子目录,如:board/samsung/目录下就是对三星一些ARM处理器的支持,有smdk2400、smdk2410和smdk6400,但没有2440,所以我们就在这里建立自己的开发板项目。
1)因2440和2410的资源差不多,主频和外设有点差别,所以我们就在board/samsung/下建立自己开发板的项目,取名叫my2440#tar -jxvf u-boot-2009.08.tar.bz2 //解压源码#cd u-boot-2009.08/board/samsung/ //进入目录#mkdir my2440 //创建my2440文件夹2)因2440和2410的资源差不多,所以就以2410项目的代码作为模板,以后再修改#cp -rf smdk2410/* my2440/ //将2410下所有的代码复制到2440下#cd my2440 //进入my2440目录#mv smdk2410.c my2440.c //将my2440下的smdk2410.c改名为my2440.c#cd ../../../ //回到u-boot根目录#cp include/configs/smdk2410.h include/configs/my2440.h//建立2440头文件#gedit board/samsung/my2440/Makefile //修改my2440下Makefile的编译项,如下:COBJS :=my2440.o flash.o //因在my2440下我们将smdk2410.c改名为my2440.c3)修改u-boot跟目录下的Makefile文件。
uboot移植(深入浅出)
移植U-Boot.1.3.1到S3C244和S3C2410首先,U-Boot1.3.1还没有支持s3c2440,移植仍是用2410的文件稍作修改而成的。
2440和2410的区别在我移植1.2.0的文章中已经写了,这里不再赘述。
对于1.3.1和1.2.0的差别,我初看了一下,(对于ARM920T内核)应该是增加了对A TMEL 公司的A T91RM9200系列处理器的支持。
至于S3C24X0系列的芯片,原理上并没有什么大的变化。
一、在U-Boot中建立自己的开发板类型,并测试编译。
我为开发板取名叫: tekkaman24400 在工作目录下解压U-Boot。
[tekkamanninja@ARM9-Host working]$ tar -xjvf u-boot-1.3.1.tar.bz21 进入U-Boot目录,修改Makefile(我在fedora 8 下,比较喜欢使用KWrite)[tekkamanninja@ARM9-Host working]$ cd u-boot-1.3.1[tekkamanninja@ARM9-Host u-boot-1.3.1]$ kwrite Makefile#为tekkaman2440建立编译项sbc2410x_config: unconfig@$(MKCONFIG) $(@:_config=) arm arm920t sbc2410x NULL s3c24x0tekkaman2440_config : unconfig@$(MKCONFIG) $(@:_config=) arm arm920t tekkaman2440 tekkaman s3c24x0LSD1808_config: unconfig@$(MKCONFIG) $(@:_config=) arm arm926ejs lsd1808 NULL am1808各项的意思如下:arm: CPU的架构(ARCH)arm920t: CPU的类型(CPU),其对应于cpu/arm920t子目录。
u-boot移植详细文档
u‐boot移植详细文档作者:Tekkaman Ninja作者博客:整理:Coolbor Xie一、Boot Loader的概念和功能1、嵌入式Linux软件结构与分布在一般情况下嵌入式Linux系统中的软件主要分为以下及部分:(1)引导加载程序:其中包括内部ROM中的固化启动代码和Boot Loader两部分。
而这个内部固化ROM是厂家在芯片生产时候固化的,作用基本上是引导Boot Loader。
有的芯片比较复杂,比如Omap3,他在flash中没有代码的时候有许多启动方式:USB、UART或以太网等等。
而S3C24x0则很简单,只有Norboot和Nandboot。
(2)Linux kernel 和drivers。
(3)文件系统。
包括根文件系统和建立于Flash内存设备之上的文件系统(EXT4、UBI、CRAMFS等等)。
它是提供管理系统的各种配置文件以及系统执行用户应用程序的良好运行环境的载体。
(4)应用程序。
用户自定义的应用程序,存放于文件系统之中。
在Flash 存储器中,他们的一般分布如下:但是以上只是大部分情况下的分布,也有一些可能根文件系统是initramfs,被一起压缩到了内核映像里,或者没有Bootloader参数区,等等。
2、在嵌入式Linux中为什么要有BootLoader在linux内核的启动运行除了内核映像必须在主存的适当位置,CPU还必须具备一定的条件:1. CPU 寄存器的设置: R0=0;R1=Machine ID(即Machine Type Number,定义在linux/arch/arm/tools/mach‐types); R2=内核启动参数在 RAM 中起始基地址;2. CPU 模式: 必须禁止中断(IRQs和FIQs); CPU 必须 SVC 模式;3. Cache 和 MMU 的设置: MMU 必须关闭;指令 Cache 可以打开也可以关闭; 数据 Cache 必须关闭;但是在CPU刚上电启动的时候,一般连内存控制器都没有配置过,根本无法在内存中运行程序,更不可能处在Linux内核的启动环境中。
一步步教你移植uboot(超精华版)
#make gec2440_config #make 编译完成时最后两句如下:
arm-linux-objcopy -O srec u-boot u-boot.srec arm-linux-objcopy --gap-fill=0xff -O binary u-boot u-boot.bin 表示编译成功。
# if defined(CONFIG_S3C2410)
ldr r1, =0x7ff //0x3ff,根据 2410 芯片手册,INTSUBMSK 有 11 位可用,vivi 也是 0x7ff, u-boot 则是 0x3ff,不过芯片复位后所有中断都被屏蔽,故这无影响
ldr r0, =INTSUBMSK
>> 2
广州广嵌电子科技有限公司
u-boot移植要点 我们可以总结出bootloader的两大功能:
1 是下载功能,既通过网口、串口或者USB口下载文件到RAM中。 2 是对flash芯片的读写功能。 u-boot对S3C2440已经有了很好的支持,在移植过程中主要是完善u-boot对nand flash 的读写功能。 u-boot移植前的准备工作 1.下载源码 Uboot的源码可以从以下网址下载: /u-boot/u-boot-2009.11.tar.bz2?modtime=1134 752480&big_mirror=0 我们这里下载的是u-boot-2009.11.tar.bz2 工具链使用cross-4.1.2
samsung: 开发者/或经销商(vender)。
s3c24x0: 片上系统(SOC)。 板子起名叫gec2440,可以依自己的喜好修改
UBoot移植详细教程
u-boot 移植步骤详解(必会)1 U-Boot简介U-Boot,全称Universal Boot Loader,是遵循GPL条款的开放源码项目。
从FADSROM、8xxROM、PPCBOOT逐步发展演化而来。
其源码目录、编译形式与Linux内核很相似,事实上,不少U-Boot源码就是相应的Linux内核源程序的简化,尤其是一些设备的驱动程序,这从U-Boot源码的注释中能体现这一点。
但是U-Boot不仅仅支持嵌入式Linux系统的引导,当前,它还支持NetBSD, VxWorks, QNX, RTEMS, ARTOS, LynxOS嵌入式操作系统。
其目前要支持的目标操作系统是OpenBSD, NetBSD, FreeBSD,4.4BSD, Linux, SVR4, Esix, Solaris, Irix, SCO, Dell, NCR, VxWorks, LynxOS, pSOS, QNX, RTEMS, ARTOS。
这是U-Boot中Universal的一层含义,另外一层含义则是U-Boot除了支持PowerPC系列的处理器外,还能支持MIPS、x86、ARM、NIOS、XScale等诸多常用系列的处理器。
这两个特点正是U-Boot项目的开发目标,即支持尽可能多的嵌入式处理器和嵌入式操作系统。
就目前来看,U-Boot对PowerPC系列处理器支持最为丰富,对Linux的支持最完善。
其它系列的处理器和操作系统基本是在2002年11 月PPCBOOT 改名为U-Boot后逐步扩充的。
从PPCBOOT向U-Boot的顺利过渡,很大程度上归功于U-Boot的维护人德国DENX软件工程中心Wolfgang Denk[以下简称W.D]本人精湛专业水平和持着不懈的努力。
当前,U-Boot项目正在他的领军之下,众多有志于开放源码BOOT LOADER移植工作的嵌入式开发人员正如火如荼地将各个不同系列嵌入式处理器的移植工作不断展开和深入,以支持更多的嵌入式操作系统的装载与引导。
uboot内核移植和裁剪详细步骤
uboot内核移植和裁剪详细步骤-U-boot内核移植步骤:Linux 3.3.5系统移植1. 将arch/arm/mach-s3c6410/下的,mach-smdk6410.c cp为mach-my6410.c;2. 打开arch/arm/mach-s3c6410/下的Kconfig,仿照MACH_SMDK6410做一个菜单项:config MACH_MY6410bool "MY6410"select CPU_S3C6410select SAMSUNG_DEV_ADCselect S3C_DEV_HSMMCselect S3C_DEV_HSMMC1select S3C_DEV_I2C1select SAMSUNG_DEV_IDEselect S3C_DEV_FBselect S3C_DEV_RTCselect SAMSUNG_DEV_TSselect S3C_DEV_USB_HOSTselect S3C_DEV_USB_HSOTGselect S3C_DEV_WDTselect SAMSUNG_DEV_BACKLIGHTselect SAMSUNG_DEV_KEYPADselect SAMSUNG_DEV_PWMselect HAVE_S3C2410_WATCHDOG if WATCHDOGselect S3C64XX_SETUP_SDHCIselect S3C64XX_SETUP_I2C1select S3C64XX_SETUP_IDEselect S3C64XX_SETUP_FB_24BPPselect S3C64XX_SETUP_KEYPADhelpMachine support for the Pillar MY64103. 打开arch/arm/tools/mach-types文件,这里面存的是机器ID必须要和uboot里面的ID保持一致,将其283行复制添加在后面并修改为: smdk6410MACH_SMDK6410 SMDK6410 1626 xx6410 MACH_XX6410 XX6410 1626 这个机器ID和UBOOT里的机器ID相同时才能启动内核;1. 修改BSP文件mach-my6410.c,内容如下:将mach-mach-my6410.c文件中的所有smdk6410改成my6410(不要改大写SMDK6410的)MACHINE_START(MY6410, "MY6410")//这个要和Kconfig里的MACH-MY6410匹配 2. 在当前目录的Makefile最后一行加上 obj-$(CONFIG_MACH_MY6410) += mach-my6410.o3. 修改顶层的Makefile:ARCH ?= armCROSS_COMPILE ?= /usr/local/arm/4.2.2-eabi/usr/bin/arm-linux- 4. 复制arch/arm/configs/下的s3c6400-defconfig文件,然后将其保存为.config,配置内核支持EABI,再选中XX6410 board这一项,保存退出;5. 执行make menuconfig对内核进行配置:执行make编译执行make zImage生成zImage将uboot根目录下的mkimage拷贝到/user/bin目录下执行make uImage生成uImage通过以上几步linux内核移植完了,剩下就移植驱动了。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
csvM X28_DDR2_regis…1.xlsx101.25KB16100: 1*16 32200: 2*32 16400: 4*16 16800: 8*16 32400: 4*32 16160: 16*16表格信息:*上面需要准确填写的是行列地址总线宽度,bank数,CS数,数据总线宽度,时钟频率。
*tFAW不小于tRRD4倍,所以设置40ns。
*tRPA:如果数据手册不能找到tRPA,那么这么位置填入tRP。
*CASLAT:设置CAS LATCH周期,这个周期在ddr初始化时由ddr控制器对ddr设置。
*根据信号线计算ram大小,如下2 ^ (1cs + 3bank + 15row + 12col + 1datapath width) = 4GB:2、下载源码与建立baseline:2.1 源码下载略。
2.2 选择一个相近的平台,编写试编译通过:./setenv.shmake mx28evk_defconfigmake u-boot.sb*这里的sb文件是加密文件,而elftosb工具生成的可以通过-z参数选择是否加密。
*如果编译器是32位,但是系统是64位,那么安装32位兼容库即可:sudo apt install libc6-dev-i386 lib32z12.3 复制文件与修改配置:cp configs/mx28evk_defconfig configs/imx280a_defconfigcp configs/mx28evk_defconfig configs/imx280a_mmc_defconfigmkdir board/zlg/ && cp -rf board/freescale/mx28evk/ board/zlg/imx280a/ mv board/zlg/imx280a/mx28evk.c board/zlg/imx280a/imx280a.cvim board/zlg/imx280a/Kconfigvim board/zlg/imx280a/Makefilecp include/configs/mx28evk.h include/configs/imx280a.hvim include/configs/imx280a.h*vim ./arch/arm/include/asm/mach-types.h*从mx28手册可以得到内存起始物理地址:*删掉FEC,USB,SPI,LCD及额外环境变量的配置。
vim include/configs/mxs.h*运行地址前面要预留一段内存,因为uboot mem map如下:*上面的nand_base是nand控制器,也就是gpmi的基地址。
*根据nand芯片手册可知地址周期为4。
vim ./arch/arm/Kconfigmake imx280a_defconfigmake ARCH=arm menuconfig*这个可能会导致偶然启动失败问题。
cp -r .config configs/imx280a_defconfig make imx280a_mmc_defconfigmake ARCH=arm menuconfigcp -r .config configs/imx280a_mmc_defconfig ./build.sh nand./build.sh mmc*编译环境配置文件与编译脚本:cat setenv.sh #!/bin/bashexport ARCH="arm"export CROSS_COMPILE="arm-arm926ejs-linux-gnueabi-"export PATH="/home/john/x-tools/arm-arm926ejs-linux-gnueabi/bin:/home/john/study/imx280a/tools/linux_x86_64/:$PATH"cat build.sh#!/bin/bashsource ./setenv.shNUM_CPUS=$(cat /proc/cpuinfo | grep -c processor)if [ "$1" = "mmc" ]; thenecho "build mmc uboot"make imx280a_mmc_defconfigelseecho "build nand uboot"make imx280a_defconfigfimake -j${NUM_CPUS} spl/u-boot-splmake -j${NUM_CPUS} u-bootelftosb -f imx28 -c arch/arm/cpu/arm926ejs/mxs/u-boot-imx28.bd -o u-boot.sbcp -rf ./u-boot.sb /home/john/share/imx280/工具/烧写工具/cfimager/imx28_ivt_uboot.sb && sync3、移植spl(bootload第一阶段)(spl大小不能超过60k,ocram app load region的大小):arch/arm/lib/vectors.S和arch/arm/lib/interrupts.c(提供中断向量表函数实体)arch/arm/cpu/arm926ejs/mxs/start.S和board/zlg/imx280a/iomux.c(提供board_init_ll函数)、arch/arm/cpu/arm926ejs/mxs/spl_boot.c(提供mxs_common_spl_init函数,在个函数里初始化电源,时钟,iomux,串口,内存等)*最后返回到bootrom中运行。
3.1 spl结构与存储关系:实际放在nand中的是sb文件,sb文件是elftosb利用bd配置文件生成的。
*load DCD就是加载DCD列表的rom command序列,jump是告诉cpu image的ivt在内存中的位置。
*load u_boot_spl表示sb第一个放u_boot_spl(除去sb header,section tag与load DCD外)。
第二个放ivt,其中ivt 入口地址是u_boot_spl的开始地址(加载地址),然后把ivt自己的加载地址置为0x8000。
ivt在nand与ram的中的关系如下图一,hab call表示hab从0x8000这个ram地址读取ivt然后开始执行。
ivt与hab call在nand中存储如下图二。
图一:mx28不支持boot data。
而且dcd也不能用ivt的方式查找位置,必须通过rom command的方式定位。
另外不一定按照上面的方式分布,cpu能找到ivt就可以了。
图二:0xd1002040是ivt的header。
image加载地址由spl或uboot代码指定,如前面章节说明。
3.2 根据.lds文件分析spl的结构:vim arch/arm/cpu/arm926ejs/mxs/u-boot-spl.lds可知spl的入口文件为mxs下的./arch/arm/lib/vectors.S,其次是start.S。
*start.S运行完成后,spl就会跳转回bootrom(xip执行),最后会跳转到uboot执行(在sdram初始化完成后,uboot的程序就已经在ram中了。
可能是dma过去的)。
*有些厂家的做法是将soc相关代码放在arch/arm/cpu/armxxx/xxx,现在大多数厂家都会放在arch/arm/mach-xxx。
*正式uboot的连接文件在arch/arm/cpu/u-boot.lds。
3.3 修改mem初始化设置(.inc中黄色部分):vim board/zlg/imx280a/iomux.cvim ./arch/arm/cpu/arm926ejs/mxs/spl_mem_init.c3.4 时钟系统修改:3.5 电源系统修改:mx28处理器提供两种供电接口,三套供电方案:*采用电池供电,pswitch必须被申明。
这样上电后dcdc才会开始工作。
*采用电池单独供电,内部的供电需要采用dcdc供电,如下菊花链所示:*在第三种方案中,bootrom固件支持掉电切换功能。
如下图所示:*cpu的LRADC可以测量电池电压,可以用来决定是否充电,切换电源或是关机。
imx280a的供电方案是供电方式三。
但是电池那路电源是由系统(usb otg接口或排插)转4.2v而来,还有一路来自外部usb otg或者排针。
由于其他电路采用系统供电方式(系统转3.3v或直接使用系统电源),所以我们就把系统供电作为唯一供电方式(也就是类似于供电方式一)。
也就是申明pswitch,关闭4.2v线性转换器,关闭充电功能(不关闭也可以,因为永远不可能有充电的情况),使用battery作为电源(spl中优先使用battery作为电源),并且按照如下连接方式设置dcdc输出。
*DCDC_VDDD设置为1.5v输出。
vim arch/arm/cpu/arm926ejs/mxs/spl_power_init.cvim arch/arm/cpu/arm926ejs/mxs/spl_mem_init.c3.6 添加与修改调试串口,然后用sb_load工具(usb启动)灌入board看能不能运行。
vim include/common.hvim board/zlg/imx280a/iomux.c*上面的iomux table是spl模式与正常模式共享的。
*默认状态下duart连接是的pwm,所以需要先解决冲突,不然会出现输入无效的现象。
vim arch/arm/cpu/arm926ejs/mxs/spl_boot.c* 这里使用如下命令生成没经加密的image用于调试。
vim arch/arm/cpu/arm926ejs/mxs/u-boot-imx28.bd./setenv.shmake imx280a_defconfigmake spl/u-boot-splmake u-bootelftosb -f imx28 -c arch/arm/cpu/arm926ejs/mxs/u-boot-imx28.bd -o u-boot.sb *如果spl都没有串口输出,或者很难定位问题,那么可以尝试用ads+jtag调试。
3.7 调试nand:vim board/zlg/imx280a/iomux.c在uboot中使用命令验证nand(这里的sector大小就是block大小):然后通过设置与保存环境变量,然后重启查看nand是否读写正常:3.8 调试mmc:vim board/zlg/imx280a/iomux.c在uboot中使用命令验证mmc:然后通过设置与保存环境变量,然后重启查看mmc是否读写正常:*mmc uboot需要使用cfimager工具烧写到sd卡(选择从sd启动,还需要硬件工程师事先将sd卡的sd配置信息写入otp中,cfgimage工具默认分三个区,fat+固件区1(TA3格式)+固件区2(OPUS格式),我们把固件区1放uboot,固件区2放rootfs固件,fat分区放内核)。