打印

NAND boot load 的疑问

[复制链接]
9385|44
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
itelectron|  楼主 | 2009-10-31 21:22 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 itelectron 于 2009-10-31 21:38 编辑

从NAND闪存启动U-BOOT的设计思路

如果S3C2410被配置成从NAND闪存启动,上电后,S3C2410的NAND闪存控制器会自动把NAND闪存中的前4K数据搬移到内部RAM中, 并把0x00000000设置为内部RAM的起始地址, CPU从内部RAM的0x00000000位置开始启动。因此要把最核心的启动程序放在NAND闪存的前4K中。

由于NAND闪存控制器从NAND闪存中搬移到内部RAM的代码是有限的,所以, 在启动代码的前4K里,必须完成S3C2410的核心配置,并把启动代码的剩余部分搬到RAM中运行。在U-BOOT中, 前4K完成的主要工作就是U-BOOT启动的第一个阶段(stage1)。

根据U-BOOT的执行流程图,可知要实现从NAND闪存中启动U-BOOT,首先需要初始化NAND闪存,并从NAND闪存中把U-BOOT搬移到RAM中,最后需要让U-BOOT支持NAND闪存的命令操作。
图 U-BOOT启动流程图
  
开发环境

本设计中目标板硬件环境如下:CPU为S3C2410,SDRAM为HY57V561620,NAND闪存为64MB的K9F1208U0A。

主机软件环境为Redhat9.0、 u-boot-1.1.3、gcc 2.95.3。修改U-BOOT的Makefile,加入:

wch2410_config : unconfig
@./mkconfig $(@:_config=) arm arm920t wch2410 NULL s3c24x0

即将开发板起名为wch2410,接下来依次进行如下操作:

mkdir board/wch2410
cp board/smdk2410 board/wch2410
mv smdk2410.c wch2410.c
cp include/configs/smdk2410.h include/configs/wch2410.h
export PATH=/usr/local/arm/2.95.3/bin:$PATH

最后执行:

make wch2410_config
make all ARCH=arm
生成u-boot.bin,即通过了测试编译。
具体设计

支持NAND闪存的

启动程序设计

因为U-BOOT的入口程序是/cpu/arm920t/start.S,故需在该程序中添加NAND闪存的复位程序,以及实现从NAND闪存中把U-BOOT搬移到RAM中的功能程序。

首先在/include/configs/wch2410.h中加入CONFIG_S3C2410_NAND_BOOT, 如下:

#define CONFIG_S3C2410_NAND_BOOT 1   @支持从NAND 闪存中启动
然后在/cpu/arm920t/start.S中添加
#ifdef CONFIG_S3C2410_NAND_BOOT
copy_myself:
mov r10, lr
ldr sp, DW_STACK_START      @安装栈的起始地址
mov fp, #0                  @初始化帧指针寄存器
bl nand_reset               @跳到复位C函数去执行,执行NAND闪存复位
.......
/*从NAND闪存中把U-BOOT拷贝到RAM*/
ldr r0, =UBOOT_RAM_BASE     @ 设置第1个参数: UBOOT在RAM中的起始地址
mov r1, #0x0                @ 设置第2个参数:NAND闪存的起始地址
mov r2, #0x20000            @ 设置第3个参数: U-BOOT的长度(128KB)
bl nand_read_whole          @ 调用nand_read_whole(),把NAND闪存中的数据读入到RAM中
tst r0, #0x0                @ 如果函数的返回值为0,表示执行成功
beq ok_nand_read             @ 执行内存比较,把RAM中的前4K内容与NAND闪存中的前4K内容进行比较, 如果完全相同, 则表示搬移成功
其中,nand_reset (),nand_read_whole()被加在/board/wch2410/wch2410.c中。

相关帖子

沙发
itelectron|  楼主 | 2009-10-31 21:27 | 只看该作者
本帖最后由 itelectron 于 2009-10-31 21:30 编辑

流程图中的  重ROM中的代码到RAM中

/*从NAND闪存中把U-BOOT拷贝到RAM*/
ldr r0, =UBOOT_RAM_BASE     @ 设置第1个参数: UBOOT在RAM中的起始地址
mov r1, #0x0                @ 设置第2个参数:NAND闪存的起始地址
mov r2, #0x20000            @ 设置第3个参数: U-BOOT的长度(128KB)


我想问的 是  是把stage1 stage2都 复制到 RAM中  
还是只把stage2复制到 RAM中
mov r1, #0x0                @ 设置第2个参数:NAND闪存的起始地址

这段 因该是 把 把stage1 stage2都 复制到 RAM中:
但是 有些书上说 的是通过把stage1把 stage2复制到RAM起始地址0X30000000中!
然后跳到0X30000000

使用特权

评论回复
板凳
itelectron|  楼主 | 2009-10-31 21:29 | 只看该作者
本帖最后由 itelectron 于 2009-10-31 22:04 编辑

解决

使用特权

评论回复
地板
itelectron|  楼主 | 2009-10-31 21:32 | 只看该作者
本帖最后由 itelectron 于 2009-10-31 22:04 编辑

