安装eldk编译器
mount -t iso9660 -o loop arm-2008-11-24.iso mount_dir
cd mount_dir
./install -d /opt/eldk
修改后的支持网络的u-boot代码,基于官方u-boot2010.12
/× 1.修改了一些小的bug,
/×2.增加debug开关
/×3.增加命令 updateuboot updatezImage updatecramfs
linux内核与 文件系统
linux内核/文件系统直接使用飞凌提供的,但kernel有一个文件需要修改,否则内核不能启动
把文件中的全局变量赋上初值
inux2.6.28_FORLINUX\arch\arm\plat-s3c\include\plat\uncompress.h
/* uart setup */
static unsigned int fifo_mask = (0x3F << 8);
static unsigned int fifo_max = 5;
===============================================================================================================================
编译:设置环境变量
OLD_PATH=$PATH
export PATH=/opt/eldk/arm/usr/bin:/opt/eldk/arm/bin/:$PATH
export CROSS_COMPILE=arm-
#export PATH=$OLD_PATH
# some targets like unconfig, clean, clobber, distclean, etc.
make mrproper
make smdk6400_config 2>&1 |tee configure.out
make 或者make all
编译后的u-boot文件名称:u-boot-nand.bin,这个专门用作nand 的启动
通过网络更换u-boot 更换 zImage,当然了,第一次还是要使用sd卡按照飞凌的方法更换u-boot
默认tftp服务器的IP为 192.168.0.11
/**********************************/
/* update uboot via net */
/* tftpboot 0x51000000 u-boot.bin */
/* nand erase 0x0 0x80000 */
/* nand write 0x51000000 0x0 0x80000 */
/**********************************/
/*****************************************/
/* update kernel via net */
/* tftpboot 0x51000000 u-boot.bin */
/* nand erase 0x50008000 0x300000 */
/* nand write 0x50008000 0x100000 0x300000 */
/*****************************************/
===============================================================================================================================
uboot2010.12 makefile分析:
常用指令:
make mrproper 恢复到初始状态
make distclean
make clobber
make clean
make unconfig
make smdk6400_config
make 或者 make all
make target_config分析:
target: 当你不知道target的具体名字的时候可以通过以下两种途径来查找
1. 一般都存在boards.cfg中,通过makefile-->sinclude .boards.depend --〉boards.cfg来引用
2. 另外如果target需要额外的处理,那么就不会放在boards.cfg,而是直接放在Makefile中,(cat Makefile|grep unconfig|grep :)该命令可以过滤出所有不再boards.cfg中的target
make smdk6400_config 的执行结果:
以下这些文件有mkconfig脚本生成,mkconfig用于生成头文件和相关的link文件
[cc@iZ23rrduja6Z ~]$ diff -r u-boot-2010.12/ u-boot-2010.12.mrproper/
Only in u-boot-2010.12/arch/arm/include/asm: arch #ln directory
Only in u-boot-2010.12/arch/arm/include/asm: proc #ln directory
Only in u-boot-2010.12/board/samsung/smdk6400: config.tmp
Only in u-boot-2010.12/: .boards.depend
Only in u-boot-2010.12/include: asm #ln directory
Only in u-boot-2010.12/include: config.h
Only in u-boot-2010.12/include: config.mk
[cc@iZ23rrduja6Z ~]$ cat u-boot-2010.12/board/samsung/smdk6400/config.tmp
RAM_TEXT = 0x57e00000
[cc@iZ23rrduja6Z ~]$ cat u-boot-2010.12/include/config.h
/* Automatically generated - do not edit */
#define CONFIG_BOARDDIR board/samsung/smdk6400
#include <config_defaults.h>
#include <configs/smdk6400.h>
#include <asm/config.h>
[cc@iZ23rrduja6Z ~]$ cat u-boot-2010.12/include/config.mk //由mkconfig根据boards.cfg中或者Makefile中的 ARCH CPU BOARD VENCOR SOC 来生成
ARCH = arm
CPU = arm1176
BOARD = smdk6400
VENDOR = samsung
SOC = s3c64xx
CONFIG_NAND_U_BOOT = y
make -p target_config的作用:
-p 选项用于打印出所有的make 目标,这样就便于分析makefile结构
uboot的makefile目标分析:使用make -p 可以分析出所有的目标
make -d 的作用:
用于打印出 更多地makefile调试信息,当你不知道makefile的结构的时候,这些都是有用的
make 相当于make all
all: u-boot.srec u-boot.bin System.map u-boot-nand.bin
=================================================================================================================================
arm-ld 连接器参数说明: -T 用于指定连接脚本及连接参数,一般包含于LDFLAGS变量
LDFLAGS = -Bstatic -T $(obj)u-boot.lds $(PLATFORM_LDFLAGS) -Ttext $(CONFIG_SYS_TEXT_BASE)
u-boot.lds #D:\cc\u-boot-2010.12\board\samsung\smdk6400\u-boot-nand.lds
CONFIG_SYS_TEXT_BASE = $(RAM_TEXT) #在makefile中smdk6400_config段被定义
-T u-boot.lds -Ttext 0x57e00000 用于指定使用u-boot.lds连接脚本 ,-Ttext 0x57e00000 用与指定正文段从0x57e00000开始
==================================================================================================================
smdk6400的编译连接分三步:
1. make 编译连接成 /home/cc/u-boot-2010.12/u-boot.map /home/cc/u-boot-2010.12/u-boot ,再由objcopy生成 u-boot.srec u-boot.bin
2. make编译连接成/home/cc/u-boot-2010.12/nand_spl/u-boot-spl.map /home/cc/u-boot-2010.12/nand_spl/u-boot-spl ,再由objcopy生成/home/cc/u-boot-2010.12/nand_spl/u-boot-spl.bin /home/cc/u-boot-2010.12/nand_spl/u-boot-spl-16k.bin
3. cat nand_spl/u-boot-spl-16k.bin u-boot.bin > u-boot-nand.bin
因为nand不同于nor,不能直接存取内存,因此在cpu内部的stepping stone controller 自动读取前4k的nand到cpu内部来启动,然后再由前4k 拷贝其他的uboot到内存中,至此才能完全启动
======================================================================================================================
smdk6410 uboot第二阶段编译地址空间分配:
CONFIG_SYS_TEXT_BASE= 0x57e00000 #/u-boot-2010.12\Makefile
#define CONFIG_SYS_SDRAM_BASE 0x50000000 /*内存开始地址*/ D:\cc\u-boot-2010.12\include\configs\smdk6400.h
/* stack address for uboot*/
#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_SDRAM_BASE + 128 * 1024 *1024 - 4*1024) #D:\cc\u-boot-2010.12\include\configs\smdk6400.h
| |
| |
| stack1 |CONFIG_SYS_INIT_SP_ADDR = 0x57fff000 调用board_init_f时的stack
| |
| gd | global data 区域
| other |
| stack2 | 调用board_init_r时 的stack
| |
| |
| |
| |
| |
| |
| text |CONFIG_SYS_SDRAM_BASE = 0x50000000
| |
| |
===============================================================================
第二阶断启动流程:
reset: -------------- #D:\cc\u-boot-2010.12\arch\arm\cpu\arm1176\start.S
|
V
bl lowlevel_init ---- #D:\cc\u-boot-2010.12\board\samsung\smdk6400\lowlevel_init.S
|
V
bl board_init_f ----- # /home/cc/u-boot-2010.12/arch/arm/lib\board.c
|
V
init_sequence ---- #/home/cc/u-boot-2010.12/arch/arm/lib\board.c
| 其中有初始化serial:
| arch_cpu_init/board_early_init_f/timer_init/
| get_clocks/env_init/init_baudrate/serial_init
console_init_f/display_banner/print_cpuinfo/
checkboard/init_func_i2c/dram_init/arm_pci_init
|
V
relocate_code (addr_sp, id, addr); # board_init_f函数为board_init_r准备好堆栈运行空间后跳转到board_init_r
|
V
board_init_r --------- #/home/cc/u-boot-2010.12/arch/arm/lib\board.c
|
V
flash_init() ------------------#/home/cc/u-boot-2010.12/common/flash.c
|
V
nand_init() ------------------#/u-boot-2010.12/drivers/mtd/nand/nand.c
|
V
main_loop -------------- #/home/cc/u-boot-2010.12/common/main.c 到此进入uboot命令行
==========================================================================================================
第一阶段,前4k的地址空间分配
| |
| |
| stack1 |CONFIG_SYS_INIT_SP_ADDR = 0x57fff000 调用board_init_f时的stack
| |
| gd | global data 区域
| other |
| stack2 | 0x57c00000 调用nand_boot时 的stack
| |
| |
| |
| |
| |
| |
| text |CONFIG_SYS_SDRAM_BASE = 0x00000000
| |
| |
===============================================================
第一阶段,前4k启动流程
reset: -------------- #D:\cc\u-boot-2010.12\arch\arm\cpu\arm1176\start.S
|
V
bl lowlevel_init ---- #D:\cc\u-boot-2010.12\board\samsung\smdk6400\lowlevel_init.S
|
V
bl board_init_f ----- # /home/cc/u-boot-2010.12/nand_spl/nand_boot.c
|
V
relocate_code ; # 仅仅设置好sp
|
V
nand_boot --------- #/home/cc/u-boot-2010.12/nand_spl/nand_boot.c
|
V
nand_load --------- #/home/cc/u-boot-2010.12/nand_spl/nand_boot.c 加载4k以后的u-boot(第二阶段u-boot)到0x57e00000
|
V
uboot = (void *)CONFIG_SYS_NAND_U_BOOT_START; --------- #/home/cc/u-boot-2010.12/nand_spl/nand_boot.c 第二阶段u-boot的第一条指令
==========================================================================
main_loop中对命令行的执行:
U_BOOT_CMD宏用于定义一个uboot命令行,如下:宏的第一个参数bootm是 命令字,do_bootm是实际调用的执行函数
U_BOOT_CMD(
bootm,CONFIG_SYS_MAXARGS,1,do_bootm,
"boot application image from memory",
"[addr [arg ...]]\n - boot application image stored in memory\n"
"\tpassing arguments 'arg ...'; when booting a Linux kernel,\n"
"\t'arg' can be the address of an initrd image\n"
输入"bootm 0x50008000" 表示从0x50008000内存地址启动kernel ;argv[0]=bootm argv[1]=x50008000
int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
常用的uboot command
run 用于运行一个存储在evn中的命令,如 :run updatezImage
=====================================================
DM9000 网卡的支持
开发板的网口插上网线后,等不会亮,PC端的网卡也显示没有连线状态,但可以使用tftpboot ping 命令后自动启动网卡。这个问题原因不详细,待稍后解决。
============================================
nandflash基本知识介绍:
==增加 Target TQ2440 到uboot (以smdk2410为蓝本)================================
主makefie的修改
## ARM920T Systems
#########################################################################
TQ2440_config : unconfig
@$(XECHO) specifiy TQ2440_config;
@mkdir -p $(obj)include $(obj)board/samsung/TQ2440
@mkdir -p $(obj)nand_spl/board/samsung/TQ2440
@echo "#define CONFIG_NAND_U_BOOT" > $(obj)include/config.h
@echo "CONFIG_NAND_U_BOOT = y" >> $(obj)include/config.mk
# @if [ -z "$(findstring smdk6400_noUSB_config,$@)" ]; then \
# # echo "RAM_TEXT = 0x57e00000" >> $(obj)board/samsung/smdk6400/config.tmp;\
# else \
# # echo "RAM_TEXT = 0xc7e00000" >> $(obj)board/samsung/smdk6400/config.tmp;\
# fi
# # ARCH CPU BOARD VENDOR SOC
@$(MKCONFIG) TQ2440 arm arm920t TQ2440 samsung s3c24x0
@echo "CONFIG_NAND_U_BOOT = y" >> $(obj)include/config.mk
boards.cfg 的修改
# Target ARCH CPU Board name Vendor SoC Options
###########################################################################################################
qong arm arm1136 - davedenx mx31
mx31ads arm arm1136 - freescale mx31
imx31_litekit arm arm1136 - logicpd mx31
omap2420h4 arm arm1136 - ti omap24xx
tnetv107x_evm arm arm1176 tnetv107xevm ti tnetv107x
armadillo arm arm720t
ep7312 arm arm720t
impa7 arm arm720t
modnet50 arm arm720t
lpc2292sodimm arm arm720t - - lpc2292
SMN42 arm arm720t - siemens lpc2292
evb4510 arm arm720t - - s3c4510b
a320evb arm arm920t - faraday a320
at91rm9200ek arm arm920t at91rm9200ek atmel at91 at91rm9200ek
at91rm9200ek_ram arm arm920t at91rm9200ek atmel at91 at91rm9200ek:RAMBOOT
eb_cpux9k2 arm arm920t - BuS at91
cm41xx arm arm920t - - ks8695
sbc2410x arm arm920t - - s3c24x0
VCMA9 arm arm920t vcma9 mpl s3c24x0
smdk2400 arm arm920t - samsung s3c24x0
smdk2410 arm arm920t - samsung s3c24x0
TQ2440 arm arm920t - samsung s3c24x0
增加board对应的文件夹及文件
include/configs/TQ2440.h ------------config文件
board/samsung/TQ2440/TQ2440.c
board/samsung/TQ2440/config.mk
board/samsung/TQ2440/Makefile
board/samsung/TQ2440/lowlevel_init.S
board/samsung/TQ2440/flash.c
board/samsung/TQ2440 -------------该board对应的文件夹
nand_spl/board/samsung/TQ2440/u-boot.lds
nand_spl/board/samsung/TQ2440/config.mk
nand_spl/board/samsung/TQ2440/Makefile
nand_spl/board/samsung/TQ2440 --------------用于nandflash启动的文件夹
make
TQ2440 uboot第二阶段编译地址空间分配:(u_boot的大小定义为1M,紧接其后是4K的ENV空间)
CONFIG_SYS_TEXT_BASE= 0x33E80000 #/u-boot-2010.12\samsung\TQ2440\config.mk 内存62.5M的地方
#define CONFIG_SYS_UBOOT_SIZE (1024 * 1024) = 1M
#define CONFIG_NAND_ENV_DST (CONFIG_SYS_UBOOT_BASE + CONFIG_SYS_UBOOT_SIZE)
#define CONFIG_ENV_SIZE 0x10000= 4K
#define CONFIG_SYS_SDRAM_BASE 3000'0000 /*内存开始地址*/ D:\cc\u-boot-2010.12\include\configs\TQ2440.h
/* stack address for uboot*/ 最顶端的4k是堆栈空间
#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_SDRAM_BASE + 64 * 1024 *1024 - 4*1024) #D:\cc\u-boot-2010.12\include\configs\TQ2440.h
| |
| |
| stack1 |CONFIG_SYS_INIT_SP_ADDR = 0x33fff000 调用board_init_f时的stack
| |
| gd | global data 区域
| other |
| stack2 | 调用board_init_r时 的stack
| |
| |
| |
| |
| text |CONFIG_SYS_TEXT_BASE = 0x33E80000
| |
| |CONFIG_SYS_SDRAM_BASE = 0x30000000
| |
| |
==========================================================================================================
第一阶段,前4k的地址空间分配
| |
| gd |global data 区域
| stack1 |CONFIG_SYS_INIT_SP_ADDR = 0x33fff000 调用board_init_f时的stack
| |
| |
| other |
| stack2 | 0x57c00000 调用nand_boot时 的stack
| |
| |
| |
| |
| |
| |
| text |CONFIG_SYS_SDRAM_BASE = 0x00000000
| |
| |
第一阶段如果使用到serial,注意配置gd的地址,防止除以0的发生,正确配置波特率
/* value is calculated so : (int)(PCLK/16./baudrate) -1 */
reg = get_PCLK() / (16 * gd->baudrate) - 1;
======nand flash==========
- nandflash的特性
nandflash支持按page进行读写,写操作能把flash 1->0 而不能 0->1 ,所有每页只能写一次(记录已写),整块的页都用过后再整block擦除,然后置1
nandflash支持按block进行擦除,擦除可以支持把flash 全部置1
- nand.h 对外函数
nand_read nand_write
nand_block_isbad nand_erase nand_read_skip_bad nand_write_skip_bad nand_erase_opts
nand_lock nand_unlock board_nand_select_device
- nand_flash 调试经验
SC2440+K9F2G08U0A芯片第一次saveenv总是失败,第二次总能成功,
最后测试发现NAND_CMD_READID命令后NAND_CMD_STATUS的状态总出现写保护异常,必须NAND_CMD_READID再调用NAND_CMD_RESET后NAND_CMD_STATUS就正常
nand_get_flash_type, type->pagesize 0 writesize: 800(2k) oobsize: 40 erasesize: 20000(2k*64) busw: 0
writesize: 每页大小,这款芯片是2k
oobSize : 扩展页字节,这款芯片是64字节
erasesize: 块大小,这款芯片是2K*64page=128K
chip->page_shift:b(11位,用于右移后得到页地址)
chip->pagemask:1ffff (17位,A12~A28,用于确定页地址最大是17位)
chip->phys_erase_shift = chip->bbt_erase_shift:11 (17位,用于右移得到block地址,A18~A28)
chip->chip_shift:1c (28位,256M,用于右移后得到chipnr)
nand_read_oob--->nand_do_read_oob--->nand_read_oob_std
页读取指令,如果A11=1 表示仅仅读出oob的64个字节
nand_read_page_raw -----后缀raw 的意思是读取page+oob数据
nand_read_oob_std -----后缀oob_std的意思是读取oob数据
nand_read_page_hwecc ------后缀hwecc的意思是,类似于nand_read_page_raw,意思是ecc方式读出page+oob
- nandflash的坏块管理:
对于每个block来讲,一般第一页OOB的第六个字节0xFF表示该block是正常的,否则为坏block
对于2440板子配置的K9F2G08X0A,每个block的第一页和第二页的第一个字节为0xFF表示该block是正常,否则为坏block
- nand bad 命令
do_nand (cmd_nand.c)
|
V
nand_block_checkbad (nand.h)
|
V
chip->scan_bbt (nand_bbt.c)
|
V
nand_default_bbt (nand_bbt.c)
|
V
nand_scan_bbt (nand_bb.c)
|
V
create_bbt (nand_bbt.c)
|
V
mtd->read_oob (nand_base.c)
|
V
nand_read_oob (nand_base.c)
|
V
nand_do_read_oob (nand_base.c)
|
V
nand_read_oob_std (nand_base.c)
- nand info命令 、nand device命令
do_nand
|
V
nand_print_info
|
V
chip->numchips nand->name, nand->erasesize >> 10
- nand erase命令
nand erase的参数有两种 : offs+size ; partName: bios 会自动把partname转化为off+size
and erase[.spread] [clean] [off [size]] ---nand erase 0x500000 0x3C00000 ----nand erase bios
|
V
do_nand cmd_nand.c
|
V
nand_erase_opts cmd_nand.c
|
V
meminfo->erase cmd_nand.c
|
V
nand_erase nand_base.c
|
V
nand_erase_nand nand_base.c
|
V
chip->erase_cmd = single_erase_cmd; nand_base.c
erase的起始地址(off)必须是block的边界地址、长度(len)会被进位到整块
- nand read
对nand的访问最终会转化为page和column,如果column的最高位为0,则读出2048+64 ,那么可以寄存器NFCMMD中读取2048+64个字节;如果column的最高位是1,则只读出64字节的OOB;同理对于nand write也是一样的
nand read - addr off|partition size -----nand read 0x30008000 0x200000 0x300000
----nand read 0x30008000 bios 0x300000 (bios partname)
nand read - addr off|partition size 从 off 读取size 到内存addr ;第二块的起始地址为0x20000
|
V
do_nand ----------cmd_nand.c
|
V
nand_read_skip_bad ----------nand_uitl.c
|
V
nand_read ----------nand_base.c
|
V
nand_do_read_ops -----------nand_base.c
|
V
ecc.read_page
|
V
nand_read_page_hwecc(NAND_ECC_HW) nand_read_page_swecc(NAND_ECC_SOFT) ----nand_base.c
nand read 起始地址必须是页地址对齐的
s3c2410_nand_enable_hwecc ----------\
s3c2410_nand_calculate_ecc ----------|------ 用于读取页数据的时候有硬件ECC生成ecc结果
s3c2410_nand_correct_data ------------------用于比较oob区域的ecc和硬件生成的ecc
- nand ECC
struct nand_ecclayout 之解义 ,eccbytes,eccpos,eccfree
这里讨论下struct nand_ecclayout,即nand 的ecc布局问题,基于2.6.32-rc2.
该结构体定义如下:
struct nand_ecclayout {
uint32_t eccbytes; //表示使用几个ecc字节
uint32_t eccpos[128]; //表示ecc占用的位置,因为现在大页面4kbyte也就128个,所以这里写了128,
//以后有更大页面的,这里也要改了。
uint32_t oobavail; //有几个oob可用,这个跟下面的成员有点像,一般用下面的
struct nand_oobfree oobfree[MTD_MAX_OOBFREE_ENTRIES]; //定义oob有效个数,从哪开始等
};
给个例子:
static struct nand_ecclayout mylayout = {
#ifdef CONFIG_SYS_NAND_PAGE_2K
.eccbytes = 40,
.eccpos = {
24, 25, 26, 27, 28,
29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
49, 50, 51, 52, 53, 54, 55, 56, 57, 58,
59, 60, 61, 62, 63,
},
.oobfree = {
{.offset = 2, .length = 22, },
},
#endif
}
其中,.eccbytes = 40,跟初始化有关系,我们一般这样初始化:
nand->ecc.size = 512;
nand->ecc.bytes = 10;
恩,这下明朗了,我们需要每512个字节产生10个ecc字节,因此对2kbyte页面的flash来说,一页就是4个512,因此需要4*10=40个ecc字节。
.eccpos就是告诉驱动,这些ecc字节放在哪里,一般是按顺序存放,不要覆盖芯片默认的坏块标记位,对2kbyte的flash来说,厂家说是前两个即第0、1个字节是坏块标志。
所以分配为eccbytes和eccpos后,后面有个oobfree,这样看来也很明白了:
offset=2表示从第2个字节开始(因为前面2个是坏块标志啊~~),length=22表示(从offset开始)共22个ecc字节可以用户随便用。
这下一目了然了吧。
u-boot-2016.03 在mini2440上移植之nandflash 硬件ecc
无论是nand_write_page_hwecc函数,还是nand_write_page_hwecc函数,内部都有一个这样的for循环体:
for(i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
…… ……
}
其中三个主要变量的定义为:
eccsize= chip->ecc.size;
eccbytes= chip->ecc.bytes;
eccsteps= chip->ecc.steps;
下面我们就来介绍一下这个循环的作用:不同的CPU的NandFlash控制器一次所能完成的硬件ECC的字节数是不一样的,例如有些CPU一次只能完成512字节的硬件ECC,但如果开发板上的NandFlash每页有2048个字节,那该怎么办呢?这时就要用到一个循环体,通过循环多次来得到一页的硬件ECC。例如上面这种情况,就要循环4次(2048÷512=4),才能得到这个页内数据完整的硬件ECC。另外每一次硬件ECC,不同的CPU所生成的ECC字节数也是不同的,有的是3个字节,有的是4个字节。
那么,上面那三个变量的含义就分别为:
ecc.size:每一次硬件ECC所检验的字节个数 ------ #define CONFIG_SYS_NAND_ECCSIZE 2048
ecc.bytes:每一次硬件ECC所生成的字节个数 ------- #define CONFIG_SYS_NAND_ECCBYTES 4
ecc.steps:每一页需要进行硬件ECC的次数
对于S3C2440来说,一次硬件ECC可以检验2048个字节,并且生成4个字节的ECC,因此ecc.size应该为2048,ecc.bytes应该为4。而ecc.steps是通过计算得到的,即系统上电后能够获知NandFlash的每页的大小,用这个值除以ecc.size就等于ecc.steps。
include/configs/smdk2410.h文件内定义
#define CONFIG_SYS_NAND_ECCSIZE 2048
#define CONFIG_SYS_NAND_ECCBYTES 4
对于2440的板子来说,以下是2440板子的手册内容:
NAND Flash controller consists of four ECC (Error Correction Code) modules. The two ECC modules (one for
data[7:0] and the other for data[15:8]) can be used for (up to) 2048 bytes ECC Parity code generation, and the
others(one for data[7:0] and the other for data[15:8]) can be used for (up to) 16 bytes ECC Parity code generation.
— 28-bit ECC Parity Code = 22-bit Line parity + 6bit Column Parity
— 14-bit ECC Parity Code = 8-bit Line parity + 6bit Column Parity
对于ECCSIZE=256或者2048硬件ECC的实际的测试结果发现,不能达到纠正1bit的错误,所有只能采用soft_ecc 检测方法,测试方法参考:
http://www.51hei.com/bbs/dpj-32707-1.html
- nand read.oob
等同于nand read,只不过用于读取同地址后边的OOB部分
- nand write
nand write - addr off|partition size -----nand write 0x33000000 0x0200000 $(filesize);
-----nand write 0x33000000 bios $(filesize); bios(mdpartname)
nand write - addr off|partition size 从内存addr写数据 到off 共size ;第二块的起始地址为0x20000
|
V
do_nand ----------cmd_nand.c
|
V
nand_write_skip_bad ----------nand_uitl.c
|
V
nand_write ---------nand_base.c
|
V
nand_do_write_ops -----------nand_base.c
|
V
ecc.write_page
|
V
nand_write_page -----------nand_base.c
|
V
nand_write_page_hwecc(NAND_ECC_HW) nand_write_page_swecc(NAND_ECC_SOFT) ---nand_base.c
- nand write.oob
- nand dump
nand dump[.oob] off - dump page
|
V
do_nand ----------cmd_nand.c
|
V
nand_dump ----------cmd_nand.c
|
V
mtd->read_oob
|
V
nand_read_oob ---------nand_base.c
|
V
nand_do_read_ops ---------nand_base.c
|
V
chip->ecc.read_page_raw
|
V
nand_read_page_raw ---------nand_base.c
内存引脚及总线配置
nXBREQ 输入: nXBREQ 总线控制请求信号,允许另一个总线控制器请求控制本地总线,nXBACK信号激活指示已经得到总线控制权
nXBACK 输出:总线应答信号。
nWAIT 输入:nWAIT请求延长当前的总线周期,只要nWAIT为低,当前的总线周期不能完成。
=========DM9000网卡的配置=======================
- DM9000用到的引脚
S3C2440的nGCS4信号接到DM9000的AEN(Adress Enable)引脚,所以网卡的地址是从0x20000000 开始
S3C2440的LADDR2接到DM9000的CMD引脚,所以: 访问IO端口:0x20000000 访问数据端口:0x20000004
dev->init = dm9000_init;
dev->halt = dm9000_halt;
dev->send = dm9000_send;
dev->recv = dm9000_rx;
- 端口的读写-
/* Read a byte from I/O port */ 先把要读的寄存器地址写入DM9000_IO,再从DM9000_DATA 读出寄存器的数据
static u8 DM9000_ior(int reg)
{
DM9000_outb(reg, DM9000_IO);
return DM9000_inb(DM9000_DATA);
}
/* Write a byte to I/O port*/ 先把需要写的寄存器地址写入DM9000_IO,在把需要写入寄存器的数据写入到DM9000_DATA
static void DM9000_iow(int reg, u8 value)
{
DM9000_outb(reg, DM9000_IO);
DM9000_outb(value, DM9000_DATA);
}
- PHY层的读写
/* Read a word from phyxcer*/
static u16 phy_read(int reg)
{
u16 val;
/* Fill the phyxcer register into REG_0C */
DM9000_iow(DM9000_EPAR, DM9000_PHY | reg);
DM9000_iow(DM9000_EPCR, 0xc); /* Issue phyxcer read command */
udelay(100); /* Wait read complete */
DM9000_iow(DM9000_EPCR, 0x0); /* Clear phyxcer read command */
val = (DM9000_ior(DM9000_EPDRH) << 8) | DM9000_ior(DM9000_EPDRL);
/* The read data keeps on REG_0D & REG_0E */
DM9000_DBG("phy_read(0x%x): 0x%x\n", reg, val);
return val;
}
/* Write a word to phyxcer */
static void phy_write(int reg, u16 value)
{
/* Fill the phyxcer register into REG_0C */
DM9000_iow(DM9000_EPAR, DM9000_PHY | reg);
/* Fill the written data into REG_0D & REG_0E */
DM9000_iow(DM9000_EPDRL, (value & 0xff));
DM9000_iow(DM9000_EPDRH, ((value >> 8) & 0xff));
DM9000_iow(DM9000_EPCR, 0xa); /* Issue phyxcer write command */
udelay(500); /* Wait write complete */
DM9000_iow(DM9000_EPCR, 0x0); /* Clear phyxcer write command */
DM9000_DBG("phy_write(reg:0x%x, value:0x%x)\n", reg, value);
}
- EEPROM 的读写
EEPROM层的读写是通过DM9000的端口寄存器转接的,转接寄存器是DM9000_EPAR DM9000_EPCR DM9000_EPDRH DM9000_EPDRL
void dm9000_read_srom_word(int offset, u8 *to)
{
DM9000_iow(DM9000_EPAR, offset);
DM9000_iow(DM9000_EPCR, 0x4);
udelay(8000);
DM9000_iow(DM9000_EPCR, 0x0);
to[0] = DM9000_ior(DM9000_EPDRL);
to[1] = DM9000_ior(DM9000_EPDRH);
}
void dm9000_write_srom_word(int offset, u16 val)
{
DM9000_iow(DM9000_EPAR, offset);
DM9000_iow(DM9000_EPDRH, ((val >> 8) & 0xff));
DM9000_iow(DM9000_EPDRL, (val & 0xff));
DM9000_iow(DM9000_EPCR, 0x12);
udelay(8000);
DM9000_iow(DM9000_EPCR, 0);
}
- dm9000_send
- dm9000_rx
- 调试过程
DM9000: running in 16 bit mode
MAC: 0a:1b:2c:3d:4e:5f
ping
Loading: dm9000_send: length: 42
dm9000_send: 00: ff ff ff ff ff ff 0a 1b 以太网帧: MAC_dst MAC_src
dm9000_send: 08: 2c 3d 4e 5f 08 06 00 01
dm9000_send: 10: 08 00 06 04 00 01 0a 1b
dm9000_send: 18: 2c 3d 4e 5f c0 a8 01 06
dm9000_send: 20: 00 00 00 00 00 00 c0 a8
dm9000_send: 28: 01 08
transmit done
============LCD控制器=========
- LCD简介
(1)LCD(Liquid Crystal Display)俗称液晶。液晶是一种材料,液晶这种材料具有一种特点:可以在电信号的驱动下液晶分子进行旋转,旋转时会影响透光性,
因此我们可以在整个液晶面板后面用白光照(称为背光),可以通过不同电信号让液晶分子进行选择性的透光,此时在液晶面板前面看到的就是各种各样不同的
颜色,这就是LCD显示。
(2)主动发光和被动发光:有些显示器(譬如LED显示器、CRT显示器)自己本身会发光称为主动发光,有些(LCD)本身不会发光只会透光,需要背光的协助
才能看起来是发光的,称为被动发光。
(3)LCD显示原理和特点(液晶分子透光+背光):白光其实是由各种不同颜色的光组成的,所以白光被选择性透光之后可以产生各种不同颜色的光。而LCD的背
光采用的就是白光。
(4)液晶应用领域:电视机、电脑显示屏、手机显示屏、工业显示屏等····
(5)LCD的发展史(TN/STN/TFT)
TN最早。坏处是响应性不够好,有拖尾现象。
STN是TN的升级版。有效解决拖尾现象,显示更清晰。
TFT的最大特点就是超薄。TFT技术之上发展出来很多更新的技术。
- LCD框图
- LCD引脚
- LCD显示过程
这是整个一幅图的概括图,其中,深蓝色的部分为实际显示出来的部分,其余的部分是非显示部分,但是非显示部分对LCD来说也是必须的。
如图中的箭头部分,LCD是按照由上到下,由左到右的顺序显示的。图中HSYNC和VSYNC是跳转信号,在每一行结束,下一行开始的时候,会产生一个HSYNC信号,在一幅图(帧)显示完毕,要显示下一张图的时候,会发出VSYNC信号。

本文介绍U-Boot编译流程与配置,包括环境变量设置、makefile指令解析等内容。同时深入探讨NAND Flash的工作原理,涉及硬件ECC、坏块管理等关键技术。
4728

被折叠的 条评论
为什么被折叠?



