分类:
2011-04-16 20:41:22
原文地址:uboot段/变量/链接相关 作者:wotaiqile
(1)如果在启动时,U-boot打印出:“Warning - bad CRC, using default environment”,说明U-boot没有在存放 ENV的固态存储器中找到有效的 ENV,只好使用编译时定义的默认ENV。如果 U-boot存放 ENV的固态存储器的驱动是没问题的,那只要运行 saveenv就可以把当前系统的所有ENV写入固态存储器,下次启动就不会有这个警告了。ENV可以放在多种固体存储器中,对于 mini2440来说 Nor Flash、Nand Flash或EEPROM都可以,这依赖 include/configs下的配置文件是如何定义的。例如:
Nor Flash:
#define CONFIG_ENV_IS_IN_FLASH 1
#define CONFIG_ENV_OFFSET 0X40000
#define CONFIG_ENV_SIZE 0x20000 /* Total Size of Environment Sector */
Nand Flash:
#define CONFIG_ENV_IS_IN_NAND 1
#define CONFIG_ENV_OFFSET 0X40000
#define CONFIG_ENV_SIZE 0x20000 /* Total Size of Environment Sector */
EEPROM:
#define CONFIG_ENV_IS_IN_EEPROM 1 /* use EEPROM for environment vars */
#define CONFIG_ENV_OFFSET 0x000 /* environment starts at offset 0 */
#define CONFIG_ENV_SIZE 0x400 /* 1KB */
CONFIG_ENV_OFFSET :是在整个存储器中的偏移地址;
CONFIG_ENV_SIZE :是指用来保存 ENV的分区大小。
注意 CONFIG_ENV_OFFSET和 CONFIG_ENV_SIZE 的设置,请不要覆盖了其他分区
===========================================================
下面说说我移植uboot_nand,drivers/mtd/nand时遇到的问题:
[MY2440] # saveenv
Saving Environment to NAND...
Erasing Nand...
Warning: Erase size 0x00010000 smaller than one erase block 0x00020000
Erasing 0x00020000 instead
NAND 256MiB 3,3V 8-bit: MTD Erase failure: -22
Writing to Nand... FAILED!
解决方法:
修改include/configs/my2440.h
Nand Flash:
#define CONFIG_ENV_IS_IN_NAND 1
#define CONFIG_ENV_OFFSET 0X40000
#define CONFIG_ENV_SIZE 0x20000 /* Total Size of Environment Sector */
=========================================================================
(2) Uboot.bin文件是可执行的二进制代码文件。我们重点是讲描.bin文件的组成。我们把可执行文件分为两种情况:分别为存放态和运行态。
1. 存放态
存放态是指可执行文件通过fromelf产生后,在存储介质(flash或磁盘)上的分布. 此时可执行文件一
般由两部分组成:分别是代码段和数据段。代码段又分为可执行代码段(.text)和只读数据段(.rodata),
数据段又分为初始化数据段(.data)和未初始化数据段(.bss)。可执行文件的存放态如下:
+----------------+-----------
| .bss |
+---------------+-- 数据段
| .data |
+---------------+-----------
| .rodata |
|__________| 代码段
| .text |
+-------------+-----------
2. 运行态
可执行文件通过装载过程, 搬入到RAM中运行, 这时候可执行文件就变成运行态。在对可执行代码各段有另一个名称:
| ... |
+-------------+-----------
| .bss | ZI 段
+-------------+-- 数据段
| .data | RW 段
+-------------+-----------
| .rodata |
|_____________| 代码段(RO 段)
| .text |
+-------------+-----------
| ... |
装载前
当可执行文件装载后, 在RAM中的分布如下:
| ... |
+-------------+-- ZI段结束地址
| ZI 段 |
+-------------+-- ZI段起始地址
| 保留区2 |
+-------------+-- RW段结束地址
| RW 段 |
+-------------+-- RW段起始地址
| 保留区1 |
+-------------+-- RO段结束地址
| RO 段 |
+-------------+-- RO段起始地址
| ... |
装载后
所以装载过程必须完成把执行文件的各个段从存储介质上搬到RAM指定的位置。而这个装载过程由谁来完成呢?由我们的启动程序来完成.
=================================================================
(3)nandflash芯片内部存储布局及存储操作特点
一片Nand flash为一个设备(device), 其数据存储分层为:
1设备(Device) = 4096 块(Blocks)
1块(Block) = 32页/行(Pages/rows) ;页与行是相同的意思,叫法不一样
1页(Page) = 528字节(Bytes) = 数据块大小(512Bytes) + OOB块大小(16Bytes)
在每一页中,最后16个字节(又称OOB)用于Nand Flash命令执行完后设置状态用,剩余512个字节又分为前半部分和后半部分。可以通过Nand Flash命令00h/01h/50h分别对前半部、后半部、OOB进行定位通过Nand Flash内置的指针指向各自的首地址。
存储操作特点:
1. 擦除操作的最小单位是块。
2. Nand Flash芯片每一位(bit)只能从1变为0,而不能从0变为1,所以在对其进行写入操作之前要一定将相应块擦除(擦除即是将相应块得位全部变为1).
3. OOB部分的第六字节(即517字节)标志是否是坏块,如果不是坏块该值为FF,否则为坏块。
4. 除OOB第六字节外,通常至少把OOB的前3个字节存放Nand Flash硬件ECC码
寻址方式
Samsung K9F1208U0B Nand Flash 片内寻址采用26位地址形式。从第0位开始分四次通过I/O0-I/O7进行
传送,并进行片内寻址。具体含义如下:
0-7位:字节在上半部、下半部及OOB内的偏移地址
8位:值为0代表对一页内前256个字节进行寻址
值为1代表对一页内后256个字节进行寻址
9-13位:对页进行寻址
14-25位:对块进行寻址
当传送地址时,从位0开始
======================================================================
以K9F2G08U0B为例:
32`31 30 29 28 27 26 25 24 `23 22 21 20 19 18 17 16 `15 14 13 12 11 10 9 8 `7 6 5 4 3 2 1 0
28`27 26 25 24 23 22 21 20 `19 18 17 16 15 14 13 12 ` - - - - 11 10 9 8 `7 6 5 4 3 2 1 0
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!@@@@@@@@@@@@@@@@@ ##########################
28~18 哪一块 17~12 哪一页 11~0 页内
1device=2048块=131072页
1block =64页
1页 =2K+64B
1000页=64×15+40页=960+40页
1989页=64×31+ 5页=1984+5页
以page(页)为单位进行读写,前两行为业内地址,所以为零
NF_ADDR(0x00); //列地址A0~A7
NF_ADDR(0x00); //列地址A8~A11
NF_ADDR((page_number) & 0xff); //行地址A12~A19
NF_ADDR((page_number >> 8) & 0xff); //行地址A20~A27
NF_ADDR((page_number >> 16) & 0xff); //行地址A28
以block(块)为单位进行擦除
//写入3个地址周期,从A18开始写起
NF_ADDR((block_number << 6) & 0xff); //行地址A18~A19
NF_ADDR((block_number >> 2) & 0xff); //行地址A20~A27
NF_ADDR((block_number >> 10) & 0xff); //行地址A28
=============================================================================================
norflash操作相关:
norflash直接可以读,不需初始化,无需相关命令
对norflash的写,擦除操作,需要相应的命令,并且要看反转位(polling)状态,以确保是否操作完或正确
对norflash的写擦除,是按扇区(一般4KB)或块为单位,且写之前必须整个扇区或块先擦除,才能写入