解决

使用特权

评论回复
5
itelectron|  楼主 | 2009-10-31 21:50 | 只看该作者
还有 异常向量表是 steppingstone的 0地址 还是 在 0X30000000地址????

使用特权

评论回复
6
itelectron|  楼主 | 2009-10-31 22:00 | 只看该作者
本帖最后由 itelectron 于 2009-10-31 22:03 编辑

在steppingstone中 把stage1 stage2都 复制到 RAM 起始地址 0X30000000:后


肯定是要跳到stage2中的 但是steppingstone 结尾 如何
获取RAM中的 stage2 中的MAIN()的 地址:

使用特权

评论回复
7
itelectron|  楼主 | 2009-10-31 22:07 | 只看该作者
本帖最后由 itelectron 于 2009-10-31 22:09 编辑

VIVI 和UBOOT  都是 连同 stage1 stage2都 从NAND复制到 RAM 中 先检查 steppingstone和RAM中的stage1 内容是否 一样  如果一样的话 就条到 RAM中的stage2的MAIN():

使用特权

评论回复
8
itelectron|  楼主 | 2009-10-31 22:11 | 只看该作者
郁闷 在MDK是咱样 才能跳到到  RAM stage2中的MAIN() 呢??

使用特权

评论回复
9
itelectron|  楼主 | 2009-11-1 11:43 | 只看该作者
GOOGLe 到了

为加载Bootloader的stage2准备RAM空间(这个地址由链接脚本指定,为运行域地址,通常为RAM的高端地址),

使用特权

评论回复
10
itelectron|  楼主 | 2009-11-1 11:43 | 只看该作者
那MDK的链接脚本该如何指定???????????????

使用特权

评论回复
11
zyok| | 2009-11-1 11:58 | 只看该作者
呵呵,lz又在自言自语,帮你顶:lol

使用特权

评论回复
12
itelectron|  楼主 | 2009-11-1 12:34 | 只看该作者
前面都是 依葫芦画瓢!
现在要仔细分析下!
NND
RAM中的stage2的MAIN():这个地址不知道咋得到 的 正在看UBOOT!
书上讲的 不清楚还得慢慢 肯代码!!

使用特权

评论回复
13
itelectron|  楼主 | 2009-11-1 12:36 | 只看该作者
cpu/arm920t/start.o (.text)
board/2440/lowlevel_init.o (.text)
board/2440/nand_read.o (.text)
怀疑和上面那3个东东 有干系

使用特权

评论回复
14
itelectron|  楼主 | 2009-11-1 12:41 | 只看该作者
本帖最后由 itelectron 于 2009-11-1 12:50 编辑

问题是我 在MDK下生成的只有一个BIN文件  这可咋弄
要是手动 定义 地址就好 了

看了MDK 官方的做法是 建3个工程 一个工程是专门从NAND的开始为 0X4000地址   复制到 0X30000000的地址(代码小于4K在2440的steppingstone中)
第二个工程是 指定地址开始地址为0X30000000 为应用程序地址
第三个工程是专门用来 下载数据到NAND 的0X4000地址!

偶想把他简化成一个 工程(分散加载么)

使用特权

评论回复
15
zyok| | 2009-11-1 12:48 | 只看该作者
你整UBOOT上系统在MDK下搞??

只有自己编写Scatter File,在Linker选项里指定..

使用特权

评论回复
16
itelectron|  楼主 | 2009-11-1 12:59 | 只看该作者
应该是要用分散加载么   empty (固定位置函数)

使用特权

评论回复
17
liliang9554| | 2009-11-1 16:15 | 只看该作者
自言自语……

使用特权

评论回复
18
贾君鹏子| | 2009-11-1 16:38 | 只看该作者
学到点东西……

使用特权

评论回复
19
itelectron|  楼主 | 2009-11-1 17:16 | 只看该作者
不用分散 加载  也可以
但是要用MMU
在 steppingstone 里运行的时候 把 stage1  stage2 复制到 RAM中
然后地址重新影射 在 跳到stage2 不就OK了么
哎问题是MMU 还真没有自己用过(以前都是在别人的基础上 修改的)
不用MMU因该也可以吧  不然CM3  ARM7是怎么重NAND启动的呢???

使用特权

评论回复
20
itelectron|  楼主 | 2009-11-1 17:20 | 只看该作者
IMPORT  |Image$$ER_ROM1$$RO$$Base|        ; Base of ROM code
        IMPORT  |Image$$ER_ROM1$$RO$$Limit|  ; End of ROM code (=start of ROM data)
        IMPORT  |Image$$RW_RAM1$$RW$$Base|   ; Base of RAM to initialise
        IMPORT  |Image$$RW_RAM1$$ZI$$Base|   ; Base and limit of area
        IMPORT  |Image$$RW_RAM1$$ZI$$Limit|  ; to zero initialise


上面那段  还真不好 理解
IMPORT 等同于C的  extern   外部声明吧???

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:MARK: zhi kan ji shu

274

主题

2762

帖子

8

粉丝