主题 : 关于nand flash 和 加载的问题 复制链接 | 浏览器收藏 | 打印
级别: 侠客
UID: 21258
精华: 1
发帖: 120
金钱: 655 两
威望: 131 点
综合积分: 260 分
注册时间: 2010-05-13
最后登录: 2023-11-17
楼主  发表于: 2010-08-29 22:55

 关于nand flash 和 加载的问题

在看一本嵌入式linux的书(韦东山的《嵌入式linux应用开发》)。书中举了个例子(第8章 nand flash),说 启动代码超过4k大小。所以不能全映射在 nand flash对应的 steppingstone 。所以在 在 head.s  中有一段代码 把 超过4k的部分读到 SDRAM 里(调用nand_read)。这个我很理解。 但我不解的 是最早的时候这个程序的一部分 肯定 要写到 nand flash大于 4k的地方。它怎么就没调用nand_write呢?

这个例子 中 共有4个 文件 。分别是初始化文件 head.s , nand相关操作的文件 nand.c , 主程序文件 main.c. 链接脚本文件 nand.lds。

nand.lds的内容如下:
复制代码
  1. SECTIONS {
  2.   firtst      0x00000000 : { head.o nand.o}
  3.   second     0x30000000 : AT(4096) { main.o }
  4. }


难道 作者就通用 nand.lds 把main.o 加载定在 4k上面 ,就是写到 nand flash了吗?没调用nand_write?

head.s 的内容如下:
复制代码
  1. .text
  2. .global _start
  3. _start:
  4.                                             @函数disable_watch_dog, memsetup, init_nand, nand_read_ll在init.c中定义
  5.             ldr     sp, =4096               @设置堆栈
  6.             bl      disable_watch_dog       @关WATCH DOG
  7.             bl      memsetup                @初始化SDRAM
  8.             bl      nand_init               @初始化NAND Flash
  9.                                             @将NAND Flash中地址4096开始的1024字节代码(main.c编译得到)复制到SDRAM中
  10.                                             @nand_read_ll函数需要3个参数:
  11.             ldr     r0,     =0x30000000     @1. 目标地址=0x30000000,这是SDRAM的起始地址
  12.             mov     r1,     #4096           @2.  源地址   = 4096,连接的时候,main.c中的代码都存在NAND Flash地址4096开始处
  13.             mov     r2,     #2048           @3.  复制长度= 2048(bytes),对于本实验的main.c,这是足够了
  14.             bl      nand_read               @调用C函数nand_read
  15.             ldr     sp, =0x34000000         @设置栈
  16.             ldr     lr, =halt_loop          @设置返回地址
  17.             ldr     pc, =main               @b指令和bl指令只能前后跳转32M的范围,所以这里使用向pc赋值的方法进行跳转
  18. halt_loop:
  19.             b       halt_loop
*無鈳取玳
级别: 论坛版主
UID: 27
精华: 12
发帖: 5398
金钱: 40120 两
威望: 17929 点
综合积分: 11036 分
注册时间: 2008-01-16
最后登录: 2014-11-22
1楼  发表于: 2010-08-29 23:08
难道 作者就通用 nand.lds 把main.o 加载定在 4k上面 ,就是写到 nand flash了吗?没调用nand_write?

对于这个程序来说,它并不具备将自己写入NAND Flash的功能。在它运行之前,必须通过一定方法将其写入NAND Flash(从NAND Flashoffset 0x0开始)。
举例来说,支持从NAND启动的u-boot启动部分逻辑和这个程序相同,但u-boot可以在运行在SDRAM之后, 由大于4K的那部分代码下载自己的完整镜像到SDRAM中(通过USB或网TFTP)并将其写入NAND Flash从而实现更新NAND中的uboot镜像。
"If you have an apple and I have an apple and we exchange apples, then you and I will
still each have one apple. But if you have an idea and I have an idea and we exchange
these ideas, then each of us will have two ideas."
级别: 侠客
UID: 21258
精华: 1
发帖: 120
金钱: 655 两
威望: 131 点
综合积分: 260 分
注册时间: 2010-05-13
最后登录: 2023-11-17
2楼  发表于: 2010-08-30 14:23
首先谢谢   kasim 了,真是无可取代。哈哈。

