移植u-boot2012.04.1 -》2440 (五)支持 nand nor 两种启动方式(完结)
来源:互联网 发布:36芯三网合一网络箱 编辑:程序博客网 时间:2024/06/05 20:49
前边4篇文章,成功将 u-boot2012 移植到了 2440 开发板上,但是它仅仅支持 norflash 启动并不够完善,下面我们设法让它支持两种启动方式。
首先,我们得先分析一下目前的启动流程:
链接地址为 0
第一阶段:start.S中的汇编部分,包括时钟、sdram 等初始化
第二阶段:board_init_f 先是调用了大量C函数进行串口什么的初始化,然后进行内存划分
第三阶段:根据第二阶段的内存划分 start.S 中进行代码重定位,清BSS,修正位置有关码,跳到sdram里去执行 board_init_r
那么,如果我们想 nandflash 启动,那么我们必须在前4K代码中就进行 nandflash 的初始化,用nandflash的读函数将代码进行重定位到sdram里,现在有一个矛盾摆在我们面前。首先是,原来的重定位的地方在第三阶段,而且第二阶段调用了大量的C函数,重定位的时候早就在 4K 之外了。如果我们把重定位放在第一阶段和第二阶段之间,那么那时内存还没有进行划分,我们不知道重定位到哪里去。
解决办法:采用 uboot1.1.6 那种老的方式,在第一阶段和第二阶段之间进行重定位,重定位到固定地址 0x33f00000 中去,第二阶段进行内存划分时,将u-boot的起始地址也固定为 0x33f0000 ,在链接时,指定链接地址为0x33f00000,这样,我们也可以去掉 *.rel 段,实际上是去掉编译时的 -pie 选项。
还有一个问题,我们nandflash启动时,norflash对cpu是不可见的,因此我们根本无法对Norflash进行初始化,更无法将环境变量保存在Norflash上了。
解决办法:判断如果是nandflash启动,不进行Norflash的初始化。无论那种方式启动,均将环境变量保存在nandflash上。
1、去掉 -pie 选项
grep "\-pie" * -nRw
arch/arm/config.mk:75:LDFLAGS_u-boot += -pie
直接注释掉即可。
2、指定链接地址
grep "Ttext" * -nRw
找到一个宏 CONFIG_SYS_TEXT_BASE 搜索这个宏,发现是在 smdk2440.h 中定义,修改为
#define CONFIG_SYS_TEXT_BASE 0x33f00000
3、在第二阶段内存划分时,固定u-boot的起始地址
在 arch/aem/lib/board.c 中的
addr -= gd->mon_len;
addr &= ~(4096 - 1); 这两行后边,新增一行
addr = 0x33f00000;//增加
4、实现判断 nor 启动还是 nand 启动的 C 函数
nor启动时,片内ram位于0x40000000处,可以直接读写,0-2M的空间可以直接读,但是没法直接写入。
nand启动时,片内ram位于0x0处,0-4k,可以直接读写。
我一开始尝试在 0x40000000 处写值,然后读取回来看是否成功,发现 nand 启动时访问0x40000000会触发异常直接死掉。那么只好尝试读写0地址了。
int isNandBoot(){#define RAMSTART (*(volatile unsigned long *)0x00000000)unsigned long temp = RAMSTART;RAMSTART = 0xbadc0de;if(RAMSTART == 0xbadc0de){RAMSTART = temp;return 1;}else{RAMSTART = temp;return 0;}}nand启动返回1,Nor启动返回0
5、将nandflash的初始化函数、读函数和上边的判断函数统一放入 smdk2440.c 中,同时,我们需要改变链接顺序,将 smdk2440.o 尽量靠前放,索性放在 start.o 的后边好了。但是经过我的尝试,smdk2440.c 和 lowlevel_init.S 会被链接成 libsmdk2440.o ,只把smdk2440.o放到前面的话,会造成函数的重定义,解决办法就是把 libsmdk2440.o 放到前边。
更改链接脚本:/arc/arm/cpu/u-boot.lds
在 CPUDIR/start.o (.text) 后边添加一行
board/samsung/smdk2440/libsmdk2440.o (.text)
尝试编译一下,正常应该没问题。
6、在第一阶段和第二阶段之间增加代码重定位等相关操作
#ifndef CONFIG_SKIP_LOWLEVEL_INITblcpu_init_crit#endif/******************此行之前的代码保持不变,增加*************************/ldrsp, =(CONFIG_SYS_INIT_SP_ADDR)bicsp, sp, #7 /* 8-byte alignment for ABI compliance *//* 判断是 nand 还是 nor 启动 */bl isNandBootmov r1,#0x01cmp r0,r1bne copy_nor/* 不相等nor 相等nand*/copy_nand:bl my_nand_initldr r0, =0x33f00000mov r1, #0x00ldr r2, =<span style="font-family: Arial, Helvetica, sans-serif;">_bss_start_ofs</span>bl my_nand_readbl clear_bsscopy_nor:movr0, #0x00ldrr1, =0x33f00000/* r1 <- scratch for copy_loop */ldrr3, _bss_start_ofsaddr2, r0, r3/* r2 <- source end address */copy_loop:ldmiar0!, {r9-r10}/* copy from source address [r0] */stmiar1!, {r9-r10}/* copy to target address [r1] */cmpr0, r2/* until source end address [r2] */blocopy_loopbl clear_bss/*****************call_board_init_f 中去掉sp的设置***********************/call_board_init_f:ldrr0,=0x00000000blboard_init_f/*************** 将 clear_bss 提升至 relocate_code 的前面****************/clear_bss:#ifndef CONFIG_SPL_BUILDldrr0, _bss_start_ofsldrr1, _bss_end_ofsldrr4, =0x33f00000/* reloc addr */addr0, r0, r4addr1, r1, r4movr2, #0x00000000/* clear */clbss_l:strr2, [r0]/* clear loop... */addr0, r0, #4cmpr0, r1bneclbss_lldr pc, =call_board_init_f // 增加跳转到sdram的指令#endif/*************** 去掉原有的代码重定位操作****************/.globlrelocate_coderelocate_code:movr4, r0/* save addr_sp */movr5, r1/* save addr of gd */movr6, r2/* save addr of destination */mov sp, r0 /* 设置栈 */ /* setup parameters for board_init_r */movr0, r5/* gd_t */movr1, r6/* dest_addr *//* jump to it ... */blboard_init_r/* ***********************之后代码保持不变********************************** * * CPU_init_critical registers * * setup important registers * setup memory timing * ************************************************************************* */7、在norflash初始化代码前,增加判断
在 arch\arm\lib\board.c -> board_init_r 中将
#if !defined(CONFIG_SYS_NO_FLASH) 作用域之内的代码放入 if(!isNandBoot()) 条件语句。
8、将环境变量存储到 nandflash
首先,我查看了一下 common 目录下,env_flash.c 是被编译进u-boot了,但是 env_nand.c 并没有,看下makefile 它依赖于哪个宏。
COBJS-$(CONFIG_ENV_IS_IN_FLASH) += env_flash.o
COBJS-$(CONFIG_ENV_IS_IN_NAND) += env_nand.o
搜索一下,发现 CONFIG_ENV_IS_IN_FLASH 在 smdk2440.h 中定义
去掉 #define CONFIG_ENV_IS_IN_FLASH
增加 #defineCONFIG_ENV_IS_IN_NAND
实际在编译测试的过程中,只定义 CONFIG_ENV_IS_IN_NAND 是不够的,会打印出错误信息
Need to define CONFIG_ENV_OFFSET when using CONFIG_ENV_IS_IN_NAND
意思很明确,我们需要定义环境变量在 nandflash 中的偏移地址,如果对 u-boot 进行分区的话,环境变量应该是存在于 params 区域,为了和内核保持一致,我们干脆分区得了。
9、查看内核启动打印信息
0x00000000-0x00040000 : "bootloader"
0x00040000-0x00060000 : "params"
0x00060000-0x00260000 : "kernel"
0x00260000-0x10000000 : "root"
这是内核的分区划分,我们按照内核的分区,也给 u-boot 进行分区。
添加分区,smdk2440.h 中要有一下宏定义:
#define CONFIG_CMD_MTDPARTS
#define CONFIG_MTD_DEVICE
#define CONFIG_MTD_PARTITIONS
加入MTD分区信息:
#define MTDIDS_DEFAULT "nand0=2440_nand"
#define MTDPARTS_DEFAULT "mtdparts=2440_nand:256k@0(bootloader)," \
"128k(params)," \
"2M(kernel)," \
"-(root)"
这个内核比较小,因此内核分区只有2M,如果内核比较大的话,在修改就是了。
环境变量的位置确定了,我们需要在smdk2440.h中定义偏移地址
#define CONFIG_ENV_OFFSET0x40000
同时,在smdk2440.h 中定义的 CONFIG_ENV_SIZE 默认为 0x10000 修改为 0x20000
10、剪裁u-boot
我尝试nand启动时,发现启动不了,是因为我们的u-boot有400多K,而我们的 bootloader 只有256k,要么修改分区,要么剪裁u-boot,是它小于256k,如何剪裁,就是修改smdk2440.h宏咯。
在 smdk2440.h 中去掉
#define CONFIG_CMD_FAT
#define CONFIG_CMD_EXT2
#define CONFIG_CMD_UBI
#define CONFIG_CMD_UBIFS
#define CONFIG_YAFFS2
#define CONFIG_RBTREE
#define CONFIG_USB_OHCI
#define CONFIG_USB_KEYBOARD
#define CONFIG_USB_STORAGE
#define CONFIG_DOS_PARTITION
#define CONFIG_BOOTP_BOOTFILESIZE
#define CONFIG_BOOTP_BOOTPATH
#define CONFIG_BOOTP_GATEWAY
#define CONFIG_BOOTP_HOSTNAME
#define CONFIG_CMD_USB
#define CONFIG_CMD_BSP
make clean
make
编译完你会发现体积大大减小,不到200K
11、烧写测试,不出意外,我们的 nor nand 都能启动了
- 移植u-boot2012.04.1 -》2440 (五)支持 nand nor 两种启动方式(完结)
- u-boot:从NOR FLASH启动并支持NAND FLASH读写的移植
- 移植u-boot2012.04.1 -》2440 (四)DM9000移植,环境变量设置
- U-boot-2014.04移植到MINI2440(9) nor flash启动和nand flash 启动
- U-boot移植 (v2012.04.1 S3C2440平台) (三) Nor flash Nand flash 驱动支持
- u-boot移植(七)支持nand启动
- U-boot-2010.09移植(六)NAND Flash启动支持
- 移植u-boot-2012.04----支持nand启动
- 基于TQ2440的u-boot 1.1.6移植(二)(支持nor flash nand flash )
- u-boot-2011.03在TQ2440上的移植(5)—实现Nand/Nor 双启动
- 移植u-boot2012.04.1 -》2440 (三)nandflash 识别
- 移植u-boot2012.04.1 -》2440 (一)新建单板,第一阶段修改
- 移植u-boot2012.04.1 -》2440 (二)norflash 识别
- u-boot-2010.12移植到2440(四,支持nand flash启动)
- 【转】u-boot-2010.12移植到2440(四,支持nand flash启动)
- U-Boot移植FL2440--2--支持从Nor FLASH启动
- u-boot-1.2.0移植到s3c2440(一)主要是对NAND和NOR的支持
- u-boot2012.04移植到jz2440 支持norflash
- Android找不到R文件
- 开发者头条(四):加入Design :TabLayout + Toolbar
- 第45课 Spark 2.0实战之Dataset:map、flatMap、mapPartitions、dropDuplicate、coalesce、repartition等
- SQL总结之跨数据库服务器之间的数据访问(MSSQL)
- MySQL 查询 select * from table where id in 如何提高效率?
- 移植u-boot2012.04.1 -》2440 (五)支持 nand nor 两种启动方式(完结)
- POJ - 3046 Ant Counting(多重集组合数DP)
- 在mac环境下eclipse中struts2一些配置的问题
- 蛇形矩阵
- 笔试题小记1
- 机房收费系统——修改密码
- hdu 5773 The All-purpose Zero (LIS)
- SpringMVC简单小案例
- 图解在Windows下使用vim(gvim)