在它运行之前,必须通过一定方法将其写入NAND Flash(从NAND Flashoffset 0x0开始)。


我懂了,是nor flash中的程序按照nand.lds 的规则把它写入nand flash的。

举例来说,支持从NAND启动的u-boot启动部分逻辑和这个程序相同,但u-boot可以在运行在SDRAM之后, 由大于4K的那部分代码下载自己的完整镜像到SDRAM中(通过USB或网TFTP)并将其写入NAND Flash从而实现更新NAND中的uboot镜像。

这个讲的是 bootloader的下载模式吧。是用来实现bootloader 的自更新。两个类比,想了半天 才想明白两者的关系。

谢谢!
[ 此帖被imjacob在2010-08-30 19:22重新编辑 ]
级别: 侠客
UID: 21258
精华: 1
发帖: 120
金钱: 655 两
威望: 131 点
综合积分: 260 分
注册时间: 2010-05-13
最后登录: 2023-11-17
3楼  发表于: 2010-08-30 22:23
再补充下,为什么当初我会有nand_write 的疑问,是我有些概念搞糊涂了。

首先。这个程序是不能在裸板上跑的。在裸板上最早跑的程序只能是放在steppingstone里即小于 4k的程序。假设程序名为A.
A的功能包括初始化 SDRAM ,cpu,关中断等。

然后下载另一段程序到SDRAM 假设程序名为B ,B 的功能包括将指定地址代码烧到flash 里的功能。B 程序可以叫 loader??

之后下载又一个程序到指定地址(方式可以是串口,usb,网络。。。),这个程序为C 。C程序可以叫 boot??

最后运行程序B ,就把程序C 烧到flash里去了。

//======================================
我觉得u-boot即可以作为程序B,又可以作为程序C。当然友善的supervivi也是了。

Kasim版主讲的 是当B,C 两个都是u-boot的情况。
而我一开始问的那个程序只能作为程序C。B 是u-boot。
[ 此帖被imjacob在2010-08-30 22:35重新编辑 ]
级别: 侠客
UID: 21258
精华: 1
发帖: 120
金钱: 655 两
威望: 131 点
综合积分: 260 分
注册时间: 2010-05-13
最后登录: 2023-11-17
4楼  发表于: 2010-09-10 10:24
没人理会,顶一下,不知道我的理解正确不?望Kasim兄 指教下
级别: 侠客
UID: 21258
精华: 1
发帖: 120
金钱: 655 两
威望: 131 点
综合积分: 260 分
注册时间: 2010-05-13
最后登录: 2023-11-17
5楼  发表于: 2010-09-20 22:18
又更新了想法,更正3楼的说明,重新说一下:

首先。这个程序是不能在裸板上跑的。在裸板上最早跑的程序只能是放在steppingstone里即小于 4k的程序。假设程序名为A.
A的功能包括初始化 SDRAM ,cpu,关中断等。

然后下载另一段程序到SDRAM 假设程序名为B ,B 的功能包括将指定地址代码烧到flash 里的功能。B 程序可以叫 storer。

之后下载又一个程序到指定地址(方式可以是串口,usb,网络。。。),这个程序为C 。C程序可以叫 bootloader

最后运行程序B ,就把程序C 烧到flash里去了。

//==============================
对程序C,bootloader的说明,它又分成两部分:
boot 和loader。
boot: 实现正常的一个硬件初始化流程,网上资料很多,不多述,可参考《嵌入式系统 Boot Loader 技术内幕》。
loader:实现把flash拷贝到ram里的功能,这部分代码一定要放在steppingstone里